Fixing all issues with MixingConsole integration (rather low level to be investigated)

pull/495/head
Vincent GAUCHE 2 years ago
parent 71f0a3ef80
commit 7e9f062e21
  1. 32
      src/fx_tube.cpp
  2. 48
      src/minidexed.cpp
  3. 54
      src/mixing_console.hpp
  4. 17
      src/test/test_fx_mixing_console.cpp

@ -22,29 +22,35 @@ void Tube::reset()
void Tube::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) void Tube::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{ {
float32_t x = inL * this->saturator_factor_; if(inL == 0.0f)
float32_t abs_x = abs(x); {
float32_t sat_x = log(1.0f + abs_x) * this->gain_factor_; outL = 0.0f;
}
outL = inL > 0 ? sat_x : -sat_x; else
{
x = inR * this->saturator_factor_; outL = std::tanh(this->saturator_factor_ * inL) * this->gain_factor_;
abs_x = abs(x); }
sat_x = log(1.0f + abs_x) * this->gain_factor_;
outR = inR > 0 ? sat_x : -sat_x; if(inR == 0.0f)
{
outR = 0.0f;
}
else
{
outR = std::tanh(this->saturator_factor_ * inR) * this->gain_factor_;
}
} }
void Tube::setOverdrive(float32_t overdrive) void Tube::setOverdrive(float32_t overdrive)
{ {
static const float32_t N = 200.0f; static const float32_t N = 3.0f;
overdrive = constrain(overdrive, 0.0f, 1.0f); overdrive = constrain(overdrive, 0.0f, 1.0f);
if(this->overdrive_ != overdrive) if(this->overdrive_ != overdrive)
{ {
this->overdrive_ = overdrive; this->overdrive_ = overdrive;
this->saturator_factor_ = 1.0f + N * overdrive; this->saturator_factor_ = 1.0 + N * overdrive;
this->gain_factor_ = this->OutputLevelCorrector / log(1.0f + this->saturator_factor_); this->gain_factor_ = this->OutputLevelCorrector / std::tanh(this->saturator_factor_);
} }
} }

@ -149,7 +149,7 @@ CMiniDexed::CMiniDexed (
this->setMasterVolume(1.0); this->setMasterVolume(1.0);
#if defined(MIXING_CONSOLE_ENABLE) #if defined(MIXING_CONSOLE_ENABLE)
this->mixing_console_ = new Mixer(static_cast<float32_t>(pConfig->GetSampleRate()), CConfig::MaxChunkSize); this->mixing_console_ = new Mixer(static_cast<float32_t>(pConfig->GetSampleRate()), CConfig::MaxChunkSize, this->m_bChannelsSwapped);
for (uint8_t i = 0; i < CConfig::ToneGenerators; i++) for (uint8_t i = 0; i < CConfig::ToneGenerators; i++)
{ {
memset(this->m_OutputLevel[i], 0, CConfig::MaxChunkSize * sizeof(float32_t)); memset(this->m_OutputLevel[i], 0, CConfig::MaxChunkSize * sizeof(float32_t));
@ -327,7 +327,7 @@ bool CMiniDexed::Initialize (void)
m_pSoundDevice->Start (); m_pSoundDevice->Start ();
#ifdef ARM_ALLOW_MULTI_CORE #if defined(ARM_ALLOW_MULTI_CORE)
// start secondary cores // start secondary cores
if (!CMultiCoreSupport::Initialize ()) if (!CMultiCoreSupport::Initialize ())
{ {
@ -1786,45 +1786,30 @@ void CMiniDexed::ProcessSound (void)
// //
// Audio signal path after tone generators starts here // Audio signal path after tone generators starts here
//
float32_t tmp_float[nFrames * 2];
int16_t tmp_int[nFrames * 2]; int16_t tmp_int[nFrames * 2];
#if defined(MIXING_CONSOLE_ENABLE) #if defined(MIXING_CONSOLE_ENABLE)
// // swap stereo channels if needed // BEGIN mixing
uint8_t indexL = StereoChannels::Left;
uint8_t indexR = StereoChannels::Right;
if(this->m_bChannelsSwapped)
{
indexL = StereoChannels::Right;
indexR = StereoChannels::Left;
}
// BEGIN TG mixing
if(this->nMasterVolume > 0.0f) if(this->nMasterVolume > 0.0f)
{ {
float32_t SampleBuffer[StereoChannels::kNumChannels][nFrames]; // temp buffering and channel indexing
float32_t interlacedSampleBuffer[nFrames << 1];
this->m_FXSpinLock.Acquire(); this->m_FXSpinLock.Acquire();
this->mixing_console_->process(SampleBuffer[indexL], SampleBuffer[indexR]); this->mixing_console_->process(interlacedSampleBuffer);
this->m_FXSpinLock.Release(); this->m_FXSpinLock.Release();
// Convert dual float array (left, right) to single int16 array (left/right) if(this->nMasterVolume < 1.0f)
this->nMasterVolume = constrain(this->nMasterVolume, 0.0f, 1.0f);
if(this->nMasterVolume == 1.0f)
{
memcpy(tmp_float, SampleBuffer[indexL], nFrames * sizeof(float32_t));
memcpy(tmp_float + nFrames, SampleBuffer[indexR], nFrames * sizeof(float32_t));
}
else // 0.0 < this->nMasterVolume < 1.0
{ {
arm_scale_f32(SampleBuffer[indexL], this->nMasterVolume, tmp_float, nFrames); arm_scale_f32(interlacedSampleBuffer, this->nMasterVolume, interlacedSampleBuffer, nFrames << 1);
arm_scale_f32(SampleBuffer[indexR], this->nMasterVolume, tmp_float + nFrames, nFrames);
} }
arm_float_to_q15(tmp_float, tmp_int, nFrames * 2);
// Convert float array (left, right) to single int16 array (left/right)
arm_float_to_q15(interlacedSampleBuffer, tmp_int, nFrames << 1);
} }
else // this->nMasterVolume == 0.0f else // this->nMasterVolume == 0.0f
{ {
arm_fill_q15(0, tmp_int, nFrames * 2); arm_fill_q15(0, tmp_int, nFrames << 1);
} }
#elif defined(PLATE_REVERB_ENABLE) #elif defined(PLATE_REVERB_ENABLE)
@ -2332,12 +2317,7 @@ void CMiniDexed::getSysExVoiceDump(uint8_t* dest, uint8_t nTG)
void CMiniDexed::setMasterVolume (float32_t vol) void CMiniDexed::setMasterVolume (float32_t vol)
{ {
if(vol < 0.0) this->nMasterVolume = constrain(vol, 0.0f, 1.0f);
vol = 0.0;
else if(vol > 1.0)
vol = 1.0;
nMasterVolume=vol;
} }
std::string CMiniDexed::GetPerformanceFileName(unsigned nID) std::string CMiniDexed::GetPerformanceFileName(unsigned nID)

@ -40,7 +40,7 @@ class MixingConsole : public FXBase
DISALLOW_COPY_AND_ASSIGN(MixingConsole); DISALLOW_COPY_AND_ASSIGN(MixingConsole);
public: public:
MixingConsole(float32_t sampling_rate, size_t buffer_size); MixingConsole(float32_t sampling_rate, size_t buffer_size, bool swapStereoImage = false);
~MixingConsole(); ~MixingConsole();
inline size_t getChannelNumber() const; inline size_t getChannelNumber() const;
@ -48,6 +48,7 @@ public:
// Send section // Send section
inline void setChannelLevel(size_t in, float32_t lvl); inline void setChannelLevel(size_t in, float32_t lvl);
inline void setPan(size_t in, float32_t pan); inline void setPan(size_t in, float32_t pan);
inline void swapStereoImage(bool swap);
inline void setSendLevel(size_t in, MixerOutput fx, float32_t lvl); inline void setSendLevel(size_t in, MixerOutput fx, float32_t lvl);
inline void setInputSample(size_t in, float32_t sampleL, float32_t sampleR); inline void setInputSample(size_t in, float32_t sampleL, float32_t sampleR);
inline void setInputSampleBuffer(size_t in, float32_t* samples); inline void setInputSampleBuffer(size_t in, float32_t* samples);
@ -75,6 +76,7 @@ public:
inline void injectInputSamples(size_t in, float32_t* samplesL, float32_t* samplesR, size_t nSamples); inline void injectInputSamples(size_t in, float32_t* samplesL, float32_t* samplesR, size_t nSamples);
inline void processSample(float32_t& outL, float32_t& outR); inline void processSample(float32_t& outL, float32_t& outR);
void process(float32_t* outL, float32_t* outR); void process(float32_t* outL, float32_t* outR);
void process(float32_t* outLR);
protected: protected:
inline void updatePan(size_t in); inline void updatePan(size_t in);
@ -88,6 +90,7 @@ private:
float32_t channel_level_[nb_inputs]; float32_t channel_level_[nb_inputs];
float32_t pan_[StereoChannels::kNumChannels + 1][nb_inputs]; float32_t pan_[StereoChannels::kNumChannels + 1][nb_inputs];
bool swap_stereo_image_;
float32_t* tg_input_sample_buffer_[nb_inputs]; float32_t* tg_input_sample_buffer_[nb_inputs];
float32_t* input_sample_buffer_[StereoChannels::kNumChannels][nb_inputs]; float32_t* input_sample_buffer_[StereoChannels::kNumChannels][nb_inputs];
float32_t input_samples_[StereoChannels::kNumChannels][nb_inputs + MixerOutput::kFXCount - 1]; float32_t input_samples_[StereoChannels::kNumChannels][nb_inputs + MixerOutput::kFXCount - 1];
@ -106,7 +109,7 @@ private:
FXUnit2<Dry>* dry_; FXUnit2<Dry>* dry_;
IMPLEMENT_DUMP( IMPLEMENT_DUMP(
const size_t space = 10; const size_t space = 9;
const size_t precision = 5; const size_t precision = 5;
std::stringstream ss; std::stringstream ss;
@ -328,9 +331,10 @@ float32_t MixingConsole<nb_inputs>::weighted_sum(const float32_t* data, const fl
} }
template<size_t nb_inputs> template<size_t nb_inputs>
MixingConsole<nb_inputs>::MixingConsole(float32_t sampling_rate, size_t buffer_size) : MixingConsole<nb_inputs>::MixingConsole(float32_t sampling_rate, size_t buffer_size, bool swapStereoImage) :
FXBase(sampling_rate), FXBase(sampling_rate),
BufferSize(buffer_size), BufferSize(buffer_size),
swap_stereo_image_(swapStereoImage),
m_nSamples(0) m_nSamples(0)
{ {
for(size_t i = 0; i < nb_inputs; ++i) for(size_t i = 0; i < nb_inputs; ++i)
@ -406,6 +410,12 @@ void MixingConsole<nb_inputs>::setPan(size_t in, float32_t pan)
this->updatePan(in); this->updatePan(in);
} }
template<size_t nb_inputs>
void MixingConsole<nb_inputs>::swapStereoImage(bool swap)
{
this->swap_stereo_image_ = swap;
}
template<size_t nb_inputs> template<size_t nb_inputs>
void MixingConsole<nb_inputs>::setSendLevel(size_t in, MixerOutput fx, float32_t lvl) void MixingConsole<nb_inputs>::setSendLevel(size_t in, MixerOutput fx, float32_t lvl)
{ {
@ -669,7 +679,14 @@ void MixingConsole<nb_inputs>::process(float32_t* outL, float32_t* outR)
); );
} }
if(this->swap_stereo_image_)
{
this->processSample(*outR, *outL);
}
else
{
this->processSample(*outL, *outR); this->processSample(*outL, *outR);
}
++outL; ++outL;
++outR; ++outR;
} }
@ -677,6 +694,37 @@ void MixingConsole<nb_inputs>::process(float32_t* outL, float32_t* outR)
this->m_nSamples = 0; this->m_nSamples = 0;
} }
template<size_t nb_inputs>
void MixingConsole<nb_inputs>::process(float32_t* outLR)
{
size_t nSamples = this->m_nSamples;
for(size_t s = 0; s < nSamples; ++s)
{
for(size_t in = 0; in < nb_inputs; ++in)
{
this->setSample(
in,
this->input_sample_buffer_[StereoChannels::Left ][in][s],
this->input_sample_buffer_[StereoChannels::Right][in][s]
);
}
if(this->swap_stereo_image_)
{
this->processSample(*(outLR + 1), *outLR);
}
else
{
this->processSample(*outLR, *(outLR + 1));
}
outLR += 2;
}
this->m_nSamples = 0;
}
template<size_t nb_inputs> template<size_t nb_inputs>
void MixingConsole<nb_inputs>::updatePan(size_t in) void MixingConsole<nb_inputs>::updatePan(size_t in)
{ {

@ -31,7 +31,7 @@ void setupMixingConsoleFX(Mixer* mixer)
mixer->setPan(0, 0.5f); mixer->setPan(0, 0.5f);
mixer->getTube()->setMute(false); mixer->getTube()->setMute(false);
mixer->getTube()->setOverdrive(0.45f); mixer->getTube()->setOverdrive(0.85f);
mixer->getChorus()->setMute(false); mixer->getChorus()->setMute(false);
mixer->getChorus()->setRate(0.4f); mixer->getChorus()->setRate(0.4f);
@ -53,8 +53,8 @@ void setupMixingConsoleFX(Mixer* mixer)
mixer->getPhaser()->setNbStages(12); mixer->getPhaser()->setNbStages(12);
mixer->getDelay()->setMute(false); mixer->getDelay()->setMute(false);
mixer->getDelay()->setLeftDelayTime(0.25f); mixer->getDelay()->setLeftDelayTime(0.15f);
mixer->getDelay()->setLeftDelayTime(0.30f); mixer->getDelay()->setLeftDelayTime(0.20f);
mixer->getDelay()->setFeedback(0.7f); mixer->getDelay()->setFeedback(0.7f);
mixer->getDelay()->setFlutterRate(0.2f); mixer->getDelay()->setFlutterRate(0.2f);
mixer->getDelay()->setFlutterAmount(0.5f); mixer->getDelay()->setFlutterAmount(0.5f);
@ -118,8 +118,8 @@ void setupMixingConsoleFX(Mixer* mixer, int scenarioId, size_t channel)
} }
else else
{ {
mixer->setSendLevel(channel, MixerOutput::MainOutput, 0.3f); mixer->setSendLevel(channel, MixerOutput::MainOutput, 0.25f);
mixer->setReturnLevel(previousActivatedFX, MixerOutput::MainOutput, 0.8f); mixer->setReturnLevel(previousActivatedFX, MixerOutput::MainOutput, 0.75f);
} }
} }
@ -520,13 +520,6 @@ TEST_P(FXScenarioTest, FXProcessingScenario)
int scenarioId = this->GetParam(); int scenarioId = this->GetParam();
setupMixingConsoleFX((&mixer), scenarioId); setupMixingConsoleFX((&mixer), scenarioId);
for(size_t i = 0; i < NB_MIXER_CHANNELS; ++i)
{
mixer.setSendLevel(i, static_cast<MixerOutput>(i), 1.0f);
mixer.setReturnLevel(static_cast<MixerOutput>(i), MixerOutput::MainOutput, 0.5f);
mixer.setSendLevel(i, MixerOutput::MainOutput, 0.5f);
}
float32_t* inS = inSamples[StereoChannels::Left]; float32_t* inS = inSamples[StereoChannels::Left];
float32_t* outS[StereoChannels::kNumChannels]; float32_t* outS[StereoChannels::kNumChannels];
outS[StereoChannels::Left ] = outSamples[StereoChannels::Left ]; outS[StereoChannels::Left ] = outSamples[StereoChannels::Left ];

Loading…
Cancel
Save