Removing EEPROMAnything and using EEPROM.get()/EEPROM.put() from EEPROM.h instead.

Trying to fix storing/loading of EEPROM data.
pull/15/head
Holger Wirtz 5 years ago
parent 9d72cc2a3a
commit 76768533a4
  1. 53
      EEPROMAnything.h
  2. 156
      MicroDexed.ino
  3. 12
      config.h
  4. 40
      dexed.cpp
  5. 76
      source_microdexed.h

@ -1,53 +0,0 @@
/*
MicroDexed
MicroDexed is a port of the Dexed sound engine
(https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6 with audio shield.
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android
(c)2018 H. Wirtz <wirtz@parasitstudio.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
// Idea from: https://playground.arduino.cc/Code/EEPROMWriteAnything/
#include <EEPROM.h>
#include <Arduino.h> // for type definitions
uint32_t crc32(uint8_t* calc_start, uint16_t calc_bytes);
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
uint8_t* p = (uint8_t*)(const void*)&value;
uint16_t i;
uint32_t checksum=crc32(p+4,sizeof(value)-4);
*p=checksum;
for (i = 0; i < sizeof(value); i++)
EEPROM.update(ee++, *p++);
return i;
}
template <class T> int EEPROM_readAnything(int ee, T& value)
{
uint8_t* p = (uint8_t*)(void*)&value;
unsigned int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}

@ -30,7 +30,6 @@
#include <SD.h> #include <SD.h>
#include <MIDI.h> #include <MIDI.h>
#include <EEPROM.h> #include <EEPROM.h>
#include "EEPROMAnything.h"
#include "midi_devices.hpp" #include "midi_devices.hpp"
#include "dexed.h" #include "dexed.h"
#include "dexed_sysex.h" #include "dexed_sysex.h"
@ -117,7 +116,11 @@ AudioOutputAnalogStereo dacOut;
AudioConnection patchCord32(stereomono1, 0, dacOut, 0); AudioConnection patchCord32(stereomono1, 0, dacOut, 0);
AudioConnection patchCord33(stereomono1, 1, dacOut, 1); AudioConnection patchCord33(stereomono1, 1, dacOut, 1);
#endif #endif
#ifdef USE_REVERB
AudioConnection * dynamicConnections[NUM_DEXED * 6]; AudioConnection * dynamicConnections[NUM_DEXED * 6];
#else
AudioConnection * dynamicConnections[NUM_DEXED * 5];
#endif
int nDynamic = 0; int nDynamic = 0;
void create_audio_connections(AudioSourceMicroDexed &d) void create_audio_connections(AudioSourceMicroDexed &d)
@ -130,10 +133,6 @@ void create_audio_connections(AudioSourceMicroDexed &d)
#if defined(USE_REVERB) #if defined(USE_REVERB)
dynamicConnections[nDynamic++] = new AudioConnection(d, 0, freeverbs1, 0); dynamicConnections[nDynamic++] = new AudioConnection(d, 0, freeverbs1, 0);
#endif #endif
for (int i = 0; i < nDynamic; i++) {
if (dynamicConnections[i] == NULL)
Serial.printf ("Bad connection %d\n", i);
}
} }
bool sd_card_available = false; bool sd_card_available = false;
@ -195,14 +194,14 @@ void setup()
pinMode(U8X8_CS_PIN, OUTPUT); pinMode(U8X8_CS_PIN, OUTPUT);
#endif #endif
delay(320); // necessary, because before this time no serial output is done :(
#ifdef ENABLE_LCD_UI #ifdef ENABLE_LCD_UI
setup_ui(); setup_ui();
#else #else
Serial.println(F("NO LCD DISPLAY ENABLED!")); Serial.println(F("NO LCD DISPLAY ENABLED!"));
#endif #endif
delay(220); // necessary, because before this time no serial output is done :(
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,2019 H. Wirtz <wirtz@parasitstudio.de>")); Serial.println(F("(c)2018,2019 H. Wirtz <wirtz@parasitstudio.de>"));
Serial.println(F("https://codeberg.org/dcoredump/MicroDexed")); Serial.println(F("https://codeberg.org/dcoredump/MicroDexed"));
@ -214,14 +213,14 @@ void setup()
for (uint8_t i = 0; i < NUM_DEXED; i++) for (uint8_t i = 0; i < NUM_DEXED; i++)
{ {
AudioSourceMicroDexed* microdexed;
Serial.print(F("Creating MicroDexed instance ")); Serial.print(F("Creating MicroDexed instance "));
Serial.print(i, DEC); Serial.print(i, DEC);
microdexed = new AudioSourceMicroDexed(SAMPLE_RATE); Serial.flush();
create_audio_connections(*microdexed); MicroDexed[i] = new AudioSourceMicroDexed(SAMPLE_RATE);
MicroDexed[i] = microdexed; //create_audio_connections(*MicroDexed[i]);
Serial.println(F("... created")); Serial.println(F("... created"));
Serial.flush();
} }
// Init EEPROM if both buttons are pressed at startup // Init EEPROM if both buttons are pressed at startup
@ -236,7 +235,7 @@ void setup()
initial_values_from_eeprom(true); initial_values_from_eeprom(true);
} }
else*/ else*/
initial_values_from_eeprom(true); initial_values_from_eeprom(false);
#if defined(TEENSY_AUDIO_BOARD) #if defined(TEENSY_AUDIO_BOARD)
sgtl5000_1.enable(); sgtl5000_1.enable();
@ -281,6 +280,7 @@ void setup()
#else #else
Serial.println(F("Internal DAC enabled.")); Serial.println(F("Internal DAC enabled."));
#endif #endif
Serial.flush();
// start SD card // start SD card
#ifndef TEENSY4 #ifndef TEENSY4
@ -326,6 +326,7 @@ void setup()
Serial.print(F("[")); Serial.print(F("["));
Serial.print(voice_names[instance_id][n]); Serial.print(voice_names[instance_id][n]);
Serial.println(F("]")); Serial.println(F("]"));
Serial.flush();
} }
#endif #endif
@ -491,19 +492,14 @@ void loop()
} }
#endif #endif
// EEPROM update handling
if (autostore >= AUTOSTORE_MS && active_voices == 0 && eeprom_update_flag == true)
{
// only store configuration data to EEPROM when AUTOSTORE_MS is reached and no voices are activated anymore
eeprom_update();
}
// MIDI input handling // MIDI input handling
check_midi_devices(); check_midi_devices();
// CONTROL-RATE-EVENT-HANDLING // CONTROL-RATE-EVENT-HANDLING
if (control_rate > CONTROL_RATE_MS) if (control_rate > CONTROL_RATE_MS)
{ {
control_rate = 0;
#ifdef ENABLE_LCD_UI #ifdef ENABLE_LCD_UI
// LCD Menu // LCD Menu
LCDML.loop(); LCDML.loop();
@ -515,7 +511,14 @@ void loop()
UI_func_voice_selection(0); UI_func_voice_selection(0);
} }
#endif #endif
control_rate = 0;
// EEPROM update handling
//if (autostore >= AUTOSTORE_MS && active_voices == 0 && eeprom_update_flag == true)
if (autostore >= AUTOSTORE_MS && eeprom_update_flag == true)
{
// only store configuration data to EEPROM when AUTOSTORE_MS is reached and no voices are activated anymore
eeprom_update();
}
// check for value changes and unused voices // check for value changes and unused voices
soften_volume.tick(); soften_volume.tick();
@ -1135,8 +1138,8 @@ void initial_values_from_eeprom(bool init)
init_configuration(); init_configuration();
else else
{ {
EEPROM_readAnything(EEPROM_START_ADDRESS, tmp_conf); EEPROM.get(EEPROM_START_ADDRESS, tmp_conf);
checksum = crc32((byte*)&tmp_conf + 4, sizeof(tmp_conf) - 4); checksum = crc32((uint32_t*)&tmp_conf + 4, sizeof(tmp_conf) - 4);
#ifdef DEBUG #ifdef DEBUG
Serial.print(F("EEPROM checksum: 0x")); Serial.print(F("EEPROM checksum: 0x"));
@ -1154,54 +1157,54 @@ void initial_values_from_eeprom(bool init)
} }
else else
{ {
/* EEPROM.get(EEPROM_START_ADDRESS, configuration);
configuration.instances = INSTANCES_MAX;
configuration.instance_mode = INSTANCE_MODE_MAX; configuration.instances %= INSTANCES_MAX;
configuration.instance_splitpoint = INSTANCE_SPLITPOINT_MAX; configuration.instance_mode %= INSTANCE_MODE_MAX;
configuration.vol = VOLUME_MAX; configuration.instance_splitpoint %= INSTANCE_SPLITPOINT_MAX;
configuration.mono = MONO_MAX; configuration.vol %= VOLUME_MAX;
configuration.reverb_roomsize = REVERB_ROOMSIZE_MAX; configuration.mono %= MONO_MAX;
configuration.reverb_damping = REVERB_DAMPING_MAX; configuration.reverb_roomsize %= REVERB_ROOMSIZE_MAX;
configuration.chorus_frequency = CHORUS_FREQUENCY_MAX; configuration.reverb_damping %= REVERB_DAMPING_MAX;
configuration.chorus_waveform = CHORUS_WAVEFORM_MAX; configuration.chorus_frequency %= CHORUS_FREQUENCY_MAX;
configuration.chorus_depth = CHORUS_DEPTH_MAX; configuration.chorus_waveform %= CHORUS_WAVEFORM_MAX;
configuration.delay_time = DELAY_TIME_MAX; configuration.chorus_depth %= CHORUS_DEPTH_MAX;
configuration.delay_feedback = DELAY_FEEDBACK_MAX; */ configuration.delay_time %= DELAY_TIME_MAX;
configuration.delay_feedback %= DELAY_FEEDBACK_MAX;
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++)
{ {
/* configuration.dexed[instance_id].midi_channel %= MIDI_CHANNEL_MAX;
configuration.dexed[instance_id].midi_channel = MIDI_CHANNEL_MAX; configuration.dexed[instance_id].bank %= MAX_BANKS;
configuration.dexed[instance_id].bank = MAX_BANKS; configuration.dexed[instance_id].voice %= MAX_VOICES;
configuration.dexed[instance_id].voice = MAX_VOICES; configuration.dexed[instance_id].pan %= PANORAMA_MAX;
configuration.dexed[instance_id].pan = PANORAMA_MAX; configuration.dexed[instance_id].reverb_level %= REVERB_LEVEL_MAX;
configuration.dexed[instance_id].reverb_level = REVERB_LEVEL_MAX; configuration.dexed[instance_id].chorus_level %= CHORUS_LEVEL_MAX;
configuration.dexed[instance_id].chorus_level = CHORUS_LEVEL_MAX; configuration.dexed[instance_id].delay_level %= DELAY_LEVEL_MAX;
configuration.dexed[instance_id].delay_level = DELAY_LEVEL_MAX; configuration.dexed[instance_id].filter_cutoff %= FILTER_CUTOFF_MAX;
configuration.dexed[instance_id].filter_cutoff = FILTER_CUTOFF_MAX; configuration.dexed[instance_id].filter_resonance %= FILTER_RESONANCE_MAX;
configuration.dexed[instance_id].filter_resonance = FILTER_RESONANCE_MAX; configuration.dexed[instance_id].loudness %= LOUDNESS_MAX;
configuration.dexed[instance_id].loudness = LOUDNESS_MAX; configuration.dexed[instance_id].polyphony %= POLYPHONY_MAX;
configuration.dexed[instance_id].polyphony = POLYPHONY_MAX; configuration.dexed[instance_id].engine %= ENGINE_MAX;
configuration.dexed[instance_id].engine = ENGINE_MAX; configuration.dexed[instance_id].monopoly %= MONOPOLY_MAX;
configuration.dexed[instance_id].monopoly = MONOPOLY_MAX; configuration.dexed[instance_id].pb_range %= PB_RANGE_MAX;
configuration.dexed[instance_id].pb_range = PB_RANGE_MAX; configuration.dexed[instance_id].pb_step %= PB_STEP_MAX;
configuration.dexed[instance_id].pb_step = PB_STEP_MAX; configuration.dexed[instance_id].mw_range %= MW_RANGE_MAX;
configuration.dexed[instance_id].mw_range = MW_RANGE_MAX; configuration.dexed[instance_id].mw_assign %= MW_ASSIGN_MAX;
configuration.dexed[instance_id].mw_assign = MW_ASSIGN_MAX; configuration.dexed[instance_id].fc_range %= FC_RANGE_MAX;
configuration.dexed[instance_id].fc_range = FC_RANGE_MAX; configuration.dexed[instance_id].fc_assign %= FC_ASSIGN_MAX;
configuration.dexed[instance_id].fc_assign = FC_ASSIGN_MAX; configuration.dexed[instance_id].bc_range %= BC_RANGE_MAX;
configuration.dexed[instance_id].bc_range = BC_RANGE_MAX; configuration.dexed[instance_id].bc_assign %= BC_ASSIGN_MAX;
configuration.dexed[instance_id].bc_assign = BC_ASSIGN_MAX; configuration.dexed[instance_id].at_range %= AT_RANGE_MAX;
configuration.dexed[instance_id].at_range = AT_RANGE_MAX; configuration.dexed[instance_id].at_assign %= AT_ASSIGN_MAX;
configuration.dexed[instance_id].at_assign = AT_ASSIGN_MAX; configuration.dexed[instance_id].op_enabled %= 0x3f;
configuration.dexed[instance_id].op_enabled = 0x3f; */
MicroDexed[instance_id]->setPBController(configuration.dexed[instance_id].pb_range, configuration.dexed[instance_id].pb_step); MicroDexed[instance_id]->setPBController(configuration.dexed[instance_id].pb_range, configuration.dexed[instance_id].pb_step);
MicroDexed[instance_id]->setMWController(configuration.dexed[instance_id].mw_range, configuration.dexed[instance_id].mw_assign); MicroDexed[instance_id]->setMWController(configuration.dexed[instance_id].mw_range, configuration.dexed[instance_id].mw_assign);
MicroDexed[instance_id]->setFCController(configuration.dexed[instance_id].fc_range, configuration.dexed[instance_id].fc_assign); MicroDexed[instance_id]->setFCController(configuration.dexed[instance_id].fc_range, configuration.dexed[instance_id].fc_assign);
MicroDexed[instance_id]->setBCController(configuration.dexed[instance_id].bc_range, configuration.dexed[instance_id].bc_assign); MicroDexed[instance_id]->setBCController(configuration.dexed[instance_id].bc_range, configuration.dexed[instance_id].bc_assign);
MicroDexed[instance_id]->setATController(configuration.dexed[instance_id].at_range, configuration.dexed[instance_id].at_assign); MicroDexed[instance_id]->setATController(configuration.dexed[instance_id].at_range, configuration.dexed[instance_id].at_assign);
MicroDexed[instance_id]->setOPs(configuration.dexed[instance_id].op_enabled);
MicroDexed[instance_id]-> setOPs(configuration.dexed[instance_id].op_enabled); MicroDexed[instance_id]->doRefreshVoice();
} }
Serial.println(F("OK, loaded!")); Serial.println(F("OK, loaded!"));
} }
@ -1217,8 +1220,11 @@ void initial_values_from_eeprom(bool init)
void init_configuration(void) void init_configuration(void)
{ {
configuration.checksum = 0xffff; #ifdef DEBUG
Serial.print(F("Initializing configuration"));
#endif
configuration.checksum = 0xffff;
configuration.instances = INSTANCES_DEFAULT; configuration.instances = INSTANCES_DEFAULT;
configuration.instance_mode = INSTANCE_MODE_DEFAULT; configuration.instance_mode = INSTANCE_MODE_DEFAULT;
configuration.instance_splitpoint = INSTANCE_SPLITPOINT_DEFAULT; configuration.instance_splitpoint = INSTANCE_SPLITPOINT_DEFAULT;
@ -1258,6 +1264,7 @@ void init_configuration(void)
configuration.dexed[instance_id].at_assign = AT_ASSIGN_DEFAULT; configuration.dexed[instance_id].at_assign = AT_ASSIGN_DEFAULT;
configuration.dexed[instance_id].op_enabled = OP_ENABLED_DEFAULT; configuration.dexed[instance_id].op_enabled = OP_ENABLED_DEFAULT;
} }
eeprom_update();
} }
void eeprom_write(void) void eeprom_write(void)
@ -1269,16 +1276,14 @@ void eeprom_write(void)
void eeprom_update(void) void eeprom_update(void)
{ {
eeprom_update_flag = false; eeprom_update_flag = false;
configuration.checksum = crc32((byte*)&configuration + 4, sizeof(configuration) - 4); configuration.checksum = crc32((uint32_t*)&configuration + 4, sizeof(configuration) - 4);
EEPROM_writeAnything(EEPROM_START_ADDRESS, configuration); EEPROM.put(EEPROM_START_ADDRESS, configuration);
Serial.println(F("Updating EEPROM with configuration data:")); Serial.println(F("Updating EEPROM"));
#ifdef DEBUG
show_configuration();
#endif
} }
uint32_t crc32(byte * calc_start, uint16_t calc_bytes) // base code from https://www.arduino.cc/en/Tutorial/EEPROMCrc uint32_t crc32(uint32_t* calc_start, uint16_t calc_bytes) // base code from https://www.arduino.cc/en/Tutorial/EEPROMCrc
{ {
uint32_t* index;
const uint32_t crc_table[16] = const uint32_t crc_table[16] =
{ {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
@ -1288,7 +1293,7 @@ uint32_t crc32(byte * calc_start, uint16_t calc_bytes) // base code from https:/
}; };
uint32_t crc = ~0L; uint32_t crc = ~0L;
for (byte* index = calc_start ; index < (calc_start + calc_bytes) ; ++index) for (index = calc_start ; index < (calc_start + calc_bytes) ; ++index)
{ {
crc = crc_table[(crc ^ *index) & 0x0f] ^ (crc >> 4); crc = crc_table[(crc ^ *index) & 0x0f] ^ (crc >> 4);
crc = crc_table[(crc ^ (*index >> 4)) & 0x0f] ^ (crc >> 4); crc = crc_table[(crc ^ (*index >> 4)) & 0x0f] ^ (crc >> 4);
@ -1337,6 +1342,7 @@ void show_cpu_and_mem_usage(void)
Serial.print(F(" ACTIVE_VOICES: ")); Serial.print(F(" ACTIVE_VOICES: "));
Serial.print(active_voices, DEC); Serial.print(active_voices, DEC);
Serial.println(); Serial.println();
Serial.flush();
AudioProcessorUsageMaxReset(); AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset(); AudioMemoryUsageMaxReset();
} }
@ -1360,6 +1366,7 @@ void show_configuration(void)
Serial.print(F("Chorus Depth ")); Serial.println(configuration.chorus_depth, DEC); Serial.print(F("Chorus Depth ")); Serial.println(configuration.chorus_depth, DEC);
Serial.print(F("Delay Time ")); Serial.println(configuration.delay_time, DEC); Serial.print(F("Delay Time ")); Serial.println(configuration.delay_time, DEC);
Serial.print(F("Delay Feedback ")); Serial.println(configuration.delay_feedback, DEC); Serial.print(F("Delay Feedback ")); Serial.println(configuration.delay_feedback, DEC);
Serial.flush();
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++)
{ {
Serial.print(F("=== DEXED INSTANCE ")); Serial.print(F("=== DEXED INSTANCE "));
@ -1389,6 +1396,7 @@ void show_configuration(void)
Serial.print(F(" Aftertouch Range ")); Serial.println(configuration.dexed[instance_id].at_range, DEC); Serial.print(F(" Aftertouch Range ")); Serial.println(configuration.dexed[instance_id].at_range, DEC);
Serial.print(F(" Aftertouch Assign ")); Serial.println(configuration.dexed[instance_id].at_assign, DEC); Serial.print(F(" Aftertouch Assign ")); Serial.println(configuration.dexed[instance_id].at_assign, DEC);
Serial.print(F(" OP Enabled ")); Serial.println(configuration.dexed[instance_id].op_enabled, DEC); Serial.print(F(" OP Enabled ")); Serial.println(configuration.dexed[instance_id].op_enabled, DEC);
Serial.flush();
} }
Serial.println(); Serial.println();
} }
@ -1450,6 +1458,7 @@ void show_patch(uint8_t instance_id)
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_FREQ_FINE], DEC); Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_FREQ_FINE], DEC);
Serial.print(F(" ")); Serial.print(F(" "));
Serial.println(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_OSC_DETUNE], DEC); Serial.println(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_OSC_DETUNE], DEC);
Serial.flush();
} }
Serial.println(F("PR1 | PR2 | PR3 | PR4 | PL1 | PL2 | PL3 | PL4")); Serial.println(F("PR1 | PR2 | PR3 | PR4 | PL1 | PL2 | PL3 | PL4"));
Serial.print(F(" ")); Serial.print(F(" "));
@ -1457,6 +1466,7 @@ void show_patch(uint8_t instance_id)
{ {
Serial.print(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + i], DEC); Serial.print(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + i], DEC);
Serial.print(F(" ")); Serial.print(F(" "));
Serial.flush();
} }
Serial.println(); Serial.println();
Serial.print(F("ALG: ")); Serial.print(F("ALG: "));
@ -1486,11 +1496,13 @@ void show_patch(uint8_t instance_id)
Serial.print(F("[")); Serial.print(F("["));
Serial.print(voicename); Serial.print(voicename);
Serial.println(F("]")); Serial.println(F("]"));
Serial.flush();
for (i = DEXED_GLOBAL_PARAMETER_OFFSET; i <= DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MAX_NOTES; i++) for (i = DEXED_GLOBAL_PARAMETER_OFFSET; i <= DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MAX_NOTES; i++)
{ {
Serial.print(i, DEC); Serial.print(i, DEC);
Serial.print(F(": ")); Serial.print(F(": "));
Serial.println(MicroDexed[instance_id]->data[i]); Serial.println(MicroDexed[instance_id]->data[i]);
Serial.flush();
} }
Serial.println(); Serial.println();

@ -200,7 +200,7 @@
#define VOICE_SELECTION_MS 2000 #define VOICE_SELECTION_MS 2000
// EEPROM address // EEPROM address
#define EEPROM_START_ADDRESS 0 #define EEPROM_START_ADDRESS 100
#define MAX_BANKS 100 #define MAX_BANKS 100
#define MAX_VOICES 32 // voices per bank #define MAX_VOICES 32 // voices per bank
@ -413,7 +413,7 @@ enum { DEXED, REVERB, DELAY, CHORUS };
#define INSTANCE_SPLITPOINT_DEFAULT MIDI_C3 #define INSTANCE_SPLITPOINT_DEFAULT MIDI_C3
// //
struct dexed_t { typedef struct {
uint8_t midi_channel; uint8_t midi_channel;
uint8_t bank; uint8_t bank;
uint8_t voice; uint8_t voice;
@ -438,10 +438,10 @@ struct dexed_t {
uint8_t at_range; uint8_t at_range;
uint8_t at_assign; uint8_t at_assign;
uint8_t op_enabled; uint8_t op_enabled;
}; } dexed_t;
// struct for holding the current configuration // struct for holding the current configuration
struct config_t { typedef struct {
uint32_t checksum; uint32_t checksum;
uint8_t instances; uint8_t instances;
uint8_t instance_mode; uint8_t instance_mode;
@ -455,8 +455,8 @@ struct config_t {
uint8_t chorus_depth; uint8_t chorus_depth;
uint8_t delay_time; uint8_t delay_time;
uint8_t delay_feedback; uint8_t delay_feedback;
struct dexed_t dexed[NUM_DEXED]; dexed_t dexed[NUM_DEXED];
}; } config_t;
inline float mapfloat(float val, float in_min, float in_max, float out_min, float out_max) inline float mapfloat(float val, float in_min, float in_max, float out_min, float out_max)
{ {

@ -172,12 +172,12 @@ void Dexed::getSamples(uint16_t n_samples, int16_t* buffer)
fx.process(sumbuf, n_samples); fx.process(sumbuf, n_samples);
//#ifdef USE_TEENSY_DSP //#ifdef USE_TEENSY_DSP
//arm_float_to_q15(sumbuf, buffer, AUDIO_BLOCK_SAMPLES); //arm_float_to_q15(sumbuf, buffer, AUDIO_BLOCK_SAMPLES);
//#else //#else
for (i = 0; i < n_samples; ++i) for (i = 0; i < n_samples; ++i)
buffer[i] = static_cast<int16_t>(sumbuf[i] * 0x7fff); buffer[i] = static_cast<int16_t>(sumbuf[i] * 0x7fff);
//#endif //#endif
} }
void Dexed::keydown(uint8_t pitch, uint8_t velo) { void Dexed::keydown(uint8_t pitch, uint8_t velo) {
@ -608,12 +608,14 @@ void Dexed::setPBController(uint8_t pb_range, uint8_t pb_step)
pb_range %= PB_RANGE_MAX; pb_range %= PB_RANGE_MAX;
pb_step %= PB_STEP_MAX; pb_step %= PB_STEP_MAX;
#ifdef DEBUG /*
Serial.print(F("pb_range=")); #ifdef DEBUG
Serial.println(pb_range, DEC); Serial.print(F("pb_range="));
Serial.print(F("pb_step=")); Serial.println(pb_range, DEC);
Serial.println(pb_step, DEC); Serial.print(F("pb_step="));
#endif Serial.println(pb_step, DEC);
#endif
*/
data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_RANGE] = pb_range; data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_RANGE] = pb_range;
controllers.values_[kControllerPitchRange] = pb_range; controllers.values_[kControllerPitchRange] = pb_range;
@ -632,12 +634,14 @@ void Dexed::setMWController(uint8_t mw_range, uint8_t mw_assign)
mw_range %= MW_RANGE_MAX; mw_range %= MW_RANGE_MAX;
mw_assign %= MW_ASSIGN_MAX; mw_assign %= MW_ASSIGN_MAX;
#ifdef DEBUG /*
Serial.print(F("mw_range=")); #ifdef DEBUG
Serial.println(mw_range, DEC); Serial.print(F("mw_range="));
Serial.print(F("mw_assign=")); Serial.println(mw_range, DEC);
Serial.println(mw_assign, DEC); Serial.print(F("mw_assign="));
#endif Serial.println(mw_assign, DEC);
#endif
*/
data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_RANGE] = mw_range; data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_RANGE] = mw_range;
controllers.wheel.setRange(mw_range); controllers.wheel.setRange(mw_range);
@ -656,12 +660,14 @@ void Dexed::setFCController(uint8_t fc_range, uint8_t fc_assign)
fc_range %= FC_RANGE_MAX; fc_range %= FC_RANGE_MAX;
fc_assign %= FC_ASSIGN_MAX; fc_assign %= FC_ASSIGN_MAX;
/*
#ifdef DEBUG #ifdef DEBUG
Serial.print(F("fc_range=")); Serial.print(F("fc_range="));
Serial.println(fc_range, DEC); Serial.println(fc_range, DEC);
Serial.print(F("fc_assign=")); Serial.print(F("fc_assign="));
Serial.println(fc_assign, DEC); Serial.println(fc_assign, DEC);
#endif #endif
*/
data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_RANGE] = fc_range; data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_RANGE] = fc_range;
controllers.foot.setRange(fc_range); controllers.foot.setRange(fc_range);
@ -680,12 +686,14 @@ void Dexed::setBCController(uint8_t bc_range, uint8_t bc_assign)
bc_range %= BC_RANGE_MAX; bc_range %= BC_RANGE_MAX;
bc_assign %= BC_ASSIGN_MAX; bc_assign %= BC_ASSIGN_MAX;
/*
#ifdef DEBUG #ifdef DEBUG
Serial.print(F("bc_range=")); Serial.print(F("bc_range="));
Serial.println(bc_range, DEC); Serial.println(bc_range, DEC);
Serial.print(F("bc_assign=")); Serial.print(F("bc_assign="));
Serial.println(bc_assign, DEC); Serial.println(bc_assign, DEC);
#endif #endif
*/
data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_RANGE] = bc_range; data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_RANGE] = bc_range;
controllers.breath.setRange(bc_range); controllers.breath.setRange(bc_range);
@ -704,12 +712,14 @@ void Dexed::setATController(uint8_t at_range, uint8_t at_assign)
at_range %= AT_RANGE_MAX; at_range %= AT_RANGE_MAX;
at_assign %= AT_ASSIGN_MAX; at_assign %= AT_ASSIGN_MAX;
/*
#ifdef DEBUG #ifdef DEBUG
Serial.print(F("at_range=")); Serial.print(F("at_range="));
Serial.println(at_range, DEC); Serial.println(at_range, DEC);
Serial.print(F("at_assign=")); Serial.print(F("at_assign="));
Serial.println(at_assign, DEC); Serial.println(at_assign, DEC);
#endif #endif
*/
data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_RANGE] = at_range; data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_RANGE] = at_range;
controllers.at.setRange(at_range); controllers.at.setRange(at_range);

@ -5,44 +5,42 @@
#include <AudioStream.h> #include <AudioStream.h>
class AudioSourceMicroDexed : public AudioStream, public Dexed { class AudioSourceMicroDexed : public AudioStream, public Dexed {
public: public:
const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES); const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES);
uint32_t xrun = 0; uint32_t xrun = 0;
uint16_t render_time_max = 0; uint16_t render_time_max = 0;
AudioSourceMicroDexed(int sample_rate) : AudioStream(0, NULL), Dexed(sample_rate) { AudioSourceMicroDexed(int sample_rate) : AudioStream(0, NULL), Dexed(sample_rate) { };
}; void update(void) {
void update(void) { if (in_update) {
if (in_update) { xrun++;
xrun++; return;
return; }
} else in_update = true;
else in_update = true;
elapsedMicros render_time;
audio_block_t *lblock;
lblock = allocate();
if (!lblock) {
in_update = false;
return;
}
getSamples(AUDIO_BLOCK_SAMPLES, lblock->data);
if (render_time > audio_block_time_us) // everything greater 2.9ms is a buffer underrun!
xrun++;
if (render_time > audio_block_time_us - (audio_block_time_us / 10)) {
Serial.println("At CPU Limit");
uint8_t nnotes = getNumNotesPlaying();
//setMaxNotes(nnotes);
max_notes = nnotes;
}
if (render_time > render_time_max) elapsedMicros render_time;
render_time_max = render_time; audio_block_t *lblock;
lblock = allocate();
transmit(lblock, 0); if (!lblock) {
release(lblock); in_update = false;
in_update = false; return;
}; }
private: getSamples(AUDIO_BLOCK_SAMPLES, lblock->data);
volatile bool in_update = false; if (render_time > audio_block_time_us) // everything greater 2.9ms is a buffer underrun!
xrun++;
/* if (render_time > audio_block_time_us - (audio_block_time_us / 10)) {
Serial.println("At CPU Limit");
uint8_t nnotes = getNumNotesPlaying();
//setMaxNotes(nnotes);
max_notes = nnotes;
} */
if (render_time > render_time_max)
render_time_max = render_time;
transmit(lblock, 0);
release(lblock);
in_update = false;
};
private:
volatile bool in_update = false;
}; };

Loading…
Cancel
Save