diff --git a/MicroDexed.ino b/MicroDexed.ino index c75796e..a0fb186 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -216,7 +216,7 @@ uint8_t active_voices[NUM_DEXED]; #ifdef SHOW_CPU_LOAD_MSEC elapsedMillis cpu_mem_millis; #endif -//uint32_t overload = 0; +uint32_t cpumax = 0; uint32_t peak_dexed = 0; float peak_dexed_value = 0.0; uint32_t peak_r = 0; @@ -773,8 +773,9 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) break; case 107: // CC 107: delay volume configuration.dexed[instance_id].delay_send = map(inValue, 0, 0x7f, DELAY_SEND_MIN, DELAY_SEND_MAX); - master_mixer_r.gain(DELAY, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); - master_mixer_l.gain(DELAY, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); + set_master_mixer_gain(DELAY, configuration.delay_level / 100.0); + //master_mixer_r.gain(DELAY, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); + //master_mixer_l.gain(DELAY, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); eeprom_write(); break; case 120: @@ -1365,6 +1366,11 @@ void check_configuration(void) configuration.dexed[instance_id].portamento_time = constrain(configuration.dexed[instance_id].portamento_time, PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX); configuration.dexed[instance_id].op_enabled = constrain(configuration.dexed[instance_id].op_enabled, OP_ENABLED_MIN, OP_ENABLED_MAX); } + set_master_mixer_gain(CHORUS, configuration.chorus_level / 100.0); + set_master_mixer_gain(DELAY, configuration.delay_level / 100.0); +#if defined(USE_REVERB) + set_master_mixer_gain(REVERB, configuration.reverb_level / 100.0); +#endif } void init_configuration(void) @@ -1462,40 +1468,39 @@ uint32_t crc32(byte * calc_start, uint16_t calc_bytes) // base code from https:/ return (crc); } -/* - void set_master_mixer_gain(uint8_t type, float level) - { +void set_master_mixer_gain(uint8_t type, float level) +{ master_mixer_level[type] = constrain(level, 0.0, 1.0); - #if defined(USE_REVERB) +#if defined(USE_REVERB) const uint8_t num_fx = 4; - #else +#else const uint8_t num_fx = 3; - #endif +#endif float new_level[num_fx]; new_level[CHORUS] = master_mixer_level[CHORUS] / float(num_fx); new_level[DELAY] = master_mixer_level[DELAY] / float(num_fx); - #if defined(USE_REVERB) +#if defined(USE_REVERB) new_level[REVERB] = master_mixer_level[REVERB] / float(num_fx); new_level[DEXED] = 1.0 - new_level[CHORUS] - new_level[DELAY] - new_level[REVERB]; - #else +#else new_level[DEXED] = 1.0 - new_level[CHORUS] - new_level[DELAY]; - #endif - - master_mixer_r.gain(DEXED, new_level[DEXED]); - master_mixer_l.gain(DEXED, new_level[DEXED]); - master_mixer_r.gain(CHORUS, new_level[CHORUS]); - master_mixer_l.gain(CHORUS, new_level[CHORUS]); - master_mixer_r.gain(DELAY, new_level[DELAY]); - master_mixer_l.gain(DELAY, new_level[DELAY]); - #if defined(USE_REVERB) - master_mixer_r.gain(REVERB, new_level[REVERB]); - master_mixer_l.gain(REVERB, new_level[REVERB]); - #endif - - #ifdef DEBUG +#endif + + master_mixer_r.gain(DEXED, new_level[DEXED]); + master_mixer_l.gain(DEXED, new_level[DEXED]); + master_mixer_r.gain(CHORUS, new_level[CHORUS]); + master_mixer_l.gain(CHORUS, new_level[CHORUS]); + master_mixer_r.gain(DELAY, new_level[DELAY]); + master_mixer_l.gain(DELAY, new_level[DELAY]); +#if defined(USE_REVERB) + master_mixer_r.gain(REVERB, new_level[REVERB]); + master_mixer_l.gain(REVERB, new_level[REVERB]); +#endif + +#ifdef DEBUG Serial.print(F("Volumes for master_mixer(type=")); Serial.print(type, DEC); Serial.print(F(",level=")); @@ -1506,15 +1511,14 @@ uint32_t crc32(byte * calc_start, uint16_t calc_bytes) // base code from https:/ Serial.print(new_level[CHORUS], 2); Serial.print(F(" DELAY=")); Serial.print(new_level[DELAY], 2); - #if defined(USE_REVERB) +#if defined(USE_REVERB) Serial.print(F(" REVERB=")); Serial.print(new_level[REVERB], 2); - #endif +#endif Serial.println(); - #endif - } -*/ +#endif +} /****************************************************************************** DEBUG HELPER @@ -1534,11 +1538,20 @@ void show_cpu_and_mem_usage(void) sum_overload += MicroDexed[instance_id]->overload; MicroDexed[instance_id]->render_time_max = 0; } + if (AudioProcessorUsageMax() > 99.9) + { + cpumax++; + Serial.print(F("*")); + } + else + Serial.print(F("")); Serial.print(F("CPU:")); Serial.print(AudioProcessorUsage(), 2); Serial.print(F("%|CPUMAX:")); Serial.print(AudioProcessorUsageMax(), 2); - Serial.print(F("%|MEM:")); + Serial.print(F("%|CPUMAXCNT:")); + Serial.print(cpumax,DEC); + Serial.print(F("|MEM:")); Serial.print(AudioMemoryUsage(), DEC); Serial.print(F("|MEMMAX:")); Serial.print(AudioMemoryUsageMax(), DEC); diff --git a/UI.hpp b/UI.hpp index 429e888..22ab2e5 100644 --- a/UI.hpp +++ b/UI.hpp @@ -57,6 +57,7 @@ extern void strip_extension(char* s, char *target); extern void eeprom_write(void); extern bool get_voice_names_from_bank(uint8_t b, uint8_t instance_id); extern bool load_sysex(uint8_t b, uint8_t v); +extern void set_master_mixer_gain(uint8_t type, float level); #ifdef DISPLAY_LCD_SPI extern void change_disp_sd(bool d); #endif @@ -1160,8 +1161,9 @@ void UI_func_reverb_level(uint8_t param) } } - master_mixer_r.gain(REVERB, mapfloat(configuration.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); - master_mixer_l.gain(REVERB, mapfloat(configuration.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); + set_master_mixer_gain(REVERB, configuration.reverb_level / 100.0); + //master_mixer_r.gain(REVERB, mapfloat(configuration.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); + //master_mixer_l.gain(REVERB, mapfloat(configuration.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); } lcd.setCursor(0, 1); @@ -1429,8 +1431,9 @@ void UI_func_chorus_level(uint8_t param) } } - master_mixer_r.gain(CHORUS, mapfloat(configuration.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); - master_mixer_l.gain(CHORUS, mapfloat(configuration.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); + set_master_mixer_gain(CHORUS, configuration.chorus_level / 100.0); + //master_mixer_r.gain(CHORUS, mapfloat(configuration.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); + //master_mixer_l.gain(CHORUS, mapfloat(configuration.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); } lcd.setCursor(0, 1); @@ -1637,8 +1640,9 @@ void UI_func_delay_level(uint8_t param) } } - master_mixer_r.gain(DELAY, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); - master_mixer_l.gain(DELAY, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); + set_master_mixer_gain(DELAY, configuration.delay_level / 100.0); + //master_mixer_r.gain(DELAY, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); + //master_mixer_l.gain(DELAY, mapfloat(configuration.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); } lcd.setCursor(0, 1); diff --git a/config.h b/config.h index 1cc4003..c07e9f5 100644 --- a/config.h +++ b/config.h @@ -229,9 +229,9 @@ enum { DEXED, REVERB, DELAY, CHORUS }; // Teensy-3.6 settings #define MIDI_DEVICE_USB_HOST 1 #if defined(USE_REVERB) -#define MAX_NOTES 14 +#define MAX_NOTES 12 #else -#define MAX_NOTES 16 +#define MAX_NOTES 14 #endif #endif diff --git a/effect_mono_stereo.cpp b/effect_mono_stereo.cpp index 2375861..9816ffb 100644 --- a/effect_mono_stereo.cpp +++ b/effect_mono_stereo.cpp @@ -51,16 +51,19 @@ void AudioEffectMonoStereo::update(void) if (in && mod && out[0] && out[1]) { - float pan = mapfloat(mod->data[0], -1.0, 1.0, 0.0, 1.0); - const float f[2] = { _pseudo_log * arm_sin_f32(pan * PI / 2), _pseudo_log * arm_cos_f32(pan * PI / 2) }; // Pan [L0.0 ... M0.5 ... 1.0R] + arm_q15_to_float(in->data, in_f, AUDIO_BLOCK_SAMPLES); + arm_q15_to_float(mod->data, pan_f, AUDIO_BLOCK_SAMPLES); + arm_offset_f32(pan_f, 1.0, pan_f_tmp, AUDIO_BLOCK_SAMPLES); + arm_scale_f32(pan_f_tmp, PI / 4.0, pan_f, AUDIO_BLOCK_SAMPLES); // PI/4 - arm_q15_to_float (in->data, in_f, AUDIO_BLOCK_SAMPLES); - - for (uint8_t i = 0; i < 2; i++) - { - arm_scale_f32 (in_f, f[i], out_f[i], AUDIO_BLOCK_SAMPLES); - arm_float_to_q15 (out_f[i], out[i]->data, AUDIO_BLOCK_SAMPLES); - } + // right + for (uint8_t n = 0; n < AUDIO_BLOCK_SAMPLES; n++) + out_f[0][n] = in_f[n] * _pseudo_log * arm_sin_f32(pan_f[n]); + arm_float_to_q15 (out_f[0], out[0]->data, AUDIO_BLOCK_SAMPLES); + // left + for (uint8_t n = 0; n < AUDIO_BLOCK_SAMPLES; n++) + out_f[1][n] = in_f[n] * _pseudo_log * arm_cos_f32(pan_f[n]); + arm_float_to_q15 (out_f[1], out[1]->data, AUDIO_BLOCK_SAMPLES); if (in) { diff --git a/effect_mono_stereo.h b/effect_mono_stereo.h index 477fbaa..538d283 100644 --- a/effect_mono_stereo.h +++ b/effect_mono_stereo.h @@ -47,6 +47,8 @@ class AudioEffectMonoStereo : public AudioStream audio_block_t *out[2]; float in_f[AUDIO_BLOCK_SAMPLES]; float out_f[2][AUDIO_BLOCK_SAMPLES]; + float pan_f[AUDIO_BLOCK_SAMPLES]; + float pan_f_tmp[AUDIO_BLOCK_SAMPLES]; const float _pseudo_log = 1048575 / (float)(1 << 20); }; diff --git a/synth.h b/synth.h index 268f4ac..b37b9d3 100644 --- a/synth.h +++ b/synth.h @@ -64,14 +64,13 @@ inline static T max(const T& a, const T& b) { #define QER(n,b) ( ((float)n)/(1<