Implement changes suggested by @rsta2

Description:
https://github.com/probonopd/MiniDexed/pull/86#issuecomment-1097912829

Thanks @rsta2
pull/86/head
probonopd 3 years ago
parent f597359dc4
commit d6f70cdddd
  1. 69
      src/effect_compressor.cpp
  2. 29
      src/effect_mixer.hpp
  3. 32
      src/minidexed.cpp
  4. 3
      src/performanceconfig.cpp
  5. 24
      src/uimenu.cpp

@ -37,12 +37,7 @@ void Compressor::setDefaultValues(const float32_t sample_rate_Hz) {
void Compressor::calcInstantaneousTargetGain(float32_t *audio_level_dB_block, float32_t *inst_targ_gain_dB_block, uint16_t len) void Compressor::calcInstantaneousTargetGain(float32_t *audio_level_dB_block, float32_t *inst_targ_gain_dB_block, uint16_t len)
{ {
// how much are we above the compression threshold? // how much are we above the compression threshold?
float32_t* above_thresh_dB_block=(float32_t*)malloc(sizeof(float32_t)*len); float32_t above_thresh_dB_block[len];
if(!above_thresh_dB_block)
{
LOGERR("Cannot allocate memory for \"above_thresh_dB_block\" - stopping\n");
while(1);
}
//arm_copy_f32(zeroblock_f32,above_thresh_dB_block,len); //arm_copy_f32(zeroblock_f32,above_thresh_dB_block,len);
@ -68,10 +63,6 @@ void Compressor::calcInstantaneousTargetGain(float32_t *audio_level_dB_block, fl
if (inst_targ_gain_dB_block[i] > 0.0f) inst_targ_gain_dB_block[i] = 0.0f; if (inst_targ_gain_dB_block[i] > 0.0f) inst_targ_gain_dB_block[i] = 0.0f;
} }
// release memory before returning
if(above_thresh_dB_block)
delete(above_thresh_dB_block);
return; //output is passed through inst_targ_gain_dB_block return; //output is passed through inst_targ_gain_dB_block
} }
@ -105,12 +96,7 @@ void Compressor::calcSmoothedGain_dB(float32_t *inst_targ_gain_dB_block, float32
void Compressor::calcAudioLevel_dB(float32_t *wav_block, float32_t *level_dB_block, uint16_t len) { void Compressor::calcAudioLevel_dB(float32_t *wav_block, float32_t *level_dB_block, uint16_t len) {
// calculate the instantaneous signal power (square the signal) // calculate the instantaneous signal power (square the signal)
float32_t* wav_pow_block=(float32_t*)malloc(sizeof(float32_t)*len); float32_t wav_pow_block[len];
if(!wav_pow_block)
{
LOGERR("Cannot allocate memory for \"wav_pow_block\" - stopping\n");
while(1);
}
//arm_copy_f32(zeroblock_f32,wav_pow_block,len); //arm_copy_f32(zeroblock_f32,wav_pow_block,len);
@ -135,10 +121,6 @@ void Compressor::calcAudioLevel_dB(float32_t *wav_block, float32_t *level_dB_blo
//scale the wav_pow_block by 10.0 to complete the conversion to dB //scale the wav_pow_block by 10.0 to complete the conversion to dB
arm_scale_f32(level_dB_block, 10.0f, level_dB_block, len); //use ARM DSP for speed! arm_scale_f32(level_dB_block, 10.0f, level_dB_block, len); //use ARM DSP for speed!
//release memory and return
if(wav_pow_block)
delete(wav_pow_block);
return; //output is passed through level_dB_block return; //output is passed through level_dB_block
} }
@ -147,23 +129,13 @@ void Compressor::calcAudioLevel_dB(float32_t *wav_block, float32_t *level_dB_blo
void Compressor::calcGain(float32_t *audio_level_dB_block, float32_t *gain_block,uint16_t len) void Compressor::calcGain(float32_t *audio_level_dB_block, float32_t *gain_block,uint16_t len)
{ {
//first, calculate the instantaneous target gain based on the compression ratio //first, calculate the instantaneous target gain based on the compression ratio
float32_t* inst_targ_gain_dB_block=(float32_t*)malloc(sizeof(float32_t)*len); float32_t inst_targ_gain_dB_block[len];
if(!inst_targ_gain_dB_block)
{
LOGERR("Cannot allocate memory for \"inst_targ_gain_dB_block\" - stopping\n");
while(1);
}
//arm_copy_f32(zeroblock_f32,inst_targ_gain_dB_block,len); //arm_copy_f32(zeroblock_f32,inst_targ_gain_dB_block,len);
calcInstantaneousTargetGain(audio_level_dB_block, inst_targ_gain_dB_block,len); calcInstantaneousTargetGain(audio_level_dB_block, inst_targ_gain_dB_block,len);
//second, smooth in time (attack and release) by stepping through each sample //second, smooth in time (attack and release) by stepping through each sample
float32_t *gain_dB_block = (float32_t*)malloc(sizeof(float32_t)*len); float32_t gain_dB_block[len];
if(!gain_dB_block)
{
LOGERR("Cannot allocate memory for \"gain_dB_block\" - stopping\n");
while(1);
}
//arm_copy_f32(zeroblock_f32,gain_dB_block,len); //arm_copy_f32(zeroblock_f32,gain_dB_block,len);
calcSmoothedGain_dB(inst_targ_gain_dB_block,gain_dB_block, len); calcSmoothedGain_dB(inst_targ_gain_dB_block,gain_dB_block, len);
@ -172,13 +144,6 @@ void Compressor::calcGain(float32_t *audio_level_dB_block, float32_t *gain_block
arm_scale_f32(gain_dB_block, 1.0f/20.0f, gain_dB_block, len); //divide by 20 arm_scale_f32(gain_dB_block, 1.0f/20.0f, gain_dB_block, len); //divide by 20
for (uint16_t i = 0; i < len; i++) gain_block[i] = pow10f(gain_dB_block[i]); //do the 10^(x) for (uint16_t i = 0; i < len; i++) gain_block[i] = pow10f(gain_dB_block[i]); //do the 10^(x)
//release memory and return
if(inst_targ_gain_dB_block)
delete(inst_targ_gain_dB_block);
if(gain_dB_block)
delete(gain_dB_block);
return; //output is passed through gain_block return; //output is passed through gain_block
} }
@ -186,7 +151,7 @@ void Compressor::calcGain(float32_t *audio_level_dB_block, float32_t *gain_block
void Compressor::doCompression(float32_t *audio_block, uint16_t len) { void Compressor::doCompression(float32_t *audio_block, uint16_t len) {
//Serial.println("AudioEffectGain_F32: updating."); //for debugging. //Serial.println("AudioEffectGain_F32: updating."); //for debugging.
if (!audio_block) { if (!audio_block) {
LOGERR("No audio_block available for Compressor!\n"); LOGERR("No audio_block available for Compressor!");
return; return;
} }
@ -199,43 +164,23 @@ void Compressor::doCompression(float32_t *audio_block, uint16_t len) {
arm_scale_f32(audio_block, pre_gain, audio_block, len); //use ARM DSP for speed! arm_scale_f32(audio_block, pre_gain, audio_block, len); //use ARM DSP for speed!
//calculate the level of the audio (ie, calculate a smoothed version of the signal power) //calculate the level of the audio (ie, calculate a smoothed version of the signal power)
float32_t* audio_level_dB_block = (float32_t*)malloc(sizeof(float32_t)*len); float32_t audio_level_dB_block[len];
if(!audio_level_dB_block)
{
LOGERR("Cannot allocate memory for \"audio_level_dB_block\" - stopping\n");
while(1);
}
//arm_copy_f32(zeroblock_f32,audio_level_dB_block,len); //arm_copy_f32(zeroblock_f32,audio_level_dB_block,len);
if(audio_level_dB_block)
calcAudioLevel_dB(audio_block, audio_level_dB_block, len); //returns through audio_level_dB_block calcAudioLevel_dB(audio_block, audio_level_dB_block, len); //returns through audio_level_dB_block
//compute the desired gain based on the observed audio level //compute the desired gain based on the observed audio level
float32_t* gain_block=(float32_t*)malloc(sizeof(float32_t)*len); float32_t gain_block[len];
if(!gain_block)
{
LOGERR("Cannot allocate memory for \"gain_block\" - stopping\n");
while(1);
}
//arm_copy_f32(zeroblock_f32,gain_block,len); //arm_copy_f32(zeroblock_f32,gain_block,len);
if(gain_block)
{
calcGain(audio_level_dB_block, gain_block, len); //returns through gain_block calcGain(audio_level_dB_block, gain_block, len); //returns through gain_block
//apply the desired gain...store the processed audio back into audio_block //apply the desired gain...store the processed audio back into audio_block
arm_mult_f32(audio_block, gain_block, audio_block, len); arm_mult_f32(audio_block, gain_block, audio_block, len);
} }
//release memory
if(audio_level_dB_block)
delete(audio_level_dB_block);
if(gain_block)
delete(gain_block);
}
//methods to set parameters of this module //methods to set parameters of this module
void Compressor::resetStates(void) void Compressor::resetStates(void)
{ {

@ -24,28 +24,24 @@ public:
for (uint8_t i=0; i<NN; i++) for (uint8_t i=0; i<NN; i++)
multiplier[i] = UNITY_GAIN; multiplier[i] = UNITY_GAIN;
sumbufL=(float32_t*)malloc(sizeof(float32_t) * buffer_length); sumbufL=new float32_t[buffer_length];
arm_fill_f32(0.0f, sumbufL, len); arm_fill_f32(0.0f, sumbufL, len);
} }
~AudioMixer() ~AudioMixer()
{ {
if(sumbufL) delete [] sumbufL;
free(sumbufL);
} }
void doAddMix(uint8_t channel, float32_t* in) void doAddMix(uint8_t channel, float32_t* in)
{ {
float32_t* tmp=(float32_t*)malloc(sizeof(float32_t)*buffer_length); float32_t tmp[buffer_length];
assert(tmp!=NULL);
assert(in); assert(in);
if(multiplier[channel]!=UNITY_GAIN) if(multiplier[channel]!=UNITY_GAIN)
arm_scale_f32(in,multiplier[channel],tmp,buffer_length); arm_scale_f32(in,multiplier[channel],tmp,buffer_length);
arm_add_f32(sumbufL, tmp, sumbufL, buffer_length); arm_add_f32(sumbufL, tmp, sumbufL, buffer_length);
free(tmp);
} }
void gain(uint8_t channel, float32_t gain) void gain(uint8_t channel, float32_t gain)
@ -95,16 +91,13 @@ public:
for (uint8_t i=0; i<NN; i++) for (uint8_t i=0; i<NN; i++)
panorama[i] = UNITY_PANORAMA; panorama[i] = UNITY_PANORAMA;
sumbufR=(float32_t*)malloc(sizeof(float32_t) * buffer_length); sumbufR=new float32_t[buffer_length];
arm_fill_f32(0.0f, sumbufR, buffer_length); arm_fill_f32(0.0f, sumbufR, buffer_length);
} }
~AudioStereoMixer() ~AudioStereoMixer()
{ {
if(sumbufL) delete [] sumbufR;
free(sumbufL);
if(sumbufR)
free(sumbufR);
} }
void pan(uint8_t channel, float32_t pan) void pan(uint8_t channel, float32_t pan)
@ -120,9 +113,8 @@ public:
void doAddMix(uint8_t channel, float32_t* in) void doAddMix(uint8_t channel, float32_t* in)
{ {
float32_t* tmp=(float32_t*)malloc(sizeof(float32_t)*buffer_length); float32_t tmp[buffer_length];
assert(tmp!=NULL);
assert(in); assert(in);
// left // left
@ -135,16 +127,12 @@ public:
if(multiplier[channel]!=UNITY_GAIN) if(multiplier[channel]!=UNITY_GAIN)
arm_scale_f32(tmp,multiplier[channel],tmp,buffer_length); arm_scale_f32(tmp,multiplier[channel],tmp,buffer_length);
arm_add_f32(sumbufR, tmp, sumbufR, buffer_length); arm_add_f32(sumbufR, tmp, sumbufR, buffer_length);
if(tmp)
free(tmp);
} }
void doAddMix(uint8_t channel, float32_t* inL, float32_t* inR) void doAddMix(uint8_t channel, float32_t* inL, float32_t* inR)
{ {
float32_t* tmp=malloc(sizeof(float32_t)*buffer_length); float32_t tmp[buffer_length];
assert(tmp!=NULL);
assert(inL); assert(inL);
assert(inR); assert(inR);
@ -156,9 +144,6 @@ public:
if(multiplier[channel]!=UNITY_GAIN) if(multiplier[channel]!=UNITY_GAIN)
arm_scale_f32(inR,multiplier[channel],tmp,buffer_length); arm_scale_f32(inR,multiplier[channel],tmp,buffer_length);
arm_add_f32(sumbufR, tmp, sumbufR, buffer_length); arm_add_f32(sumbufR, tmp, sumbufR, buffer_length);
if(tmp)
free(tmp);
} }
void getMix(float32_t* bufferL, float32_t* bufferR) void getMix(float32_t* bufferL, float32_t* bufferR)

@ -371,8 +371,8 @@ void CMiniDexed::SetPan (unsigned nPan, unsigned nTG)
assert (nTG < CConfig::ToneGenerators); assert (nTG < CConfig::ToneGenerators);
m_nPan[nTG] = nPan; m_nPan[nTG] = nPan;
tg_mixer->pan(nTG,mapfloat(nPan,-99,99,0.0f,1.0f)); tg_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f));
reverb_send_mixer->pan(nTG,mapfloat(nPan,-99,99,0.0f,1.0f)); reverb_send_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f));
m_UI.ParameterChanged (); m_UI.ParameterChanged ();
} }
@ -391,7 +391,7 @@ void CMiniDexed::SetReverbSend (unsigned nReverbSend, unsigned nTG)
void CMiniDexed::SetMasterTune (int nMasterTune, unsigned nTG) void CMiniDexed::SetMasterTune (int nMasterTune, unsigned nTG)
{ {
constrain((int)nMasterTune,-99,99); nMasterTune=constrain((int)nMasterTune,-99,99);
assert (nTG < CConfig::ToneGenerators); assert (nTG < CConfig::ToneGenerators);
m_nMasterTune[nTG] = nMasterTune; m_nMasterTune[nTG] = nMasterTune;
@ -529,49 +529,49 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue)
break; break;
case ParameterReverbEnable: case ParameterReverbEnable:
constrain((int)nValue,0,1); nValue=constrain((int)nValue,0,1);
m_ReverbSpinLock.Acquire (); m_ReverbSpinLock.Acquire ();
reverb->set_bypass (!nValue); reverb->set_bypass (!nValue);
m_ReverbSpinLock.Release (); m_ReverbSpinLock.Release ();
break; break;
case ParameterReverbSize: case ParameterReverbSize:
constrain((int)nValue,0,99); nValue=constrain((int)nValue,0,99);
m_ReverbSpinLock.Acquire (); m_ReverbSpinLock.Acquire ();
reverb->size (nValue / 99.0f); reverb->size (nValue / 99.0f);
m_ReverbSpinLock.Release (); m_ReverbSpinLock.Release ();
break; break;
case ParameterReverbHighDamp: case ParameterReverbHighDamp:
constrain((int)nValue,0,99); nValue=constrain((int)nValue,0,99);
m_ReverbSpinLock.Acquire (); m_ReverbSpinLock.Acquire ();
reverb->hidamp (nValue / 99.0f); reverb->hidamp (nValue / 99.0f);
m_ReverbSpinLock.Release (); m_ReverbSpinLock.Release ();
break; break;
case ParameterReverbLowDamp: case ParameterReverbLowDamp:
constrain((int)nValue,0,99); nValue=constrain((int)nValue,0,99);
m_ReverbSpinLock.Acquire (); m_ReverbSpinLock.Acquire ();
reverb->lodamp (nValue / 99.0f); reverb->lodamp (nValue / 99.0f);
m_ReverbSpinLock.Release (); m_ReverbSpinLock.Release ();
break; break;
case ParameterReverbLowPass: case ParameterReverbLowPass:
constrain((int)nValue,0,99); nValue=constrain((int)nValue,0,99);
m_ReverbSpinLock.Acquire (); m_ReverbSpinLock.Acquire ();
reverb->lowpass (nValue / 99.0f); reverb->lowpass (nValue / 99.0f);
m_ReverbSpinLock.Release (); m_ReverbSpinLock.Release ();
break; break;
case ParameterReverbDiffusion: case ParameterReverbDiffusion:
constrain((int)nValue,0,99); nValue=constrain((int)nValue,0,99);
m_ReverbSpinLock.Acquire (); m_ReverbSpinLock.Acquire ();
reverb->diffusion (nValue / 99.0f); reverb->diffusion (nValue / 99.0f);
m_ReverbSpinLock.Release (); m_ReverbSpinLock.Release ();
break; break;
case ParameterReverbLevel: case ParameterReverbLevel:
constrain((int)nValue,0,99); nValue=constrain((int)nValue,0,99);
m_ReverbSpinLock.Acquire (); m_ReverbSpinLock.Acquire ();
reverb->level (nValue / 99.0f); reverb->level (nValue / 99.0f);
m_ReverbSpinLock.Release (); m_ReverbSpinLock.Release ();
@ -699,15 +699,9 @@ void CMiniDexed::ProcessSound (void)
float32_t SampleBuffer[nFrames]; float32_t SampleBuffer[nFrames];
m_pTG[0]->getSamples (SampleBuffer, nFrames); m_pTG[0]->getSamples (SampleBuffer, nFrames);
// Convert dual float array (left, right) to single int16 array (left/right) // Convert single float array (mono) to int16 array
float32_t tmp_float[nFrames*2]; int16_t tmp_int[nFrames];
int16_t tmp_int[nFrames*2]; arm_float_to_q15(SampleBuffer,tmp_int,nFrames);
for(uint16_t i=0; i<nFrames;i++)
{
tmp_float[i*2]=SampleBuffer[i];
tmp_float[(i*2)+1]=SampleBuffer[i];
}
arm_float_to_q15(tmp_float,tmp_int,nFrames*2);
if (m_pSoundDevice->Write (tmp_int, sizeof(tmp_int)) != (int) sizeof(tmp_int)) if (m_pSoundDevice->Write (tmp_int, sizeof(tmp_int)) != (int) sizeof(tmp_int))
{ {

@ -154,6 +154,9 @@ bool CPerformanceConfig::Save (void)
PropertyName.Format ("NoteShift%u", nTG+1); PropertyName.Format ("NoteShift%u", nTG+1);
m_Properties.SetSignedNumber (PropertyName, m_nNoteShift[nTG]); m_Properties.SetSignedNumber (PropertyName, m_nNoteShift[nTG]);
PropertyName.Format ("ReverbSend%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nReverbSend[nTG]);
} }
m_Properties.SetNumber ("CompressorEnable", m_bCompressorEnable ? 1 : 0); m_Properties.SetNumber ("CompressorEnable", m_bCompressorEnable ? 1 : 0);

@ -158,16 +158,17 @@ const CUIMenu::TMenuItem CUIMenu::s_SaveMenu[] =
{0} {0}
}; };
// must match CMiniDexed::TTGParameter // must match CMiniDexed::TParameter
const CUIMenu::TParameter CUIMenu::s_TGParameter[CMiniDexed::TGParameterUnknown] = const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::ParameterUnknown] =
{ {
{0, CSysExFileLoader::MaxVoiceBankID, 1}, // TGParameterVoiceBank {0, 1, 1, ToOnOff}, // ParameterCompessorEnable
{0, CSysExFileLoader::VoicesPerBank-1, 1}, // TGParameterProgram {0, 1, 1, ToOnOff}, // ParameterReverbEnable
{0, 127, 8, ToVolume}, // TGParameterVolume {0, 99, 1}, // ParameterReverbSize
{0, 127, 8, ToPan}, // TGParameterPan {0, 99, 1}, // ParameterReverbHighDamp
{-99, 99, 1}, // TGParameterMasterTune {0, 99, 1}, // ParameterReverbLowDamp
{0, CMIDIDevice::ChannelUnknown-1, 1, ToMIDIChannel}, // TGParameterMIDIChannel {0, 99, 1}, // ParameterReverbLowPass
{0, 99, 1} // TGParameterReverbSend {0, 99, 1}, // ParameterReverbDiffusion
{0, 99, 1} // ParameterReverbLevel
}; };
// must match CMiniDexed::TTGParameter // must match CMiniDexed::TTGParameter
@ -178,7 +179,8 @@ const CUIMenu::TParameter CUIMenu::s_TGParameter[CMiniDexed::TGParameterUnknown]
{0, 127, 8, ToVolume}, // TGParameterVolume {0, 127, 8, ToVolume}, // TGParameterVolume
{0, 127, 8, ToPan}, // TGParameterPan {0, 127, 8, ToPan}, // TGParameterPan
{-99, 99, 1}, // TGParameterMasterTune {-99, 99, 1}, // TGParameterMasterTune
{0, CMIDIDevice::ChannelUnknown-1, 1, ToMIDIChannel} // TGParameterMIDIChannel {0, CMIDIDevice::ChannelUnknown-1, 1, ToMIDIChannel}, // TGParameterMIDIChannel
{0, 99, 1} // TGParameterReverbSend
}; };
// must match DexedVoiceParameters in Synth_Dexed // must match DexedVoiceParameters in Synth_Dexed

Loading…
Cancel
Save