Browse Source

MIDI controls for tracks complete

Move `struct Track` into own module
main
heck 7 months ago
parent
commit
25a2729e4a
  1. 113
      src/main_perkons.cc
  2. 81
      src/track.hh

113
src/main_perkons.cc

@ -1,10 +1,9 @@
// Hecks perkons extension
#include <array>
#include <memory>
#include "daisy_seed.h"
#include "daisysp.h"
#include "globals.hh"
#include "track.hh"
#include "utils.hh"
#include "instr_abstract.hh"
#include "instr_kick.hh"
@ -14,13 +13,13 @@
namespace ld = daisy;
namespace dsp = daisysp;
namespace Heck {
namespace Heck {
// =============================================================================================
// INIT
// =============================================================================================
ld::DaisySeed hw{};
static ld::DaisySeed hw{};
static ld::MidiUartHandler midi{};
static ld::FIFO<ld::MidiEvent, 128> event_log{};
@ -29,55 +28,11 @@ namespace Heck {
Instrument::FM instrument2{};
Instrument::Kick instrument3{};
struct Track {
public:
void init(Instrument::AbstractInstrument& instrument)
{
instrument_.reset(&instrument);
ctl_volume_ = 1.;
// filter_.Init();
}
float nextsample()
{
float sig = instrument_->nextsample();
sig = vca_(sig, ctl_volume_);
// sig = filter_.Low();
return sig;
}
void trigger()
{
instrument_->trigger();
}
void volume(float vol)
{
ctl_volume_ = vol;
}
void filter(float freq)
{
filter_.SetFreq(freq);
}
void drive(float amt)
{
filter_.SetDrive(amt);
}
private:
std::shared_ptr<Instrument::AbstractInstrument> instrument_{};
dsp::LinearVCA vca_{};
dsp::Svf filter_{};
float ctl_volume_{};
};
std::array<Track, Constants::TRACK_COUNT> tracks;
// function prototypes
int create_tracks();
void AudioCallback(
ld::AudioHandle::InterleavingInputBuffer in,
ld::AudioHandle::InterleavingOutputBuffer out,
@ -86,14 +41,10 @@ namespace Heck {
void init()
{
int* npt = nullptr;
int i = *npt;
hw.Configure();
hw.Init();
hw.StartLog(true);
hw.StartLog();
// Start Audio
hw.PrintLine("Setting Blocksize: %i", Constants::BUFFERSIZE);
hw.SetAudioBlockSize(Constants::BUFFERSIZE);
@ -120,17 +71,12 @@ namespace Heck {
break;
}
hw.PrintLine("Creating Tracks");
create_tracks();
hw.PrintLine("Starting Audio");
hw.StartAudio(AudioCallback);
// MIDI RX
hw.PrintLine("Setting up MIDI");
ld::MidiUartHandler::Config midi_config;
ld::MidiUartHandler::Config midi_config{};
midi.Init(midi_config);
u32 systick_last_rt_msg{};
midi.realtime_callback = [&systick_last_rt_msg](ld::MidiEvent& msg) {
@ -155,6 +101,9 @@ namespace Heck {
midi.StartReceive();
midi.Listen();
hw.PrintLine("Starting Audio");
hw.StartAudio(AudioCallback);
hw.PrintLine("Entering MainLoop");
}
@ -171,12 +120,10 @@ namespace Heck {
return 0;
}
// =============================================================================================
// RUN
// =============================================================================================
void AudioCallback(
ld::AudioHandle::InterleavingInputBuffer in,
ld::AudioHandle::InterleavingOutputBuffer out,
@ -187,7 +134,6 @@ namespace Heck {
for (int i = 0; i < Constants::TRACK_COUNT; i++) {
sig_out += tracks[i].nextsample();
}
sig_out *= 0.1;
out[i] = sig_out;
out[i + 1] = sig_out;
@ -205,22 +151,51 @@ namespace Heck {
now = ld::System::GetNow();
while (midi.HasEvents()) {
ld::MidiEvent msg = midi.PopEvent();
event_log.PushBack(msg);
if (msg.type == ld::MidiMessageType::NoteOn) {
if (msg.channel >= 0 && msg.channel < Constants::TRACK_COUNT) {
tracks[msg.channel].trigger();
tracks[msg.channel].instrument->trigger();
}
} else if (msg.type == ld::MidiMessageType::ControlChange) {
event_log.PushBack(msg);
ld::ControlChangeEvent cc = msg.AsControlChange();
float val_normalized = cc.value / 127.;
switch (cc.control_number) {
case Constants::MIDI_Mapping::TRACK_VOLUME:
tracks[cc.channel].volume(cc.value);
// 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].instrument->ctl(1, 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].volume(cc.value);
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;
}
event_log.PushBack(msg);
} else {
}
}

81
src/track.hh

@ -0,0 +1,81 @@
#ifndef HECK_PERKONS_TRACK_HH
#define HECK_PERKONS_TRACK_HH
#include "daisysp.h"
#include "instr_abstract.hh"
namespace dsp = daisysp;
namespace Heck {
struct Track {
public:
void init(Instrument::AbstractInstrument& instr)
{
instrument.reset(&instr);
ctl_volume_ = 0.;
ladder_.Init(Constants::SAMPLERATE);
ladder_.SetFilterMode(daisysp::LadderFilter::FilterMode::LP24);
ladder_.SetRes(0.7);
ladder_.SetInputDrive(1.3);
od_.Init();
}
float nextsample()
{
float sig = instrument->nextsample();
sig = ladder_.Process(sig);
sig = od_.Process(sig);
sig = vca_(sig, ctl_volume_);
return sig;
}
void volume(float vol)
{
ctl_volume_ = vol;
}
void filter(float val)
{
float ladder_freq = 80 + (val * 9000);
ladder_.SetFreq(val * ladder_freq);
}
void drive(float amt)
{
od_.SetDrive(0.35 + amt * 0.15);
}
// range: 0-1
void filtermode(float val)
{
ctl_filtermode_ = val;
// MID
if (ctl_filtermode_ < 0.33) {
ladder_.SetFilterMode(daisysp::LadderFilter::FilterMode::BP24);
}
// HIGH
if (ctl_filtermode_ >= 0.33 && ctl_filtermode_ < 0.66) {
ladder_.SetFilterMode(daisysp::LadderFilter::FilterMode::HP24);
}
// LOW
if (ctl_filtermode_ >= 0.66) {
ladder_.SetFilterMode(daisysp::LadderFilter::FilterMode::LP24);
}
}
std::shared_ptr<Instrument::AbstractInstrument> instrument{};
private:
dsp::LinearVCA vca_{};
dsp::LadderFilter ladder_{};
dsp::Overdrive od_{};
float ctl_volume_{};
float ctl_filtermode_{};
};
} // namespace Heck
#endif
Loading…
Cancel
Save