Commit 231daf07 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Control unison voice stacking via CC

parent e559666b
......@@ -28,7 +28,7 @@ Pitch bend has a range of +/- 2 semitones.
- MIDI program 0: poly mode (last note priority)
- MIDI program 1: poly mode (first note priority)
- MIDI program 2: unison (use CC 14 for detune)
- MIDI program 2: unison (use CC 14 for detune, CC 17 for number of stacked voices)
- MIDI program 3: mono (voice 1 only)
## License
......
......@@ -17,6 +17,7 @@ enum _cc {
CC_DETUNE = 14,
CC_PITCH_ENV_DECAY = 15,
CC_PITCH_ENV_AMOUNT = 16,
CC_STACKED_VOICES = 17,
CC_VIB_RATE = 76,
};
......
......@@ -10,13 +10,17 @@
INIT_LIST(held_notes, NUM_NOTES);
const float detune_factor[NUM_VOICES] = {
1.2,
-1.2,
0.6,
-0.6,
};
const float detune_factor[] = {1.2, -1.2, 0.6, -0.6, 0.9, -0.9, 0.3, -0.3};
static uint8_t detune_amount;
static uint8_t stacked_voices;
uint8_t active_voices(void) {
if (stacked_voices && stacked_voices < NUM_VOICES) {
return stacked_voices;
} else {
return NUM_VOICES;
}
}
void mono_init(void) { l_flush(held_notes); }
......@@ -26,7 +30,7 @@ void mono_set_pitch(void) {
}
uint8_t current_note = l_last(held_notes);
for_each_voice (v) {
for (uint8_t v = 0; v < active_voices(); v++) {
int16_t detune = detune_factor[v] * detune_amount;
pitch_set_note(v, current_note, detune);
}
......@@ -40,7 +44,10 @@ void mono_note_on(uint8_t n) {
l_pushr(held_notes, n);
mono_set_pitch();
for_each_voice (v) { gate_on(v); }
for (uint8_t v = 0; v < active_voices(); v++) {
gate_on(v);
}
}
void mono_note_off(uint8_t n) {
......@@ -54,11 +61,10 @@ void mono_note_off(uint8_t n) {
}
l_delete(held_notes, n);
if (l_empty(held_notes)) {
for_each_voice (v) { gate_off(v); }
} else {
mono_set_pitch();
for_each_voice (v) { gate_on(v); }
void (*f)(uint8_t) = l_empty(held_notes) ? gate_off : gate_on;
for (uint8_t v = 0; v < active_voices(); v++) {
f(v);
}
}
......@@ -67,5 +73,11 @@ void mono_control_change(uint8_t ctl, uint8_t val) {
case CC_DETUNE:
detune_amount = val;
break;
case CC_STACKED_VOICES:
stacked_voices = val;
for (uint8_t v = active_voices(); v < NUM_VOICES; v++) {
gate_off(v);
}
break;
}
}
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