Tranform TapeDelay into a Delay as Flutter is a noise artifact generator

pull/409/head
abscisys 2 years ago
parent 8227a3abe1
commit d0fe01f652
  1. 3
      .gitignore
  2. 2
      src/Makefile
  3. 18
      src/fx_delay.h
  4. 10
      src/fx_rack.cpp
  5. 6
      src/fx_rack.h
  6. 153
      src/fx_tape_delay.cpp
  7. 63
      src/minidexed.cpp
  8. 13
      src/minidexed.h
  9. 11
      src/performance.ini
  10. 72
      src/performanceconfig.cpp
  11. 33
      src/performanceconfig.h
  12. 4
      src/test/Makefile
  13. 144
      src/test/fxrack_test.cpp
  14. 28
      src/uimenu.cpp
  15. 2
      src/uimenu.h

3
.gitignore vendored

@ -49,4 +49,5 @@ sdcard
# temporary tests
src/test/fxrack_test
src/test/result.wav
src/test/result*.wav
src/test/*.csv

@ -12,7 +12,7 @@ OBJS = main.o kernel.o minidexed.o config.o userinterface.o uimenu.o \
effect_compressor.o effect_platervbstereo.o \
fx.o fx_components.o \
fx_svf.o fx_tube.o fx_chorus.o fx_flanger.o fx_orbitone.o fx_phaser.o \
fx_tape_delay.o fx_shimmer_reverb.o fx_rack.o \
fx_delay.o fx_shimmer_reverb.o fx_rack.o \
uibuttons.o midipin.o
OPTIMIZE = -O3

@ -15,7 +15,7 @@
//
// fx_tape_delay.h
//
// Stereo Tape Delay proposed in the context of the MiniDexed project
// Stereo Delay proposed in the context of the MiniDexed project
//
#pragma once
@ -24,9 +24,9 @@
#include <random>
class TapeDelay : public FXElement
class Delay : public FXElement
{
DISALLOW_COPY_AND_ASSIGN(TapeDelay);
DISALLOW_COPY_AND_ASSIGN(Delay);
class LowHighPassFilter : public FXElement
{
@ -47,8 +47,8 @@ class TapeDelay : public FXElement
public:
TapeDelay(const float32_t sampling_rate, float32_t default_delay_time = 0.25f, float32_t default_flutter_level = 1.0f, float32_t default_wet_level = 0.5f);
virtual ~TapeDelay();
Delay(const float32_t sampling_rate, float32_t default_delay_time = 0.25f, float32_t default_flutter_level = 1.0f, float32_t default_wet_level = 0.5f);
virtual ~Delay();
virtual void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) override;
@ -58,15 +58,9 @@ public:
void setRightDelayTime(float32_t delay_time);
float32_t getRightDelayTime() const;
void setFlutterLevel(float32_t flutter_level);
float32_t getFlutterLevel() const;
void setFeedbak(float32_t feedback);
float32_t getFeedbackLevel() const;
private:
inline float32_t getFlutteredDelayTime();
private:
const size_t MaxSampleDelayTime;
size_t read_pos_L_;
@ -75,9 +69,7 @@ private:
float32_t* buffer_R_;
float32_t delay_time_L_; // Left delay time in seconds (0.0 - 2.0)
float32_t delay_time_R_; // Right delay time in seconds (0.0 - 2.0)
float32_t flutter_level_; // Flutter level (0.0 - 0.1)
float32_t feedback_; // Feedback (0.0 - 1.0)
LowHighPassFilter filter_;
JitterGenerator jitter_generator_;
};

@ -14,7 +14,7 @@ FXRack::FXRack(float32_t sampling_rate, bool enable, float32_t wet) :
this->fxFlanger_ = new FXUnit<Flanger>(sampling_rate);
this->fxOrbitone_ = new FXUnit<Orbitone>(sampling_rate);
this->fxPhaser_ = new FXUnit<Phaser>(sampling_rate);
this->fxTapeDelay_ = new FXUnit<TapeDelay>(sampling_rate);
this->fxDelay_ = new FXUnit<Delay>(sampling_rate);
this->fxShimmerReverb_ = new FXUnit<ShimmerReverb>(sampling_rate);
this->registerFX(this->fxTube_);
@ -22,7 +22,7 @@ FXRack::FXRack(float32_t sampling_rate, bool enable, float32_t wet) :
this->registerFX(this->fxFlanger_);
this->registerFX(this->fxOrbitone_);
this->registerFX(this->fxPhaser_);
this->registerFX(this->fxTapeDelay_);
this->registerFX(this->fxDelay_);
this->registerFX(this->fxShimmerReverb_);
}
@ -35,7 +35,7 @@ FXRack::~FXRack()
delete this->fxFlanger_;
delete this->fxOrbitone_;
delete this->fxPhaser_;
delete this->fxTapeDelay_;
delete this->fxDelay_;
delete this->fxShimmerReverb_;
}
@ -139,9 +139,9 @@ FXUnit<Phaser>* FXRack::getPhaser()
return this->fxPhaser_;
}
FXUnit<TapeDelay>* FXRack::getTapeDelay()
FXUnit<Delay>* FXRack::getDelay()
{
return this->fxTapeDelay_;
return this->fxDelay_;
}
FXUnit<ShimmerReverb>* FXRack::getShimmerReverb()

@ -25,7 +25,7 @@
#include "fx_flanger.h"
#include "fx_orbitone.h"
#include "fx_phaser.h"
#include "fx_tape_delay.h"
#include "fx_delay.h"
#include "fx_shimmer_reverb.h"
#include <vector>
@ -54,7 +54,7 @@ public:
FXUnit<Flanger>* getFlanger();
FXUnit<Orbitone>* getOrbitone();
FXUnit<Phaser>* getPhaser();
FXUnit<TapeDelay>* getTapeDelay();
FXUnit<Delay>* getDelay();
FXUnit<ShimmerReverb>* getShimmerReverb();
private:
@ -69,6 +69,6 @@ private:
FXUnit<Flanger>* fxFlanger_;
FXUnit<Orbitone>* fxOrbitone_;
FXUnit<Phaser>* fxPhaser_;
FXUnit<TapeDelay>* fxTapeDelay_;
FXUnit<Delay>* fxDelay_;
FXUnit<ShimmerReverb>* fxShimmerReverb_;
};

@ -1,153 +0,0 @@
#include "fx_tape_delay.h"
#include <cmath>
#define MAX_DELAY_TIME 1.0f
#define MAX_FLUTTER_DELAY_TIME 0.01f
#define LPF_CUTOFF_REF 14000.0f
#define HPF_CUTOFF_REF 60.0f
TapeDelay::LowHighPassFilter::LowHighPassFilter(float32_t sampling_rate) :
FXElement(sampling_rate),
lpf_(sampling_rate, StateVariableFilter::Type::LPF, LPF_CUTOFF_REF),
hpf_(sampling_rate, StateVariableFilter::Type::HPF, HPF_CUTOFF_REF)
{
this->setCutoffChangeRatio(0.0f);
}
TapeDelay::LowHighPassFilter::~LowHighPassFilter()
{
}
void TapeDelay::LowHighPassFilter::setCutoffChangeRatio(float32_t ratio)
{
ratio += 1.0f;
this->lpf_.setCutoff(LPF_CUTOFF_REF * ratio);
this->hpf_.setCutoff(HPF_CUTOFF_REF * ratio);
}
void TapeDelay::LowHighPassFilter::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{
this->lpf_.processSample(inL, inR, outL, outR);
this->hpf_.processSample(outL, outR, outL, outR);
}
TapeDelay::TapeDelay(const float32_t sampling_rate, float32_t default_delay_time, float32_t default_flutter_level, float32_t default_feedback_level) :
FXElement(sampling_rate),
MaxSampleDelayTime((MAX_DELAY_TIME + MAX_FLUTTER_DELAY_TIME) * sampling_rate * MAX_DELAY_TIME),
read_pos_L_(0),
read_pos_R_(0),
filter_(sampling_rate),
jitter_generator_(sampling_rate)
{
this->buffer_L_ = new float32_t[this->MaxSampleDelayTime];
this->buffer_R_ = new float32_t[this->MaxSampleDelayTime];
memset(this->buffer_L_, 0, this->MaxSampleDelayTime * sizeof(float32_t));
memset(this->buffer_R_, 0, this->MaxSampleDelayTime * sizeof(float32_t));
this->setLeftDelayTime(default_delay_time);
this->setRightDelayTime(default_delay_time);
this->setFlutterLevel(default_flutter_level);
this->setFeedbak(default_feedback_level);
}
TapeDelay::~TapeDelay()
{
delete[] this->buffer_L_;
delete[] this->buffer_R_;
}
void TapeDelay::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{
// Calculate the fluttered delay time
float32_t fluttered_delay_time = this->getFlutteredDelayTime();
this->filter_.setCutoffChangeRatio(fluttered_delay_time);
float32_t fluttered_delay_time_L = (MAX_DELAY_TIME * this->getLeftDelayTime() * (1.0f + fluttered_delay_time)) * this->getSamplingRate();
float32_t fluttered_delay_time_R = (MAX_DELAY_TIME * this->getRightDelayTime() * (1.0f + fluttered_delay_time)) * this->getSamplingRate();
// Calculate write positions
unsigned write_pos_L = static_cast<unsigned>(this->MaxSampleDelayTime + this->read_pos_L_ + fluttered_delay_time_L) % this->MaxSampleDelayTime;
unsigned write_pos_R = static_cast<unsigned>(this->MaxSampleDelayTime + this->read_pos_R_ + fluttered_delay_time_R) % this->MaxSampleDelayTime;
// Write input to delay buffers
this->buffer_L_[write_pos_L] = inL;
this->buffer_R_[write_pos_R] = inR;
// Read from delay buffers and apply feedback
this->filter_.processSample(
this->buffer_L_[this->read_pos_L_],
this->buffer_R_[this->read_pos_R_],
outL,
outR
);
this->buffer_L_[write_pos_L] += outL * this->getFeedbackLevel();
this->buffer_R_[write_pos_R] += outR * this->getFeedbackLevel();
// Increment read positions
++this->read_pos_L_;
if(this->read_pos_L_ >= this->MaxSampleDelayTime)
{
this->read_pos_L_ -= this->MaxSampleDelayTime;
}
++this->read_pos_R_;
if(this->read_pos_R_ >= this->MaxSampleDelayTime)
{
this->read_pos_R_ -= this->MaxSampleDelayTime;
}
}
void TapeDelay::setLeftDelayTime(float32_t delay_time)
{
this->delay_time_L_ = constrain(delay_time, 0.0f, 1.0f);
}
float32_t TapeDelay::getLeftDelayTime() const
{
return this->delay_time_L_;
}
void TapeDelay::setRightDelayTime(float32_t delay_time)
{
this->delay_time_R_ = constrain(delay_time, 0.0f, 1.0f);
}
float32_t TapeDelay::getRightDelayTime() const
{
return this->delay_time_R_;
}
void TapeDelay::setFlutterLevel(float32_t flutter_level)
{
this->flutter_level_ = constrain(flutter_level, 0.0f, 1.0f);
this->jitter_generator_.setSpeed(0.2f * (1.0f - this->flutter_level_));
this->jitter_generator_.setMagnitude(this->flutter_level_ / 100.0f);
}
float32_t TapeDelay::getFlutterLevel() const
{
return this->flutter_level_;
}
void TapeDelay::setFeedbak(float32_t feedback)
{
this->feedback_ = constrain(feedback, 0.0, 1.0);
}
float32_t TapeDelay::getFeedbackLevel() const
{
return this->feedback_;
}
float32_t TapeDelay::getFlutteredDelayTime()
{
// Genarate a random number in the range [-1.0 , 1.0]
float32_t r = this->jitter_generator_.process();
// Scale and bias the random number to the desired flutter range
return MAX_FLUTTER_DELAY_TIME * r * this->getFlutterLevel();
}

@ -197,13 +197,12 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
this->SetParameter(ParameterFXChainPhaserRate, 5);
this->SetParameter(ParameterFXChainPhaserResonance, 45);
// FXChain > TapeDelay parameters
this->SetParameter(ParameterFXChainTapeDelayEnable, 1);
this->SetParameter(ParameterFXChainTapeDelayWet, 50);
this->SetParameter(ParameterFXChainTapeDelayLeftDelayTime, 15);
this->SetParameter(ParameterFXChainTapeDelayRightDelayTime, 22);
this->SetParameter(ParameterFXChainTapeDelayFlutter, 7);
this->SetParameter(ParameterFXChainTapeDelayFeedback, 35);
// FXChain > Delay parameters
this->SetParameter(ParameterFXChainDelayEnable, 1);
this->SetParameter(ParameterFXChainDelayWet, 50);
this->SetParameter(ParameterFXChainDelayLeftDelayTime, 15);
this->SetParameter(ParameterFXChainDelayRightDelayTime, 22);
this->SetParameter(ParameterFXChainDelayFeedback, 35);
// FXChain > ShimmerReverb parameters
this->SetParameter(ParameterFXChainShimmerReverbEnable, 1);
@ -894,41 +893,35 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue)
this->m_FXSpinLock.Release();
break;
// FXChain > TapeDelay parameters
case ParameterFXChainTapeDelayEnable:
// FXChain > Delay parameters
case ParameterFXChainDelayEnable:
nValue = constrain((int)nValue, 0, 1);
this->m_FXSpinLock.Acquire();
this->fx_rack->getTapeDelay()->setEnable(!!nValue);
this->fx_rack->getDelay()->setEnable(!!nValue);
this->m_FXSpinLock.Release();
break;
case ParameterFXChainTapeDelayWet:
case ParameterFXChainDelayWet:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
this->fx_rack->getTapeDelay()->setWetLevel(nValue / 99.0f);
this->fx_rack->getDelay()->setWetLevel(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
case ParameterFXChainTapeDelayLeftDelayTime:
case ParameterFXChainDelayLeftDelayTime:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
this->fx_rack->getTapeDelay()->setLeftDelayTime(nValue / 99.0f);
this->fx_rack->getDelay()->setLeftDelayTime(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
case ParameterFXChainTapeDelayRightDelayTime:
case ParameterFXChainDelayRightDelayTime:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
this->fx_rack->getTapeDelay()->setRightDelayTime(nValue / 99.0f);
this->fx_rack->getDelay()->setRightDelayTime(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
case ParameterFXChainTapeDelayFlutter:
case ParameterFXChainDelayFeedback:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
this->fx_rack->getTapeDelay()->setFlutterLevel(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
case ParameterFXChainTapeDelayFeedback:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
this->fx_rack->getTapeDelay()->setFeedbak(nValue / 99.0f);
this->fx_rack->getDelay()->setFeedbak(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
@ -1414,12 +1407,11 @@ bool CMiniDexed::DoSavePerformance (void)
this->m_PerformanceConfig.SetFXChainPhaserWet(this->m_nParameter[ParameterFXChainPhaserWet]);
this->m_PerformanceConfig.SetFXChainPhaserRate(this->m_nParameter[ParameterFXChainPhaserRate]);
this->m_PerformanceConfig.SetFXChainPhaserResonance(this->m_nParameter[ParameterFXChainPhaserResonance]);
this->m_PerformanceConfig.SetFXChainTapeDelayEnable(!!this->m_nParameter[ParameterFXChainTapeDelayEnable]);
this->m_PerformanceConfig.SetFXChainTapeDelayWet(this->m_nParameter[ParameterFXChainTapeDelayWet]);
this->m_PerformanceConfig.SetFXChainTapeDelayLeftDelayTime(this->m_nParameter[ParameterFXChainTapeDelayLeftDelayTime]);
this->m_PerformanceConfig.SetFXChainTapeDelayRightDelayTime(this->m_nParameter[ParameterFXChainTapeDelayRightDelayTime]);
this->m_PerformanceConfig.SetFXChainTapeDelayFlutter(this->m_nParameter[ParameterFXChainTapeDelayFlutter]);
this->m_PerformanceConfig.SetFXChainTapeDelayFeedback(this->m_nParameter[ParameterFXChainTapeDelayFeedback]);
this->m_PerformanceConfig.SetFXChainDelayEnable(!!this->m_nParameter[ParameterFXChainDelayEnable]);
this->m_PerformanceConfig.SetFXChainDelayWet(this->m_nParameter[ParameterFXChainDelayWet]);
this->m_PerformanceConfig.SetFXChainDelayLeftDelayTime(this->m_nParameter[ParameterFXChainDelayLeftDelayTime]);
this->m_PerformanceConfig.SetFXChainDelayRightDelayTime(this->m_nParameter[ParameterFXChainDelayRightDelayTime]);
this->m_PerformanceConfig.SetFXChainDelayFeedback(this->m_nParameter[ParameterFXChainDelayFeedback]);
this->m_PerformanceConfig.SetFXChainShimmerReverbEnable(!!this->m_nParameter[ParameterFXChainShimmerReverbEnable]);
this->m_PerformanceConfig.SetFXChainShimmerReverbWet(this->m_nParameter[ParameterFXChainShimmerReverbWet]);
this->m_PerformanceConfig.SetFXChainShimmerReverbInputGain(this->m_nParameter[ParameterFXChainShimmerReverbInputGain]);
@ -1842,12 +1834,11 @@ void CMiniDexed::LoadPerformanceParameters(void)
this->SetParameter(ParameterFXChainPhaserWet, this->m_PerformanceConfig.GetFXChainPhaserWet());
this->SetParameter(ParameterFXChainPhaserRate, this->m_PerformanceConfig.GetFXChainPhaserRate());
this->SetParameter(ParameterFXChainPhaserResonance, this->m_PerformanceConfig.GetFXChainPhaserResonance());
this->SetParameter(ParameterFXChainTapeDelayEnable, this->m_PerformanceConfig.GetFXChainTapeDelayEnable());
this->SetParameter(ParameterFXChainTapeDelayWet, this->m_PerformanceConfig.GetFXChainTapeDelayWet());
this->SetParameter(ParameterFXChainTapeDelayLeftDelayTime, this->m_PerformanceConfig.GetFXChainTapeDelayLeftDelayTime());
this->SetParameter(ParameterFXChainTapeDelayRightDelayTime, this->m_PerformanceConfig.GetFXChainTapeDelayRightDelayTime());
this->SetParameter(ParameterFXChainTapeDelayFlutter, this->m_PerformanceConfig.GetFXChainTapeDelayFlutter());
this->SetParameter(ParameterFXChainTapeDelayFeedback, this->m_PerformanceConfig.GetFXChainTapeDelayFeedback());
this->SetParameter(ParameterFXChainDelayEnable, this->m_PerformanceConfig.GetFXChainDelayEnable());
this->SetParameter(ParameterFXChainDelayWet, this->m_PerformanceConfig.GetFXChainDelayWet());
this->SetParameter(ParameterFXChainDelayLeftDelayTime, this->m_PerformanceConfig.GetFXChainDelayLeftDelayTime());
this->SetParameter(ParameterFXChainDelayRightDelayTime, this->m_PerformanceConfig.GetFXChainDelayRightDelayTime());
this->SetParameter(ParameterFXChainDelayFeedback, this->m_PerformanceConfig.GetFXChainDelayFeedback());
this->SetParameter(ParameterFXChainShimmerReverbEnable, this->m_PerformanceConfig.GetFXChainShimmerReverbEnable());
this->SetParameter(ParameterFXChainShimmerReverbWet, this->m_PerformanceConfig.GetFXChainShimmerReverbWet());
this->SetParameter(ParameterFXChainShimmerReverbInputGain, this->m_PerformanceConfig.GetFXChainShimmerReverbInputGain());

@ -177,13 +177,12 @@ public:
ParameterFXChainPhaserRate,
ParameterFXChainPhaserResonance,
// FXChain > TapeDelay parameters
ParameterFXChainTapeDelayEnable,
ParameterFXChainTapeDelayWet,
ParameterFXChainTapeDelayLeftDelayTime,
ParameterFXChainTapeDelayRightDelayTime,
ParameterFXChainTapeDelayFlutter,
ParameterFXChainTapeDelayFeedback,
// FXChain > Delay parameters
ParameterFXChainDelayEnable,
ParameterFXChainDelayWet,
ParameterFXChainDelayLeftDelayTime,
ParameterFXChainDelayRightDelayTime,
ParameterFXChainDelayFeedback,
// FXChain > ShimmerReverb parameters
ParameterFXChainShimmerReverbEnable,

@ -307,12 +307,11 @@ FXChainPhaserEnable=0
FXChainPhaserWet=50
FXChainPhaserRate=5
FXChainPhaserResonance=45
FXChainTapeDelayEnable=0
FXChainTapeDelayWet=50
FXChainTapeDelayLeftDelayTime=15
FXChainTapeDelayRightDelayTime=22
FXChainTapeDelayFlutter=0
FXChainTapeDelayFeedback=35
FXChainDelayEnable=0
FXChainDelayWet=50
FXChainDelayLeftDelayTime=15
FXChainDelayRightDelayTime=22
FXChainDelayFeedback=35
FXChainShimmerReverbEnable=1
FXChainShimmerReverbWet=70
FXChainShimmerReverbInputGain=55

@ -183,12 +183,11 @@ bool CPerformanceConfig::Load (void)
this->m_nFXChainPhaserWet = this->m_Properties.GetNumber("FXChainPhaserWet", 50);
this->m_nFXChainPhaserRate = this->m_Properties.GetNumber("FXChainPhaserRate", 5);
this->m_nFXChainPhaserResonance = this->m_Properties.GetNumber("FXChainPhaserResonance", 45);
this->m_bFXChainTapeDelayEnable = this->m_Properties.GetNumber("FXChainTapeDelayEnable", 1);
this->m_nFXChainTapeDelayWet = this->m_Properties.GetNumber("FXChainTapeDelayWet", 50);
this->m_nFXChainTapeDelayLeftDelayTime = this->m_Properties.GetNumber("FXChainTapeDelayLeftDelayTime", 15);
this->m_nFXChainTapeDelayRightDelayTime = this->m_Properties.GetNumber("FXChainTapeDelayRightDelayTime", 22);
this->m_nFXChainTapeDelayFlutter = this->m_Properties.GetNumber("FXChainTapeDelayFlutter", 7);
this->m_nFXChainTapeDelayFeedback = this->m_Properties.GetNumber("FXChainTapeDelayFeedback", 35);
this->m_bFXChainDelayEnable = this->m_Properties.GetNumber("FXChainDelayEnable", 1);
this->m_nFXChainDelayWet = this->m_Properties.GetNumber("FXChainDelayWet", 50);
this->m_nFXChainDelayLeftDelayTime = this->m_Properties.GetNumber("FXChainDelayLeftDelayTime", 15);
this->m_nFXChainDelayRightDelayTime = this->m_Properties.GetNumber("FXChainDelayRightDelayTime", 22);
this->m_nFXChainDelayFeedback = this->m_Properties.GetNumber("FXChainDelayFeedback", 35);
this->m_bFXChainShimmerReverbEnable = this->m_Properties.GetNumber("FXChainShimmerReverbEnable", 1);
this->m_nFXChainShimmerReverbWet = this->m_Properties.GetNumber("FXChainShimmerReverbWet", 70);
this->m_nFXChainShimmerReverbInputGain = this->m_Properties.GetNumber("FXChainShimmerReverbInputGain", 30);
@ -339,12 +338,11 @@ bool CPerformanceConfig::Save (void)
this->m_Properties.SetNumber("FXChainPhaserWet", m_nFXChainPhaserWet);
this->m_Properties.SetNumber("FXChainPhaserRate", m_nFXChainPhaserRate);
this->m_Properties.SetNumber("FXChainPhaserResonance", m_nFXChainPhaserResonance);
this->m_Properties.SetNumber("FXChainTapeDelayEnable", m_bFXChainTapeDelayEnable ? 1 : 0);
this->m_Properties.SetNumber("FXChainTapeDelayWet", m_nFXChainTapeDelayWet);
this->m_Properties.SetNumber("FXChainTapeDelayLeftDelayTime", m_nFXChainTapeDelayLeftDelayTime);
this->m_Properties.SetNumber("FXChainTapeDelayRightDelayTime", m_nFXChainTapeDelayRightDelayTime);
this->m_Properties.SetNumber("FXChainTapeDelayFlutter", m_nFXChainTapeDelayFlutter);
this->m_Properties.SetNumber("FXChainTapeDelayFeedback", m_nFXChainTapeDelayFeedback);
this->m_Properties.SetNumber("FXChainDelayEnable", m_bFXChainDelayEnable ? 1 : 0);
this->m_Properties.SetNumber("FXChainDelayWet", m_nFXChainDelayWet);
this->m_Properties.SetNumber("FXChainDelayLeftDelayTime", m_nFXChainDelayLeftDelayTime);
this->m_Properties.SetNumber("FXChainDelayRightDelayTime", m_nFXChainDelayRightDelayTime);
this->m_Properties.SetNumber("FXChainDelayFeedback", m_nFXChainDelayFeedback);
this->m_Properties.SetNumber("FXChainShimmerReverbEnable", m_bFXChainShimmerReverbEnable ? 1 : 0);
this->m_Properties.SetNumber("FXChainShimmerReverbWet", m_nFXChainShimmerReverbWet);
this->m_Properties.SetNumber("FXChainShimmerReverbInputGain", m_nFXChainShimmerReverbInputGain);
@ -1116,34 +1114,29 @@ unsigned CPerformanceConfig::GetFXChainPhaserResonance(void) const
return this->m_nFXChainPhaserResonance;
}
bool CPerformanceConfig::GetFXChainTapeDelayEnable(void) const
bool CPerformanceConfig::GetFXChainDelayEnable(void) const
{
return this->m_bFXChainTapeDelayEnable;
return this->m_bFXChainDelayEnable;
}
unsigned CPerformanceConfig::GetFXChainTapeDelayWet(void) const
unsigned CPerformanceConfig::GetFXChainDelayWet(void) const
{
return this->m_nFXChainTapeDelayWet;
return this->m_nFXChainDelayWet;
}
unsigned CPerformanceConfig::GetFXChainTapeDelayLeftDelayTime(void) const
unsigned CPerformanceConfig::GetFXChainDelayLeftDelayTime(void) const
{
return this->m_nFXChainTapeDelayLeftDelayTime;
return this->m_nFXChainDelayLeftDelayTime;
}
unsigned CPerformanceConfig::GetFXChainTapeDelayRightDelayTime(void) const
unsigned CPerformanceConfig::GetFXChainDelayRightDelayTime(void) const
{
return this->m_nFXChainTapeDelayRightDelayTime;
return this->m_nFXChainDelayRightDelayTime;
}
unsigned CPerformanceConfig::GetFXChainTapeDelayFlutter(void) const
unsigned CPerformanceConfig::GetFXChainDelayFeedback(void) const
{
return this->m_nFXChainTapeDelayFlutter;
}
unsigned CPerformanceConfig::GetFXChainTapeDelayFeedback(void) const
{
return this->m_nFXChainTapeDelayFeedback;
return this->m_nFXChainDelayFeedback;
}
bool CPerformanceConfig::GetFXChainShimmerReverbEnable(void) const
@ -1291,34 +1284,29 @@ void CPerformanceConfig::SetFXChainPhaserResonance(unsigned nValue)
this->m_nFXChainPhaserResonance = nValue;
}
void CPerformanceConfig::SetFXChainTapeDelayEnable(unsigned bValue)
{
this->m_bFXChainTapeDelayEnable = bValue;
}
void CPerformanceConfig::SetFXChainTapeDelayWet(unsigned nValue)
void CPerformanceConfig::SetFXChainDelayEnable(unsigned bValue)
{
this->m_nFXChainTapeDelayWet = nValue;
this->m_bFXChainDelayEnable = bValue;
}
void CPerformanceConfig::SetFXChainTapeDelayLeftDelayTime(unsigned nValue)
void CPerformanceConfig::SetFXChainDelayWet(unsigned nValue)
{
this->m_nFXChainTapeDelayLeftDelayTime = nValue;
this->m_nFXChainDelayWet = nValue;
}
void CPerformanceConfig::SetFXChainTapeDelayRightDelayTime(unsigned nValue)
void CPerformanceConfig::SetFXChainDelayLeftDelayTime(unsigned nValue)
{
this->m_nFXChainTapeDelayRightDelayTime = nValue;
this->m_nFXChainDelayLeftDelayTime = nValue;
}
void CPerformanceConfig::SetFXChainTapeDelayFlutter(unsigned nValue)
void CPerformanceConfig::SetFXChainDelayRightDelayTime(unsigned nValue)
{
this->m_nFXChainTapeDelayFlutter = nValue;
this->m_nFXChainDelayRightDelayTime = nValue;
}
void CPerformanceConfig::SetFXChainTapeDelayFeedback(unsigned nValue)
void CPerformanceConfig::SetFXChainDelayFeedback(unsigned nValue)
{
this->m_nFXChainTapeDelayFeedback = nValue;
this->m_nFXChainDelayFeedback = nValue;
}
void CPerformanceConfig::SetFXChainShimmerReverbEnable(unsigned bValue)

@ -141,12 +141,11 @@ public:
unsigned GetFXChainPhaserWet(void) const;
unsigned GetFXChainPhaserRate(void) const;
unsigned GetFXChainPhaserResonance(void) const;
bool GetFXChainTapeDelayEnable(void) const;
unsigned GetFXChainTapeDelayWet(void) const;
unsigned GetFXChainTapeDelayLeftDelayTime(void) const;
unsigned GetFXChainTapeDelayRightDelayTime(void) const;
unsigned GetFXChainTapeDelayFlutter(void) const;
unsigned GetFXChainTapeDelayFeedback(void) const;
bool GetFXChainDelayEnable(void) const;
unsigned GetFXChainDelayWet(void) const;
unsigned GetFXChainDelayLeftDelayTime(void) const;
unsigned GetFXChainDelayRightDelayTime(void) const;
unsigned GetFXChainDelayFeedback(void) const;
bool GetFXChainShimmerReverbEnable(void) const;
unsigned GetFXChainShimmerReverbWet(void) const;
unsigned GetFXChainShimmerReverbInputGain(void) const;
@ -177,12 +176,11 @@ public:
void SetFXChainPhaserWet(unsigned nValue);
void SetFXChainPhaserRate(unsigned nValue);
void SetFXChainPhaserResonance(unsigned nValue);
void SetFXChainTapeDelayEnable(unsigned nValue);
void SetFXChainTapeDelayWet(unsigned nValue);
void SetFXChainTapeDelayLeftDelayTime(unsigned nValue);
void SetFXChainTapeDelayRightDelayTime(unsigned nValue);
void SetFXChainTapeDelayFlutter(unsigned nValue);
void SetFXChainTapeDelayFeedback(unsigned nValue);
void SetFXChainDelayEnable(unsigned nValue);
void SetFXChainDelayWet(unsigned nValue);
void SetFXChainDelayLeftDelayTime(unsigned nValue);
void SetFXChainDelayRightDelayTime(unsigned nValue);
void SetFXChainDelayFeedback(unsigned nValue);
void SetFXChainShimmerReverbEnable(unsigned nValue);
void SetFXChainShimmerReverbWet(unsigned nValue);
void SetFXChainShimmerReverbInputGain(unsigned nValue);
@ -282,12 +280,11 @@ private:
unsigned m_nFXChainPhaserWet;
unsigned m_nFXChainPhaserRate;
unsigned m_nFXChainPhaserResonance;
bool m_bFXChainTapeDelayEnable;
unsigned m_nFXChainTapeDelayWet;
unsigned m_nFXChainTapeDelayLeftDelayTime;
unsigned m_nFXChainTapeDelayRightDelayTime;
unsigned m_nFXChainTapeDelayFlutter;
unsigned m_nFXChainTapeDelayFeedback;
bool m_bFXChainDelayEnable;
unsigned m_nFXChainDelayWet;
unsigned m_nFXChainDelayLeftDelayTime;
unsigned m_nFXChainDelayRightDelayTime;
unsigned m_nFXChainDelayFeedback;
bool m_bFXChainShimmerReverbEnable;
unsigned m_nFXChainShimmerReverbWet;
unsigned m_nFXChainShimmerReverbInputGain;

@ -19,7 +19,7 @@ OBJS := \
fx_phaser.o \
fx_orbitone.o \
fx_flanger.o \
fx_tape_delay.o \
fx_delay.o \
fx_shimmer_reverb.o \
fx_rack.o \
fxrack_test.o
@ -63,7 +63,7 @@ fx_orbitone.o: ../fx_orbitone.cpp
fx_flanger.o: ../fx_flanger.cpp
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
fx_tape_delay.o: ../fx_tape_delay.cpp
fx_delay.o: ../fx_delay.cpp
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
../fx_shimmer_reverb3.cpp: ../fx_engine.hpp

@ -1,103 +1,56 @@
#include "../fx_rack.h"
#include <iomanip>
#include <iostream>
#include <fstream>
#include <locale>
#include <ctime>
#include <random>
#include "wave.h"
using namespace std;
#define FS 44100.0f
#define MAX_SVF_SAMPLES 10000000
#define MAX_NB_ERRORS 100
enum CosineOscillatorMode
{
COSINE_OSCILLATOR_APPROXIMATE,
COSINE_OSCILLATOR_EXACT
};
class CosineOscillator
{
public:
CosineOscillator() {}
~CosineOscillator() {}
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float32_t> dist(-1.0f, 1.0f);
template <CosineOscillatorMode mode>
inline void Init(float frequency)
{
if (mode == COSINE_OSCILLATOR_APPROXIMATE)
{
InitApproximate(frequency);
}
else
void testLFO(unsigned& step)
{
iir_coefficient_ = 2.0f * cosf(2.0f * M_PI * frequency);
initial_amplitude_ = iir_coefficient_ * 0.25f;
}
Start();
}
cout << "Step #" << (++step) << ": Testing LFO" << endl;
inline void InitApproximate(float frequency)
{
float sign = 16.0f;
frequency -= 0.25f;
if (frequency < 0.0f)
{
frequency = -frequency;
}
else
{
if (frequency > 0.5f)
{
frequency -= 0.5f;
}
else
{
sign = -16.0f;
}
}
iir_coefficient_ = sign * frequency * (1.0f - 2.0f * frequency);
initial_amplitude_ = iir_coefficient_ * 0.25f;
}
const float32_t freq = 10.0f;
inline void Start()
{
y1_ = initial_amplitude_;
y0_ = 0.5f;
}
LFO lfo(FS, LFO::Waveform::Sine, 0.0f, freq);
unsigned size = static_cast<unsigned>(8.0f * FS / freq);
float32_t rate = 0.0f;
float32_t rate_increment = freq / 2.0f / FS;
inline float value() const
{
return y1_ + 0.5f;
}
// float32_t* output = new float32_t[size];
ofstream out("result.csv");
inline float Next()
struct comma_separator : std::numpunct<char>
{
float temp = y0_;
y0_ = iir_coefficient_ * y0_ - y1_;
y1_ = temp;
return temp + 0.5f;
}
private:
float y1_;
float y0_;
float iir_coefficient_;
float initial_amplitude_;
DISALLOW_COPY_AND_ASSIGN(CosineOscillator);
virtual char do_decimal_point() const override { return ','; }
};
void testCosineOsc(unsigned& step)
{
cout << "Step #" << (++step) << ": Testing CosineOscillator" << endl;
out.imbue(std::locale(out.getloc(), new comma_separator));
out << fixed << showpoint;
CosineOscillator osc;
osc.template Init<CosineOscillatorMode::COSINE_OSCILLATOR_APPROXIMATE>(32.0f * 0.5f / 32000.0f);
out << "index;LFO" << endl;
for(unsigned i = 0; i < size; ++i)
{
lfo.setNormalizedFrequency(rate);
out << i << ";" << lfo.process() << endl;
rate += rate_increment;
for(unsigned i = 0; i < 2000; ++i)
if(rate >= 1.0f || rate <= 0.0f)
{
cout << "LFO #" << i << ": " << osc.Next() << endl;
rate_increment *= -1.0f;
}
}
}
@ -105,7 +58,7 @@ void testFlutter(unsigned& step)
{
cout << "Step #" << (++step) << ": Testing JitterGenerator" << endl;
JitterGenerator jg(44100.0f);
JitterGenerator jg(FS);
jg.setSpeed(1.0f);
jg.setMagnitude(0.1f);
@ -115,11 +68,11 @@ void testFlutter(unsigned& step)
}
}
void testSVF(unsigned& step, std::mt19937& gen, std::uniform_real_distribution<float32_t> dist)
void testSVF(unsigned& step)
{
float32_t inL, inR;
float32_t outL, outR;
StateVariableFilter svf(44100.0f, StateVariableFilter::Type::LPF, 12000.0f);
StateVariableFilter svf(FS, StateVariableFilter::Type::LPF, 12000.0f);
cout << "Step #" << (++step) << ": Testing SVF in LPF mode" << endl;
{
@ -166,18 +119,8 @@ void testSVF(unsigned& step, std::mt19937& gen, std::uniform_real_distribution<f
}
}
int main()
void testFXRack(unsigned& step)
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float32_t> dist(-1.0f, 1.0f);
unsigned step = 0;
// testCosineOsc(step);
// testFlutter(step, gen, dist);
// testSVF(step);
cout << "Step #" << (++step) << ": Intanciation FXRack" << endl;
FXRack *rack = new FXRack(44100.0f);
@ -203,12 +146,11 @@ int main()
rack->getFlanger()->setEnable(false);
rack->getTapeDelay()->setEnable(false);
rack->getTapeDelay()->setWetLevel(0.6f);
rack->getTapeDelay()->setLeftDelayTime(0.075f);
rack->getTapeDelay()->setLeftDelayTime(0.05f);
rack->getTapeDelay()->setFlutterLevel(0.0f);
rack->getTapeDelay()->setFeedbak(0.5f);
rack->getDelay()->setEnable(false);
rack->getDelay()->setWetLevel(0.6f);
rack->getDelay()->setLeftDelayTime(0.075f);
rack->getDelay()->setLeftDelayTime(0.05f);
rack->getDelay()->setFeedbak(0.5f);
rack->getShimmerReverb()->setEnable(false);
rack->getShimmerReverb()->setWetLevel(0.7f);
@ -263,6 +205,16 @@ int main()
cout << "Step #" << (++step) << ": Test cleanup" << endl;
delete rack;
}
int main()
{
unsigned step = 0;
testLFO(step);
// testFlutter(step);
// testSVF(step);
// testFXRack(step);
return 0;
}

@ -151,7 +151,7 @@ const CUIMenu::TMenuItem CUIMenu::s_FXChainMenu[] =
{"FlangR", MenuHandler, s_FXChainFlanger},
{"Orb", MenuHandler, s_FXChainOrbitone},
{"PhasR", MenuHandler, s_FXChainPhaser},
{"Delay", MenuHandler, s_FXChainTapeDelay},
{"Delay", MenuHandler, s_FXChainDelay},
{"Shimmer", MenuHandler, s_FXChainShimmerReverb},
{0}
};
@ -202,14 +202,13 @@ const CUIMenu::TMenuItem CUIMenu::s_FXChainPhaser[] =
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_FXChainTapeDelay[] =
const CUIMenu::TMenuItem CUIMenu::s_FXChainDelay[] =
{
{"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTapeDelayEnable},
{"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTapeDelayWet},
{"L Delay", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTapeDelayLeftDelayTime},
{"R Delay", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTapeDelayRightDelayTime},
{"Flutter", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTapeDelayFlutter},
{"Feedbck", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTapeDelayFeedback},
{"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainDelayEnable},
{"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainDelayWet},
{"L Delay", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainDelayLeftDelayTime},
{"R Delay", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainDelayRightDelayTime},
{"Feedbck", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainDelayFeedback},
{0}
};
@ -343,13 +342,12 @@ const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::ParameterUnknow
{0, 99, 1}, // ParameterFXChainPhaserRate
{0, 99, 1}, // ParameterFXChainPhaserResonance
// FXChain > TapeDelay parameters
{0, 1, 1, ToOnOff}, // ParameterFXChainTapeDelayEnable
{0, 99, 1}, // ParameterFXChainTapeDelayWet
{0, 99, 1}, // ParameterFXChainTapeDelayLeftDelayTime
{0, 99, 1}, // ParameterFXChainTapeDelayRightDelayTime
{0, 99, 1}, // ParameterFXChainTapeDelayFlutter
{0, 99, 1}, // ParameterFXChainTapeDelayFeedback
// FXChain > Delay parameters
{0, 1, 1, ToOnOff}, // ParameterFXChainDelayEnable
{0, 99, 1}, // ParameterFXChainDelayWet
{0, 99, 1}, // ParameterFXChainDelayLeftDelayTime
{0, 99, 1}, // ParameterFXChainDelayRightDelayTime
{0, 99, 1}, // ParameterFXChainDelayFeedback
// FXChain > ShimmerReverb parameters
{0, 1, 1, ToOnOff}, // ParameterFXChainShimmerReverbEnable

@ -149,7 +149,7 @@ private:
static const TMenuItem s_FXChainFlanger[];
static const TMenuItem s_FXChainOrbitone[];
static const TMenuItem s_FXChainPhaser[];
static const TMenuItem s_FXChainTapeDelay[];
static const TMenuItem s_FXChainDelay[];
static const TMenuItem s_FXChainShimmerReverb[];
#endif
static const TMenuItem s_EditVoiceMenu[];

Loading…
Cancel
Save