Fixes for chorus and stereo panning.

pull/112/head
Holger Wirtz 3 years ago
parent 021dd2075a
commit 68508e9148
  1. 50
      MicroDexed.ino
  2. 4
      UI.hpp
  3. 70
      effect_modulated_delay.cpp
  4. 9
      effect_modulated_delay.h
  5. 9
      effect_stereo_panorama.cpp

@ -85,9 +85,7 @@ AudioSynthWaveform ep_chorus_modulator;
#if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT #if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT
AudioFilterBiquad ep_modchorus_filter; AudioFilterBiquad ep_modchorus_filter;
#endif #endif
AudioEffectModulatedDelay ep_modchorus_r; AudioEffectModulatedDelayStereo ep_modchorus;
AudioEffectModulatedDelay ep_modchorus_l;
AudioAmplifier ep_chorus_inverter;
AudioMixer<2> ep_chorus_mixer_r; AudioMixer<2> ep_chorus_mixer_r;
AudioMixer<2> ep_chorus_mixer_l; AudioMixer<2> ep_chorus_mixer_l;
#endif #endif
@ -254,19 +252,16 @@ AudioConnection patchCord[] = {
#if defined(USE_FX) #if defined(USE_FX)
{ep_stereo_panorama, 0, ep_chorus_mixer_r, 0}, {ep_stereo_panorama, 0, ep_chorus_mixer_r, 0},
{ep_stereo_panorama, 1, ep_chorus_mixer_l, 0}, {ep_stereo_panorama, 1, ep_chorus_mixer_l, 0},
{ep_stereo_panorama, 0, ep_modchorus_r, 0}, {ep_stereo_panorama, 0, ep_modchorus, 0},
{ep_stereo_panorama, 1, ep_modchorus_l, 0}, {ep_stereo_panorama, 1, ep_modchorus, 1},
#if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT #if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT
{ep_chorus_modulator, 0, ep_modchorus_filter, 0}, {ep_chorus_modulator, 0, ep_modchorus_filter, 0},
{ep_modchorus_filter, 0, ep_modchorus_r, 1}, {ep_modchorus_filter, 0, ep_modchorus, 2},
{ep_modchorus_filter, 0, ep_chorus_inverter, 0},
#else #else
{ep_chorus_modulator, 0, ep_modchorus_r, 1}, {ep_chorus_modulator, 0, ep_modchorus, 2},
{ep_chorus_modulator, 0, ep_chorus_inverter, 0},
#endif #endif
{ep_chorus_inverter, 0, ep_modchorus_l, 1}, {ep_modchorus, 0, ep_chorus_mixer_r, 1},
{ep_modchorus_r, 0, ep_chorus_mixer_r, 1}, {ep_modchorus, 1, ep_chorus_mixer_l, 1},
{ep_modchorus_l, 0, ep_chorus_mixer_l, 1},
{ep_chorus_mixer_r, 0, reverb_mixer_r, REVERB_MIX_CH_EPIANO}, {ep_chorus_mixer_r, 0, reverb_mixer_r, REVERB_MIX_CH_EPIANO},
{ep_chorus_mixer_l, 0, reverb_mixer_l, REVERB_MIX_CH_EPIANO}, {ep_chorus_mixer_l, 0, reverb_mixer_l, REVERB_MIX_CH_EPIANO},
{ep_stereo_panorama, 0, master_mixer_r, MASTER_MIX_CH_EPIANO}, {ep_stereo_panorama, 0, master_mixer_r, MASTER_MIX_CH_EPIANO},
@ -588,41 +583,26 @@ void setup()
#if defined(USE_EPIANO) #if defined(USE_EPIANO)
// EP_CHORUS // EP_CHORUS
ep_delayline_r = (int16_t*)malloc(MOD_DELAY_SAMPLE_BUFFER * sizeof(int16_t)); ep_delayline_r = (int16_t*)malloc(MOD_DELAY_SAMPLE_BUFFER * sizeof(int16_t));
if (ep_delayline_r != NULL) if (ep_delayline_r == NULL)
{
memset(ep_delayline_r, 0, MOD_DELAY_SAMPLE_BUFFER * sizeof(int16_t));
if (!ep_modchorus_r.begin(ep_delayline_r, MOD_DELAY_SAMPLE_BUFFER))
{
#ifdef DEBUG
Serial.println(F("AudioEffectModulatedDelay R - begin failed EP"));
#endif
while (1);
}
}
else
{ {
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("AudioEffectModulatedDelay R - memory allocation failed EP")); Serial.println(F("AudioEffectModulatedDelay R - memory allocation failed EP"));
#endif #endif
while (1); while (1);
} }
ep_delayline_l = (int16_t*)malloc(MOD_DELAY_SAMPLE_BUFFER * sizeof(int16_t)); ep_delayline_l = (int16_t*)malloc(MOD_DELAY_SAMPLE_BUFFER * sizeof(int16_t));
if (ep_delayline_l != NULL) if (ep_delayline_l == NULL)
{
memset(ep_delayline_l, 0, MOD_DELAY_SAMPLE_BUFFER * sizeof(int16_t));
if (!ep_modchorus_l.begin(ep_delayline_l, MOD_DELAY_SAMPLE_BUFFER))
{ {
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("AudioEffectModulatedDelay L - begin failed EP")); Serial.println(F("AudioEffectModulatedDelay L - memory allocation failed EP"));
#endif #endif
while (1); while (1);
} }
}
else if (!ep_modchorus.begin(ep_delayline_r, ep_delayline_l, MOD_DELAY_SAMPLE_BUFFER))
{ {
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("AudioEffectModulatedDelay L - memory allocation failed EP")); Serial.println(F("AudioEffectModulatedDelayStereo - begin failed EP"));
#endif #endif
while (1); while (1);
} }
@ -641,7 +621,6 @@ void setup()
ep_chorus_mixer_l.gain(0, 1.0); ep_chorus_mixer_l.gain(0, 1.0);
ep_chorus_mixer_r.gain(1, mapfloat(EP_CHORUS_LEVEL_DEFAULT, EP_CHORUS_LEVEL_MIN, EP_CHORUS_LEVEL_MAX, 0.0, 0.5)); ep_chorus_mixer_r.gain(1, mapfloat(EP_CHORUS_LEVEL_DEFAULT, EP_CHORUS_LEVEL_MIN, EP_CHORUS_LEVEL_MAX, 0.0, 0.5));
ep_chorus_mixer_l.gain(1, mapfloat(EP_CHORUS_LEVEL_DEFAULT, EP_CHORUS_LEVEL_MIN, EP_CHORUS_LEVEL_MAX, 0.0, 0.5)); ep_chorus_mixer_l.gain(1, mapfloat(EP_CHORUS_LEVEL_DEFAULT, EP_CHORUS_LEVEL_MIN, EP_CHORUS_LEVEL_MAX, 0.0, 0.5));
ep_chorus_inverter.gain(-1.0);
ep_stereo_panorama.panorama(mapfloat(EP_PANORAMA_DEFAULT, EP_PANORAMA_MIN, EP_PANORAMA_MAX, -1.0, 1.0)); ep_stereo_panorama.panorama(mapfloat(EP_PANORAMA_DEFAULT, EP_PANORAMA_MIN, EP_PANORAMA_MAX, -1.0, 1.0));
#endif #endif
#endif #endif
@ -797,6 +776,8 @@ void setup()
Serial.println(F("<setup end>")); Serial.println(F("<setup end>"));
#endif #endif
ep_modchorus.set_bypass(true);
strcpy(seq.seq_name, "INIT Perf"); strcpy(seq.seq_name, "INIT Perf");
LCDML.OTHER_jumpToFunc(UI_func_voice_select); LCDML.OTHER_jumpToFunc(UI_func_voice_select);
} }
@ -2608,7 +2589,6 @@ void set_fx_params(void)
ep_chorus_mixer_l.gain(0, 1.0); ep_chorus_mixer_l.gain(0, 1.0);
ep_chorus_mixer_r.gain(1, mapfloat(configuration.fx.ep_chorus_level, EP_CHORUS_LEVEL_MIN, EP_CHORUS_LEVEL_MAX, 0.0, 0.5)); ep_chorus_mixer_r.gain(1, mapfloat(configuration.fx.ep_chorus_level, EP_CHORUS_LEVEL_MIN, EP_CHORUS_LEVEL_MAX, 0.0, 0.5));
ep_chorus_mixer_l.gain(1, mapfloat(configuration.fx.ep_chorus_level, EP_CHORUS_LEVEL_MIN, EP_CHORUS_LEVEL_MAX, 0.0, 0.5)); ep_chorus_mixer_l.gain(1, mapfloat(configuration.fx.ep_chorus_level, EP_CHORUS_LEVEL_MIN, EP_CHORUS_LEVEL_MAX, 0.0, 0.5));
ep_chorus_inverter.gain(-1.0);
#endif #endif
#endif #endif

@ -132,9 +132,7 @@ extern AudioSynthWaveform ep_chorus_modulator;
#if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT #if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT
extern AudioFilterBiquad ep_modchorus_filter; extern AudioFilterBiquad ep_modchorus_filter;
#endif #endif
extern AudioEffectModulatedDelay ep_modchorus_r; extern AudioEffectModulatedDelayStereo ep_modchorus;
extern AudioEffectModulatedDelay ep_modchorus_l;
extern AudioAmplifier ep_chorus_inverter;
extern AudioMixer<2> ep_chorus_mixer_r; extern AudioMixer<2> ep_chorus_mixer_r;
extern AudioMixer<2> ep_chorus_mixer_l; extern AudioMixer<2> ep_chorus_mixer_l;
extern AudioMixer<2> ep_delay_fb_mixer_r; extern AudioMixer<2> ep_delay_fb_mixer_r;

@ -111,6 +111,19 @@ void AudioEffectModulatedDelay::update(void)
if (!modulation) if (!modulation)
modulation = (audio_block_t*)&zeroblock; modulation = (audio_block_t*)&zeroblock;
if (bypass == true)
{
if (modulation != (audio_block_t*)&zeroblock)
release(modulation);
if (block != (audio_block_t*)&zeroblock)
{
transmit(block, 0);
release(block);
}
return;
}
if (block && modulation) if (block && modulation)
{ {
int16_t *bp; int16_t *bp;
@ -165,6 +178,16 @@ void AudioEffectModulatedDelay::update(void)
} }
} }
void AudioEffectModulatedDelay::set_bypass(bool b)
{
bypass = b;
}
bool AudioEffectModulatedDelay::get_bypass(void)
{
return (bypass);
}
boolean AudioEffectModulatedDelayStereo::begin(short *delayline_l, short *delayline_r, uint16_t d_length) boolean AudioEffectModulatedDelayStereo::begin(short *delayline_l, short *delayline_r, uint16_t d_length)
{ {
#if 0 #if 0
@ -200,6 +223,8 @@ boolean AudioEffectModulatedDelayStereo::begin(short *delayline_l, short *delayl
memset(_delayline[1], 0, _delay_length * sizeof(int16_t)); memset(_delayline[1], 0, _delay_length * sizeof(int16_t));
_delay_offset[1] = _delay_length >> 1 ; _delay_offset[1] = _delay_length >> 1 ;
stereo = true;
return (true); return (true);
} }
@ -213,7 +238,7 @@ void AudioEffectModulatedDelayStereo::update(void)
audio_block_t *block[2]; audio_block_t *block[2];
audio_block_t *modulation; audio_block_t *modulation;
if (_delayline == NULL) if (_delayline[0] == NULL || _delayline[1] == NULL)
return; return;
block[0] = receiveWritable(0); block[0] = receiveWritable(0);
@ -228,6 +253,25 @@ void AudioEffectModulatedDelayStereo::update(void)
if (!modulation) if (!modulation)
modulation = (audio_block_t*)&zeroblock; modulation = (audio_block_t*)&zeroblock;
if (bypass == true)
{
if (modulation != (audio_block_t*)&zeroblock)
release(modulation);
if (block[0] != (audio_block_t*)&zeroblock)
{
transmit(block[0], 0);
release(block[0]);
}
if (block[1] != (audio_block_t*)&zeroblock)
{
transmit(block[1], 0);
release(block[1]);
}
return;
}
if (block[0] && block[1] && modulation) if (block[0] && block[1] && modulation)
{ {
int16_t *bp[2]; int16_t *bp[2];
@ -274,7 +318,11 @@ void AudioEffectModulatedDelayStereo::update(void)
// RIGHT // RIGHT
// calculate the modulation-index as a floating point number for interpolation // calculate the modulation-index as a floating point number for interpolation
if (stereo == true)
mod_index = -1.0 * *mp * _delay_offset[0]; mod_index = -1.0 * *mp * _delay_offset[0];
else
mod_index = *mp * _delay_offset[0];
mod_fraction = modff(mod_index, &mod_number); // split float of mod_index into integer (= mod_number) and fraction part mod_fraction = modff(mod_index, &mod_number); // split float of mod_index into integer (= mod_number) and fraction part
// write data into circular buffer (delayline) // write data into circular buffer (delayline)
@ -316,3 +364,23 @@ void AudioEffectModulatedDelayStereo::update(void)
release(block[1]); release(block[1]);
} }
} }
void AudioEffectModulatedDelayStereo::set_stereo(bool s)
{
stereo = s;
}
bool AudioEffectModulatedDelayStereo::get_stereo(void)
{
return (stereo);
}
void AudioEffectModulatedDelayStereo::set_bypass(bool b)
{
bypass = b;
}
bool AudioEffectModulatedDelayStereo::get_bypass(void)
{
return (bypass);
}

@ -45,6 +45,8 @@ class AudioEffectModulatedDelay :
boolean begin(short *delayline, uint16_t delay_length); boolean begin(short *delayline, uint16_t delay_length);
virtual void update(void); virtual void update(void);
virtual uint16_t get_delay_length(void); virtual uint16_t get_delay_length(void);
virtual void set_bypass(bool b);
virtual bool get_bypass(void);
private: private:
audio_block_t *inputQueueArray[2]; audio_block_t *inputQueueArray[2];
@ -53,6 +55,7 @@ class AudioEffectModulatedDelay :
uint16_t _delay_length; // calculated number of samples of the delay uint16_t _delay_length; // calculated number of samples of the delay
int16_t cb_mod_index; // current read pointer with modulation for the circular buffer int16_t cb_mod_index; // current read pointer with modulation for the circular buffer
uint16_t _delay_offset; uint16_t _delay_offset;
bool bypass;
}; };
class AudioEffectModulatedDelayStereo : class AudioEffectModulatedDelayStereo :
@ -66,6 +69,10 @@ class AudioEffectModulatedDelayStereo :
boolean begin(short *delayline_l, short *delayline_r, uint16_t delay_length); boolean begin(short *delayline_l, short *delayline_r, uint16_t delay_length);
virtual void update(void); virtual void update(void);
virtual uint16_t get_delay_length(void); virtual uint16_t get_delay_length(void);
virtual void set_stereo(bool s);
virtual bool get_stereo(void);
virtual void set_bypass(bool b);
virtual bool get_bypass(void);
private: private:
audio_block_t *inputQueueArray[3]; audio_block_t *inputQueueArray[3];
@ -74,5 +81,7 @@ class AudioEffectModulatedDelayStereo :
uint16_t _delay_length; // calculated number of samples of the delay uint16_t _delay_length; // calculated number of samples of the delay
int16_t cb_mod_index[2]; // current read pointer with modulation for the circular buffer int16_t cb_mod_index[2]; // current read pointer with modulation for the circular buffer
uint16_t _delay_offset[2]; uint16_t _delay_offset[2];
bool stereo;
bool bypass;
}; };
#endif #endif

@ -68,7 +68,7 @@ inline float mapfloat(float val, float in_min, float in_max, float out_min, floa
void AudioEffectStereoPanorama::panorama(float p) void AudioEffectStereoPanorama::panorama(float p)
{ {
pan = mapfloat(p, 0.0, 1.0, -1.0, 1.0); pan = mapfloat(p, -1.0, 1.0, -1.0, 1.0);
} }
void AudioEffectStereoPanorama::update(void) void AudioEffectStereoPanorama::update(void)
@ -98,13 +98,14 @@ void AudioEffectStereoPanorama::update(void)
{ {
if (pan > 0.0) if (pan > 0.0)
{ {
out_f[0][n] = (pan / 2.0 * in_f[1][n]) + ((1.0 - pan) / 2.0 * in_f[0][n]); out_f[0][n] = (pan * in_f[1][n]) + ((1.0 - pan) * in_f[0][n]);
out_f[1][n] = (1.0 - pan) * in_f[1][n]; out_f[1][n] = (1.0 - pan) * in_f[1][n];
} }
else else
{ {
out_f[1][n] = (pan / 2.0 * in_f[0][n]) + ((1.0 - pan) / 2.0 * in_f[1][n]); float _pan_ = fabs(pan);
out_f[0][n] = (1.0 - pan) * in_f[0][n]; out_f[1][n] = (_pan_ * in_f[0][n]) + ((1.0 - _pan_) * in_f[1][n]);
out_f[0][n] = (1.0 - _pan_) * in_f[0][n];
} }
} }
else else

Loading…
Cancel
Save