|
|
@ -14,146 +14,174 @@ |
|
|
|
|
|
|
|
#define TRACK_COUNT 4 |
|
|
|
|
|
|
|
using namespace daisy; |
|
|
|
using namespace daisysp; |
|
|
|
namespace Heck { |
|
|
|
// =============================================================================================
|
|
|
|
// INIT
|
|
|
|
// =============================================================================================
|
|
|
|
using namespace daisy; |
|
|
|
using namespace daisysp; |
|
|
|
|
|
|
|
static DaisySeed hw{}; |
|
|
|
static MidiUartHandler midi{}; |
|
|
|
static FIFO<MidiEvent, 128> event_log{}; |
|
|
|
|
|
|
|
Instrument::Noise instrument0{}; |
|
|
|
Instrument::FM instrument1{}; |
|
|
|
Instrument::FM instrument2{}; |
|
|
|
Instrument::Kick instrument3{}; |
|
|
|
|
|
|
|
std::array<std::shared_ptr<PerkonsInstrumentInterface>, TRACK_COUNT> tracks{}; |
|
|
|
|
|
|
|
// function prototypes
|
|
|
|
int create_tracks(float samplerate); |
|
|
|
void AudioCallback( |
|
|
|
AudioHandle::InterleavingInputBuffer in, |
|
|
|
AudioHandle::InterleavingOutputBuffer out, |
|
|
|
size_t size); |
|
|
|
|
|
|
|
|
|
|
|
void init() |
|
|
|
{ |
|
|
|
int* npt = nullptr; |
|
|
|
int i = *npt; |
|
|
|
|
|
|
|
hw.Configure(); |
|
|
|
hw.Init(); |
|
|
|
hw.StartLog(true); |
|
|
|
|
|
|
|
// Start Audio
|
|
|
|
hw.SetAudioBlockSize(4); |
|
|
|
float samplerate = hw.AudioSampleRate(); |
|
|
|
|
|
|
|
hw.PrintLine("Creating Tracks"); |
|
|
|
create_tracks(samplerate); |
|
|
|
|
|
|
|
hw.PrintLine("Starting Audio"); |
|
|
|
hw.StartAudio(AudioCallback); |
|
|
|
|
|
|
|
|
|
|
|
// MIDI RX
|
|
|
|
hw.PrintLine("Setting up MIDI"); |
|
|
|
MidiUartHandler::Config midi_config; |
|
|
|
midi.Init(midi_config); |
|
|
|
u32 systick_last_rt_msg{}; |
|
|
|
midi.realtime_callback = [&systick_last_rt_msg](MidiEvent& msg) { |
|
|
|
u32 systick_now = System::GetNow(); |
|
|
|
u32 systick_since_last = systick_now - systick_last_rt_msg; |
|
|
|
systick_last_rt_msg = systick_now; |
|
|
|
|
|
|
|
char outstr[128]; |
|
|
|
char rttype_str[32]; |
|
|
|
GetMidiRTTypeAsString(msg, rttype_str); |
|
|
|
|
|
|
|
// sprintf(
|
|
|
|
// outstr,
|
|
|
|
// "RT: systick: %i\ttimedelta: %i\ttype: %s\n",
|
|
|
|
// (unsigned int)systick_now,
|
|
|
|
// (unsigned int)systick_since_last,
|
|
|
|
// rttype_str);
|
|
|
|
// hw.PrintLine("%s", outstr);
|
|
|
|
}; |
|
|
|
|
|
|
|
hw.PrintLine("Starting MIDI Receive"); |
|
|
|
midi.StartReceive(); |
|
|
|
midi.Listen(); |
|
|
|
|
|
|
|
hw.PrintLine("Entering MainLoop"); |
|
|
|
} |
|
|
|
|
|
|
|
static DaisySeed hw{}; |
|
|
|
static MidiUartHandler midi{}; |
|
|
|
static FIFO<MidiEvent, 128> event_log{}; |
|
|
|
int create_tracks(float samplerate) |
|
|
|
{ |
|
|
|
instrument0.init(samplerate); |
|
|
|
tracks[0] = std::shared_ptr<PerkonsInstrumentInterface>(&instrument0); |
|
|
|
instrument1.init(samplerate); |
|
|
|
tracks[1] = std::shared_ptr<PerkonsInstrumentInterface>(&instrument1); |
|
|
|
instrument2.init(samplerate); |
|
|
|
tracks[2] = std::shared_ptr<PerkonsInstrumentInterface>(&instrument2); |
|
|
|
instrument3.init(samplerate); |
|
|
|
tracks[3] = std::shared_ptr<PerkonsInstrumentInterface>(&instrument3); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
Heck::Instrument::Noise instrument0{}; |
|
|
|
Heck::Instrument::FM instrument1{}; |
|
|
|
Heck::Instrument::FM instrument2{}; |
|
|
|
Heck::Instrument::Kick instrument3{}; |
|
|
|
|
|
|
|
std::array<std::shared_ptr<PerkonsInstrumentInterface>, TRACK_COUNT> tracks{}; |
|
|
|
// =============================================================================================
|
|
|
|
// RUN
|
|
|
|
// =============================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
void AudioCallback( |
|
|
|
AudioHandle::InterleavingInputBuffer in, |
|
|
|
AudioHandle::InterleavingOutputBuffer out, |
|
|
|
size_t size) |
|
|
|
{ |
|
|
|
float sig_out{}; |
|
|
|
for (size_t i = 0; i < size; i += 2) { |
|
|
|
for (int i = 0; i < TRACK_COUNT; i++) { |
|
|
|
sig_out += tracks[i]->nextsample(); |
|
|
|
} |
|
|
|
void AudioCallback( |
|
|
|
AudioHandle::InterleavingInputBuffer in, |
|
|
|
AudioHandle::InterleavingOutputBuffer out, |
|
|
|
size_t size) |
|
|
|
{ |
|
|
|
float sig_out{}; |
|
|
|
for (size_t i = 0; i < size; i += 2) { |
|
|
|
for (int i = 0; i < TRACK_COUNT; i++) { |
|
|
|
sig_out += tracks[i]->nextsample(); |
|
|
|
} |
|
|
|
|
|
|
|
sig_out *= 0.1; |
|
|
|
out[i] = sig_out; |
|
|
|
out[i + 1] = sig_out; |
|
|
|
sig_out *= 0.1; |
|
|
|
out[i] = sig_out; |
|
|
|
out[i + 1] = sig_out; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int create_tracks(float samplerate) |
|
|
|
{ |
|
|
|
instrument0.init(samplerate); |
|
|
|
tracks[0] = std::shared_ptr<PerkonsInstrumentInterface>(&instrument0); |
|
|
|
instrument1.init(samplerate); |
|
|
|
tracks[1] = std::shared_ptr<PerkonsInstrumentInterface>(&instrument1); |
|
|
|
instrument2.init(samplerate); |
|
|
|
tracks[2] = std::shared_ptr<PerkonsInstrumentInterface>(&instrument2); |
|
|
|
instrument3.init(samplerate); |
|
|
|
tracks[3] = std::shared_ptr<PerkonsInstrumentInterface>(&instrument3); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int main(void) |
|
|
|
{ |
|
|
|
int* npt = nullptr; |
|
|
|
int i = *npt; |
|
|
|
|
|
|
|
hw.Configure(); |
|
|
|
hw.Init(); |
|
|
|
hw.StartLog(true); |
|
|
|
|
|
|
|
uint32_t now = System::GetNow(); |
|
|
|
uint32_t log_time{}; |
|
|
|
bool heartbeat_led_state{ false }; |
|
|
|
uint32_t heartbeat_time{}; |
|
|
|
|
|
|
|
|
|
|
|
// Start Audio
|
|
|
|
hw.SetAudioBlockSize(4); |
|
|
|
float samplerate = hw.AudioSampleRate(); |
|
|
|
|
|
|
|
hw.PrintLine("Creating Tracks"); |
|
|
|
create_tracks(samplerate); |
|
|
|
|
|
|
|
hw.PrintLine("Starting Audio"); |
|
|
|
hw.StartAudio(AudioCallback); |
|
|
|
|
|
|
|
|
|
|
|
// MIDI RX
|
|
|
|
hw.PrintLine("Setting up MIDI"); |
|
|
|
MidiUartHandler::Config midi_config; |
|
|
|
midi.Init(midi_config); |
|
|
|
uint32_t systick_last_rt_msg{}; |
|
|
|
midi.realtime_callback = [&systick_last_rt_msg](MidiEvent& msg) { |
|
|
|
uint32_t systick_now = System::GetNow(); |
|
|
|
uint32_t systick_since_last = systick_now - systick_last_rt_msg; |
|
|
|
systick_last_rt_msg = systick_now; |
|
|
|
|
|
|
|
char outstr[128]; |
|
|
|
char rttype_str[32]; |
|
|
|
GetMidiRTTypeAsString(msg, rttype_str); |
|
|
|
|
|
|
|
// sprintf(
|
|
|
|
// outstr,
|
|
|
|
// "RT: systick: %i\ttimedelta: %i\ttype: %s\n",
|
|
|
|
// (unsigned int)systick_now,
|
|
|
|
// (unsigned int)systick_since_last,
|
|
|
|
// rttype_str);
|
|
|
|
// hw.PrintLine("%s", outstr);
|
|
|
|
}; |
|
|
|
|
|
|
|
hw.PrintLine("Starting MIDI Receive"); |
|
|
|
midi.StartReceive(); |
|
|
|
midi.Listen(); |
|
|
|
|
|
|
|
hw.PrintLine("Entering MainLoop"); |
|
|
|
while (1) { |
|
|
|
now = System::GetNow(); |
|
|
|
while (midi.HasEvents()) { |
|
|
|
MidiEvent msg = midi.PopEvent(); |
|
|
|
event_log.PushBack(msg); |
|
|
|
if (msg.type == MidiMessageType::NoteOn) { |
|
|
|
if (msg.channel >= 0 && msg.channel < TRACK_COUNT) { |
|
|
|
tracks[msg.channel]->trigger(); |
|
|
|
} |
|
|
|
} else if (msg.type == MidiMessageType::ControlChange) { |
|
|
|
// ControlChangeEvent cc = msg.AsControlChange();
|
|
|
|
void mainloop() |
|
|
|
{ |
|
|
|
u32 now = System::GetNow(); |
|
|
|
u32 log_time{}; |
|
|
|
bool heartbeat_led_state{ false }; |
|
|
|
u32 heartbeat_time{}; |
|
|
|
|
|
|
|
while (1) { |
|
|
|
now = System::GetNow(); |
|
|
|
while (midi.HasEvents()) { |
|
|
|
MidiEvent msg = midi.PopEvent(); |
|
|
|
event_log.PushBack(msg); |
|
|
|
} else { |
|
|
|
if (msg.type == MidiMessageType::NoteOn) { |
|
|
|
if (msg.channel >= 0 && msg.channel < TRACK_COUNT) { |
|
|
|
tracks[msg.channel]->trigger(); |
|
|
|
} |
|
|
|
} else if (msg.type == MidiMessageType::ControlChange) { |
|
|
|
// ControlChangeEvent cc = msg.AsControlChange();
|
|
|
|
event_log.PushBack(msg); |
|
|
|
} else { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (now - log_time > 5) { |
|
|
|
log_time = now; |
|
|
|
if (!event_log.IsEmpty()) { |
|
|
|
auto msg = event_log.PopFront(); |
|
|
|
char outstr[128]; |
|
|
|
char type_str[32]; |
|
|
|
GetMidiTypeAsString(msg, type_str); |
|
|
|
sprintf( |
|
|
|
outstr, |
|
|
|
"time-last:\t%ld\ttype: %s\tChannel: %d\tData MSB: " |
|
|
|
"%d\tData LSB: %d\n", |
|
|
|
now, |
|
|
|
type_str, |
|
|
|
msg.channel, |
|
|
|
msg.data[0], |
|
|
|
msg.data[1]); |
|
|
|
hw.PrintLine(outstr); |
|
|
|
if (now - log_time > 5) { |
|
|
|
log_time = now; |
|
|
|
if (!event_log.IsEmpty()) { |
|
|
|
auto msg = event_log.PopFront(); |
|
|
|
char outstr[128]; |
|
|
|
char type_str[32]; |
|
|
|
GetMidiTypeAsString(msg, type_str); |
|
|
|
sprintf( |
|
|
|
outstr, |
|
|
|
"time-last:\t%ld\ttype: %s\tChannel: %d\tData MSB: " |
|
|
|
"%d\tData LSB: %d\n", |
|
|
|
now, |
|
|
|
type_str, |
|
|
|
msg.channel, |
|
|
|
msg.data[0], |
|
|
|
msg.data[1]); |
|
|
|
hw.PrintLine(outstr); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (now - heartbeat_time > 500) { |
|
|
|
heartbeat_time = now; |
|
|
|
hw.SetLed(heartbeat_led_state); |
|
|
|
heartbeat_led_state = !heartbeat_led_state; |
|
|
|
if (now - heartbeat_time > 500) { |
|
|
|
heartbeat_time = now; |
|
|
|
hw.SetLed(heartbeat_led_state); |
|
|
|
heartbeat_led_state = !heartbeat_led_state; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} // namespace Heck
|
|
|
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
{ |
|
|
|
Heck::init(); |
|
|
|
Heck::mainloop(); |
|
|
|
} |