diff --git a/src/effect_platervbstereo.cpp b/src/effect_platervbstereo.cpp index dd8c9ec..4d987e9 100644 --- a/src/effect_platervbstereo.cpp +++ b/src/effect_platervbstereo.cpp @@ -1,6 +1,6 @@ /* Stereo plate reverb for Teensy 4 * - * Adapted for use in MiniDexed (Holger Wirtz ) + * Adapted for MiniDexed (Holger Wirtz ) * * Author: Piotr Zapart * www.hexefx.com @@ -33,6 +33,7 @@ #include #include +#include #include "effect_platervbstereo.h" #define INP_ALLP_COEFF (0.65f) // default input allpass coeff @@ -151,11 +152,13 @@ AudioEffectPlateReverb::AudioEffectPlateReverb(float32_t samplerate) lfo1_adder = (UINT32_MAX + 1)/(samplerate * LFO1_FREQ_HZ); lfo2_phase_acc = 0; lfo2_adder = (UINT32_MAX + 1)/(samplerate * LFO2_FREQ_HZ); + + send_level = 0.0; } // #define sat16(n, rshift) signed_saturate_rshift((n), 16, (rshift)) -void AudioEffectPlateReverb::doReverb(uint16_t len, int16_t inblock[][2], int16_t outblock[][2]) +void AudioEffectPlateReverb::doReverb(uint16_t len, int16_t audioblock[][2]) { int i; float32_t input, acc, temp1, temp2; @@ -193,17 +196,11 @@ void AudioEffectPlateReverb::doReverb(uint16_t len, int16_t inblock[][2], int16_ cleanup_done = true; } - if (!inblock && outblock) - memset(outblock,0,len*sizeof(int16_t)*2); return; } cleanup_done = false; - // convert data to float32 - //arm_q15_to_float((q15_t *)inblockL, input_blockL, len); - //arm_q15_to_float((q15_t *)inblockR, input_blockR, len); - rv_time = rv_time_k; for (i=0; i < len; i++) @@ -239,7 +236,8 @@ void AudioEffectPlateReverb::doReverb(uint16_t len, int16_t inblock[][2], int16_ y += (int64_t)y1 * idx; lfo2_out_cos = (int32_t) (y >> (32-8)); // 16bit output - input = (float32_t(inblock[i][0])/32768.0f) * input_attn; + input = (float32_t(audioblock[i][0])/32767.0f) * input_attn; + // chained input allpasses, channel L acc = in_allp1_bufL[in_allp1_idxL] + input * in_allp_k; in_allp1_bufL[in_allp1_idxL] = input - in_allp_k * acc; @@ -261,7 +259,8 @@ void AudioEffectPlateReverb::doReverb(uint16_t len, int16_t inblock[][2], int16_ in_allp_out_L = acc; if (++in_allp4_idxL >= sizeof(in_allp4_bufL)/sizeof(float32_t)) in_allp4_idxL = 0; - input = (float32_t(inblock[i][1])/32768.0f) * input_attn; + input = (float32_t(audioblock[i][1])/32767.0f) * input_attn; + // chained input allpasses, channel R acc = in_allp1_bufR[in_allp1_idxR] + input * in_allp_k; in_allp1_bufR[in_allp1_idxR] = input - in_allp_k * acc; @@ -407,7 +406,13 @@ void AudioEffectPlateReverb::doReverb(uint16_t len, int16_t inblock[][2], int16_ temp1 = acc - master_lowpass_l; master_lowpass_l += temp1 * master_lowpass_f; - outblock[i][0]=(int16_t)(master_lowpass_l * 32767.0f); //sat16(output * 30, 0); + int32_t out = audioblock[i][0] + int16_t(master_lowpass_l * 32767.0f * send_level); + if(out > INT16_MAX) + audioblock[i][0] = INT16_MAX; + else if(out < INT16_MIN) + audioblock[i][0] = INT16_MIN; + else + audioblock[i][0] = out; // Channel R #ifdef TAP1_MODULATED @@ -450,6 +455,13 @@ void AudioEffectPlateReverb::doReverb(uint16_t len, int16_t inblock[][2], int16_ // Master lowpass filter temp1 = acc - master_lowpass_r; master_lowpass_r += temp1 * master_lowpass_f; - outblock[i][1]=(int16_t)(master_lowpass_r * 32767.0f); + + out = audioblock[i][1] + int16_t(master_lowpass_l * 32767.0f * send_level); + if(out > INT16_MAX) + audioblock[i][1] = INT16_MAX; + else if(out < INT16_MIN) + audioblock[i][1] = INT16_MIN; + else + audioblock[i][1] = out; } } diff --git a/src/effect_platervbstereo.h b/src/effect_platervbstereo.h index 18a6fb8..3abc62d 100644 --- a/src/effect_platervbstereo.h +++ b/src/effect_platervbstereo.h @@ -89,7 +89,7 @@ class AudioEffectPlateReverb { public: AudioEffectPlateReverb(float32_t samplerate); - void doReverb(uint16_t len, int16_t inblock[][2], int16_t outblock[][2]); + void doReverb(uint16_t len, int16_t audioblock[][2]); void size(float n) { @@ -136,12 +136,18 @@ public: //__enable_irq(); } + void send(float n) + { + send_level = constrain(n, 0.0f, 1.0f); + } + float32_t get_size(void) {return rv_time_k;} bool get_bypass(void) {return bypass;} void set_bypass(bool state) {bypass = state;}; void tgl_bypass(void) {bypass ^=1;} private: bool bypass = false; + float32_t send_level; float32_t input_attn; float32_t in_allp_k; // input allpass coeff diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 6fbc90a..d3f49c9 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -112,10 +112,11 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, // BEGIN setup reverb reverb = new AudioEffectPlateReverb(pConfig->GetSampleRate()); reverb->size(0.7); - reverb->hidamp(0.8); + reverb->hidamp(0.5); reverb->lodamp(0.5); reverb->lowpass(0.3); reverb->diffusion(0.2); + reverb->send(0.8); // END setup reverb }; @@ -558,6 +559,7 @@ void CMiniDexed::ProcessSound (void) // now mix the output of all TGs int16_t SampleBuffer[nFrames][2]; + assert (CConfig::ToneGenerators == 8); for (unsigned i = 0; i < nFrames; i++) { @@ -594,14 +596,7 @@ void CMiniDexed::ProcessSound (void) } // BEGIN adding reverb - int16_t ReverbBuffer[nFrames][2]; - - reverb->doReverb(nFrames,SampleBuffer,ReverbBuffer); - for (unsigned i = 0; i < nFrames; i++) - { - SampleBuffer[i][0] = ReverbBuffer[i][0]; - SampleBuffer[i][1] = ReverbBuffer[i][1]; - } + reverb->doReverb(nFrames,SampleBuffer); // END adding reverb if (m_pSoundDevice->Write (SampleBuffer, sizeof SampleBuffer) != (int) sizeof SampleBuffer) diff --git a/src/minidexed.ini b/src/minidexed.ini index f2f1c6a..b9f33ce 100644 --- a/src/minidexed.ini +++ b/src/minidexed.ini @@ -4,6 +4,7 @@ # Sound device SoundDevice=pwm +#SoundDevice=hdmi SampleRate=48000 #ChunkSize=256 DACI2CAddress=0 @@ -29,5 +30,5 @@ EncoderPinData=6 EncoderPinSwitch=26 # Debug -MIDIDumpEnabled=1 -ProfileEnabled=1 +MIDIDumpEnabled=0 +ProfileEnabled=0