|
|
@ -21,6 +21,57 @@ |
|
|
|
|
|
|
|
float DSY_SDRAM_BSS sdram_block1[4000000]; |
|
|
|
|
|
|
|
namespace Heck::OSP { |
|
|
|
struct MidiLoggerBuffered { |
|
|
|
|
|
|
|
void push(const ld::MidiEvent& msg) |
|
|
|
{ |
|
|
|
event_log_.PushBack(msg); |
|
|
|
} |
|
|
|
|
|
|
|
void print() |
|
|
|
{ |
|
|
|
u32 time_now{ 0 }; |
|
|
|
if (!event_log_.IsEmpty()) { |
|
|
|
auto msg = event_log_.PopFront(); |
|
|
|
switch (msg.type) { |
|
|
|
case ld::MidiMessageType::SystemRealTime: { |
|
|
|
if constexpr (Constants::Developer::LOG_MIDI_REALTIME) { |
|
|
|
char outstr[256]; |
|
|
|
char rttype_str[32]; |
|
|
|
dz::GetMidiRTTypeAsString(msg, rttype_str); |
|
|
|
sprintf(outstr, "RT: type: %s\n", rttype_str); |
|
|
|
if (msg.srt_type != ld::TimingClock) { |
|
|
|
seed.PrintLine("%s", outstr); |
|
|
|
} |
|
|
|
} |
|
|
|
} break; |
|
|
|
case ld::NoteOn: |
|
|
|
case ld::NoteOff: |
|
|
|
case ld::MidiMessageType::ControlChange: { |
|
|
|
if constexpr (Constants::Developer::LOG_MIDI_NOTESANDCC) { |
|
|
|
char outstr[256]; |
|
|
|
char type_str[32]; |
|
|
|
dz::GetMidiTypeAsString(msg, type_str); |
|
|
|
sprintf( |
|
|
|
outstr, |
|
|
|
"time-last:\t%ld\ttype: %s\tChannel: %d\tData MSB: " |
|
|
|
"%d\tData LSB: %d\n", |
|
|
|
time_now, |
|
|
|
type_str, |
|
|
|
msg.channel, |
|
|
|
msg.data[0], |
|
|
|
msg.data[1]); |
|
|
|
seed.PrintLine("%s", outstr); |
|
|
|
} |
|
|
|
} break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ld::FIFO<ld::MidiEvent, 128> event_log_{}; |
|
|
|
}; |
|
|
|
} // namespace Heck::OSP
|
|
|
|
namespace Heck::OSP { |
|
|
|
namespace State { |
|
|
|
bool record_mode{ false }; |
|
|
@ -35,7 +86,7 @@ namespace Heck::OSP { |
|
|
|
ld::Switch but_clear{}; |
|
|
|
|
|
|
|
static ld::MidiUartHandler midi{}; |
|
|
|
static ld::FIFO<ld::MidiEvent, 128> event_log{}; |
|
|
|
static MidiLoggerBuffered logger_midi{}; |
|
|
|
|
|
|
|
Instrument::ZOsc instrument0{}; |
|
|
|
Instrument::FM instrument1{}; |
|
|
@ -140,7 +191,7 @@ namespace Heck::OSP { |
|
|
|
|
|
|
|
void midi_realtime_handler(const ld::MidiEvent& msg) |
|
|
|
{ |
|
|
|
event_log.PushBack(msg); |
|
|
|
logger_midi.push(msg); |
|
|
|
switch (msg.srt_type) { |
|
|
|
case ld::TimingClock: |
|
|
|
clock.tick_advance(); |
|
|
@ -231,7 +282,7 @@ namespace Heck::OSP { |
|
|
|
{ |
|
|
|
while (midi.HasEvents()) { |
|
|
|
ld::MidiEvent msg = midi.PopEvent(); |
|
|
|
event_log.PushBack(msg); |
|
|
|
logger_midi.push(msg); |
|
|
|
midi_dispatch(msg, false); |
|
|
|
} |
|
|
|
} |
|
|
@ -244,59 +295,25 @@ namespace Heck::OSP { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void task_heartbeat_func(u32) |
|
|
|
{ |
|
|
|
static bool heartbeat_led_state{ false }; |
|
|
|
heartbeat_led_state = !heartbeat_led_state; |
|
|
|
seed.SetLed(heartbeat_led_state); |
|
|
|
} |
|
|
|
|
|
|
|
void task_logger_midi_print_func(u32) { |
|
|
|
logger_midi.print(); |
|
|
|
} |
|
|
|
|
|
|
|
dz::PeriodicTaskCT<task_heartbeat_func, 100> task_heartbeat{}; |
|
|
|
dz::PeriodicTaskCT<task_logger_midi_print_func, 5> task_logger_midi_print{}; |
|
|
|
|
|
|
|
|
|
|
|
void mainloop() |
|
|
|
{ |
|
|
|
seed.PrintLine("Entering MainLoop"); |
|
|
|
u32 time_boot_ms{}; |
|
|
|
|
|
|
|
bool heartbeat_led_state{ false }; |
|
|
|
|
|
|
|
dz::SWTimer heartbeat{}; |
|
|
|
heartbeat.set_period(100); |
|
|
|
heartbeat.set_callback([&heartbeat_led_state](u32 time_now) { |
|
|
|
heartbeat_led_state = !heartbeat_led_state; |
|
|
|
seed.SetLed(heartbeat_led_state); |
|
|
|
}); |
|
|
|
|
|
|
|
dz::SWTimer async_log_tx{}; |
|
|
|
async_log_tx.set_period(5); |
|
|
|
async_log_tx.set_callback([](u32 time_now) { |
|
|
|
if (!event_log.IsEmpty()) { |
|
|
|
auto msg = event_log.PopFront(); |
|
|
|
switch (msg.type) { |
|
|
|
case ld::MidiMessageType::SystemRealTime: { |
|
|
|
if constexpr (Constants::Developer::LOG_MIDI_REALTIME) { |
|
|
|
char outstr[256]; |
|
|
|
char rttype_str[32]; |
|
|
|
dz::GetMidiRTTypeAsString(msg, rttype_str); |
|
|
|
sprintf(outstr, "RT: type: %s\n", rttype_str); |
|
|
|
if (msg.srt_type != ld::TimingClock) { |
|
|
|
seed.PrintLine("%s", outstr); |
|
|
|
} |
|
|
|
} |
|
|
|
} break; |
|
|
|
case ld::NoteOn: |
|
|
|
case ld::NoteOff: |
|
|
|
case ld::MidiMessageType::ControlChange: { |
|
|
|
if constexpr (Constants::Developer::LOG_MIDI_NOTESANDCC) { |
|
|
|
char outstr[256]; |
|
|
|
char type_str[32]; |
|
|
|
dz::GetMidiTypeAsString(msg, type_str); |
|
|
|
sprintf( |
|
|
|
outstr, |
|
|
|
"time-last:\t%ld\ttype: %s\tChannel: %d\tData MSB: " |
|
|
|
"%d\tData LSB: %d\n", |
|
|
|
time_now, |
|
|
|
type_str, |
|
|
|
msg.channel, |
|
|
|
msg.data[0], |
|
|
|
msg.data[1]); |
|
|
|
seed.PrintLine("%s", outstr); |
|
|
|
} |
|
|
|
} break; |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
u32 uptime_ms{}; |
|
|
|
|
|
|
|
bool but_record_new{ false }; |
|
|
|
bool but_record_current{ false }; |
|
|
@ -321,7 +338,7 @@ namespace Heck::OSP { |
|
|
|
// if update is different
|
|
|
|
// Update state
|
|
|
|
// handle change
|
|
|
|
time_boot_ms = ld::System::GetNow(); |
|
|
|
uptime_ms = ld::System::GetNow(); |
|
|
|
|
|
|
|
clock_time_new = clock.tick_infinite(); |
|
|
|
if (clock_time_current != clock_time_new) { |
|
|
@ -384,8 +401,8 @@ namespace Heck::OSP { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
async_log_tx.is_it_already_time_again(time_boot_ms); |
|
|
|
heartbeat.is_it_already_time_again(time_boot_ms); |
|
|
|
task_logger_midi_print.run_pending(uptime_ms); |
|
|
|
task_heartbeat.run_pending(uptime_ms); |
|
|
|
} |
|
|
|
} |
|
|
|
} // namespace Heck::OSP
|
|
|
|