Changes for autothrottling max simulatinious note.

Changes for dexed setup format.
pull/32/head
Holger Wirtz 5 years ago
parent dcccc77712
commit 1533e6ba12
  1. 35
      MicroDexed.ino
  2. 10
      config.h
  3. 17
      dexed.cpp
  4. 3
      dexed_sysex.cpp
  5. 40
      doc/sysex-format_dexed-setup.txt

@ -177,25 +177,17 @@ AudioConnection * dynamicConnections[NUM_DEXED * 8];
#endif
void create_audio_connections(AudioSourceMicroDexed &dexed, AudioEffectMonoStereo &mono2stereo, uint8_t instance_id)
{
Serial.print(F("Connecting Dexed "));
Serial.print(instance_id, DEC);
Serial.println(F(":"));
dynamicConnections[nDynamic++] = new AudioConnection(dexed, 0, microdexed_peak_mixer, instance_id);
dynamicConnections[nDynamic++] = new AudioConnection(dexed, 0, mono2stereo, 0);
Serial.println(F(" -> Peakmeter"));
dynamicConnections[nDynamic++] = new AudioConnection(mono2stereo, 0, dexed_mixer_r, instance_id);
dynamicConnections[nDynamic++] = new AudioConnection(mono2stereo, 1, dexed_mixer_l, instance_id);
Serial.println(F(" -> Dexed mixer"));
dynamicConnections[nDynamic++] = new AudioConnection(mono2stereo, 0, chorus_send_mixer_r, instance_id);
dynamicConnections[nDynamic++] = new AudioConnection(mono2stereo, 1, chorus_send_mixer_l, instance_id);
Serial.println(F(" -> Chorus send"));
dynamicConnections[nDynamic++] = new AudioConnection(mono2stereo, 0, delay_send_mixer_r, instance_id);
dynamicConnections[nDynamic++] = new AudioConnection(mono2stereo, 1, delay_send_mixer_l, instance_id);
Serial.println(F(" -> Delay send"));
#if defined(USE_REVERB)
dynamicConnections[nDynamic++] = new AudioConnection(mono2stereo, 0, reverb_send_mixer_r, instance_id);
dynamicConnections[nDynamic++] = new AudioConnection(mono2stereo, 1, reverb_send_mixer_l, instance_id);
Serial.println(F(" -> Reverb send"));
#endif
}
@ -217,6 +209,7 @@ uint8_t active_voices[NUM_DEXED];
elapsedMillis cpu_mem_millis;
#endif
uint32_t cpumax = 0;
elapsedMillis cpu_overload_throttle_timer;
uint32_t peak_dexed = 0;
float peak_dexed_value = 0.0;
uint32_t peak_r = 0;
@ -538,23 +531,26 @@ void setup()
// set initial volume
set_volume(configuration.vol, configuration.mono);
#if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
// Initialize processor and memory measurements
AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset();
#endif
#ifdef DEBUG
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++)
{
Serial.print(F("Dexed instance "));
Serial.print(instance_id);
Serial.println(F(":"));
Serial.print(F("Bank/Voice from EEPROM ["));
Serial.print(configuration.dexed[instance_id].bank, DEC);
Serial.print(F("/"));
Serial.print(configuration.dexed[instance_id].voice, DEC);
Serial.println(F("]"));
Serial.print(F("Polyphony: "));
Serial.println(configuration.dexed[instance_id].polyphony, DEC);
#ifdef DEBUG
show_patch(instance_id);
}
#endif
}
Serial.print(F("AUDIO_BLOCK_SAMPLES="));
Serial.print(AUDIO_BLOCK_SAMPLES);
@ -604,16 +600,19 @@ void loop()
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++)
{
active_voices[instance_id] = MicroDexed[instance_id]->getNumNotesPlaying();
#ifdef CPU_OVERLOAD_THROTTLE
if (AudioProcessorUsageMax() > 99.9)
#if defined(CPU_OVERLOAD_THROTTLE)
if (AudioProcessorUsageMax() > CPU_OVERLOAD_THROTTLE && cpu_overload_throttle_timer >= CPU_OVERLOAD_THROTTLE_TIMER)
{
cpu_overload_throttle_timer = 0;
AudioProcessorUsageMaxReset();
MicroDexed[instance_id]->keyup(-1); // kills the oldest note and decreases max_notes
Serial.print(F("!!!CPU overload!!! Automatic throttling max_notes to "));
Serial.print(F("!!!CPU overload!!! Automatic throttling polyphony down to "));
Serial.print(MicroDexed[instance_id]->getMaxNotes(), DEC);
Serial.print(F(" for instance "));
Serial.print(instance_id, DEC);
Serial.println(F("."));
configuration.dexed[instance_id].polyphony = MicroDexed[instance_id]->getMaxNotes();
eeprom_update(); // useful to do this???
}
#endif
}
@ -1258,21 +1257,19 @@ void initial_values_from_eeprom(bool init)
init_configuration();
else
{
Serial.println(F("Loading inital data from EEPROM."));
EEPROM.get(EEPROM_START_ADDRESS, tmp_conf);
checksum = crc32((byte*)&tmp_conf + 4, sizeof(tmp_conf) - 4);
#ifdef DEBUG
Serial.print(F("EEPROM checksum: 0x"));
Serial.print(tmp_conf.checksum, HEX);
Serial.print(F(" / 0x"));
Serial.println(checksum, HEX);
#endif
if (checksum != tmp_conf.checksum)
{
#ifdef DEBUG
Serial.println(F("Checksum mismatch -> initializing EEPROM!"));
#endif
init_configuration();
}
else

@ -212,8 +212,8 @@
#define NUM_DEXED 1
#define MAX_DEXED 2
#define NORMALIZE_DX_VELOCITY 1
#define CPU_OVERLOAD_THROTTLE 1
#define CPU_OVERLOAD_THROTTLE 95.0 // Level (in percent) when throttling should start
#define CPU_OVERLOAD_THROTTLE_TIMER 100 // timer (in ms) when next throttling is possible
enum { DEXED, CHORUS, DELAY, REVERB};
// MIDI
@ -231,9 +231,11 @@ enum { DEXED, CHORUS, DELAY, REVERB};
#define MIDI_DEVICE_USB_HOST 1
#if defined(USE_REVERB)
#if defined(DEBUG)
#define MAX_NOTES 11
//#define MAX_NOTES 12
#define MAX_NOTES 16
#else
#define MAX_NOTES 12
//#define MAX_NOTES 11
#define MAX_NOTES 16
#endif
#else
#define MAX_NOTES 15

@ -248,28 +248,24 @@ void Dexed::keydown(int16_t pitch, uint8_t velo) {
}
void Dexed::keyup(int16_t pitch) {
pitch += data[144] - TRANSPOSE_FIX;
uint8_t note;
if (pitch < 0) // for disabling the oldest note when cpu overload is detected
{
note = abs((currentNote + 1) % max_notes);
voices[note].keydown = false;
if (max_notes == note)
voices[currentNote].keydown = false;
if (--max_notes == currentNote)
currentNote = 0;
else
currentNote = note;
max_notes--;
}
else
{
uint8_t note;
pitch += data[144] - TRANSPOSE_FIX;
for (note = 0; note < max_notes; note++) {
if ( voices[note].midi_note == pitch && voices[note].keydown ) {
voices[note].keydown = false;
break;
}
}
}
// note not found ?
if ( note >= max_notes ) {
@ -298,6 +294,7 @@ void Dexed::keyup(int16_t pitch) {
} else {
voices[note].dx7_note->keyup();
}
}
}
void Dexed::doRefreshVoice(void)

@ -409,7 +409,8 @@ bool get_sysex_setup(File sysex, config_t configuration)
return (false);
}
sysex.seek(3);
if (sysex.read() != 0x4b) // check for sysex type (0x75=MicroDexed setup)
uint8_t dexed_sysex_setup_type = sysex.read();
if (dexed_sysex_setup_type >= 0x42 && dexed_sysex_setup_type < 0x45) // check for sysex type (0x75=MicroDexed setup for one to four instances)
{
#ifdef DEBUG
Serial.println(F("E : SysEx type not MicroDexed setup."));

@ -7,16 +7,44 @@ SYSEX Message Controller-Set
11110000 F0 Status byte - start sysex
0iiiiiii 67 ID # (i=103; unofficial SYSEX-ID for MicroDexed)
0sssnnnn 00 Sub-status (s=0) & channel number (n=0; ch 1)
0fffffff 00 format number (f=75; 1 MicroDexed setup)
0fffffff 00 format number (f=66..69; 1..4 MicroDexed setup(s))
0bbbbbbb 01 byte count MS byte
0bbbbbbb 1B byte count LS byte (b=38; 1 setup using 1 instance
b=69; 1 setup using 2 instances)
0ddddddd ** data byte 1 controller-set
0bbbbbbb 1B byte count LS byte (b=44; 1 instance
b=73; 2 instances
b=102; 3 instances
b=131; 4 instances)
0ddddddd ** data byte 1 setup config
| | |
0ddddddd ** data byte 38 or 69
0eeeeeee ** checksum (masked 2's comp. of sum of 38 or 69 bytes)
0ddddddd ** data byte 19
0ddddddd ** data byte 20 instance config 0
| | |
0ddddddd ** data byte 43
/-Optional--------------------------------------------\
0ddddddd ** data byte 44 instance config 1
| | |
0ddddddd ** data byte 72
\-----------------------------------------------------/
/-Optional--------------------------------------------\
0ddddddd ** data byte 73 instance config 2
| | |
0ddddddd ** data byte 101
\-----------------------------------------------------/
/-Optional--------------------------------------------\
0ddddddd ** data byte 102 instance config 3
| | |
0ddddddd ** data byte 131
\-----------------------------------------------------/
0eeeeeee ** checksum (masked 2's comp. of sum of ** bytes)
11110111 F7 Status - end sysex
Data Structure: MicroDexed Setup Dump

Loading…
Cancel
Save