Added full implementation of plate reverb.

pull/59/head
Holger Wirtz 3 years ago
parent c0c62916bb
commit 2a20eb82a0
  1. 36
      src/effect_platervbstereo.cpp
  2. 8
      src/effect_platervbstereo.h
  3. 13
      src/minidexed.cpp
  4. 5
      src/minidexed.ini

@ -1,6 +1,6 @@
/* Stereo plate reverb for Teensy 4
*
* Adapted for use in MiniDexed (Holger Wirtz <wirtz@parasitstudio.de>)
* Adapted for MiniDexed (Holger Wirtz <dcoredump@googlemail.com>)
*
* Author: Piotr Zapart
* www.hexefx.com
@ -33,6 +33,7 @@
#include <stdio.h>
#include <cstdlib>
#include <assert.h>
#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;
}
}

@ -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

@ -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)

@ -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

Loading…
Cancel
Save