|
|
@ -19,6 +19,11 @@ namespace ld = daisy; |
|
|
|
namespace dsp = daisysp; |
|
|
|
|
|
|
|
namespace Heck { |
|
|
|
namespace State { |
|
|
|
bool record_mode{ false }; |
|
|
|
bool clear_mode{ false }; |
|
|
|
} // namespace State
|
|
|
|
|
|
|
|
// =============================================================================================
|
|
|
|
// INIT
|
|
|
|
// =============================================================================================
|
|
|
@ -150,7 +155,7 @@ namespace Heck { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void tracks_midi_in(ld::MidiEvent msg) |
|
|
|
void midi_in_from_uart_polling(ld::MidiEvent msg) |
|
|
|
{ |
|
|
|
switch (msg.type) { |
|
|
|
case ld::MidiMessageType::NoteOn: { |
|
|
@ -159,44 +164,50 @@ namespace Heck { |
|
|
|
} |
|
|
|
} break; |
|
|
|
case ld::MidiMessageType::ControlChange: { |
|
|
|
sequencer.midi_in(msg); |
|
|
|
ld::ControlChangeEvent cc = msg.AsControlChange(); |
|
|
|
float val_normalized = cc.value / 127.; |
|
|
|
switch (cc.control_number) { |
|
|
|
// Pots
|
|
|
|
case Constants::MIDI_Mapping::TRACK_PITCH: |
|
|
|
tracks[cc.channel].instrument->ctl(0, val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_DECAY: |
|
|
|
tracks[cc.channel].decay(val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_PARAM1: |
|
|
|
tracks[cc.channel].instrument->ctl(2, val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_PARAM2: |
|
|
|
tracks[cc.channel].instrument->ctl(3, val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_FILTER: |
|
|
|
tracks[cc.channel].filter(val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_DRIVE: |
|
|
|
tracks[cc.channel].drive(val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_VOLUME: |
|
|
|
tracks[cc.channel].volume(val_normalized); |
|
|
|
break; |
|
|
|
// Switches
|
|
|
|
case Constants::MIDI_Mapping::TRACK_MODE1: |
|
|
|
tracks[cc.channel].instrument->switch_mode1(int(val_normalized * 2.)); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_MODE2: |
|
|
|
tracks[cc.channel].instrument->switch_mode2(int(val_normalized * 2.)); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_FILTERMODE: |
|
|
|
tracks[cc.channel].filtermode(val_normalized); |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
if (State::clear_mode) { |
|
|
|
ld::ControlChangeEvent cc = msg.AsControlChange(); |
|
|
|
hw.PrintLine("Clear: ch: %i, cc: %i",cc.channel,cc.control_number); |
|
|
|
sequencer.clear_track_cc(cc.channel, cc.control_number); |
|
|
|
} else { |
|
|
|
sequencer.midi_in(msg); |
|
|
|
float val_normalized = cc.value / 127.; |
|
|
|
switch (cc.control_number) { |
|
|
|
// Pots
|
|
|
|
case Constants::MIDI_Mapping::TRACK_PITCH: |
|
|
|
tracks[cc.channel].instrument->ctl(0, val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_DECAY: |
|
|
|
tracks[cc.channel].decay(val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_PARAM1: |
|
|
|
tracks[cc.channel].instrument->ctl(2, val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_PARAM2: |
|
|
|
tracks[cc.channel].instrument->ctl(3, val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_FILTER: |
|
|
|
tracks[cc.channel].filter(val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_DRIVE: |
|
|
|
tracks[cc.channel].drive(val_normalized); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_VOLUME: |
|
|
|
tracks[cc.channel].volume(val_normalized); |
|
|
|
break; |
|
|
|
// Switches
|
|
|
|
case Constants::MIDI_Mapping::TRACK_MODE1: |
|
|
|
tracks[cc.channel].instrument->switch_mode1(int(val_normalized * 2.)); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_MODE2: |
|
|
|
tracks[cc.channel].instrument->switch_mode2(int(val_normalized * 2.)); |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_FILTERMODE: |
|
|
|
tracks[cc.channel].filtermode(val_normalized); |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} break; |
|
|
|
default: { |
|
|
@ -205,20 +216,20 @@ namespace Heck { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void midi_async_handler() |
|
|
|
void midi_in_from_uart_interrupt() |
|
|
|
{ |
|
|
|
while (midi.HasEvents()) { |
|
|
|
ld::MidiEvent msg = midi.PopEvent(); |
|
|
|
event_log.PushBack(msg); |
|
|
|
tracks_midi_in(msg); |
|
|
|
midi_in_from_uart_polling(msg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void sequencer_midi_handler() |
|
|
|
void midi_in_from_sequencer() |
|
|
|
{ |
|
|
|
std::vector<ld::MidiEvent> queue = sequencer.midi_out(); |
|
|
|
for (ld::MidiEvent msg : queue) { |
|
|
|
tracks_midi_in(msg); |
|
|
|
midi_in_from_uart_polling(msg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -276,18 +287,26 @@ namespace Heck { |
|
|
|
sequencer.next_step(); |
|
|
|
} |
|
|
|
|
|
|
|
sequencer_midi_handler(); |
|
|
|
midi_async_handler(); |
|
|
|
midi_in_from_sequencer(); |
|
|
|
midi_in_from_uart_interrupt(); |
|
|
|
|
|
|
|
// REC
|
|
|
|
but_rec.Debounce(); |
|
|
|
but_record_new = but_rec.Pressed(); |
|
|
|
if (but_record_current != but_record_new) { |
|
|
|
// State changed
|
|
|
|
but_record_current = but_record_new; |
|
|
|
if (but_record_current) { |
|
|
|
hw.PrintLine("BUTTON RECORD ON"); |
|
|
|
if (State::clear_mode) { |
|
|
|
hw.PrintLine("CLEAR SEQUENCE"); |
|
|
|
sequencer.clear_sequence(); |
|
|
|
} else { |
|
|
|
hw.PrintLine("BUTTON RECORD ON"); |
|
|
|
State::record_mode = true; |
|
|
|
} |
|
|
|
} else { |
|
|
|
hw.PrintLine("BUTTON RECORD OFF"); |
|
|
|
State::record_mode = false; |
|
|
|
} |
|
|
|
sequencer.recording = but_record_current; |
|
|
|
} |
|
|
@ -296,15 +315,18 @@ namespace Heck { |
|
|
|
but_clear.Debounce(); |
|
|
|
but_clear_new = but_clear.Pressed(); |
|
|
|
if (but_clear_current != but_clear_new) { |
|
|
|
// State changed
|
|
|
|
but_clear_current = but_clear_new; |
|
|
|
if (but_clear_current) { |
|
|
|
hw.PrintLine("BUTTON CLEAR ON"); |
|
|
|
State::clear_mode = true; |
|
|
|
} else { |
|
|
|
hw.PrintLine("BUTTON CLEAR OFF"); |
|
|
|
sequencer.clear_sequence(); |
|
|
|
State::clear_mode = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (systick_now - midi_log_systick_last > 5) { |
|
|
|
midi_log_systick_last = systick_now; |
|
|
|
if (!event_log.IsEmpty()) { |
|
|
|