Browse Source

namespacing, introduce globals.hh,

instr_abstract.hh
replace using namespace with ns aliases, etc..
main
heck 7 months ago
parent
commit
6dc14634b5
  1. 34
      src/globals.hh
  2. 28
      src/instr_abstract.hh
  3. 14
      src/instr_fm.cc
  4. 7
      src/instr_fm.hh
  5. 18
      src/instr_kick.cc
  6. 8
      src/instr_kick.hh
  7. 9
      src/instr_noise.cc
  8. 8
      src/instr_noise.hh
  9. 157
      src/main_perkons.cc
  10. 21
      src/perkons_instrument_interface.hh
  11. 19
      src/types.hh
  12. 2
      src/utils.hh

34
src/globals.hh

@ -0,0 +1,34 @@
#ifndef HECK_DAISY_GLOBALS_HH
#define HECK_DAISY_GLOBALS_HH
#include <cstdint>
namespace Constants {
constexpr int BUFFERSIZE = 4;
constexpr int SAMPLERATE = 48000;
constexpr int TRACK_COUNT = 4;
namespace MIDI_Mapping {
constexpr int TRACK_PITCH = 70;
constexpr int TRACK_DECAY = 71;
constexpr int TRACK_PARAM1 = 72;
constexpr int TRACK_PARAM2 = 73;
constexpr int TRACK_FILTER = 74;
constexpr int TRACK_DRIVE = 75;
constexpr int TRACK_VOLUME = 76;
} // namespace MIDI_Mapping
} // namespace Constants
// Types
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using f32 = float;
using f64 = double;
#endif

28
src/instr_abstract.hh

@ -0,0 +1,28 @@
#ifndef HECK_DAISY_PERKONS_INSTR_ABSTRACT
#define HECK_DAISY_PERKONS_INSTR_ABSTRACT
#include "globals.hh"
namespace Heck {
namespace Instrument {
int samplerate = Constants::SAMPLERATE;
class AbstractInstrument {
public:
virtual void trigger() = 0;
// ctl-nr must be 0-3
// val must be 0-1
virtual void ctl(unsigned int ctl_nr, float val) = 0;
// pos must be either 0,1,2
virtual void switch_mode(unsigned int pos) = 0;
virtual void switch_variation(unsigned int pos) = 0;
virtual float nextsample() = 0;
private:
};
} // namespace Instruments
} // namespace Heck
#endif // HECK_DAISY_PERKONS_INSTR_ABSTRACT

14
src/instr_fm.cc

@ -1,13 +1,10 @@
#include "instr_fm.hh"
#include "daisysp.h"
using namespace daisysp;
namespace Heck {
namespace Instrument {
void FM::init(float samplerate)
void FM::init()
{
osc.Init(samplerate);
osc.SetFrequency(100);
@ -15,17 +12,15 @@ namespace Heck {
osc.SetIndex(0.);
volEnv.Init(samplerate);
volEnv.SetTime(ADENV_SEG_ATTACK, .0001);
volEnv.SetTime(ADENV_SEG_DECAY, 1.);
volEnv.SetTime(dsp::ADENV_SEG_ATTACK, .0001);
volEnv.SetTime(dsp::ADENV_SEG_DECAY, 1.);
volEnv.SetMax(1);
volEnv.SetMin(0);
}
void FM::trigger()
{
volEnv.Trigger();
return;
}
void FM::ctl(unsigned int ctl_nr, float val)
@ -35,7 +30,7 @@ namespace Heck {
osc.SetFrequency(val * 200.);
break;
case 1:
volEnv.SetTime(ADENV_SEG_DECAY, val * 2.);
volEnv.SetTime(dsp::ADENV_SEG_DECAY, val * 2.);
break;
case 2:
osc.SetRatio(val * 1.);
@ -52,7 +47,6 @@ namespace Heck {
void FM::switch_mode(unsigned int pos) {}
void FM::switch_variation(unsigned int pos) {}
void FM::switch_filter(unsigned int pos) {}
float FM::nextsample()
{

7
src/instr_fm.hh

@ -1,7 +1,7 @@
#ifndef HECK_DAISY_INSTR_FM_HH
#define HECK_DAISY_INSTR_FM_HH
#include "perkons_instrument_interface.hh"
#include "instr_abstract.hh"
#include "daisy_seed.h"
#include "daisysp.h"
@ -11,15 +11,14 @@ namespace dsp = daisysp;
namespace Heck {
namespace Instrument {
class FM : public PerkonsInstrumentInterface {
class FM : public AbstractInstrument {
public:
void init(float samplerate);
void init();
void trigger() override;
void ctl(unsigned int ctl_nr, float val) override;
void switch_mode(unsigned int pos) override;
void switch_variation(unsigned int pos) override;
void switch_filter(unsigned int pos) override;
float nextsample() override;

18
src/instr_kick.cc

@ -1,44 +1,38 @@
#include "instr_kick.hh"
#include "daisysp.h"
using namespace daisysp;
namespace Heck {
namespace Instrument {
void Kick::init(float samplerate)
void Kick::init()
{
osc.Init(samplerate);
osc.SetWaveform(Oscillator::WAVE_TRI);
osc.SetWaveform(dsp::Oscillator::WAVE_TRI);
osc.SetAmp(1);
pitchEnv.Init(samplerate);
pitchEnv.SetTime(ADENV_SEG_ATTACK, .001);
pitchEnv.SetTime(ADENV_SEG_DECAY, .01);
pitchEnv.SetTime(dsp::ADENV_SEG_ATTACK, .001);
pitchEnv.SetTime(dsp::ADENV_SEG_DECAY, .01);
pitchEnv.SetMax(250);
pitchEnv.SetMin(20);
volEnv.Init(samplerate);
volEnv.SetTime(ADENV_SEG_ATTACK, .0001);
volEnv.SetTime(ADENV_SEG_DECAY, 0.1);
volEnv.SetTime(dsp::ADENV_SEG_ATTACK, .0001);
volEnv.SetTime(dsp::ADENV_SEG_DECAY, 0.1);
volEnv.SetMax(1);
volEnv.SetMin(0);
}
void Kick::trigger()
{
volEnv.Trigger();
pitchEnv.Trigger();
return;
}
void Kick::ctl(unsigned int ctl_nr, float val) {}
void Kick::switch_mode(unsigned int pos) {}
void Kick::switch_variation(unsigned int pos) {}
void Kick::switch_filter(unsigned int pos) {}
float Kick::nextsample()
{

8
src/instr_kick.hh

@ -1,7 +1,7 @@
#ifndef HECK_DAISY_INSTR_KICK_HH
#define HECK_DAISY_INSTR_KICK_HH
#include "perkons_instrument_interface.hh"
#include "instr_abstract.hh"
#include "daisy_seed.h"
#include "daisysp.h"
@ -11,18 +11,16 @@ namespace dsp = daisysp;
namespace Heck {
namespace Instrument {
class Kick : public PerkonsInstrumentInterface {
class Kick : public AbstractInstrument {
public:
void init(float samplerate);
void init();
void trigger() override;
void ctl(unsigned int ctl_nr, float val) override;
void switch_mode(unsigned int pos) override;
void switch_variation(unsigned int pos) override;
void switch_filter(unsigned int pos) override;
float nextsample() override;
private:
dsp::Oscillator osc;
dsp::AdEnv volEnv;

9
src/instr_noise.cc

@ -1,18 +1,16 @@
#include "instr_noise.hh"
#include "daisysp.h"
using namespace daisysp;
namespace Heck {
namespace Instrument {
void Noise::init(float samplerate)
void Noise::init()
{
noise.Init();
env.Init(samplerate);
env.SetTime(ADENV_SEG_ATTACK, .0001);
env.SetTime(ADENV_SEG_DECAY, .01);
env.SetTime(dsp::ADENV_SEG_ATTACK, .0001);
env.SetTime(dsp::ADENV_SEG_DECAY, .01);
env.SetMax(1);
env.SetMin(0);
}
@ -25,7 +23,6 @@ namespace Heck {
void Noise::ctl(unsigned int ctl_nr, float val) {}
void Noise::switch_mode(unsigned int pos) {}
void Noise::switch_variation(unsigned int pos) {}
void Noise::switch_filter(unsigned int pos) {}
float Noise::nextsample()
{

8
src/instr_noise.hh

@ -1,7 +1,7 @@
#ifndef HECK_DAISY_INSTR_NOISE_HH
#define HECK_DAISY_INSTR_NOISE_HH
#include "perkons_instrument_interface.hh"
#include "instr_abstract.hh"
#include "daisy_seed.h"
#include "daisysp.h"
@ -11,18 +11,16 @@ namespace dsp = daisysp;
namespace Heck {
namespace Instrument {
class Noise : public PerkonsInstrumentInterface {
class Noise : public AbstractInstrument {
public:
void init(float samplerate);
void init();
void trigger() override;
void ctl(unsigned int ctl_nr, float val) override;
void switch_mode(unsigned int pos) override;
void switch_variation(unsigned int pos) override;
void switch_filter(unsigned int pos) override;
float nextsample() override;
private:
dsp::WhiteNoise noise;
dsp::AdEnv env;

157
src/main_perkons.cc

@ -1,42 +1,86 @@
// Hecks perkons extension
#include <map>
#include <array>
#include <memory>
#include "daisy_seed.h"
#include "daisysp.h"
#include "types.hh"
#include "globals.hh"
#include "utils.hh"
#include "perkons_instrument_interface.hh"
#include "instr_abstract.hh"
#include "instr_kick.hh"
#include "instr_noise.hh"
#include "instr_fm.hh"
#define TRACK_COUNT 4
namespace ld = daisy;
namespace dsp = daisysp;
namespace Heck {
// =============================================================================================
// INIT
// =============================================================================================
using namespace daisy;
using namespace daisysp;
static DaisySeed hw{};
static MidiUartHandler midi{};
static FIFO<MidiEvent, 128> event_log{};
static ld::DaisySeed hw{};
static ld::MidiUartHandler midi{};
static ld::FIFO<ld::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{};
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(float samplerate);
int create_tracks();
void AudioCallback(
AudioHandle::InterleavingInputBuffer in,
AudioHandle::InterleavingOutputBuffer out,
ld::AudioHandle::InterleavingInputBuffer in,
ld::AudioHandle::InterleavingOutputBuffer out,
size_t size);
@ -50,11 +94,35 @@ namespace Heck {
hw.StartLog(true);
// Start Audio
hw.SetAudioBlockSize(4);
float samplerate = hw.AudioSampleRate();
hw.PrintLine("Setting Blocksize: %i", Constants::BUFFERSIZE);
hw.SetAudioBlockSize(Constants::BUFFERSIZE);
hw.PrintLine("Setting Samplerate: %i", Constants::SAMPLERATE);
switch (Constants::SAMPLERATE) {
case 8000:
hw.SetAudioSampleRate(daisy::SaiHandle::Config::SampleRate::SAI_8KHZ);
break;
case 16000:
hw.SetAudioSampleRate(daisy::SaiHandle::Config::SampleRate::SAI_16KHZ);
break;
case 32000:
hw.SetAudioSampleRate(daisy::SaiHandle::Config::SampleRate::SAI_32KHZ);
break;
case 48000:
hw.SetAudioSampleRate(daisy::SaiHandle::Config::SampleRate::SAI_48KHZ);
break;
case 96000:
hw.SetAudioSampleRate(daisy::SaiHandle::Config::SampleRate::SAI_48KHZ);
break;
default:
hw.PrintLine("Samplerate not supported, fallback to 48000");
hw.SetAudioSampleRate(daisy::SaiHandle::Config::SampleRate::SAI_48KHZ);
break;
}
hw.PrintLine("Creating Tracks");
create_tracks(samplerate);
create_tracks();
hw.PrintLine("Starting Audio");
hw.StartAudio(AudioCallback);
@ -62,11 +130,11 @@ namespace Heck {
// MIDI RX
hw.PrintLine("Setting up MIDI");
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](MidiEvent& msg) {
u32 systick_now = System::GetNow();
midi.realtime_callback = [&systick_last_rt_msg](ld::MidiEvent& msg) {
u32 systick_now = ld::System::GetNow();
u32 systick_since_last = systick_now - systick_last_rt_msg;
systick_last_rt_msg = systick_now;
@ -90,17 +158,16 @@ namespace Heck {
hw.PrintLine("Entering MainLoop");
}
int create_tracks(float samplerate)
int create_tracks()
{
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);
instrument0.init();
tracks[0].init(instrument0);
instrument1.init();
tracks[1].init(instrument1);
instrument2.init();
tracks[2].init(instrument2);
instrument3.init();
tracks[3].init(instrument3);
return 0;
}
@ -111,14 +178,14 @@ namespace Heck {
void AudioCallback(
AudioHandle::InterleavingInputBuffer in,
AudioHandle::InterleavingOutputBuffer out,
ld::AudioHandle::InterleavingInputBuffer in,
ld::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();
for (int i = 0; i < Constants::TRACK_COUNT; i++) {
sig_out += tracks[i].nextsample();
}
sig_out *= 0.1;
@ -129,22 +196,30 @@ namespace Heck {
void mainloop()
{
u32 now = System::GetNow();
u32 now = ld::System::GetNow();
u32 log_time{};
bool heartbeat_led_state{ false };
u32 heartbeat_time{};
while (1) {
now = System::GetNow();
now = ld::System::GetNow();
while (midi.HasEvents()) {
MidiEvent msg = midi.PopEvent();
ld::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();
if (msg.type == ld::MidiMessageType::NoteOn) {
if (msg.channel >= 0 && msg.channel < Constants::TRACK_COUNT) {
tracks[msg.channel].trigger();
}
} else if (msg.type == ld::MidiMessageType::ControlChange) {
ld::ControlChangeEvent cc = msg.AsControlChange();
switch (cc.control_number) {
case Constants::MIDI_Mapping::TRACK_VOLUME:
tracks[cc.channel].volume(cc.value);
break;
case Constants::MIDI_Mapping::TRACK_FILTER:
tracks[cc.channel].volume(cc.value);
break;
}
} else if (msg.type == MidiMessageType::ControlChange) {
// ControlChangeEvent cc = msg.AsControlChange();
event_log.PushBack(msg);
} else {
}

21
src/perkons_instrument_interface.hh

@ -1,21 +0,0 @@
#ifndef HECK_DAISY_PERKONS_INSTRUMENT_INTERFACE
#define HECK_DAISY_PERKONS_INSTRUMENT_INTERFACE
class PerkonsInstrumentInterface {
public:
virtual void trigger() = 0;
// ctl-nr must be 0-5
// val must be 0-1
virtual void ctl(unsigned int ctl_nr, float val) = 0;
// pos must be either 0,1,2
virtual void switch_mode(unsigned int pos) = 0;
virtual void switch_variation(unsigned int pos) = 0;
virtual void switch_filter(unsigned int pos) = 0;
virtual float nextsample() = 0;
private:
};
#endif // HECK_DAISY_PERKONS_INSTRUMENT_INTERFACE

19
src/types.hh

@ -1,19 +0,0 @@
#ifndef HECK_DAISY_TYPES_HH
#define HECK_DAISY_TYPES_HH
#include <cstdint>
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using f32 = float;
using f64 = double;
#endif

2
src/utils.hh

@ -2,7 +2,7 @@
#define HECK_DAISY_UTILS_HH
#include "daisy_seed.h"
#include "types.hh"
#include "globals.hh"
void GetMidiTypeAsString(daisy::MidiEvent& msg, char* str);
void GetMidiRTTypeAsString(daisy::MidiEvent& msg, char* str);

Loading…
Cancel
Save