Commit 883a2bbc authored by Jacob Vosmaer's avatar Jacob Vosmaer

Add vibrato (mod wheel) to mono mode

parent efbc9d2d
......@@ -35,6 +35,11 @@ void (*pitch_bend[NUM_PGM])(uint16_t bend) = {
mono_pitch_bend,
};
void (*update_clock[NUM_PGM])(uint8_t delta) = {
poly_update_clock,
mono_update_clock,
};
void
io_init(void)
{
......@@ -48,6 +53,13 @@ io_init(void)
DDRD = _BV(PORTD1) | _BV(PORTD2) | _BV(PORTD3) | _BV(PORTD4) | _BV(PORTD5) | _BV(PORTD6) | _BV(PORTD7);
}
void
clock_init(void)
{
// Run Timer0 (8-bit timer) at F_CPU/256 = 62.5 kHz
TCCR0B |= _BV(CS00) | _BV(CS02);
}
void
program_change(uint8_t pgm)
{
......@@ -77,12 +89,20 @@ main(void)
io_init();
dac_init();
midi_init();
clock_init();
program_change(PGM_POLY);
uint8_t prev_clock = 0;
for (;;) {
uint8_t clock = TCNT0;
(*update_clock[current_program])(clock - prev_clock);
prev_clock = clock;
if (!midi_read()) {
continue;
}
uint16_t data = midi_data();
if (midi_status() == MIDI_NOTE_ON) {
......
......@@ -21,8 +21,9 @@ const uint16_t dac_scale[NUM_VOICES] = {
8384,
};
#define NUM_SEMITONES 12
// This tuning is chosen to be 'good enough' for the 8382-8384 scale range above
const int16_t dac_semitones[12] = {
const int16_t dac_semitones[NUM_SEMITONES] = {
0,
699,
1397,
......@@ -37,6 +38,16 @@ const int16_t dac_semitones[12] = {
7684,
};
uint16_t
dac_pitch_delta(uint8_t semitones)
{
if (semitones >= NUM_SEMITONES) {
semitones = NUM_SEMITONES -1;
}
return dac_semitones[semitones];
}
uint8_t
spi_io(uint8_t data)
{
......@@ -61,7 +72,6 @@ send_dac(uint8_t command, uint16_t data)
PORTB |= _BV(DAC_SYNC);
}
void
spi_init(void)
{
......@@ -125,14 +135,14 @@ dac_set_note2(uint8_t voice, uint8_t note, int16_t detune, uint16_t bend)
note = 127;
}
uint8_t octave = (note - MIDI_LOWEST) / 12;
uint8_t octave = (note - MIDI_LOWEST) / NUM_SEMITONES;
if (octave > 7) {
return;
}
uint16_t data = safe_add(
dac_offset[voice] + octave * dac_scale[voice],
dac_semitones[(note - MIDI_LOWEST) % 12]
dac_semitones[(note - MIDI_LOWEST) % NUM_SEMITONES]
);
data = safe_add(data, detune);
......
......@@ -5,6 +5,7 @@
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);
#define BEND_CENTER 8192
#define BEND_MAX 16383
......
......@@ -15,7 +15,7 @@ static struct list notes = {
static uint16_t current_bend;
void mono_set_pitch(uint8_t n);
void mono_set_pitch(void);
const uint8_t detune_factor[NUM_VOICES] = {
10,
......@@ -25,12 +25,20 @@ const uint8_t detune_factor[NUM_VOICES] = {
};
static uint8_t detune_amount;
static uint8_t mod_wheel;
static uint16_t phase;
static uint8_t phase_inc;
static int16_t vibrato;
void
mono_init(void)
{
l_flush(&notes);
detune_amount = 0;
current_bend = BEND_CENTER;
mod_wheel = 0;
vibrato = 0;
phase_inc = 0;
}
void
......@@ -42,17 +50,24 @@ mono_note_on(uint8_t n)
l_push(&notes, n);
mono_set_pitch(n);
mono_set_pitch();
for (uint8_t v = 0; v < NUM_VOICES; v++) {
gate_on(v);
}
}
void
mono_set_pitch(uint8_t n)
mono_set_pitch(void)
{
if (l_empty(&notes)) {
return;
}
uint8_t n = l_first(&notes);
for (uint8_t v = 0; v < NUM_VOICES; v++) {
dac_set_note2(v, n, (detune_factor[v] * detune_amount)/128, current_bend);
int16_t detune = (detune_factor[v] * detune_amount)/128;
detune += vibrato;
dac_set_note2(v, n, detune, current_bend);
}
}
......@@ -72,20 +87,29 @@ mono_note_off(uint8_t n)
return;
}
mono_set_pitch(l_first(&notes));
mono_set_pitch();
}
#define CC_DETUNE 14
enum _cc {
CC_MOD_WHEEL = 1,
CC_DETUNE = 14,
CC_VIB_RATE = 76,
};
void
mono_control_change(uint8_t ctl, uint8_t val)
{
if (ctl == CC_DETUNE) {
switch (ctl) {
case CC_DETUNE:
detune_amount = val;
if (!l_empty(&notes)) {
mono_set_pitch(l_first(&notes));
}
mono_set_pitch();
break;
case CC_MOD_WHEEL:
mod_wheel = val;
break;
case CC_VIB_RATE:
phase_inc = val;
break;
}
}
......@@ -93,8 +117,41 @@ void
mono_pitch_bend(uint16_t bend)
{
current_bend = bend;
mono_set_pitch();
}
if (!l_empty(&notes)) {
mono_set_pitch(l_first(&notes));
#define VIB_MID (INT16_MAX >> 1)
void
mono_update_vibrato(void)
{
int16_t old_vibrato = vibrato;
if (phase < INT16_MAX) {
vibrato = phase - VIB_MID;
} else {
vibrato = phase - INT16_MAX;
vibrato = INT16_MAX - vibrato;
vibrato -= VIB_MID;
}
float pitch_factor = dac_pitch_delta(2) / ((float) INT16_MAX);
vibrato *= pitch_factor;
float mod_factor = mod_wheel / 127.0;
vibrato *= mod_factor;
if (vibrato == old_vibrato) {
return;
}
mono_set_pitch();
}
void
mono_update_clock(uint8_t delta)
{
phase += delta * (1 + phase_inc/2.0);
mono_update_vibrato();
}
......@@ -8,5 +8,6 @@ void mono_note_on(uint8_t note);
void mono_note_off(uint8_t note);
void mono_control_change(uint8_t ctl, uint8_t val);
void mono_pitch_bend(uint16_t bend);
void mono_update_clock(uint8_t delta);
#endif
......@@ -58,3 +58,9 @@ poly_pitch_bend(uint16_t bend)
poly_set_pitch(v, notes[v]);
}
}
void
poly_update_clock(uint8_t delta)
{
// nop
}
......@@ -8,5 +8,6 @@ void poly_note_on(uint8_t note);
void poly_note_off(uint8_t note);
void poly_control_change(uint8_t ctl, uint8_t val);
void poly_pitch_bend(uint16_t bend);
void poly_update_clock(uint8_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