Added function for setting max acceptable notes.

Limited to 10 notes at a time to avoid xruns.
pull/4/head
Holger Wirtz 7 years ago
parent bbebaa85d3
commit ba27df8a81
  1. 65
      MicroDexed.ino
  2. 70
      dexed.cpp
  3. 9
      dexed.h

@ -14,14 +14,14 @@
#include <MIDI.h> #include <MIDI.h>
#include "dexed.h" #include "dexed.h"
#define AUDIO_MEM 32 #define AUDIO_MEM 2
#define AUDIO_BUFFER_SIZE 128 #define AUDIO_BUFFER_SIZE 128
#define SAMPLEAUDIO_BUFFER_SIZE 44100 #define SAMPLEAUDIO_BUFFER_SIZE 44100
#define INIT_AUDIO_QUEUE 1 #define INIT_AUDIO_QUEUE 1
//#define SHOW_DEXED_TIMING 1 //#define SHOW_DEXED_TIMING 1
#define SHOW_XRUN 1 #define SHOW_XRUN 1
#define SHOW_CPU_LOAD
#define SHOW_CPU_LOAD_MSEC 5000 #define SHOW_CPU_LOAD_MSEC 5000
#define MAX_NOTES 10
#define TEST_MIDI 1 #define TEST_MIDI 1
#define TEST_NOTE 40 #define TEST_NOTE 40
#define TEST_VEL 60 #define TEST_VEL 60
@ -40,7 +40,7 @@ IntervalTimer sched;
void setup() void setup()
{ {
while (!Serial) ; // wait for Arduino Serial Monitor //while (!Serial) ; // wait for Arduino Serial Monitor
Serial.begin(115200); Serial.begin(115200);
Serial.println(F("MicroDexed based on https://github.com/asb2m10/dexed")); Serial.println(F("MicroDexed based on https://github.com/asb2m10/dexed"));
Serial.println(F("(c)2018 H. Wirtz")); Serial.println(F("(c)2018 H. Wirtz"));
@ -56,7 +56,7 @@ void setup()
sgtl5000_1.volume(0.2); sgtl5000_1.volume(0.2);
// Initialize processor and memory measurements // Initialize processor and memory measurements
#ifdef SHOW_CPU_LOAD #ifdef SHOW_CPU_LOAD_MSEC
AudioProcessorUsageMaxReset(); AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset(); AudioMemoryUsageMaxReset();
#endif #endif
@ -75,7 +75,8 @@ void setup()
#endif #endif
dexed->activate(); dexed->activate();
dexed->setMaxNotes(MAX_NOTES);
#ifdef TEST_MIDI #ifdef TEST_MIDI
queue_midi_event(0x90, TEST_NOTE, TEST_VEL); // 1 queue_midi_event(0x90, TEST_NOTE, TEST_VEL); // 1
@ -89,17 +90,18 @@ void setup()
queue_midi_event(0x90, TEST_NOTE + 32, TEST_VEL); // 9 queue_midi_event(0x90, TEST_NOTE + 32, TEST_VEL); // 9
queue_midi_event(0x90, TEST_NOTE + 37, TEST_VEL); // 10 queue_midi_event(0x90, TEST_NOTE + 37, TEST_VEL); // 10
queue_midi_event(0x90, TEST_NOTE + 40, TEST_VEL); // 11 queue_midi_event(0x90, TEST_NOTE + 40, TEST_VEL); // 11
//queue_midi_event(0x90, TEST_NOTE + 44, TEST_VEL); // 12 queue_midi_event(0x90, TEST_NOTE + 44, TEST_VEL); // 12
//queue_midi_event(0x90, TEST_NOTE + 49, TEST_VEL); // 13 queue_midi_event(0x90, TEST_NOTE + 49, TEST_VEL); // 13
//queue_midi_event(0x90, TEST_NOTE + 52, TEST_VEL); // 14 queue_midi_event(0x90, TEST_NOTE + 52, TEST_VEL); // 14
//queue_midi_event(0x90, TEST_NOTE + 57, TEST_VEL); // 15 queue_midi_event(0x90, TEST_NOTE + 57, TEST_VEL); // 15
//queue_midi_event(0x90, TEST_NOTE + 60, TEST_VEL); // 16 queue_midi_event(0x90, TEST_NOTE + 60, TEST_VEL); // 16
#endif #endif
#ifdef SHOW_CPU_LOAD #ifdef SHOW_CPU_LOAD_MSEC
sched.begin(cpu_and_mem_usage, SHOW_CPU_LOAD_MSEC*1000); sched.begin(cpu_and_mem_usage, SHOW_CPU_LOAD_MSEC * 1000);
#endif #endif
Serial.println(F("setup end")); Serial.println(F("setup end"));
cpu_and_mem_usage();
} }
void loop() void loop()
@ -107,32 +109,35 @@ void loop()
int16_t* audio_buffer; // pointer to 128 * int16_t int16_t* audio_buffer; // pointer to 128 * int16_t
bool break_for_calculation; bool break_for_calculation;
audio_buffer = queue1.getBuffer(); while (42 == 42) // DON'T PANIC!
if (audio_buffer == NULL)
{ {
Serial.println(F("audio_buffer allocation problems!")); audio_buffer = queue1.getBuffer();
} if (audio_buffer == NULL)
{
Serial.println(F("audio_buffer allocation problems!"));
}
while (MIDI.read()) while (MIDI.read())
{ {
break_for_calculation = dexed->ProcessMidiMessage(MIDI.getType(), MIDI.getData1(), MIDI.getData2()); break_for_calculation = dexed->ProcessMidiMessage(MIDI.getType(), MIDI.getData1(), MIDI.getData2());
if (break_for_calculation == true) if (break_for_calculation == true)
break; break;
} }
#if defined(SHOW_DEXED_TIMING) || defined(SHOW_XRUN) #if defined(SHOW_DEXED_TIMING) || defined(SHOW_XRUN)
elapsedMicros t1; elapsedMicros t1;
#endif #endif
dexed->GetSamples(AUDIO_BUFFER_SIZE, audio_buffer); dexed->GetSamples(AUDIO_BUFFER_SIZE, audio_buffer);
#ifdef SHOW_XRUN #ifdef SHOW_XRUN
uint32_t t2 = t1; uint32_t t2 = t1;
if (t2 > 2900) if (t2 > 2900)
Serial.println(F("xrun")); Serial.println(F("xrun"));
#endif #endif
#ifdef SHOW_DEXED_TIMING #ifdef SHOW_DEXED_TIMING
Serial.println(t1, DEC); Serial.println(t1, DEC);
#endif #endif
queue1.playBuffer(); queue1.playBuffer();
}
} }
bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2) bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2)
@ -140,7 +145,7 @@ bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2)
return (dexed->ProcessMidiMessage(type, data1, data2)); return (dexed->ProcessMidiMessage(type, data1, data2));
} }
#ifdef SHOW_CPU_LOAD #ifdef SHOW_CPU_LOAD_MSEC
void cpu_and_mem_usage(void) void cpu_and_mem_usage(void)
{ {
Serial.print(F("CPU:")); Serial.print(F("CPU:"));

@ -106,7 +106,7 @@ Dexed::~Dexed()
{ {
currentNote = -1; currentNote = -1;
for (uint8_t note = 0; note < MAX_ACTIVE_NOTES; ++note) for (uint8_t note = 0; note < MAX_ACTIVE_NOTES; note++)
delete voices[note].dx7_note; delete voices[note].dx7_note;
delete(engineMsfa); delete(engineMsfa);
@ -195,45 +195,45 @@ void Dexed::GetSamples(uint16_t n_samples, int16_t* buffer)
extra_buf_size_ = i - n_samples; extra_buf_size_ = i - n_samples;
} }
/* if (++_k_rate_counter == 0 && !monoMode) /* if (++_k_rate_counter == 0 && !monoMode)
{
uint8_t op_carrier = controllers.core->get_carrier_operators(data[134]); // look for carriers
for (i = 0; i < max_notes; i++)
{ {
if (voices[i].live == true) uint8_t op_carrier = controllers.core->get_carrier_operators(data[134]); // look for carriers
{
uint8_t op_amp = 0;
uint8_t op_carrier_num = 0;
voices[i].dx7_note->peekVoiceStatus(voiceStatus); for (i = 0; i < max_notes; i++)
{
for (uint8_t op = 0; op < 6; op++) if (voices[i].live == true)
{ {
uint8_t op_bit = static_cast<uint8_t>(pow(2, op)); uint8_t op_amp = 0;
uint8_t op_carrier_num = 0;
if ((op_carrier & op_bit) > 0) voices[i].dx7_note->peekVoiceStatus(voiceStatus);
for (uint8_t op = 0; op < 6; op++)
{ {
// this voice is a carrier! uint8_t op_bit = static_cast<uint8_t>(pow(2, op));
op_carrier_num++;
if ((op_carrier & op_bit) > 0)
{
// this voice is a carrier!
op_carrier_num++;
//TRACE("Voice[%2d] OP [%d] amp=%ld,amp_step=%d,pitch_step=%d",i,op,voiceStatus.amp[op],voiceStatus.ampStep[op],voiceStatus.pitchStep); //TRACE("Voice[%2d] OP [%d] amp=%ld,amp_step=%d,pitch_step=%d",i,op,voiceStatus.amp[op],voiceStatus.ampStep[op],voiceStatus.pitchStep);
if (voiceStatus.amp[op] <= 1069 && voiceStatus.ampStep[op] == 4) // this voice produces no audio output if (voiceStatus.amp[op] <= 1069 && voiceStatus.ampStep[op] == 4) // this voice produces no audio output
op_amp++; op_amp++;
}
}
if (op_amp == op_carrier_num)
{
// all carrier-operators are silent -> disable the voice
voices[i].live = false;
voices[i].sustained = false;
voices[i].keydown = false;
TRACE("Shutted down Voice[%2d]", i);
} }
}
if (op_amp == op_carrier_num)
{
// all carrier-operators are silent -> disable the voice
voices[i].live = false;
voices[i].sustained = false;
voices[i].keydown = false;
TRACE("Shutted down Voice[%2d]", i);
} }
} }
} } */
} */
} }
bool Dexed::ProcessMidiMessage(uint8_t type, uint8_t data1, uint8_t data2) bool Dexed::ProcessMidiMessage(uint8_t type, uint8_t data1, uint8_t data2)
@ -575,6 +575,16 @@ void Dexed::notes_off(void) {
} }
} }
void Dexed::setMaxNotes(uint8_t n) {
if (n <= MAX_ACTIVE_NOTES)
{
notes_off();
max_notes = n;
panic();
controllers.refresh();
}
}
void Dexed::set_params(void) void Dexed::set_params(void)
{ {
/* //TRACE("Hi"); /* //TRACE("Hi");

@ -66,7 +66,9 @@ class Dexed
void set_params(void); void set_params(void);
void GetSamples(uint16_t n_samples, int16_t* buffer); void GetSamples(uint16_t n_samples, int16_t* buffer);
bool ProcessMidiMessage(uint8_t type, uint8_t data1, uint8_t data2); bool ProcessMidiMessage(uint8_t type, uint8_t data1, uint8_t data2);
void panic(void);
void notes_off(void);
void setMaxNotes(uint8_t n);
Controllers controllers; Controllers controllers;
VoiceStatus voiceStatus; VoiceStatus voiceStatus;
@ -74,10 +76,9 @@ class Dexed
//void onParam(uint8_t param_num,float param_val); //void onParam(uint8_t param_num,float param_val);
void keyup(uint8_t pitch); void keyup(uint8_t pitch);
void keydown(uint8_t pitch, uint8_t velo); void keydown(uint8_t pitch, uint8_t velo);
void panic(void);
void notes_off(void);
static const uint8_t MAX_ACTIVE_NOTES = 32;
static const uint8_t MAX_ACTIVE_NOTES = 16;
uint8_t max_notes = MAX_ACTIVE_NOTES; uint8_t max_notes = MAX_ACTIVE_NOTES;
ProcessorVoice voices[MAX_ACTIVE_NOTES]; ProcessorVoice voices[MAX_ACTIVE_NOTES];
uint8_t currentNote; uint8_t currentNote;

Loading…
Cancel
Save