Commit d2385e6c authored by Jacob Vosmaer's avatar Jacob Vosmaer

Separate pitch from dac logic

parent 812bf7bd
PRG = crowbx
OBJ = crowbx.o midi.o dac.o uart.o gate.o poly.o mono.o list.o vibrato.o poly2.o poly_voice.o
OBJ = crowbx.o midi.o dac.o uart.o gate.o poly.o mono.o list.o vibrato.o poly2.o poly_voice.o safe_add.o pitch.o
MCU_TARGET = atmega328p
#MCU_TARGET = at90s2313
#MCU_TARGET = at90s2333
......
......@@ -2,6 +2,7 @@
#include <util/delay.h>
#include "dac.h"
#include "voice.h"
#include "safe_add.h"
const uint8_t dac_chan[NUM_VOICES] = {2, 3, 4, 5};
......@@ -63,8 +64,18 @@ spi_io(uint8_t data)
#define SCK PORTB5
#define SS PORTB2
uint8_t
dac_command_set(uint8_t voice)
{
if (voice >= NUM_VOICES) {
return 0;
}
return 0b00110000 | dac_chan[voice];
}
void
send_dac(uint8_t command, uint16_t data)
dac_send(uint8_t command, uint16_t data)
{
PORTB &= ~_BV(DAC_SYNC);
spi_io(command);
......@@ -98,34 +109,16 @@ dac_init(void)
_delay_ms(1); // let dac boot up
send_dac(0b01000000, 0b1111000000001111); // power down dacs 0, 1, 6, 7
dac_send(0b01000000, 0b1111000000001111); // power down dacs 0, 1, 6, 7
}
#define MIDI_LOWEST 24
uint16_t
safe_add(uint16_t x, int16_t delta)
{
if (delta < 0) {
uint16_t sub = -delta;
if (x < sub) {
return 0;
}
return x - sub;
}
uint16_t add = delta;
if (UINT16_MAX - x < add) {
return UINT16_MAX;
}
return x + add;
}
void
dac_set_note2(uint8_t voice, uint8_t note, int16_t detune, uint16_t bend)
dac_note_pitch(uint8_t voice, uint8_t note)
{
if (voice >= NUM_VOICES) {
return;
return 0;
}
// Don't go lower than "C0"
......@@ -138,18 +131,11 @@ dac_set_note2(uint8_t voice, uint8_t note, int16_t detune, uint16_t bend)
uint8_t octave = (note - MIDI_LOWEST) / NUM_SEMITONES;
if (octave > 7) {
return;
return 0;
}
uint16_t data = safe_add(
return safe_add(
dac_offset[voice] + octave * dac_scale[voice],
dac_semitones[(note - MIDI_LOWEST) % NUM_SEMITONES]
);
data = safe_add(data, detune);
float bend_factor = ((int16_t) (bend & BEND_MAX) - BEND_CENTER) / ((float) BEND_MAX);
int16_t bend_data = dac_semitones[4] * bend_factor;
data = safe_add(data, bend_data);
send_dac(0b00110000 | dac_chan[voice], data);
}
......@@ -3,13 +3,10 @@
#include <stdint.h>
void dac_set_note2(uint8_t voice, uint8_t note, int16_t detune, uint16_t bend);
void dac_init(void);
uint16_t dac_pitch_delta(uint8_t semitones);
enum {
BEND_CENTER = 8192,
BEND_MAX = 16383,
};
void dac_send(uint8_t command, uint16_t data);
uint16_t dac_note_pitch(uint8_t voice, uint8_t note);
uint8_t dac_command_set(uint8_t voice);
#endif
#include "mono.h"
#include "dac.h"
#include "pitch.h"
#include "gate.h"
#include "voice.h"
#include "list.h"
......@@ -58,7 +58,7 @@ mono_set_pitch(void)
for_each_voice(v) {
int16_t detune = detune_factor[v] * detune_amount;
detune += vibrato_detune();
dac_set_note2(v, current_note, detune, current_bend);
pitch_set_note(v, current_note, detune, current_bend);
}
}
......
#include "pitch.h"
#include "voice.h"
#include "dac.h"
#include "safe_add.h"
void
pitch_set_note(uint8_t voice, uint8_t note, int16_t detune, uint16_t bend)
{
if ((voice >= NUM_VOICES) || (note > 127)) {
return;
}
uint16_t data = dac_note_pitch(voice, note);
data = safe_add(data, detune);
float bend_factor = ((int16_t) (bend & BEND_MAX) - BEND_CENTER) / ((float) BEND_MAX);
int16_t bend_data = dac_pitch_delta(4) * bend_factor;
data = safe_add(data, bend_data);
dac_send(dac_command_set(voice), data);
}
#ifndef pitch_h
#define pitch_h
#include <stdint.h>
void pitch_set_note(uint8_t voice, uint8_t note, int16_t detune, uint16_t bend);
uint16_t pitch_delta(uint8_t semitones);
enum {
BEND_CENTER = 8192,
BEND_MAX = 16383,
};
#endif
#include "dac.h"
#include "pitch.h"
#include "poly.h"
#include "gate.h"
#include "voice.h"
......@@ -23,7 +23,7 @@ poly_init(void)
void
poly_set_pitch(uint8_t v, uint8_t note)
{
dac_set_note2(v, note, vibrato_detune(), current_bend);
pitch_set_note(v, note, vibrato_detune(), current_bend);
}
void
......
#include "dac.h"
#include "pitch.h"
#include "poly2.h"
#include "gate.h"
#include "voice.h"
......@@ -31,7 +31,7 @@ poly2_init(void)
void
poly2_set_pitch(uint8_t v, uint8_t note)
{
dac_set_note2(v, note, vibrato_detune(), current_bend);
pitch_set_note(v, note, vibrato_detune(), current_bend);
}
void
......
#include "safe_add.h"
uint16_t
safe_add(uint16_t x, int16_t delta)
{
if (delta < 0) {
uint16_t sub = -delta;
if (x < sub) {
return 0;
}
return x - sub;
}
uint16_t add = delta;
if (UINT16_MAX - x < add) {
return UINT16_MAX;
}
return x + add;
}
#ifndef safe_add_h
#define safe_add_h
#include <stdint.h>
uint16_t safe_add(uint16_t x, int16_t delta);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment