Finalizing Delay FX adding the possibility to accept negative delay values enabling playing processed sound reversed

pull/495/head
Vincent GAUCHE 2 years ago
parent 1fe0559f43
commit 29cbdc0d94
  1. 2
      src/fx_components.cpp
  2. 93
      src/fx_delay.cpp
  3. 34
      src/fx_delay.h
  4. 16
      src/minidexed.cpp
  5. 2
      src/minidexed.h
  6. 24
      src/performanceconfig.cpp
  7. 6
      src/performanceconfig.h
  8. 8
      src/uimenu.cpp
  9. 32
      wiki-update/fx-page.md
  10. BIN
      wiki-update/mixing-console-overview.png

@ -610,7 +610,7 @@ void JitterGenerator::reset()
float32_t JitterGenerator::process() float32_t JitterGenerator::process()
{ {
float32_t out = arm_sin_f32(this->phase_); float32_t out = InterpolatedSineOscillator::Sin(this->phase_);
this->phase_ += this->phase_increment_ * (1.0f + this->magnitude_ * this->rnd_distribution_(this->rnd_generator_)); this->phase_ += this->phase_increment_ * (1.0f + this->magnitude_ * this->rnd_distribution_(this->rnd_generator_));
if(this->phase_ > Constants::M2PI) if(this->phase_ > Constants::M2PI)

@ -52,11 +52,10 @@ void Delay::LowHighPassFilter::processSample(float32_t inL, float32_t inR, float
Delay::Delay(const float32_t sampling_rate, float32_t default_delay_time, float32_t default_flutter_level, float32_t default_feedback_level) : Delay::Delay(const float32_t sampling_rate, float32_t default_delay_time, float32_t default_flutter_level, float32_t default_feedback_level) :
FXElement(sampling_rate, 2.2587f), FXElement(sampling_rate, 2.2587f),
MaxSampleDelayTime((MAX_DELAY_TIME + MAX_FLUTTER_DELAY_TIME) * sampling_rate * MAX_DELAY_TIME), MaxSampleDelayTime((MAX_DELAY_TIME + MAX_FLUTTER_DELAY_TIME) * sampling_rate),
read_pos_L_(0), write_pos_L_(0),
read_pos_R_(0), write_pos_R_(0),
filter_(sampling_rate), filter_(sampling_rate)
jitter_generator_(sampling_rate)
{ {
this->buffer_L_ = new float32_t[this->MaxSampleDelayTime]; this->buffer_L_ = new float32_t[this->MaxSampleDelayTime];
this->buffer_R_ = new float32_t[this->MaxSampleDelayTime]; this->buffer_R_ = new float32_t[this->MaxSampleDelayTime];
@ -64,8 +63,6 @@ Delay::Delay(const float32_t sampling_rate, float32_t default_delay_time, float3
this->setLeftDelayTime(default_delay_time); this->setLeftDelayTime(default_delay_time);
this->setRightDelayTime(default_delay_time); this->setRightDelayTime(default_delay_time);
this->setFeedback(default_feedback_level); this->setFeedback(default_feedback_level);
this->setFlutterRate(0.2f);
this->setFlutterAmount(0.0f);
this->reset(); this->reset();
} }
@ -80,59 +77,49 @@ void Delay::reset()
{ {
memset(this->buffer_L_, 0, this->MaxSampleDelayTime * sizeof(float32_t)); memset(this->buffer_L_, 0, this->MaxSampleDelayTime * sizeof(float32_t));
memset(this->buffer_R_, 0, this->MaxSampleDelayTime * sizeof(float32_t)); memset(this->buffer_R_, 0, this->MaxSampleDelayTime * sizeof(float32_t));
this->read_pos_L_ = 0; this->write_pos_L_ = 0;
this->read_pos_R_ = 0; this->write_pos_R_ = 0;
this->filter_.reset(); this->filter_.reset();
this->jitter_generator_.reset();
} }
void Delay::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) void Delay::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{ {
float32_t jitter_delay_time = 0.0f; // Write input to delay buffers
if(this->jitter_amount_ != 0.0f) this->buffer_L_[this->write_pos_L_] *= this->getFeedback();;
{ this->buffer_L_[this->write_pos_L_] += inL;
float32_t jitter_ratio = this->jitter_generator_.process(); this->buffer_R_[this->write_pos_R_] *= this->getFeedback();;
if(jitter_ratio != 0.0f) this->buffer_R_[this->write_pos_R_] += inR;
{
jitter_ratio *= this->jitter_amount_ * MAX_FLUTTER_DELAY_AMOUNT;
jitter_delay_time = MAX_FLUTTER_DELAY_TIME * jitter_ratio;
this->filter_.setCutoffChangeRatio(jitter_ratio);
}
}
// const float32_t max_delay_time = MAX_DELAY_TIME * this->getSamplingRate();
float32_t delay_time_L = (MAX_DELAY_TIME * this->getLeftDelayTime() + jitter_delay_time) * this->getSamplingRate();
float32_t delay_time_R = (MAX_DELAY_TIME * this->getRightDelayTime() + jitter_delay_time) * this->getSamplingRate();
// Calculate write positions // Calculate read positions
unsigned write_pos_L = static_cast<unsigned>(this->MaxSampleDelayTime + this->read_pos_L_ + delay_time_L) % this->MaxSampleDelayTime; float32_t delay_time_L = std::abs(MAX_DELAY_TIME * this->getLeftDelayTime() ) * this->getSamplingRate();
unsigned write_pos_R = static_cast<unsigned>(this->MaxSampleDelayTime + this->read_pos_R_ + delay_time_R) % this->MaxSampleDelayTime; float32_t delay_time_R = std::abs(MAX_DELAY_TIME * this->getRightDelayTime()) * this->getSamplingRate();
float32_t signL = this->getLeftDelayTime() >= 0 ? 1.0f : -1.0f;
float32_t signR = this->getRightDelayTime() >= 0 ? 1.0f : -1.0f;
unsigned read_pos_L = static_cast<unsigned>(this->MaxSampleDelayTime + signL * this->write_pos_L_ - delay_time_L) % this->MaxSampleDelayTime;
unsigned read_pos_R = static_cast<unsigned>(this->MaxSampleDelayTime + signR * this->write_pos_R_ - 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 // Read from delay buffers and apply feedback
this->filter_.processSample( this->filter_.processSample(
this->buffer_L_[this->read_pos_L_], this->buffer_L_[read_pos_L],
this->buffer_R_[this->read_pos_R_], this->buffer_R_[read_pos_R],
outL, outL,
outR outR
); );
this->buffer_L_[write_pos_L] += outL * this->getFeedback(); this->buffer_L_[this->write_pos_L_] += outL * this->getFeedback();
this->buffer_R_[write_pos_R] += outR * this->getFeedback(); this->buffer_R_[this->write_pos_R_] += outR * this->getFeedback();
// Increment read positions // Increment read positions
++this->read_pos_L_; ++ this->write_pos_L_;
if(this->read_pos_L_ >= this->MaxSampleDelayTime) if(this->write_pos_L_ >= this->MaxSampleDelayTime)
{ {
this->read_pos_L_ -= this->MaxSampleDelayTime; this->write_pos_L_ -= this->MaxSampleDelayTime;
} }
++this->read_pos_R_; ++ this->write_pos_R_;
if(this->read_pos_R_ >= this->MaxSampleDelayTime) if(this->write_pos_R_ >= this->MaxSampleDelayTime)
{ {
this->read_pos_R_ -= this->MaxSampleDelayTime; this->write_pos_R_ -= this->MaxSampleDelayTime;
} }
outL *= this->OutputLevelCorrector; outL *= this->OutputLevelCorrector;
@ -141,7 +128,7 @@ void Delay::processSample(float32_t inL, float32_t inR, float32_t& outL, float32
void Delay::setLeftDelayTime(float32_t delay_time) void Delay::setLeftDelayTime(float32_t delay_time)
{ {
this->delay_time_L_ = constrain(delay_time, 0.0f, 1.0f); this->delay_time_L_ = constrain(delay_time, -1.0f, 1.0f);
} }
float32_t Delay::getLeftDelayTime() const float32_t Delay::getLeftDelayTime() const
@ -151,7 +138,7 @@ float32_t Delay::getLeftDelayTime() const
void Delay::setRightDelayTime(float32_t delay_time) void Delay::setRightDelayTime(float32_t delay_time)
{ {
this->delay_time_R_ = constrain(delay_time, 0.0f, 1.0f); this->delay_time_R_ = constrain(delay_time, -1.0f, 1.0f);
} }
float32_t Delay::getRightDelayTime() const float32_t Delay::getRightDelayTime() const
@ -168,23 +155,3 @@ float32_t Delay::getFeedback() const
{ {
return this->feedback_; return this->feedback_;
} }
void Delay::setFlutterRate(float32_t rate)
{
this->jitter_generator_.setRate(rate);
}
float32_t Delay::getFlutterRate() const
{
return this->jitter_generator_.getRate();
}
void Delay::setFlutterAmount(float32_t amount)
{
this->jitter_amount_ = constrain(amount, 0.0f, 1.0f);
}
float32_t Delay::getFlutterAmount() const
{
return this->jitter_amount_;
}

@ -105,25 +105,17 @@ public:
void setFeedback(float32_t feedback); void setFeedback(float32_t feedback);
float32_t getFeedback() const; float32_t getFeedback() const;
void setFlutterRate(float32_t rate);
float32_t getFlutterRate() const;
void setFlutterAmount(float32_t amount);
float32_t getFlutterAmount() const;
private: private:
const size_t MaxSampleDelayTime; const size_t MaxSampleDelayTime;
unsigned read_pos_L_; unsigned write_pos_L_;
unsigned read_pos_R_; unsigned write_pos_R_;
float32_t* buffer_L_; float32_t* buffer_L_;
float32_t* buffer_R_; float32_t* buffer_R_;
float32_t delay_time_L_; // Left delay time in seconds (0.0 - 2.0) 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 delay_time_R_; // Right delay time in seconds (0.0 - 2.0)
float32_t feedback_; // Feedback (0.0 - 1.0) float32_t feedback_; // Feedback (0.0 - 1.0)
float32_t jitter_amount_;
LowHighPassFilter filter_; LowHighPassFilter filter_;
PerlinNoiseGenerator jitter_generator_;
IMPLEMENT_DUMP( IMPLEMENT_DUMP(
const size_t space = 18; const size_t space = 18;
@ -134,12 +126,11 @@ private:
out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl; out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
SS_RESET(ss, precision, std::left); SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space, std::left, '|', "read_pos_L_"); SS__TEXT(ss, ' ', space, std::left, '|', "write_pos_L_");
SS__TEXT(ss, ' ', space, std::left, '|', "read_pos_R_"); SS__TEXT(ss, ' ', space, std::left, '|', "write_pos_R_");
SS__TEXT(ss, ' ', space, std::left, '|', "delay_time_L_"); SS__TEXT(ss, ' ', space, std::left, '|', "delay_time_L_");
SS__TEXT(ss, ' ', space, std::left, '|', "delay_time_R_"); SS__TEXT(ss, ' ', space, std::left, '|', "delay_time_R_");
SS__TEXT(ss, ' ', space, std::left, '|', "feedback_"); SS__TEXT(ss, ' ', space, std::left, '|', "feedback_");
SS__TEXT(ss, ' ', space, std::left, '|', "jitter_amount_");
out << "\t" << ss.str() << std::endl; out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, std::left); SS_RESET(ss, precision, std::left);
@ -148,16 +139,14 @@ private:
SS_SPACE(ss, '-', space, std::left, '+'); SS_SPACE(ss, '-', space, std::left, '+');
SS_SPACE(ss, '-', space, std::left, '+'); SS_SPACE(ss, '-', space, std::left, '+');
SS_SPACE(ss, '-', space, std::left, '+'); SS_SPACE(ss, '-', space, std::left, '+');
SS_SPACE(ss, '-', space, std::left, '+');
out << "\t" << ss.str() << std::endl; out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, std::left); SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->read_pos_L_); SS__TEXT(ss, ' ', space - 1, std::right, " |", this->write_pos_L_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->read_pos_R_); SS__TEXT(ss, ' ', space - 1, std::right, " |", this->write_pos_R_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->delay_time_L_); SS__TEXT(ss, ' ', space - 1, std::right, " |", this->delay_time_L_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->delay_time_R_); SS__TEXT(ss, ' ', space - 1, std::right, " |", this->delay_time_R_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->feedback_); SS__TEXT(ss, ' ', space - 1, std::right, " |", this->feedback_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->jitter_amount_);
out << "\t" << ss.str() << std::endl; out << "\t" << ss.str() << std::endl;
if(deepInspection) if(deepInspection)
@ -186,7 +175,6 @@ private:
} }
this->filter_.dump(out, deepInspection, tag + ".filter_"); this->filter_.dump(out, deepInspection, tag + ".filter_");
this->jitter_generator_.dump(out, deepInspection, tag + ".jitter_generator_");
} }
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl; out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
@ -194,12 +182,11 @@ private:
IMPLEMENT_INSPECT( IMPLEMENT_INSPECT(
size_t nb_errors = 0; size_t nb_errors = 0;
nb_errors += inspector(tag + ".read_pos_L_", static_cast<float32_t>(this->read_pos_L_), 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection); nb_errors += inspector(tag + ".write_pos_L_", static_cast<float32_t>(this->write_pos_L_), 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection);
nb_errors += inspector(tag + ".read_pos_R_", static_cast<float32_t>(this->read_pos_R_), 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection); nb_errors += inspector(tag + ".write_pos_R_", static_cast<float32_t>(this->write_pos_R_), 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection);
nb_errors += inspector(tag + ".delay_time_L_", this->delay_time_L_, 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection); nb_errors += inspector(tag + ".delay_time_L_", this->delay_time_L_, -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".delay_time_R_", this->delay_time_R_, 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection); nb_errors += inspector(tag + ".delay_time_R_", this->delay_time_R_, -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".feedback_", this->feedback_, 0.0f, 1.0f, deepInspection); nb_errors += inspector(tag + ".feedback_", this->feedback_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".jitter_amount_", this->jitter_amount_, 0.0f, 1.0f, deepInspection);
if(deepInspection) if(deepInspection)
{ {
@ -210,7 +197,6 @@ private:
} }
nb_errors += this->filter_.inspect(inspector, deepInspection, tag + ".filter_"); nb_errors += this->filter_.inspect(inspector, deepInspection, tag + ".filter_");
nb_errors += this->jitter_generator_.inspect(inspector, deepInspection, tag + ".jitter_generator_");
} }
return nb_errors; return nb_errors;

@ -938,13 +938,13 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue)
this->m_FXSpinLock.Release(); this->m_FXSpinLock.Release();
break; break;
case TParameter::ParameterFXDelayLeftDelayTime: case TParameter::ParameterFXDelayLeftDelayTime:
nValue = constrain((int)nValue, 0, 99); nValue = constrain((int)nValue, -99, 99);
this->m_FXSpinLock.Acquire(); this->m_FXSpinLock.Acquire();
this->mixing_console_->getDelay()->setLeftDelayTime(nValue / 99.0f); this->mixing_console_->getDelay()->setLeftDelayTime(nValue / 99.0f);
this->m_FXSpinLock.Release(); this->m_FXSpinLock.Release();
break; break;
case TParameter::ParameterFXDelayRightDelayTime: case TParameter::ParameterFXDelayRightDelayTime:
nValue = constrain((int)nValue, 0, 99); nValue = constrain((int)nValue, -99, 99);
this->m_FXSpinLock.Acquire(); this->m_FXSpinLock.Acquire();
this->mixing_console_->getDelay()->setRightDelayTime(nValue / 99.0f); this->mixing_console_->getDelay()->setRightDelayTime(nValue / 99.0f);
this->m_FXSpinLock.Release(); this->m_FXSpinLock.Release();
@ -955,18 +955,6 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue)
this->mixing_console_->getDelay()->setFeedback(nValue / 99.0f); this->mixing_console_->getDelay()->setFeedback(nValue / 99.0f);
this->m_FXSpinLock.Release(); this->m_FXSpinLock.Release();
break; break;
case TParameter::ParameterFXDelayFlutterRate:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
this->mixing_console_->getDelay()->setFlutterRate(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
case TParameter::ParameterFXDelayFlutterAmount:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
this->mixing_console_->getDelay()->setFlutterAmount(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
// AudioEffectPlateReverb parameters // AudioEffectPlateReverb parameters
case TParameter::ParameterReverbEnable: case TParameter::ParameterReverbEnable:

@ -195,8 +195,6 @@ public:
ParameterFXDelayLeftDelayTime, ParameterFXDelayLeftDelayTime,
ParameterFXDelayRightDelayTime, ParameterFXDelayRightDelayTime,
ParameterFXDelayFeedback, ParameterFXDelayFeedback,
ParameterFXDelayFlutterRate,
ParameterFXDelayFlutterAmount,
// Reverberator parameters // Reverberator parameters
ParameterFXReverberatorEnable, ParameterFXReverberatorEnable,

@ -191,8 +191,6 @@ bool CPerformanceConfig::Load (void)
this->m_nFXDelayLeftDelayTime = this->m_Properties.GetNumber("FXDelayLeftDelayTime", 15); this->m_nFXDelayLeftDelayTime = this->m_Properties.GetNumber("FXDelayLeftDelayTime", 15);
this->m_nFXDelayRightDelayTime = this->m_Properties.GetNumber("FXDelayRightDelayTime", 22); this->m_nFXDelayRightDelayTime = this->m_Properties.GetNumber("FXDelayRightDelayTime", 22);
this->m_nFXDelayFeedback = this->m_Properties.GetNumber("FXDelayFeedback", 35); this->m_nFXDelayFeedback = this->m_Properties.GetNumber("FXDelayFeedback", 35);
this->m_nFXDelayFlutterRate = this->m_Properties.GetNumber("FXDelayFlutterRate", 0);
this->m_nFXDelayFlutterAmount = this->m_Properties.GetNumber("FXDelayFlutterAmount", 0);
this->m_bFXReverberatorEnable = this->m_Properties.GetNumber("FXReverberatorEnable", 1); this->m_bFXReverberatorEnable = this->m_Properties.GetNumber("FXReverberatorEnable", 1);
this->m_nFXReverberatorInputGain = this->m_Properties.GetNumber("FXReverberatorInputGain", 30); this->m_nFXReverberatorInputGain = this->m_Properties.GetNumber("FXReverberatorInputGain", 30);
@ -387,8 +385,6 @@ bool CPerformanceConfig::Save (void)
this->m_Properties.SetNumber("FXDelayLeftDelayTime", this->m_nFXDelayLeftDelayTime); this->m_Properties.SetNumber("FXDelayLeftDelayTime", this->m_nFXDelayLeftDelayTime);
this->m_Properties.SetNumber("FXDelayRightDelayTime", this->m_nFXDelayRightDelayTime); this->m_Properties.SetNumber("FXDelayRightDelayTime", this->m_nFXDelayRightDelayTime);
this->m_Properties.SetNumber("FXDelayFeedback", this->m_nFXDelayFeedback); this->m_Properties.SetNumber("FXDelayFeedback", this->m_nFXDelayFeedback);
this->m_Properties.SetNumber("FXDelayFlutterRate", this->m_nFXDelayFlutterRate);
this->m_Properties.SetNumber("FXDelayFlutterAmount", this->m_nFXDelayFlutterAmount);
this->m_Properties.SetNumber("FXReverberatorEnable", this->m_bFXReverberatorEnable ? 1 : 0); this->m_Properties.SetNumber("FXReverberatorEnable", this->m_bFXReverberatorEnable ? 1 : 0);
this->m_Properties.SetNumber("FXReverberatorInputGain", this->m_nFXReverberatorInputGain); this->m_Properties.SetNumber("FXReverberatorInputGain", this->m_nFXReverberatorInputGain);
@ -1178,16 +1174,6 @@ unsigned CPerformanceConfig::GetFXDelayFeedback(void) const
return this->m_nFXDelayFeedback; return this->m_nFXDelayFeedback;
} }
unsigned CPerformanceConfig::GetFXDelayFlutterRate(void) const
{
return this->m_nFXDelayFlutterRate;
}
unsigned CPerformanceConfig::GetFXDelayFlutterAmount(void) const
{
return this->m_nFXDelayFlutterAmount;
}
bool CPerformanceConfig::GetFXReverberatorEnable(void) const bool CPerformanceConfig::GetFXReverberatorEnable(void) const
{ {
return this->m_bFXReverberatorEnable; return this->m_bFXReverberatorEnable;
@ -1332,16 +1318,6 @@ void CPerformanceConfig::SetFXDelayFeedback(unsigned nValue)
this->m_nFXDelayFeedback = nValue; this->m_nFXDelayFeedback = nValue;
} }
void CPerformanceConfig::SetFXDelayFlutterRate(unsigned nValue)
{
this->m_nFXDelayFlutterRate = nValue;
}
void CPerformanceConfig::SetFXDelayFlutterAmount(unsigned nValue)
{
this->m_nFXDelayFlutterAmount = nValue;
}
void CPerformanceConfig::SetFXReverberatorEnable(unsigned bValue) void CPerformanceConfig::SetFXReverberatorEnable(unsigned bValue)
{ {
this->m_bFXReverberatorEnable = bValue; this->m_bFXReverberatorEnable = bValue;

@ -149,8 +149,6 @@ public:
unsigned GetFXDelayLeftDelayTime(void) const; unsigned GetFXDelayLeftDelayTime(void) const;
unsigned GetFXDelayRightDelayTime(void) const; unsigned GetFXDelayRightDelayTime(void) const;
unsigned GetFXDelayFeedback(void) const; unsigned GetFXDelayFeedback(void) const;
unsigned GetFXDelayFlutterRate(void) const;
unsigned GetFXDelayFlutterAmount(void) const;
bool GetFXReverberatorEnable(void) const; bool GetFXReverberatorEnable(void) const;
unsigned GetFXReverberatorInputGain(void) const; unsigned GetFXReverberatorInputGain(void) const;
@ -186,8 +184,6 @@ public:
void SetFXDelayLeftDelayTime(unsigned nValue); void SetFXDelayLeftDelayTime(unsigned nValue);
void SetFXDelayRightDelayTime(unsigned nValue); void SetFXDelayRightDelayTime(unsigned nValue);
void SetFXDelayFeedback(unsigned nValue); void SetFXDelayFeedback(unsigned nValue);
void SetFXDelayFlutterRate(unsigned nValue);
void SetFXDelayFlutterAmount(unsigned nValue);
void SetFXReverberatorEnable(unsigned nValue); void SetFXReverberatorEnable(unsigned nValue);
void SetFXReverberatorInputGain(unsigned nValue); void SetFXReverberatorInputGain(unsigned nValue);
@ -299,8 +295,6 @@ private:
unsigned m_nFXDelayLeftDelayTime; unsigned m_nFXDelayLeftDelayTime;
unsigned m_nFXDelayRightDelayTime; unsigned m_nFXDelayRightDelayTime;
unsigned m_nFXDelayFeedback; unsigned m_nFXDelayFeedback;
unsigned m_nFXDelayFlutterRate;
unsigned m_nFXDelayFlutterAmount;
bool m_bFXReverberatorEnable; bool m_bFXReverberatorEnable;
unsigned m_nFXReverberatorInputGain; unsigned m_nFXReverberatorInputGain;

@ -232,8 +232,6 @@ const CUIMenu::TMenuItem CUIMenu::s_FXDelay[] =
{"L Delay", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayLeftDelayTime}, {"L Delay", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayLeftDelayTime},
{"R Delay", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayRightDelayTime}, {"R Delay", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayRightDelayTime},
{"Feedbck", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayFeedback}, {"Feedbck", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayFeedback},
{"Flt Rte", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayFlutterRate},
{"Flt Amt", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayFlutterAmount},
{"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXDelayLevels}, {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXDelayLevels},
{"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXDelaySend}, {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXDelaySend},
{0} {0}
@ -671,11 +669,9 @@ const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::TParameter::Par
// FX > Delay parameters // FX > Delay parameters
{0, 1, 1, ToOnOff}, // ParameterFXDelayEnable {0, 1, 1, ToOnOff}, // ParameterFXDelayEnable
{0, 99, 1}, // ParameterFXDelayLeftDelayTime {-99, 99, 1}, // ParameterFXDelayLeftDelayTime
{0, 99, 1}, // ParameterFXDelayRightDelayTime {-99, 99, 1}, // ParameterFXDelayRightDelayTime
{0, 99, 1}, // ParameterFXDelayFeedback {0, 99, 1}, // ParameterFXDelayFeedback
{0, 99, 1}, // ParameterFXDelayFlutterRate
{0, 99, 1}, // ParameterFXDelayFlutterAmount
// FX > Reverberator parameters // FX > Reverberator parameters
{0, 1, 1, ToOnOff}, // ParameterFXReverberatorEnable {0, 1, 1, ToOnOff}, // ParameterFXReverberatorEnable

@ -1,7 +1,5 @@
# Mixing Console & Audio Effect # Mixing Console & Audio Effect
<img src="mixing-console-overview.png" alt="Mixing Console - TG Channel Strip" width="100%" style="background-color: #fff">
On multi-core devices, MiniDexed can now be equiped with a complex and versatile mixing console that is composed of a multi-FX processor. On multi-core devices, MiniDexed can now be equiped with a complex and versatile mixing console that is composed of a multi-FX processor.
After the volume and pan controls, it is possible to set the send level of each Tone Generator to the individual Audio Effect and Main output. Below is the TG channel strip: After the volume and pan controls, it is possible to set the send level of each Tone Generator to the individual Audio Effect and Main output. Below is the TG channel strip:
@ -12,6 +10,8 @@ Each FX has the possibility to return to any other Audio FX unit as well as Main
The diagram below shows the synopsis of this Mixing Console. The diagram below shows the synopsis of this Mixing Console.
<img src="mixing-console-overview.png" alt="Mixing Console - TG Channel Strip" width="100%" style="background-color: #fff">
## The Audio FX ## The Audio FX
The following audio FX are available: The following audio FX are available:
@ -20,6 +20,7 @@ The following audio FX are available:
<img src="Tube--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff"> <img src="Tube--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff">
* ***Enable [Off - On]:*** Enable / disable the FX unit.
* ***Overdrive [0 - 99]:*** the overdrive amount the more the overdrive the less linear is the amplification. Below is the amplifier response based on different value of the overdrive: ![Tube - Overdrive response](Tube--overdrive-response.png) * ***Overdrive [0 - 99]:*** the overdrive amount the more the overdrive the less linear is the amplification. Below is the amplifier response based on different value of the overdrive: ![Tube - Overdrive response](Tube--overdrive-response.png)
<br> <br>
@ -37,6 +38,7 @@ This implementation is a standard Chorus FX that is based on 4 LFO:
<img src="Chorus--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff"> <img src="Chorus--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff">
* ***Enable [Off - On]:*** Enable / disable the FX unit.
* ***Rate [0 - 99]:*** modulate the LFO rate between thei minimum frequency (Rate = 0) and their maximum frequency (Rate = 99). * ***Rate [0 - 99]:*** modulate the LFO rate between thei minimum frequency (Rate = 0) and their maximum frequency (Rate = 99).
* ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is. * ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is.
@ -54,6 +56,7 @@ This implementation is based on 2 LFO:
<img src="Flanger--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff"> <img src="Flanger--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff">
* ***Enable [Off - On]:*** Enable / disable the FX unit.
* ***Rate [0 - 99]:*** modulate the LFO rate between thei minimum frequency (Rate = 0) and their maximum frequency (Rate = 99). * ***Rate [0 - 99]:*** modulate the LFO rate between thei minimum frequency (Rate = 0) and their maximum frequency (Rate = 99).
* ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is. * ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is.
* ***Feedback [0 - 99]:*** the amount of of processed signal that is re-injected at the audio effect input. * ***Feedback [0 - 99]:*** the amount of of processed signal that is re-injected at the audio effect input.
@ -76,6 +79,7 @@ This implementation is based on 4 LFO:
<img src="Orbitone--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff"> <img src="Orbitone--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff">
* ***Enable [Off - On]:*** Enable / disable the FX unit.
* ***Rate [0 - 99]:*** modulate the LFO rate between thei minimum frequency (Rate = 0) and their maximum frequency (Rate = 99). * ***Rate [0 - 99]:*** modulate the LFO rate between thei minimum frequency (Rate = 0) and their maximum frequency (Rate = 99).
* ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is. * ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is.
* ***Feedback [0 - 99]:*** the amount of of processed signal that is re-injected at the audio effect input. * ***Feedback [0 - 99]:*** the amount of of processed signal that is re-injected at the audio effect input.
@ -93,6 +97,7 @@ This implementation is based on 2 LFO:
<img src="Phaser--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff"> <img src="Phaser--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff">
* ***Enable [Off - On]:*** Enable / disable the FX unit.
* ***Rate [0 - 99]:*** modulate the LFO rate between thei minimum frequency (Rate = 0) and their maximum frequency (Rate = 99). * ***Rate [0 - 99]:*** modulate the LFO rate between thei minimum frequency (Rate = 0) and their maximum frequency (Rate = 99).
* ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is. * ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is.
* ***Feedback [0 - 99]:*** the amount of of processed signal that is re-injected at the audio effect input. * ***Feedback [0 - 99]:*** the amount of of processed signal that is re-injected at the audio effect input.
@ -102,19 +107,16 @@ This implementation is based on 2 LFO:
<br> <br>
* **Delay:** the is an audio signal processing technique that creates a repeated, delayed version of an original sound. It does this by temporarily storing a copy of the original audio signal in a buffer, and then playing it back at a later time. * **Delay:** the is an audio signal processing technique that creates a repeated, delayed version of an original sound. It does this by temporarily storing a copy of the original audio signal in a buffer, and then playing it back at a later time.
The delay time can be set to vary from a few milliseconds to 2 seconds, and the repeated sound can be manipulated in various ways to create a range of different effects. The delay time can be set to vary from a few milliseconds to 1 second, and the repeated sound can be manipulated in various ways to create a range of different effects.
Delay effects are used in a wide variety of musical genres to add texture, depth, and interest to a mix. They can be used on almost any sound source, including vocals, guitars, keyboards, and drums. In addition to their creative uses, delay effects can also be used as a practical tool for correcting timing issues in a recording or performance. Delay effects are used in a wide variety of musical genres to add texture, depth, and interest to a mix. They can be used on almost any sound source, including vocals, guitars, keyboards, drums and other melodic instruments.
This implementation is inpired of a tape delay and integrates a kind of flutter effect. The flutter effect of a tape delay refers to the subtle, random variations in the pitch and timing of the delayed signal that result from imperfections in the tape transport mechanism of an analog tape delay unit. The implemention of this delay accept negative values for both left and right delay. Negative values will echo sound reversed.
As the tape passes through the transport mechanism, it can be subject to various irregularities, such as fluctuations in tension, speed, and alignment. These imperfections can cause slight variations in the pitch and timing of the delayed signal, which can add a subtle, organic character to the sound.
The flutter effect is often sought after by musicians and producers who want to add warmth and character to their recordings. It can be particularly effective on guitars, vocals, and other melodic instruments, and is often used in genres such as rock, pop, and reggae.
<img src="Delay--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff"> <img src="Delay--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff">
* **Left Delay [0 - 99]:** the left delay from 0 to 2 seconds. * ***Enable [Off - On]:*** Enable / disable the FX unit.
* **Right Delay [0 - 99]:** the left delay from 0 to 2 seconds. * **Left Delay [-99 - 99]:** the left delay from 0 to 2 seconds.
* **Right Delay [-99 - 99]:** the left delay from 0 to 2 seconds.
* ***Feedback [0 - 99]:*** the amount of of processed signal that is re-injected at the audio effect input. * ***Feedback [0 - 99]:*** the amount of of processed signal that is re-injected at the audio effect input.
* ***Flutter Rate [0 - 99]:*** the speed at which the flutter effect will impact the signal processing.
* ***Flutter Amount [0 - 99]:*** the depth of the flutter effect that will impact the signal processing.
<br> <br>
<br> <br>
@ -125,6 +127,7 @@ Plate reverb effects are often used in music production to add space, depth, and
<img src="PlateReverb--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff"> <img src="PlateReverb--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff">
* ***Enable [Off - On]:*** Enable / disable the FX unit.
* ***Size [0 - 99]:*** the size of the simulated metallic plate hence of the room. * ***Size [0 - 99]:*** the size of the simulated metallic plate hence of the room.
* ***High Damping [0 - 99]:*** the amount of high-frequency attenuation or absorption applied to the plate's vibrations. It is a key parameter that can have a significant impact on the overall sound of the plate reverb effect. * ***High Damping [0 - 99]:*** the amount of high-frequency attenuation or absorption applied to the plate's vibrations. It is a key parameter that can have a significant impact on the overall sound of the plate reverb effect.
* ***Low Damping [0 - 99]:*** the amount of low-frequency attenuation or absorption applied to the plate's vibrations. It is a key parameter that can have a significant impact on the overall sound of the plate reverb effect. * ***Low Damping [0 - 99]:*** the amount of low-frequency attenuation or absorption applied to the plate's vibrations. It is a key parameter that can have a significant impact on the overall sound of the plate reverb effect.
@ -147,6 +150,7 @@ This implementation pushes the reverberation to reach almost the shimmer effect.
<img src="Reverberator--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff"> <img src="Reverberator--Channel.png" alt="FX Tube Channel Strip" width="10%" style="background-color: #fff">
* ***Enable [Off - On]:*** Enable / disable the FX unit.
* **Gain [0 - 99]:** the gain parameter of the reverberator refers to the overall level or amplitude of the reverberator effect. It determines how loud the reverberator signal is in relation to the dry or unprocessed signal. * **Gain [0 - 99]:** the gain parameter of the reverberator refers to the overall level or amplitude of the reverberator effect. It determines how loud the reverberator signal is in relation to the dry or unprocessed signal.
* **Time [0 - 99]:** the time determines the size of the simulated reverberating space. * **Time [0 - 99]:** the time determines the size of the simulated reverberating space.
* **Diffusion [0 - 99]:** the diffusion parameter of a reverberator refers to the degree to which the reflections in the reverb decay are dispersed or spread out in time and space. It determines how "dense" or "sparse" the reverberator effect sounds and how the individual reflections blend together. * **Diffusion [0 - 99]:** the diffusion parameter of a reverberator refers to the degree to which the reflections in the reverb decay are dispersed or spread out in time and space. It determines how "dense" or "sparse" the reverberator effect sounds and how the individual reflections blend together.
@ -348,11 +352,9 @@ This implementation pushes the reverberation to reach almost the shimmer effect.
* **> Main** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Main output. * **> Main** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Main output.
* **Delay** * **Delay**
* **Enable** *[on - off]*: Enable / disable the FX unit. * **Enable** *[on - off]*: Enable / disable the FX unit.
* **L Delay** *[0 - 99]*: The delay time for the Left channel. * **L Delay** *[-99 - 99]*: The delay time for the Left channel. Negtive values play the echoed part of the processed sound reversed.
* **R Delay** *[0 - 99]*: The delay time for the Right channel. * **R Delay** *[-99 - 99]*: The delay time for the Right channel. Negtive values play the echoed part of the processed sound reversed.
* **Feedbck** *[0 - 99]*: The amount of processed signal that will be reinjected at the input. * **Feedbck** *[0 - 99]*: The amount of processed signal that will be reinjected at the input.
* **Flt Rte** *[0 - 99]*: The flutter rate.
* **Flt Amt** *[0 - 99]*: The flutter depth.
* **Levels** * **Levels**
* **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Dly] * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Dly]
* **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Dly] * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Dly]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 KiB

After

Width:  |  Height:  |  Size: 762 KiB

Loading…
Cancel
Save