|
|
@ -14,7 +14,14 @@ |
|
|
|
#include "instr_hihat.hh" |
|
|
|
#include "instr_zosc.hh" |
|
|
|
|
|
|
|
namespace Heck { |
|
|
|
// DTCM_MEM_SECTION
|
|
|
|
// DMA_BUFFER_MEM_SECTION
|
|
|
|
// DSY_SDRAM_DATA
|
|
|
|
// DSY_SDRAM_BSS
|
|
|
|
|
|
|
|
float DSY_SDRAM_BSS sdram_block1[4000000]; |
|
|
|
|
|
|
|
namespace Heck::OSP { |
|
|
|
namespace State { |
|
|
|
bool record_mode{ false }; |
|
|
|
bool clear_mode{ false }; |
|
|
@ -88,43 +95,45 @@ namespace Heck { |
|
|
|
// =============================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
void audio_callback(ld::AudioHandle::InputBuffer in, ld::AudioHandle::OutputBuffer out, size_t size) |
|
|
|
Sig::RingBuffer<30000> buff1{}; |
|
|
|
Sig::Delay101<30000> dly1{}; |
|
|
|
|
|
|
|
volatile float sig_in[Constants::AUDIO_BUFFERSIZE]; |
|
|
|
volatile float sig_out[Constants::AUDIO_BUFFERSIZE]; |
|
|
|
volatile float delaytime{}; |
|
|
|
volatile float delayfb{}; |
|
|
|
|
|
|
|
float sig_dly1{}; |
|
|
|
float sig_osp{}; |
|
|
|
float sig_bus{}; |
|
|
|
|
|
|
|
void process_signals() |
|
|
|
{ |
|
|
|
float sig_out{}; |
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
|
for (int i = 0; i < Constants::TRACK_COUNT; i++) { |
|
|
|
sig_out += tracks[i].nextsample(); |
|
|
|
} |
|
|
|
sig_out *= 0.1; |
|
|
|
out[0][i] = sig_out; |
|
|
|
for (size_t i = 0; i < Constants::AUDIO_BUFFERSIZE; i++) { |
|
|
|
sig_osp = tracks[0].nextsample(); |
|
|
|
sig_osp += tracks[1].nextsample(); |
|
|
|
sig_osp += tracks[2].nextsample(); |
|
|
|
sig_osp += tracks[3].nextsample(); |
|
|
|
|
|
|
|
sig_bus = sig_osp + sig_in[i]; |
|
|
|
dly1.delayfb_ = delayfb; |
|
|
|
dly1.delaytime_ = delaytime; |
|
|
|
sig_bus += dly1.process(sig_bus); |
|
|
|
sig_out[i] = sig_bus; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void audio_callback(ld::AudioHandle::InputBuffer in, ld::AudioHandle::OutputBuffer out, size_t size) |
|
|
|
{ |
|
|
|
// Output 1
|
|
|
|
{ |
|
|
|
float sig_out{}; |
|
|
|
float sig_osp{}; |
|
|
|
float sig_ext_in_1{}; |
|
|
|
float sig_ext_in_2{}; |
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
|
for (int i = 0; i < Constants::TRACK_COUNT; i++) { |
|
|
|
sig_osp += tracks[i].nextsample(); |
|
|
|
} |
|
|
|
sig_osp /= Constants::TRACK_COUNT; |
|
|
|
sig_ext_in_1 = in[0][i]; |
|
|
|
sig_ext_in_2 = in[1][i]; |
|
|
|
out[0][i] = sig_osp + sig_ext_in_1 + sig_ext_in_2 / 3.; |
|
|
|
out[1][i] = out[0][i]; |
|
|
|
} |
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
|
sig_in[i] = in[0][i]; |
|
|
|
} |
|
|
|
|
|
|
|
// Output 2
|
|
|
|
if constexpr (false) { |
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
|
out[1][i] = in[1][i]; |
|
|
|
} |
|
|
|
process_signals(); |
|
|
|
|
|
|
|
for (size_t i = 0; i < size; i++) { |
|
|
|
out[0][i] = sig_out[i]; |
|
|
|
out[1][i] = sig_out[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -153,7 +162,7 @@ namespace Heck { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void midi_in_from_uart_polling(ld::MidiEvent msg, bool from_seq) |
|
|
|
void midi_dispatch(ld::MidiEvent msg, bool from_seq) |
|
|
|
{ |
|
|
|
switch (msg.type) { |
|
|
|
case ld::MidiMessageType::NoteOn: { |
|
|
@ -188,9 +197,11 @@ namespace Heck { |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_FILTER: |
|
|
|
tracks[cc.channel].filter(val_normalized); |
|
|
|
delaytime = val_normalized; |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_DRIVE: |
|
|
|
tracks[cc.channel].drive(val_normalized); |
|
|
|
delayfb = val_normalized; |
|
|
|
break; |
|
|
|
case Constants::MIDI_Mapping::TRACK_VOLUME: |
|
|
|
tracks[cc.channel].volume(val_normalized); |
|
|
@ -216,20 +227,20 @@ namespace Heck { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void midi_in_from_uart_interrupt() |
|
|
|
void midi_from_uart() |
|
|
|
{ |
|
|
|
while (midi.HasEvents()) { |
|
|
|
ld::MidiEvent msg = midi.PopEvent(); |
|
|
|
event_log.PushBack(msg); |
|
|
|
midi_in_from_uart_polling(msg, false); |
|
|
|
midi_dispatch(msg, false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void midi_in_from_sequencer() |
|
|
|
void midi_from_sequencer() |
|
|
|
{ |
|
|
|
std::vector<ld::MidiEvent> queue = sequencer.midi_out(); |
|
|
|
for (ld::MidiEvent msg : queue) { |
|
|
|
midi_in_from_uart_polling(msg, true); |
|
|
|
midi_dispatch(msg, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -240,14 +251,14 @@ namespace Heck { |
|
|
|
|
|
|
|
bool heartbeat_led_state{ false }; |
|
|
|
|
|
|
|
SWTimer heartbeat{}; |
|
|
|
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); |
|
|
|
}); |
|
|
|
|
|
|
|
SWTimer async_log_tx{}; |
|
|
|
dz::SWTimer async_log_tx{}; |
|
|
|
async_log_tx.set_period(5); |
|
|
|
async_log_tx.set_callback([](u32 time_now) { |
|
|
|
if (!event_log.IsEmpty()) { |
|
|
@ -257,7 +268,7 @@ namespace Heck { |
|
|
|
if constexpr (Constants::Developer::LOG_MIDI_REALTIME) { |
|
|
|
char outstr[256]; |
|
|
|
char rttype_str[32]; |
|
|
|
GetMidiRTTypeAsString(msg, rttype_str); |
|
|
|
dz::GetMidiRTTypeAsString(msg, rttype_str); |
|
|
|
sprintf(outstr, "RT: type: %s\n", rttype_str); |
|
|
|
if (msg.srt_type != ld::TimingClock) { |
|
|
|
seed.PrintLine("%s", outstr); |
|
|
@ -270,7 +281,7 @@ namespace Heck { |
|
|
|
if constexpr (Constants::Developer::LOG_MIDI_NOTESANDCC) { |
|
|
|
char outstr[256]; |
|
|
|
char type_str[32]; |
|
|
|
GetMidiTypeAsString(msg, type_str); |
|
|
|
dz::GetMidiTypeAsString(msg, type_str); |
|
|
|
sprintf( |
|
|
|
outstr, |
|
|
|
"time-last:\t%ld\ttype: %s\tChannel: %d\tData MSB: " |
|
|
@ -302,6 +313,8 @@ namespace Heck { |
|
|
|
int clock_16n_new{}; |
|
|
|
int clock_16n_current{}; |
|
|
|
|
|
|
|
buff1.init(sdram_block1); |
|
|
|
dly1.init(&buff1); |
|
|
|
|
|
|
|
while (1) { |
|
|
|
// Get current values for state
|
|
|
@ -332,8 +345,8 @@ namespace Heck { |
|
|
|
sequencer.next_step(); |
|
|
|
} |
|
|
|
|
|
|
|
midi_in_from_sequencer(); |
|
|
|
midi_in_from_uart_interrupt(); |
|
|
|
midi_from_sequencer(); |
|
|
|
midi_from_uart(); |
|
|
|
|
|
|
|
// REC
|
|
|
|
but_rec.Debounce(); |
|
|
|