diff --git a/.gitignore b/.gitignore
index b28afb9..6d2b104 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,10 +45,8 @@ sdcard
# Editor related files
*.swp
*.swo
-.vscode/
-# temporary tests
-src/test/*.bin
-src/test/bin
-src/test/results
-src/test/objects
+.vscode/
+src/test/bin/
+src/test/objects/
+src/test/results/
\ No newline at end of file
diff --git a/src/CFileDevice.hpp b/src/CFileDevice.hpp
new file mode 100644
index 0000000..c595809
--- /dev/null
+++ b/src/CFileDevice.hpp
@@ -0,0 +1,78 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//
+// CFileDevice.h
+//
+// Device implementation that writes into a file.
+// This device is a singleton dedicated to allow the Circle CLogger class to output log event into the file instead of the internal buffer.
+// Author: Vincent Gauché
+//
+
+#pragma once
+
+#include "extra_features.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+class CFileDevice : public CDevice
+{
+ DISALLOW_COPY_AND_ASSIGN(CFileDevice);
+
+private:
+ CFileDevice() :
+ m_file(new FIL())
+ {
+ FRESULT res = f_open(this->m_file, "SD:/debuglog.txt", FA_WRITE | FA_CREATE_ALWAYS);
+ assert(res == FR_OK);
+ }
+
+public:
+ static void UseMeForLogger()
+ {
+ CLogger::Get()->SetNewTarget(&CFileDevice::GetInstance());
+ }
+
+ static CFileDevice& GetInstance()
+ {
+ static CFileDevice Instance;
+
+ return Instance;
+ }
+
+ ~CFileDevice()
+ {
+ f_sync(this->m_file);
+ f_close(this->m_file);
+ }
+
+ virtual int Write(const void* pBuffer, size_t nCount) override
+ {
+ UINT nb = 0;
+ if(nCount > 0)
+ {
+ f_write(this->m_file, pBuffer, nCount, &nb);
+ f_sync(this->m_file);
+ }
+
+ return (int)nb;
+ }
+
+private:
+ FIL* m_file;
+};
diff --git a/src/Makefile b/src/Makefile
index 9fc196c..b9f244b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -30,8 +30,12 @@ OBJS += fx_flanger.o
OBJS += fx_orbitone.o
OBJS += fx_phaser.o
OBJS += fx_delay.o
+OBJS += fx_shimmer_helper.o
+OBJS += fx_diffuser.o
+OBJS += fx_pitch_shifter.o
OBJS += fx_reverberator.o
-OBJS += fx_rack.o
+OBJS += fx_shimmer_reverb.o
+OBJS += fx_dry.o
OBJS += uibuttons.o
OBJS += midipin.o
diff --git a/src/debug.hpp b/src/debug.hpp
index b0f845b..24a3adc 100644
--- a/src/debug.hpp
+++ b/src/debug.hpp
@@ -76,7 +76,7 @@ public:
#define INSPECTABLE(clazz) clazz : public ValueInpectorDebugger
#define IMPLEMENT_DUMP(code) \
public:\
- virtual void dump(std::ostream& out, bool deepInspection = true, const std::string& tag = "") const override\
+ __attribute__((noinline)) virtual void dump(std::ostream& out, bool deepInspection = true, const std::string& tag = "") const override\
{\
code\
}
@@ -88,7 +88,7 @@ public:\
#define IMPLEMENT_INSPECT(code) \
public:\
- virtual size_t inspect(ValueInpector inspector, bool deepInspection = true, const std::string& tag = "") const override\
+ __attribute__((noinline)) virtual size_t inspect(ValueInpector inspector, bool deepInspection = true, const std::string& tag = "") const override\
{\
code\
}
@@ -102,7 +102,7 @@ public:\
#define INSPECTABLE(clazz) clazz
#define IMPLEMENT_DUMP(code)
-#define IMPLEMENT_INSPECT(code)
+#define IMPLEMENT_INSPECT(code)
#define DUMP(clazz, out)
#define DUMP2(clazz, out, tag)
diff --git a/src/extra_features.h b/src/extra_features.h
index 1a0c373..f3ee508 100644
--- a/src/extra_features.h
+++ b/src/extra_features.h
@@ -15,6 +15,7 @@
// extra_features.h
//
// Header file that centralizes MACROS to enable / disable extra features
+// Author: Vincent Gauché
//
#pragma once
@@ -23,7 +24,13 @@
void operator=(const TypeName&) = delete
#if defined(ARM_ALLOW_MULTI_CORE)
-#define FXRACK_ENABLE //Add support for the FXRack
+
+ #if RASPPI < 3
+ #define PLATE_REVERB_ENABLE // Add support for the PlateReverb
+ #else
+ #define MIXING_CONSOLE_ENABLE // Add support for the MixingConsole
+ #endif
+
#endif
#ifdef DEBUG
@@ -34,6 +41,8 @@
#include
#include
+using namespace std;
+
inline long long int getElapseTime(std::string marker = "")
{
static std::unordered_map marker_times;
diff --git a/src/fx.cpp b/src/fx.cpp
index b7cc565..7652e9e 100644
--- a/src/fx.cpp
+++ b/src/fx.cpp
@@ -16,7 +16,8 @@ float32_t FXBase::getSamplingRate() const
FXElement::FXElement(float32_t sampling_rate, float32_t output_level_corrector) :
FXBase(sampling_rate),
- OutputLevelCorrector(output_level_corrector)
+ OutputLevelCorrector(output_level_corrector),
+ bypass_fx_process_(false)
{
}
@@ -24,6 +25,15 @@ FXElement::~FXElement()
{
}
+void FXElement::bypassFXProcess(bool bypass)
+{
+ this->bypass_fx_process_ = bypass;
+}
+
+bool FXElement::bypassFXProcess() const
+{
+ return this->bypass_fx_process_;
+}
FX::FX(float32_t sampling_rate) :
FXBase(sampling_rate)
diff --git a/src/fx.h b/src/fx.h
index 520ca3f..27a0f50 100644
--- a/src/fx.h
+++ b/src/fx.h
@@ -15,6 +15,7 @@
// fx.h
//
// Base classes for Stereo audio effects proposed in the context of the MiniDexed project
+// Author: Vincent Gauché
//
#pragma once
@@ -59,7 +60,13 @@ protected:
public:
virtual ~FXElement();
+ virtual void bypassFXProcess(bool bypass);
+ virtual bool bypassFXProcess() const;
+
virtual void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) = 0;
+
+private:
+ bool bypass_fx_process_;
};
class FX : public FXBase
diff --git a/src/fx_base.h b/src/fx_base.h
index ec6f135..9ae019b 100644
--- a/src/fx_base.h
+++ b/src/fx_base.h
@@ -1,3 +1,23 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//
+// fx_base.h
+//
+// Base header file for the FX section of the MiniDexed project
+// Author: Vincent Gauché
+//
+
#pragma once
#include "extra_features.h"
diff --git a/src/fx_chorus.h b/src/fx_chorus.h
index a7575c4..2186e64 100644
--- a/src/fx_chorus.h
+++ b/src/fx_chorus.h
@@ -16,6 +16,7 @@
//
// Stereo Chorus audio effects proposed in the context of the MiniDexed project
// This implemelntation is based on the Chorus FX from the Rings Eurorack module from Mutable Instruments
+// Ported by: Vincent Gauché
//
#pragma once
diff --git a/src/fx_components.cpp b/src/fx_components.cpp
index 3610a8c..04ba3b9 100644
--- a/src/fx_components.cpp
+++ b/src/fx_components.cpp
@@ -174,6 +174,7 @@ FastLFO2::FastLFO2(float32_t sampling_rate, float32_t min_frequency, float32_t m
max_frequency_(max_frequency),
centered_(centered),
frequency_(0.0f),
+ normalized_frequency_(0.0f),
phase_(initial_phase),
phase_increment_(0.0f),
current_(0.0f)
@@ -267,18 +268,53 @@ float32_t FastLFO2::current() const
////////////////////////////////////////////////
// InterpolatedSineOscillator implemlentation //
////////////////////////////////////////////////
+float32_t InterpolatedSineOscillator::Sin(float32_t phase)
+{
+ static bool initialized = false;
+ if(!initialized)
+ {
+ initialized = InterpolatedSineOscillator::ClassInitializer();
+ }
+
+ if(phase < 0.0f) while(phase < 0.0f) phase += Constants::M2PI;
+ else while(phase > Constants::M2PI) phase -= Constants::M2PI;
+
+ float32_t findex = phase / InterpolatedSineOscillator::DeltaTime;
+
+ size_t index1 = static_cast(findex);
+ size_t index2 = index1 + 1;
+
+ float32_t f1 = InterpolatedSineOscillator::CenteredDataPoints[index1];
+ float32_t f2 = InterpolatedSineOscillator::CenteredDataPoints[index2];
+ float32_t r = findex - index1;
+
+ return f1 + (f2 - f1) * r * InterpolatedSineOscillator::DeltaTime;
+}
+
+float32_t InterpolatedSineOscillator::Cos(float32_t phase)
+{
+ return InterpolatedSineOscillator::Sin(Constants::MPI_2 - phase);
+}
+
bool InterpolatedSineOscillator::ClassInitializer()
{
- float32_t phase_increment = Constants::M2PI / static_cast(InterpolatedSineOscillator::DataPointSize);
- float32_t phase = 0.0;
- for(size_t i = 0; i <= InterpolatedSineOscillator::DataPointSize; ++i)
+ static bool initialized = false;
+
+ if(!initialized)
{
- InterpolatedSineOscillator::CenteredDataPoints[i] = std::sin(phase);
- InterpolatedSineOscillator::UpliftDataPoints[i] = InterpolatedSineOscillator::CenteredDataPoints[i] * 0.5f + 0.5f;
- phase += phase_increment;
+ float32_t phase_increment = Constants::M2PI / static_cast(InterpolatedSineOscillator::DataPointSize);
+ float32_t phase = 0.0;
+ for(size_t i = 0; i <= InterpolatedSineOscillator::DataPointSize; ++i)
+ {
+ InterpolatedSineOscillator::CenteredDataPoints[i] = std::sin(phase);
+ InterpolatedSineOscillator::UpliftDataPoints[i] = InterpolatedSineOscillator::CenteredDataPoints[i] * 0.5f + 0.5f;
+ phase += phase_increment;
+ }
+
+ initialized = true;
}
- return true;
+ return initialized;
}
float32_t InterpolatedSineOscillator::CenteredDataPoints[InterpolatedSineOscillator::DataPointSize + 1];
@@ -574,7 +610,7 @@ void JitterGenerator::reset()
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_));
if(this->phase_ > Constants::M2PI)
diff --git a/src/fx_components.h b/src/fx_components.h
index 2a404fb..45276e1 100644
--- a/src/fx_components.h
+++ b/src/fx_components.h
@@ -15,6 +15,7 @@
// fx_components.h
//
// Several tools and components used in the implemlentation of FX
+// Quthor: Vincent Gauché
//
#pragma once
@@ -231,6 +232,9 @@ class InterpolatedSineOscillator : public FXBase
DISALLOW_COPY_AND_ASSIGN(InterpolatedSineOscillator);
public:
+ static float32_t Sin(float32_t phase);
+ static float32_t Cos(float32_t phase);
+
InterpolatedSineOscillator(float32_t sampling_rate, float32_t min_frequency = LFO_MIN_FREQUENCY, float32_t max_frequency = LFO_MAX_FREQUENCY, float32_t initial_phase = 0.0f, bool centered = true);
virtual ~InterpolatedSineOscillator();
diff --git a/src/fx_delay.cpp b/src/fx_delay.cpp
index e0b33f5..6ddaacb 100644
--- a/src/fx_delay.cpp
+++ b/src/fx_delay.cpp
@@ -2,8 +2,9 @@
#include
-#define MAX_DELAY_TIME 2.0f
-#define MAX_FLUTTER_DELAY_TIME 0.001f
+#define MAX_DELAY_TIME 1.0f
+#define MAX_FLUTTER_DELAY_TIME 0.2f
+#define MAX_FLUTTER_DELAY_AMOUNT 0.01f
#define LPF_CUTOFF_REF 12000.0f
#define HPF_CUTOFF_REF 80.0f
@@ -51,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) :
FXElement(sampling_rate, 2.2587f),
- 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)
+ MaxSampleDelayTime((MAX_DELAY_TIME + MAX_FLUTTER_DELAY_TIME) * sampling_rate),
+ write_pos_L_(0),
+ write_pos_R_(0),
+ filter_(sampling_rate)
{
this->buffer_L_ = new float32_t[this->MaxSampleDelayTime];
this->buffer_R_ = new float32_t[this->MaxSampleDelayTime];
@@ -63,8 +63,6 @@ Delay::Delay(const float32_t sampling_rate, float32_t default_delay_time, float3
this->setLeftDelayTime(default_delay_time);
this->setRightDelayTime(default_delay_time);
this->setFeedback(default_feedback_level);
- this->setFlutterRate(0.2f);
- this->setFlutterAmount(0.0f);
this->reset();
}
@@ -79,59 +77,49 @@ void Delay::reset()
{
memset(this->buffer_L_, 0, this->MaxSampleDelayTime * sizeof(float32_t));
memset(this->buffer_R_, 0, this->MaxSampleDelayTime * sizeof(float32_t));
- this->read_pos_L_ = 0;
- this->read_pos_R_ = 0;
+ this->write_pos_L_ = 0;
+ this->write_pos_R_ = 0;
this->filter_.reset();
- this->jitter_generator_.reset();
}
void Delay::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{
- static const float32_t max_delay_time = MAX_DELAY_TIME * this->getSamplingRate();
- float32_t jitter_delay_time = 0.0f;
- if(this->jitter_amount_ != 0.0f)
- {
- float32_t jitter_ratio = this->jitter_generator_.process();
- if(jitter_ratio != 0.0f)
- {
- jitter_ratio *= this->jitter_amount_;
- jitter_delay_time = MAX_FLUTTER_DELAY_TIME * jitter_ratio * this->getSamplingRate();
- }
- }
-
- // this->filter_.setCutoffChangeRatio(jitter_ratio);
- float32_t delay_time_L = jitter_delay_time + max_delay_time * this->getLeftDelayTime();
- float32_t delay_time_R = jitter_delay_time + max_delay_time * this->getRightDelayTime();
+ // Write input to delay buffers
+ this->buffer_L_[this->write_pos_L_] *= this->getFeedback();;
+ this->buffer_L_[this->write_pos_L_] += inL;
+ this->buffer_R_[this->write_pos_R_] *= this->getFeedback();;
+ this->buffer_R_[this->write_pos_R_] += inR;
- // Calculate write positions
- unsigned write_pos_L = static_cast(this->MaxSampleDelayTime + this->read_pos_L_ + delay_time_L) % this->MaxSampleDelayTime;
- unsigned write_pos_R = static_cast(this->MaxSampleDelayTime + this->read_pos_R_ + delay_time_R) % this->MaxSampleDelayTime;
+ // Calculate read positions
+ float32_t delay_time_L = std::abs(MAX_DELAY_TIME * this->getLeftDelayTime() ) * this->getSamplingRate();
+ 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(this->MaxSampleDelayTime + signL * this->write_pos_L_ - delay_time_L) % this->MaxSampleDelayTime;
+ unsigned read_pos_R = static_cast(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
this->filter_.processSample(
- this->buffer_L_[this->read_pos_L_],
- this->buffer_R_[this->read_pos_R_],
+ this->buffer_L_[read_pos_L],
+ this->buffer_R_[read_pos_R],
outL,
outR
);
- this->buffer_L_[write_pos_L] += outL * this->getFeedback();
- this->buffer_R_[write_pos_R] += outR * this->getFeedback();
+ this->buffer_L_[this->write_pos_L_] += outL * this->getFeedback();
+ this->buffer_R_[this->write_pos_R_] += outR * this->getFeedback();
// Increment read positions
- ++this->read_pos_L_;
- if(this->read_pos_L_ >= this->MaxSampleDelayTime)
+ ++ this->write_pos_L_;
+ if(this->write_pos_L_ >= this->MaxSampleDelayTime)
{
- this->read_pos_L_ -= this->MaxSampleDelayTime;
+ this->write_pos_L_ -= this->MaxSampleDelayTime;
}
- ++this->read_pos_R_;
- if(this->read_pos_R_ >= this->MaxSampleDelayTime)
+ ++ this->write_pos_R_;
+ if(this->write_pos_R_ >= this->MaxSampleDelayTime)
{
- this->read_pos_R_ -= this->MaxSampleDelayTime;
+ this->write_pos_R_ -= this->MaxSampleDelayTime;
}
outL *= this->OutputLevelCorrector;
@@ -140,7 +128,7 @@ void Delay::processSample(float32_t inL, float32_t inR, float32_t& outL, float32
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
@@ -150,7 +138,7 @@ float32_t Delay::getLeftDelayTime() const
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
@@ -167,23 +155,3 @@ float32_t Delay::getFeedback() const
{
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_;
-}
diff --git a/src/fx_delay.h b/src/fx_delay.h
index 08dc879..30e063e 100644
--- a/src/fx_delay.h
+++ b/src/fx_delay.h
@@ -16,6 +16,7 @@
// fx_tape_delay.h
//
// Stereo Delay proposed in the context of the MiniDexed project
+// Author: Vincent Gauché
//
#pragma once
@@ -104,25 +105,17 @@ public:
void setFeedback(float32_t feedback);
float32_t getFeedback() const;
- void setFlutterRate(float32_t rate);
- float32_t getFlutterRate() const;
-
- void setFlutterAmount(float32_t amount);
- float32_t getFlutterAmount() const;
-
private:
const size_t MaxSampleDelayTime;
- unsigned read_pos_L_;
- unsigned read_pos_R_;
+ unsigned write_pos_L_;
+ unsigned write_pos_R_;
float32_t* buffer_L_;
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 feedback_; // Feedback (0.0 - 1.0)
- float32_t jitter_amount_;
LowHighPassFilter filter_;
- PerlinNoiseGenerator jitter_generator_;
IMPLEMENT_DUMP(
const size_t space = 18;
@@ -133,13 +126,11 @@ private:
out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
SS_RESET(ss, precision, std::left);
- SS__TEXT(ss, ' ', space, std::left, '|', "read_pos_L_");
- SS__TEXT(ss, ' ', space, std::left, '|', "read_pos_R_");
+ SS__TEXT(ss, ' ', space, std::left, '|', "write_pos_L_");
+ 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_R_");
SS__TEXT(ss, ' ', space, std::left, '|', "feedback_");
- SS__TEXT(ss, ' ', space, std::left, '|', "jitter_amount_");
- SS__TEXT(ss, ' ', space, std::left, '|', "filter_");
out << "\t" << ss.str() << std::endl;
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, '+');
out << "\t" << ss.str() << std::endl;
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->read_pos_R_);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->write_pos_L_);
+ 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_R_);
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;
if(deepInspection)
@@ -186,7 +175,6 @@ private:
}
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;
@@ -194,12 +182,11 @@ private:
IMPLEMENT_INSPECT(
size_t nb_errors = 0;
- nb_errors += inspector(tag + ".read_pos_L_", static_cast(this->read_pos_L_), 0.0f, static_cast(this->MaxSampleDelayTime), deepInspection);
- nb_errors += inspector(tag + ".read_pos_R_", static_cast(this->read_pos_R_), 0.0f, static_cast(this->MaxSampleDelayTime), deepInspection);
- nb_errors += inspector(tag + ".delay_time_L_", this->delay_time_L_, 0.0f, static_cast(this->MaxSampleDelayTime), deepInspection);
- nb_errors += inspector(tag + ".delay_time_R_", this->delay_time_R_, 0.0f, static_cast(this->MaxSampleDelayTime), deepInspection);
+ nb_errors += inspector(tag + ".write_pos_L_", static_cast(this->write_pos_L_), 0.0f, static_cast(this->MaxSampleDelayTime), deepInspection);
+ nb_errors += inspector(tag + ".write_pos_R_", static_cast(this->write_pos_R_), 0.0f, static_cast(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_, -1.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)
{
@@ -210,7 +197,6 @@ private:
}
nb_errors += this->filter_.inspect(inspector, deepInspection, tag + ".filter_");
- nb_errors += this->jitter_generator_.inspect(inspector, deepInspection, tag + ".jitter_generator_");
}
return nb_errors;
diff --git a/src/fx_diffuser.cpp b/src/fx_diffuser.cpp
new file mode 100644
index 0000000..936f2d3
--- /dev/null
+++ b/src/fx_diffuser.cpp
@@ -0,0 +1,71 @@
+#include "fx_diffuser.h"
+
+#include
+#include
+
+#define TAIL , -1
+
+Diffuser::Diffuser(float32_t sampling_frequency) :
+ FXElement(sampling_frequency),
+ engine_(sampling_frequency)
+{
+}
+
+Diffuser::~Diffuser()
+{
+}
+
+void Diffuser::reset()
+{
+ this->engine_.reset();
+}
+
+void Diffuser::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
+{
+ typedef Engine::Reserve<126,
+ Engine::Reserve<180,
+ Engine::Reserve<269,
+ Engine::Reserve<444,
+ Engine::Reserve<151,
+ Engine::Reserve<205,
+ Engine::Reserve<245,
+ Engine::Reserve<405> > > > > > > > Memory;
+ Engine::DelayLine apl1;
+ Engine::DelayLine apl2;
+ Engine::DelayLine apl3;
+ Engine::DelayLine apl4;
+ Engine::DelayLine apr1;
+ Engine::DelayLine apr2;
+ Engine::DelayLine apr3;
+ Engine::DelayLine apr4;
+ Engine::Context c;
+
+ const float32_t kap = 0.625f;
+ float wet = 0.0f;
+
+ engine_.start(&c);
+
+ c.load(inL);
+ c.read(apl1 TAIL, kap);
+ c.writeAllPass(apl1, -kap);
+ c.read(apl2 TAIL, kap);
+ c.writeAllPass(apl2, -kap);
+ c.read(apl3 TAIL, kap);
+ c.writeAllPass(apl3, -kap);
+ c.read(apl4 TAIL, kap);
+ c.writeAllPass(apl4, -kap);
+ c.writeAndLoad(wet, 0.0f);
+ outL = wet;
+
+ c.load(inR);
+ c.read(apr1 TAIL, kap);
+ c.writeAllPass(apr1, -kap);
+ c.read(apr2 TAIL, kap);
+ c.writeAllPass(apr2, -kap);
+ c.read(apr3 TAIL, kap);
+ c.writeAllPass(apr3, -kap);
+ c.read(apr4 TAIL, kap);
+ c.writeAllPass(apr4, -kap);
+ c.writeAndLoad(wet, 0.0f);
+ outR = wet;
+}
diff --git a/src/fx_diffuser.h b/src/fx_diffuser.h
new file mode 100644
index 0000000..2fe1d48
--- /dev/null
+++ b/src/fx_diffuser.h
@@ -0,0 +1,65 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+
+//
+// fx_shimmer_reverb3.h
+//
+// Stereo Diffuser proposed in the context of the MiniDexed project
+// It is adapted from the Diffuser that could be found on Cloud EuroRack module from Mutable Instrruments
+// Ported by: Vincent Gauché
+//
+#pragma once
+
+#include "fx_components.h"
+#include "fx_engine.hpp"
+
+#define DIFFUSER_BUFFER_SIZE 2048
+
+class Diffuser : public FXElement
+{
+ DISALLOW_COPY_AND_ASSIGN(Diffuser);
+
+public:
+ Diffuser(float32_t sampling_frequency);
+ virtual ~Diffuser();
+
+ virtual void reset() override;
+ virtual void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) override;
+
+private:
+ typedef FxEngine Engine;
+ Engine engine_;
+
+ IMPLEMENT_DUMP(
+ out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+
+ if(deepInspection)
+ {
+ this->engine_.dump(out, deepInspection, tag + ".engine_");
+ }
+
+ out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+ )
+
+ IMPLEMENT_INSPECT(
+ size_t nb_errors = 0u;
+
+ if(deepInspection)
+ {
+ nb_errors += this->engine_.inspect(inspector, deepInspection, tag + ".engine_");
+ }
+
+ return nb_errors;
+ )
+};
diff --git a/src/fx_dry.cpp b/src/fx_dry.cpp
new file mode 100644
index 0000000..a4c2931
--- /dev/null
+++ b/src/fx_dry.cpp
@@ -0,0 +1,21 @@
+#include "fx_dry.h"
+
+Dry::Dry(float32_t samplingRate) :
+ FXElement(samplingRate)
+{
+}
+
+Dry::~Dry()
+{
+}
+
+void Dry::reset()
+{
+ // nothing to be done
+}
+
+void Dry::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
+{
+ outL = inL;
+ outR = inR;
+}
diff --git a/src/fx_dry.h b/src/fx_dry.h
new file mode 100644
index 0000000..52cd552
--- /dev/null
+++ b/src/fx_dry.h
@@ -0,0 +1,43 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//
+// fx_dry.h
+//
+// An FX that does nothing but used to generalize the processing.
+// Author: Vincent Gauché
+//
+#pragma once
+
+#include "fx_components.h"
+
+class Dry : public FXElement
+{
+ DISALLOW_COPY_AND_ASSIGN(Dry);
+
+public:
+ Dry(float32_t sampling_rate);
+ virtual ~Dry();
+
+ virtual void reset() override;
+ virtual void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) override;
+
+ IMPLEMENT_DUMP(
+ out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+ out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+ )
+
+ IMPLEMENT_INSPECT(
+ return 0u;
+ )
+};
\ No newline at end of file
diff --git a/src/fx_engine.hpp b/src/fx_engine.hpp
index ec4de06..239969f 100644
--- a/src/fx_engine.hpp
+++ b/src/fx_engine.hpp
@@ -1,3 +1,24 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//
+// fx_engine.h
+//
+// FX Engine used in some of the Mutable Instruments Eurorack modules.
+// This version is ported for the MiniDexed project and brings some additional optimization to avoid unecessary multiplications.
+// Ported by: Vincent Gauché
+//
+
#pragma once
#include
diff --git a/src/fx_flanger.h b/src/fx_flanger.h
index 8a52bf5..89c7513 100644
--- a/src/fx_flanger.h
+++ b/src/fx_flanger.h
@@ -15,6 +15,7 @@
// fx_flanger.h
//
// Stereo Flanger audio effects proposed in the context of the MiniDexed project
+// Author: Vincent Gauché
//
#pragma once
diff --git a/src/fx_orbitone.cpp b/src/fx_orbitone.cpp
index 0632715..764b46d 100644
--- a/src/fx_orbitone.cpp
+++ b/src/fx_orbitone.cpp
@@ -69,14 +69,13 @@ void Orbitone::processSample(float32_t inL, float32_t inR, float32_t& outL, floa
float32_t wet = 0.0f;
c.directWrite(inL, line_l);
- c.directWrite(inR, line_r);
-
c.interpolate(line_l, mod_1 + 1024, 0.33f);
c.interpolate(line_l, mod_2 + 1024, 0.33f);
c.interpolate(line_r, mod_3 + 1024, 0.33f);
c.writeAndLoad(wet, 0.0f);
outL = wet * this->OutputLevelCorrector;
+ c.directWrite(inR, line_r);
c.interpolate(line_r, mod_1 + 1024, 0.33f);
c.interpolate(line_r, mod_2 + 1024, 0.33f);
c.interpolate(line_l, mod_3 + 1024, 0.33f);
diff --git a/src/fx_orbitone.h b/src/fx_orbitone.h
index bd0b9ff..f8e81e9 100644
--- a/src/fx_orbitone.h
+++ b/src/fx_orbitone.h
@@ -16,6 +16,7 @@
//
// Stereo Orbitone audio effects proposed in the context of the MiniDexed project
// This audio effect is based on the Ensemble audio effect of the Rings Eurorack module by Mutable Instruments
+// Ported by: Vincent Gauché
//
#pragma once
diff --git a/src/fx_phaser.cpp b/src/fx_phaser.cpp
index 13fb5da..ba4f375 100644
--- a/src/fx_phaser.cpp
+++ b/src/fx_phaser.cpp
@@ -72,8 +72,8 @@ void Phaser::reset()
void Phaser::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{
- float32_t dL = this->dmin_ + (this->dmax_ - this->dmin_) * ((1.0f + this->lfo_[StereoChannels::Left ]->process()) / 2.0f);
- float32_t dR = this->dmin_ + (this->dmax_ - this->dmin_) * ((1.0f + this->lfo_[StereoChannels::Right]->process()) / 2.0f);
+ float32_t dL = this->dmin_ + (this->dmax_ - this->dmin_) * this->lfo_[StereoChannels::Left ]->process();
+ float32_t dR = this->dmin_ + (this->dmax_ - this->dmin_) * this->lfo_[StereoChannels::Right]->process();
float32_t sampleL = inL + this->feedback_ * this->z_[StereoChannels::Left ];
float32_t sampleR = inR + this->feedback_ * this->z_[StereoChannels::Right];
diff --git a/src/fx_phaser.h b/src/fx_phaser.h
index 3b46a3a..6ff605b 100644
--- a/src/fx_phaser.h
+++ b/src/fx_phaser.h
@@ -15,6 +15,7 @@
// fx_phaser.h
//
// Stereo Phaser audio effects proposed in the context of the MiniDexed project
+// Author: Vincent Gauché
//
#pragma once
diff --git a/src/fx_pitch_shifter.cpp b/src/fx_pitch_shifter.cpp
new file mode 100644
index 0000000..5bb053a
--- /dev/null
+++ b/src/fx_pitch_shifter.cpp
@@ -0,0 +1,104 @@
+#include "fx_pitch_shifter.h"
+#include "fx_shimmer_helper.h"
+
+#include
+#include
+
+#define ONE_POLE(out, in, coefficient) out += (coefficient) * ((in) - out);
+
+#define TAIL , -1
+
+PitchShifter::PitchShifter(float32_t sampling_rate, float32_t transpose_boundary) :
+ FXElement(sampling_rate),
+ engine_(sampling_rate),
+ TransposeBoundary(transpose_boundary),
+ phase_(0.0f),
+ transpose_(0.0f),
+ ratio_(0.0f),
+ size_(-1.0f),
+ sample_size_(0.0f)
+{
+ this->setTranspose(0.0f);
+ this->setSize(0.5f);
+}
+
+PitchShifter::~PitchShifter()
+{
+}
+
+void PitchShifter::reset()
+{
+ this->engine_.reset();
+}
+
+void PitchShifter::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
+{
+ typedef Engine::Reserve<2047, Engine::Reserve<2047> > Memory;
+ Engine::DelayLine left;
+ Engine::DelayLine right;
+ Engine::Context c;
+
+ this->engine_.start(&c);
+
+ this->phase_ += (1.0f - this->ratio_) / this->sample_size_;
+ if(this->phase_ >= 1.0f)
+ {
+ phase_ -= 1.0f;
+ }
+ if(this->phase_ <= 0.0f)
+ {
+ this->phase_ += 1.0f;
+ }
+
+ float tri = 2.0f * (this->phase_ >= 0.5f ? 1.0f - phase_ : phase_);
+ float phase = this->phase_ * this->sample_size_;
+ float half = phase + this->sample_size_ * 0.5f;
+ if(half >= this->sample_size_)
+ {
+ half -= this->sample_size_;
+ }
+
+ c.load(inL);
+ c.writeAndLoad(left, 0.0f);
+ c.interpolate(left, phase, tri);
+ c.interpolate(left, half, 1.0f - tri);
+ c.writeAndLoad(outL, 0.0f);
+
+ c.load(inR);
+ c.writeAndLoad(right, 0.0f);
+ c.interpolate(right, phase, tri);
+ c.interpolate(right, half, 1.0f - tri);
+ c.writeAndLoad(outR, 0.0f);
+}
+
+void PitchShifter::setTranspose(float32_t transpose)
+{
+ transpose = constrain(transpose, -this->TransposeBoundary, this->TransposeBoundary);
+ if(this->transpose_ != transpose)
+ {
+ this->transpose_ = transpose;
+ this->ratio_ = semitoneToRatio(transpose);
+ }
+}
+
+float32_t PitchShifter::getTranspose() const
+{
+ return this->transpose_;
+}
+
+void PitchShifter::setSize(float32_t size)
+{
+ size = constrain(size, 0.0f, 1.0f);
+ if(size != this->size_)
+ {
+ this->size_ = size;
+
+ float32_t target_size = 128.0f + (2047.0f - 128.0f) * size * size * size;
+ ONE_POLE(this->sample_size_, target_size, 0.05f);
+ }
+}
+
+float32_t PitchShifter::getSize() const
+{
+ return this->size_;
+}
\ No newline at end of file
diff --git a/src/fx_pitch_shifter.h b/src/fx_pitch_shifter.h
new file mode 100644
index 0000000..f7fdeec
--- /dev/null
+++ b/src/fx_pitch_shifter.h
@@ -0,0 +1,115 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+
+//
+// fx_shimmer_reverb3.h
+//
+// Stereo Pitch Shifter proposed in the context of the MiniDexed project
+// It is adapted from the Pitch Shifter that could be found on Cloud EuroRack module from Mutable Instrruments
+// Ported by: Vincent Gauché
+//
+#pragma once
+
+#include "fx_components.h"
+#include "fx_engine.hpp"
+
+#define PITCH_SHIFTER_BUFFER_SIZE 4096
+#define PITCH_SHIFTER_TRANSPOSE_BOUNDARY 36.0f
+
+class PitchShifter : public FXElement
+{
+ DISALLOW_COPY_AND_ASSIGN(PitchShifter);
+
+public:
+ PitchShifter(float32_t sampling_rate, float32_t transpose_boundary = PITCH_SHIFTER_TRANSPOSE_BOUNDARY);
+ virtual ~PitchShifter();
+
+ virtual void reset() override;
+ virtual void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) override;
+
+ void setTranspose(float32_t transpose);
+ float32_t getTranspose() const;
+
+ void setSize(float32_t size);
+ float32_t getSize() const;
+
+private:
+ typedef FxEngine Engine;
+ Engine engine_;
+
+ const float32_t TransposeBoundary;
+ float32_t phase_;
+ float32_t transpose_;
+ float32_t ratio_;
+ float32_t size_;
+ float32_t sample_size_;
+
+ IMPLEMENT_DUMP(
+ const size_t space = 12;
+ const size_t precision = 6;
+
+ std::stringstream ss;
+
+ out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+
+ SS_RESET(ss, precision, std::left);
+ SS__TEXT(ss, ' ', space, std::left, '|', "phase_");
+ SS__TEXT(ss, ' ', space, std::left, '|', "transpose_");
+ SS__TEXT(ss, ' ', space, std::left, '|', "ratio_");
+ SS__TEXT(ss, ' ', space, std::left, '|', "size_");
+ SS__TEXT(ss, ' ', space, std::left, '|', "sample_size_");
+ out << "\t" << ss.str() << std::endl;
+
+ SS_RESET(ss, precision, 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;
+
+ SS_RESET(ss, precision, std::left);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->transpose_);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->ratio_);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->size_);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->sample_size_);
+ out << "\t" << ss.str() << std::endl;
+
+ if(deepInspection)
+ {
+ this->engine_.dump(out, deepInspection, tag + ".engine_");
+ }
+
+ out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+ )
+
+ IMPLEMENT_INSPECT(
+ size_t nb_errors = 0u;
+
+ nb_errors += inspector(tag + ".phase_", this->phase_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".transpose_", this->transpose_, -PITCH_SHIFTER_TRANSPOSE_BOUNDARY, PITCH_SHIFTER_TRANSPOSE_BOUNDARY, deepInspection);
+ nb_errors += inspector(tag + ".ratio_", this->ratio_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".size_", this->size_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".sample_size_", this->sample_size_, 0.0f, 1.0f, deepInspection);
+
+ if(deepInspection)
+ {
+ nb_errors += this->engine_.inspect(inspector, deepInspection, tag + ".engine_");
+ }
+
+ return nb_errors;
+ )
+};
diff --git a/src/fx_rack.h b/src/fx_rack.h
index 8e82675..0c61d72 100644
--- a/src/fx_rack.h
+++ b/src/fx_rack.h
@@ -15,6 +15,7 @@
// fx_rack.h
//
// Rack of audio effects proposed in the context of the MiniDexed project
+// Author: Vincent Gauché
//
#pragma once
diff --git a/src/fx_reverberator.h b/src/fx_reverberator.h
index c5dc618..ef79883 100644
--- a/src/fx_reverberator.h
+++ b/src/fx_reverberator.h
@@ -17,6 +17,7 @@
//
// Stereo Reverberator proposed in the context of the MiniDexed project
// It is adapted from the Reverb that could be found on Cloud EuroRack module from Mutable Instrruments
+// Ported by: Vincent Gauché
//
#pragma once
diff --git a/src/fx_shimmer_helper.cpp b/src/fx_shimmer_helper.cpp
new file mode 100644
index 0000000..bed1fad
--- /dev/null
+++ b/src/fx_shimmer_helper.cpp
@@ -0,0 +1,135 @@
+#include "fx_shimmer_helper.h"
+
+const float lut_pitch_ratio_high[] = {
+ 6.151958251e-04, 6.517772725e-04, 6.905339660e-04, 7.315952524e-04,
+ 7.750981699e-04, 8.211879055e-04, 8.700182794e-04, 9.217522585e-04,
+ 9.765625000e-04, 1.034631928e-03, 1.096154344e-03, 1.161335073e-03,
+ 1.230391650e-03, 1.303554545e-03, 1.381067932e-03, 1.463190505e-03,
+ 1.550196340e-03, 1.642375811e-03, 1.740036559e-03, 1.843504517e-03,
+ 1.953125000e-03, 2.069263856e-03, 2.192308688e-03, 2.322670146e-03,
+ 2.460783301e-03, 2.607109090e-03, 2.762135864e-03, 2.926381010e-03,
+ 3.100392680e-03, 3.284751622e-03, 3.480073118e-03, 3.687009034e-03,
+ 3.906250000e-03, 4.138527712e-03, 4.384617376e-03, 4.645340293e-03,
+ 4.921566601e-03, 5.214218180e-03, 5.524271728e-03, 5.852762019e-03,
+ 6.200785359e-03, 6.569503244e-03, 6.960146235e-03, 7.374018068e-03,
+ 7.812500000e-03, 8.277055425e-03, 8.769234752e-03, 9.290680586e-03,
+ 9.843133202e-03, 1.042843636e-02, 1.104854346e-02, 1.170552404e-02,
+ 1.240157072e-02, 1.313900649e-02, 1.392029247e-02, 1.474803614e-02,
+ 1.562500000e-02, 1.655411085e-02, 1.753846950e-02, 1.858136117e-02,
+ 1.968626640e-02, 2.085687272e-02, 2.209708691e-02, 2.341104808e-02,
+ 2.480314144e-02, 2.627801298e-02, 2.784058494e-02, 2.949607227e-02,
+ 3.125000000e-02, 3.310822170e-02, 3.507693901e-02, 3.716272234e-02,
+ 3.937253281e-02, 4.171374544e-02, 4.419417382e-02, 4.682209615e-02,
+ 4.960628287e-02, 5.255602595e-02, 5.568116988e-02, 5.899214454e-02,
+ 6.250000000e-02, 6.621644340e-02, 7.015387802e-02, 7.432544469e-02,
+ 7.874506562e-02, 8.342749089e-02, 8.838834765e-02, 9.364419230e-02,
+ 9.921256575e-02, 1.051120519e-01, 1.113623398e-01, 1.179842891e-01,
+ 1.250000000e-01, 1.324328868e-01, 1.403077560e-01, 1.486508894e-01,
+ 1.574901312e-01, 1.668549818e-01, 1.767766953e-01, 1.872883846e-01,
+ 1.984251315e-01, 2.102241038e-01, 2.227246795e-01, 2.359685782e-01,
+ 2.500000000e-01, 2.648657736e-01, 2.806155121e-01, 2.973017788e-01,
+ 3.149802625e-01, 3.337099635e-01, 3.535533906e-01, 3.745767692e-01,
+ 3.968502630e-01, 4.204482076e-01, 4.454493591e-01, 4.719371563e-01,
+ 5.000000000e-01, 5.297315472e-01, 5.612310242e-01, 5.946035575e-01,
+ 6.299605249e-01, 6.674199271e-01, 7.071067812e-01, 7.491535384e-01,
+ 7.937005260e-01, 8.408964153e-01, 8.908987181e-01, 9.438743127e-01,
+ 1.000000000e+00, 1.059463094e+00, 1.122462048e+00, 1.189207115e+00,
+ 1.259921050e+00, 1.334839854e+00, 1.414213562e+00, 1.498307077e+00,
+ 1.587401052e+00, 1.681792831e+00, 1.781797436e+00, 1.887748625e+00,
+ 2.000000000e+00, 2.118926189e+00, 2.244924097e+00, 2.378414230e+00,
+ 2.519842100e+00, 2.669679708e+00, 2.828427125e+00, 2.996614154e+00,
+ 3.174802104e+00, 3.363585661e+00, 3.563594873e+00, 3.775497251e+00,
+ 4.000000000e+00, 4.237852377e+00, 4.489848193e+00, 4.756828460e+00,
+ 5.039684200e+00, 5.339359417e+00, 5.656854249e+00, 5.993228308e+00,
+ 6.349604208e+00, 6.727171322e+00, 7.127189745e+00, 7.550994501e+00,
+ 8.000000000e+00, 8.475704755e+00, 8.979696386e+00, 9.513656920e+00,
+ 1.007936840e+01, 1.067871883e+01, 1.131370850e+01, 1.198645662e+01,
+ 1.269920842e+01, 1.345434264e+01, 1.425437949e+01, 1.510198900e+01,
+ 1.600000000e+01, 1.695140951e+01, 1.795939277e+01, 1.902731384e+01,
+ 2.015873680e+01, 2.135743767e+01, 2.262741700e+01, 2.397291323e+01,
+ 2.539841683e+01, 2.690868529e+01, 2.850875898e+01, 3.020397801e+01,
+ 3.200000000e+01, 3.390281902e+01, 3.591878555e+01, 3.805462768e+01,
+ 4.031747360e+01, 4.271487533e+01, 4.525483400e+01, 4.794582646e+01,
+ 5.079683366e+01, 5.381737058e+01, 5.701751796e+01, 6.040795601e+01,
+ 6.400000000e+01, 6.780563804e+01, 7.183757109e+01, 7.610925536e+01,
+ 8.063494719e+01, 8.542975067e+01, 9.050966799e+01, 9.589165292e+01,
+ 1.015936673e+02, 1.076347412e+02, 1.140350359e+02, 1.208159120e+02,
+ 1.280000000e+02, 1.356112761e+02, 1.436751422e+02, 1.522185107e+02,
+ 1.612698944e+02, 1.708595013e+02, 1.810193360e+02, 1.917833058e+02,
+ 2.031873347e+02, 2.152694823e+02, 2.280700718e+02, 2.416318240e+02,
+ 2.560000000e+02, 2.712225522e+02, 2.873502844e+02, 3.044370214e+02,
+ 3.225397888e+02, 3.417190027e+02, 3.620386720e+02, 3.835666117e+02,
+ 4.063746693e+02, 4.305389646e+02, 4.561401437e+02, 4.832636481e+02,
+ 5.120000000e+02, 5.424451043e+02, 5.747005687e+02, 6.088740429e+02,
+ 6.450795775e+02, 6.834380053e+02, 7.240773439e+02, 7.671332234e+02,
+ 8.127493386e+02, 8.610779292e+02, 9.122802874e+02, 9.665272962e+02,
+ 1.024000000e+03, 1.084890209e+03, 1.149401137e+03, 1.217748086e+03,
+ 1.290159155e+03, 1.366876011e+03, 1.448154688e+03, 1.534266447e+03,
+};
+
+const float lut_pitch_ratio_low[] = {
+ 1.000000000e+00, 1.000225659e+00, 1.000451370e+00, 1.000677131e+00,
+ 1.000902943e+00, 1.001128806e+00, 1.001354720e+00, 1.001580685e+00,
+ 1.001806701e+00, 1.002032768e+00, 1.002258886e+00, 1.002485055e+00,
+ 1.002711275e+00, 1.002937546e+00, 1.003163868e+00, 1.003390242e+00,
+ 1.003616666e+00, 1.003843141e+00, 1.004069668e+00, 1.004296246e+00,
+ 1.004522874e+00, 1.004749554e+00, 1.004976285e+00, 1.005203068e+00,
+ 1.005429901e+00, 1.005656786e+00, 1.005883722e+00, 1.006110709e+00,
+ 1.006337747e+00, 1.006564836e+00, 1.006791977e+00, 1.007019169e+00,
+ 1.007246412e+00, 1.007473707e+00, 1.007701053e+00, 1.007928450e+00,
+ 1.008155898e+00, 1.008383398e+00, 1.008610949e+00, 1.008838551e+00,
+ 1.009066205e+00, 1.009293910e+00, 1.009521667e+00, 1.009749475e+00,
+ 1.009977334e+00, 1.010205245e+00, 1.010433207e+00, 1.010661221e+00,
+ 1.010889286e+00, 1.011117403e+00, 1.011345571e+00, 1.011573790e+00,
+ 1.011802061e+00, 1.012030384e+00, 1.012258758e+00, 1.012487183e+00,
+ 1.012715661e+00, 1.012944189e+00, 1.013172770e+00, 1.013401401e+00,
+ 1.013630085e+00, 1.013858820e+00, 1.014087607e+00, 1.014316445e+00,
+ 1.014545335e+00, 1.014774277e+00, 1.015003270e+00, 1.015232315e+00,
+ 1.015461411e+00, 1.015690560e+00, 1.015919760e+00, 1.016149011e+00,
+ 1.016378315e+00, 1.016607670e+00, 1.016837077e+00, 1.017066536e+00,
+ 1.017296046e+00, 1.017525609e+00, 1.017755223e+00, 1.017984889e+00,
+ 1.018214607e+00, 1.018444376e+00, 1.018674198e+00, 1.018904071e+00,
+ 1.019133996e+00, 1.019363973e+00, 1.019594002e+00, 1.019824083e+00,
+ 1.020054216e+00, 1.020284401e+00, 1.020514637e+00, 1.020744926e+00,
+ 1.020975266e+00, 1.021205659e+00, 1.021436104e+00, 1.021666600e+00,
+ 1.021897149e+00, 1.022127749e+00, 1.022358402e+00, 1.022589107e+00,
+ 1.022819863e+00, 1.023050672e+00, 1.023281533e+00, 1.023512446e+00,
+ 1.023743411e+00, 1.023974428e+00, 1.024205498e+00, 1.024436619e+00,
+ 1.024667793e+00, 1.024899019e+00, 1.025130297e+00, 1.025361627e+00,
+ 1.025593009e+00, 1.025824444e+00, 1.026055931e+00, 1.026287470e+00,
+ 1.026519061e+00, 1.026750705e+00, 1.026982401e+00, 1.027214149e+00,
+ 1.027445949e+00, 1.027677802e+00, 1.027909707e+00, 1.028141664e+00,
+ 1.028373674e+00, 1.028605736e+00, 1.028837851e+00, 1.029070017e+00,
+ 1.029302237e+00, 1.029534508e+00, 1.029766832e+00, 1.029999209e+00,
+ 1.030231638e+00, 1.030464119e+00, 1.030696653e+00, 1.030929239e+00,
+ 1.031161878e+00, 1.031394569e+00, 1.031627313e+00, 1.031860109e+00,
+ 1.032092958e+00, 1.032325859e+00, 1.032558813e+00, 1.032791820e+00,
+ 1.033024879e+00, 1.033257991e+00, 1.033491155e+00, 1.033724372e+00,
+ 1.033957641e+00, 1.034190964e+00, 1.034424338e+00, 1.034657766e+00,
+ 1.034891246e+00, 1.035124779e+00, 1.035358364e+00, 1.035592003e+00,
+ 1.035825694e+00, 1.036059437e+00, 1.036293234e+00, 1.036527083e+00,
+ 1.036760985e+00, 1.036994940e+00, 1.037228947e+00, 1.037463008e+00,
+ 1.037697121e+00, 1.037931287e+00, 1.038165506e+00, 1.038399777e+00,
+ 1.038634102e+00, 1.038868479e+00, 1.039102910e+00, 1.039337393e+00,
+ 1.039571929e+00, 1.039806518e+00, 1.040041160e+00, 1.040275855e+00,
+ 1.040510603e+00, 1.040745404e+00, 1.040980258e+00, 1.041215165e+00,
+ 1.041450125e+00, 1.041685138e+00, 1.041920204e+00, 1.042155323e+00,
+ 1.042390495e+00, 1.042625720e+00, 1.042860998e+00, 1.043096329e+00,
+ 1.043331714e+00, 1.043567151e+00, 1.043802642e+00, 1.044038185e+00,
+ 1.044273782e+00, 1.044509433e+00, 1.044745136e+00, 1.044980892e+00,
+ 1.045216702e+00, 1.045452565e+00, 1.045688481e+00, 1.045924450e+00,
+ 1.046160473e+00, 1.046396549e+00, 1.046632678e+00, 1.046868860e+00,
+ 1.047105096e+00, 1.047341385e+00, 1.047577727e+00, 1.047814123e+00,
+ 1.048050572e+00, 1.048287074e+00, 1.048523630e+00, 1.048760239e+00,
+ 1.048996902e+00, 1.049233618e+00, 1.049470387e+00, 1.049707210e+00,
+ 1.049944086e+00, 1.050181015e+00, 1.050417999e+00, 1.050655035e+00,
+ 1.050892125e+00, 1.051129269e+00, 1.051366466e+00, 1.051603717e+00,
+ 1.051841021e+00, 1.052078378e+00, 1.052315790e+00, 1.052553255e+00,
+ 1.052790773e+00, 1.053028345e+00, 1.053265971e+00, 1.053503650e+00,
+ 1.053741383e+00, 1.053979169e+00, 1.054217010e+00, 1.054454903e+00,
+ 1.054692851e+00, 1.054930852e+00, 1.055168907e+00, 1.055407016e+00,
+ 1.055645178e+00, 1.055883395e+00, 1.056121664e+00, 1.056359988e+00,
+ 1.056598366e+00, 1.056836797e+00, 1.057075282e+00, 1.057313821e+00,
+ 1.057552413e+00, 1.057791060e+00, 1.058029760e+00, 1.058268515e+00,
+ 1.058507323e+00, 1.058746185e+00, 1.058985101e+00, 1.059224071e+00,
+};
diff --git a/src/fx_shimmer_helper.h b/src/fx_shimmer_helper.h
new file mode 100644
index 0000000..582131c
--- /dev/null
+++ b/src/fx_shimmer_helper.h
@@ -0,0 +1,34 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//
+// fx_shimmer_helper.h
+//
+// Helper class for the FX Shimmer FX that is ported from Mutable Instruments
+// Ported by: Vincent Gauché
+//
+
+#pragma once
+
+#include "fx.h"
+
+extern const float lut_pitch_ratio_high[257];
+extern const float lut_pitch_ratio_low[257];
+
+inline float32_t semitoneToRatio(float32_t semitones)
+{
+ float32_t pitch = semitones + 128.0f;
+ MAKE_INTEGRAL_FRACTIONAL(pitch);
+
+ return lut_pitch_ratio_high[pitch_integral] * lut_pitch_ratio_low[static_cast(pitch_fractional * 256.0f)];
+}
diff --git a/src/fx_shimmer_reverb.cpp b/src/fx_shimmer_reverb.cpp
new file mode 100644
index 0000000..cc9ce02
--- /dev/null
+++ b/src/fx_shimmer_reverb.cpp
@@ -0,0 +1,169 @@
+#include "fx_shimmer_reverb.h"
+
+#define TAIL , -1
+
+ShimmerReverb::ShimmerReverb(float32_t sampling_frequency) :
+ FXElement(sampling_frequency, 1.2f),
+ pitch_shifter_(sampling_frequency, PITCH_SHIFTER_TRANSPOSE_BOUNDARY),
+ lp_filter_(sampling_frequency, SVF::FilterMode::SVF_LP),
+ hp_filter_(sampling_frequency, SVF::FilterMode::SVF_HP),
+ reverberator_(sampling_frequency),
+ texture_(0.0f),
+ lp_cutoff_(0.0f),
+ hp_cutoff_(0.0f),
+ lpq_(0.0f),
+ amount_(0.0f),
+ feedback_(0.0f),
+ cutoff_(0.0f)
+{
+ this->setInputGain(0.2f);
+ this->setDiffusion(0.7f);
+ this->setCutoff(1.0f);
+
+ this->reset();
+}
+
+ShimmerReverb::~ShimmerReverb()
+{
+}
+
+void ShimmerReverb::reset()
+{
+ this->pitch_shifter_.reset();
+ this->lp_filter_.reset();
+ this->hp_filter_.reset();
+ this->reverberator_.reset();
+}
+
+void ShimmerReverb::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
+{
+ this->pitch_shifter_.processSample(inL, inR, outL, outR);
+ this->lp_filter_.processSample(outL, outR, outL, outR);
+ this->hp_filter_.processSample(outL, outR, outL, outR);
+ this->reverberator_.processSample(outL, outR, outL, outR);
+
+ outL *= this->OutputLevelCorrector;
+ outR *= this->OutputLevelCorrector;
+}
+
+void ShimmerReverb::setInputGain(float32_t input_gain)
+{
+ this->reverberator_.setInputGain(input_gain);
+}
+
+float32_t ShimmerReverb::getInputGain() const
+{
+ return this->reverberator_.getInputGain();
+}
+
+void ShimmerReverb::setDiffusion(float32_t diffusion)
+{
+ this->reverberator_.setDiffusion(diffusion);
+}
+
+float32_t ShimmerReverb::getDiffusion() const
+{
+ return this->reverberator_.getDiffusion();
+}
+
+void ShimmerReverb::setTime(float32_t time)
+{
+ this->reverberator_.setTime(time);
+}
+
+float32_t ShimmerReverb::getTime() const
+{
+ return this->reverberator_.getTime();
+}
+
+void ShimmerReverb::setReverbAmount(float32_t amount)
+{
+ amount = constrain(amount, 0.0f, 1.0f);
+ if(this->amount_ != amount)
+ {
+ this->amount_ = amount;
+ this->updateReverberatorCoefficients();
+ }
+}
+
+void ShimmerReverb::setTexture(float32_t texture)
+{
+ texture = constrain(texture, 0.0f, 1.0f);
+ if(this->texture_ != texture)
+ {
+ this->texture_ = texture;
+ this->updateFilterCoefficients();
+ }
+}
+
+float32_t ShimmerReverb::getTexture() const
+{
+ return this->texture_;
+}
+
+void ShimmerReverb::setFeedback(float32_t feedback)
+{
+ feedback = constrain(feedback, 0.0f, 1.0f);
+ if(this->feedback_ != feedback)
+ {
+ this->feedback_ = feedback;
+ this->updateFilterCoefficients();
+ this->updateReverberatorCoefficients();
+ }
+}
+
+float32_t ShimmerReverb::getFeedback() const
+{
+ return this->feedback_;
+}
+
+void ShimmerReverb::setCutoff(float32_t cutoff)
+{
+ cutoff = constrain(cutoff, 0.0f, 1.0f);
+ if(this->cutoff_ != cutoff)
+ {
+ this->cutoff_ = cutoff;
+ this->updateFilterCoefficients();
+ }
+}
+
+void ShimmerReverb::updateFilterCoefficients()
+{
+ this->lp_cutoff_ = constrain(0.50f * semitoneToRatio((this->cutoff_ < 0.5f ? this->cutoff_ - 0.5f : 0.0f ) * 216.0f), 0.0f, 0.499f);
+ this->hp_cutoff_ = constrain(0.25f * semitoneToRatio((this->cutoff_ < 0.5f ? -0.5f : this->cutoff_ - 1.0f) * 216.0f), 0.0f, 0.499f);
+ this->lpq_ = 1.0f + 3.0f * (1.0f - this->feedback_) * (0.5f - this->lp_cutoff_);
+
+ this->lp_filter_.setFQ(this->lp_cutoff_, this->lpq_);
+ this->hp_filter_.setFQ(this->hp_cutoff_, 1.0f);
+
+ this->reverberator_.setLP(0.6f + 0.37f * this->feedback_);
+}
+
+void ShimmerReverb::updateReverberatorCoefficients()
+{
+ float32_t reverb_amount = this->amount_ * 0.95f;
+ reverb_amount += this->feedback_ * (2.0f - this->feedback_);
+ reverb_amount = constrain(reverb_amount, 0.0f, 1.0f);
+
+ this->setTime(0.35f + 0.63f * reverb_amount);
+}
+
+void ShimmerReverb::setPitch(float32_t pitch)
+{
+ this->pitch_shifter_.setTranspose(pitch);
+}
+
+float32_t ShimmerReverb::getPitch() const
+{
+ return this->pitch_shifter_.getTranspose();
+}
+
+void ShimmerReverb::setSize(float32_t size)
+{
+ this->pitch_shifter_.setSize(size);
+}
+
+float32_t ShimmerReverb::getSize() const
+{
+ return this->pitch_shifter_.getSize();
+}
diff --git a/src/fx_shimmer_reverb.h b/src/fx_shimmer_reverb.h
new file mode 100644
index 0000000..115ed85
--- /dev/null
+++ b/src/fx_shimmer_reverb.h
@@ -0,0 +1,111 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+
+//
+// fx_shimmer_reverb.h
+//
+// Stereo ShimmerReverb Reverb proposed in the context of the MiniDexed project
+// It is adapted from the ShimmerReverb Reverb that could be found on Cloud EuroRack module from Mutable Instrruments
+// Ported by: Vincent Gauché
+//
+#pragma once
+
+#include "fx_components.h"
+#include "fx_svf.h"
+#include "fx_shimmer_helper.h"
+#include "fx_pitch_shifter.h"
+#include "fx_reverberator.h"
+
+class ShimmerReverb : public FXElement
+{
+ DISALLOW_COPY_AND_ASSIGN(ShimmerReverb);
+
+public:
+ ShimmerReverb(float32_t sampling_rate);
+ virtual ~ShimmerReverb();
+
+ virtual void reset() override;
+ virtual void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) override;
+
+ void setInputGain(float32_t input_gain);
+ float32_t getInputGain() const;
+
+ void setDiffusion(float32_t diffusion);
+ float32_t getDiffusion() const;
+
+ void setTime(float32_t time);
+ float32_t getTime() const;
+
+ void setReverbAmount(float32_t amount);
+
+ void setTexture(float32_t texture);
+ float32_t getTexture() const;
+
+ void setFeedback(float32_t feedback);
+ float32_t getFeedback() const;
+
+ void setPitch(float32_t pitch);
+ float32_t getPitch() const;
+
+ void setSize(float32_t size);
+ float32_t getSize() const;
+
+ void setCutoff(float32_t cutoff);
+ float32_t getCutoff() const;
+
+private:
+ void updateFilterCoefficients();
+ void updateReverberatorCoefficients();
+
+ PitchShifter pitch_shifter_;
+ SVF lp_filter_;
+ SVF hp_filter_;
+ Reverberator reverberator_;
+
+ float32_t texture_;
+ float32_t lp_cutoff_;
+ float32_t hp_cutoff_;
+ float32_t lpq_;
+ float32_t amount_;
+ float32_t feedback_;
+ float32_t cutoff_;
+
+ IMPLEMENT_DUMP(
+ out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+
+ out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+ )
+
+ IMPLEMENT_INSPECT(
+ size_t nb_errors = 0u;
+
+ nb_errors += inspector(tag + ".texture_", this->texture_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".lp_cutoff_", this->lp_cutoff_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".hp_cutoff_", this->hp_cutoff_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".lpq_", this->lpq_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".amount_", this->amount_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".feedback_", this->feedback_, 0.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".cutoff_", this->cutoff_, 0.0f, 1.0f, deepInspection);
+
+ if(deepInspection)
+ {
+ nb_errors += this->pitch_shifter_.inspect(inspector, deepInspection, tag + ".pitch_shifter_");
+ nb_errors += this->lp_filter_.inspect(inspector, deepInspection, tag + ".lp_filter_");
+ nb_errors += this->hp_filter_.inspect(inspector, deepInspection, tag + ".hp_filter_");
+ nb_errors += this->reverberator_.inspect(inspector, deepInspection, tag + ".reverberator_");
+ }
+
+ return nb_errors;
+ )
+};
diff --git a/src/fx_svf.h b/src/fx_svf.h
index 61a53ba..361dc6e 100644
--- a/src/fx_svf.h
+++ b/src/fx_svf.h
@@ -16,6 +16,7 @@
// fx_svf.h
//
// State Variable Filter used in Tape Delay
+// Author: Vincent Gauché
//
#pragma once
diff --git a/src/fx_tube.cpp b/src/fx_tube.cpp
index 7e926fe..2b171d9 100644
--- a/src/fx_tube.cpp
+++ b/src/fx_tube.cpp
@@ -22,29 +22,35 @@ void Tube::reset()
void Tube::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR)
{
- float32_t x = inL * this->saturator_factor_;
- float32_t abs_x = abs(x);
- float32_t sat_x = log(1.0f + abs_x) * this->gain_factor_;
-
- outL = inL > 0 ? sat_x : -sat_x;
-
- x = inR * this->saturator_factor_;
- abs_x = abs(x);
- sat_x = log(1.0f + abs_x) * this->gain_factor_;
+ if(inL == 0.0f)
+ {
+ outL = 0.0f;
+ }
+ else
+ {
+ outL = std::tanh(this->saturator_factor_ * inL) * 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)
{
- static const float32_t N = 200.0f;
+ static const float32_t N = 3.0f;
overdrive = constrain(overdrive, 0.0f, 1.0f);
if(this->overdrive_ != overdrive)
{
this->overdrive_ = overdrive;
- this->saturator_factor_ = 1.0f + N * overdrive;
- this->gain_factor_ = this->OutputLevelCorrector / log(1.0f + this->saturator_factor_);
+ this->saturator_factor_ = 1.0 + N * overdrive;
+ this->gain_factor_ = this->OutputLevelCorrector / std::tanh(this->saturator_factor_);
}
}
diff --git a/src/fx_tube.h b/src/fx_tube.h
index fa775e3..99a163d 100644
--- a/src/fx_tube.h
+++ b/src/fx_tube.h
@@ -15,6 +15,7 @@
// fx_tube.h
//
// Stereo Tube overdrive audio effects proposed in the context of the MiniDexed project
+// Author: Vincent Gauché
//
#pragma once
@@ -77,4 +78,4 @@ private:
return nb_errors;
)
-};
\ No newline at end of file
+};
diff --git a/src/fx_unit.hpp b/src/fx_unit.hpp
index 3761497..344cdc7 100644
--- a/src/fx_unit.hpp
+++ b/src/fx_unit.hpp
@@ -15,6 +15,7 @@
// fx_unit.h
//
// Unit of FX that handle enable and wet parameters
+// Author: Vincent Gauché
//
#pragma once
diff --git a/src/fx_unit2.hpp b/src/fx_unit2.hpp
new file mode 100644
index 0000000..e26213c
--- /dev/null
+++ b/src/fx_unit2.hpp
@@ -0,0 +1,104 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//
+// fx_unit2.h
+//
+// Unit of FX that handle the mute parameter
+// Author: Vincent Gauché
+//
+#pragma once
+
+#include "fx_components.h"
+
+class FXUnitModule2
+{
+ DISALLOW_COPY_AND_ASSIGN(FXUnitModule2);
+
+public:
+ FXUnitModule2(bool mute = false)
+ {
+ this->setMute(mute);
+ }
+
+ virtual ~FXUnitModule2()
+ {
+ }
+
+ virtual void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) = 0;
+
+ inline void setMute(bool mute = false)
+ {
+ this->mute_ = mute;
+ }
+
+ inline bool isMute() const
+ {
+ return this->mute_;
+ }
+
+protected:
+ bool mute_;
+};
+
+template
+class FXUnit2 : public virtual FXUnitModule2, public virtual _FXElement
+{
+ DISALLOW_COPY_AND_ASSIGN(FXUnit2);
+
+public:
+ FXUnit2(float32_t sampling_rate, bool mute = false) :
+ FXUnitModule2(mute),
+ _FXElement(sampling_rate),
+ is_reset_(false)
+ {
+ this->setMute(mute);
+ }
+
+ virtual ~FXUnit2()
+ {
+ }
+
+ inline void reset() override
+ {
+ if(!this->is_reset_)
+ {
+ _FXElement::reset();
+ this->is_reset_ = true;
+ }
+ }
+
+ inline void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) override
+ {
+ if(this->isMute())
+ {
+ this->reset();
+
+ outL = 0.0f;
+ outR = 0.0f;
+ }
+ else if(this->bypassFXProcess())
+ {
+ outL = inL;
+ outR = inR;
+ }
+ else
+ {
+ this->is_reset_ = false;
+ _FXElement::processSample(inL, inR, outL, outR);
+ }
+ }
+
+private:
+ bool is_reset_;
+};
diff --git a/src/mididevice.cpp b/src/mididevice.cpp
index e1f983c..fadfd61 100644
--- a/src/mididevice.cpp
+++ b/src/mididevice.cpp
@@ -29,41 +29,44 @@
#include
#include "userinterface.h"
-LOGMODULE ("mididevice");
-
-#define MIDI_NOTE_OFF 0b1000
-#define MIDI_NOTE_ON 0b1001
-#define MIDI_AFTERTOUCH 0b1010 // TODO
-#define MIDI_CHANNEL_AFTERTOUCH 0b1101 // right now Synth_Dexed just manage Channel Aftertouch not Polyphonic AT -> 0b1010
-#define MIDI_CONTROL_CHANGE 0b1011
- #define MIDI_CC_BANK_SELECT_MSB 0
- #define MIDI_CC_MODULATION 1
- #define MIDI_CC_BREATH_CONTROLLER 2
- #define MIDI_CC_FOOT_PEDAL 4
- #define MIDI_CC_VOLUME 7
- #define MIDI_CC_PAN_POSITION 10
- #define MIDI_CC_BANK_SELECT_LSB 32
- #define MIDI_CC_BANK_SUSTAIN 64
- #define MIDI_CC_RESONANCE 71
- #define MIDI_CC_FREQUENCY_CUTOFF 74
- #define MIDI_CC_REVERB_LEVEL 91
- #define MIDI_CC_DETUNE_LEVEL 94
- #define MIDI_CC_ALL_SOUND_OFF 120
- #define MIDI_CC_ALL_NOTES_OFF 123
-#define MIDI_PROGRAM_CHANGE 0b1100
-#define MIDI_PITCH_BEND 0b1110
-
-#define MIDI_SYSTEM_EXCLUSIVE_BEGIN 0xF0
-#define MIDI_SYSTEM_EXCLUSIVE_END 0xF7
-#define MIDI_TIMING_CLOCK 0xF8
-#define MIDI_ACTIVE_SENSING 0xFE
+LOGMODULE("mididevice");
+
+#define MIDI_NOTE_OFF 0b1000
+#define MIDI_NOTE_ON 0b1001
+#define MIDI_AFTERTOUCH 0b1010 // TODO
+#define MIDI_CHANNEL_AFTERTOUCH 0b1101 // right now Synth_Dexed just manage Channel Aftertouch not Polyphonic AT -> 0b1010
+#define MIDI_CONTROL_CHANGE 0b1011
+#define MIDI_CC_BANK_SELECT_MSB 0
+#define MIDI_CC_MODULATION 1
+#define MIDI_CC_BREATH_CONTROLLER 2
+#define MIDI_CC_FOOT_PEDAL 4
+#define MIDI_CC_VOLUME 7
+#define MIDI_CC_PAN_POSITION 10
+#define MIDI_CC_BANK_SELECT_LSB 32
+#define MIDI_CC_BANK_SUSTAIN 64
+#define MIDI_CC_RESONANCE 71
+#define MIDI_CC_FREQUENCY_CUTOFF 74
+#define MIDI_CC_REVERB_LEVEL 91
+#define MIDI_CC_ORBITONE_LEVEL 92 // added with mixing console
+#define MIDI_CC_CHORUS_LEVEL 93 // added with mixing console
+#define MIDI_CC_DETUNE_LEVEL 94
+#define MIDI_CC_PHASER_LEVEL 95 // added with mixing console
+#define MIDI_CC_ALL_SOUND_OFF 120
+#define MIDI_CC_ALL_NOTES_OFF 123
+#define MIDI_PROGRAM_CHANGE 0b1100
+#define MIDI_PITCH_BEND 0b1110
+
+#define MIDI_SYSTEM_EXCLUSIVE_BEGIN 0xF0
+#define MIDI_SYSTEM_EXCLUSIVE_END 0xF7
+#define MIDI_TIMING_CLOCK 0xF8
+#define MIDI_ACTIVE_SENSING 0xFE
CMIDIDevice::TDeviceMap CMIDIDevice::s_DeviceMap;
-CMIDIDevice::CMIDIDevice (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI)
-: m_pSynthesizer (pSynthesizer),
- m_pConfig (pConfig),
- m_pUI (pUI)
+CMIDIDevice::CMIDIDevice(CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI)
+ : m_pSynthesizer(pSynthesizer),
+ m_pConfig(pConfig),
+ m_pUI(pUI)
{
for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
@@ -71,94 +74,93 @@ CMIDIDevice::CMIDIDevice (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInter
}
}
-CMIDIDevice::~CMIDIDevice (void)
+CMIDIDevice::~CMIDIDevice(void)
{
m_pSynthesizer = 0;
}
-void CMIDIDevice::SetChannel (u8 ucChannel, unsigned nTG)
+void CMIDIDevice::SetChannel(u8 ucChannel, unsigned nTG)
{
- assert (nTG < CConfig::ToneGenerators);
+ assert(nTG < CConfig::ToneGenerators);
m_ChannelMap[nTG] = ucChannel;
}
-u8 CMIDIDevice::GetChannel (unsigned nTG) const
+u8 CMIDIDevice::GetChannel(unsigned nTG) const
{
- assert (nTG < CConfig::ToneGenerators);
+ assert(nTG < CConfig::ToneGenerators);
return m_ChannelMap[nTG];
}
-void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsigned nCable)
+void CMIDIDevice::MIDIMessageHandler(const u8 *pMessage, size_t nLength, unsigned nCable)
{
// The packet contents are just normal MIDI data - see
// https://www.midi.org/specifications/item/table-1-summary-of-midi-message
- if (m_pConfig->GetMIDIDumpEnabled ())
+ if (m_pConfig->GetMIDIDumpEnabled())
{
switch (nLength)
{
case 1:
- if ( pMessage[0] != MIDI_TIMING_CLOCK
- && pMessage[0] != MIDI_ACTIVE_SENSING)
+ if (pMessage[0] != MIDI_TIMING_CLOCK && pMessage[0] != MIDI_ACTIVE_SENSING)
{
- printf ("MIDI%u: %02X\n", nCable, (unsigned) pMessage[0]);
+ printf("MIDI%u: %02X\n", nCable, (unsigned)pMessage[0]);
}
break;
case 2:
- printf ("MIDI%u: %02X %02X\n", nCable,
- (unsigned) pMessage[0], (unsigned) pMessage[1]);
+ printf("MIDI%u: %02X %02X\n", nCable,
+ (unsigned)pMessage[0], (unsigned)pMessage[1]);
break;
case 3:
- printf ("MIDI%u: %02X %02X %02X\n", nCable,
- (unsigned) pMessage[0], (unsigned) pMessage[1],
- (unsigned) pMessage[2]);
+ printf("MIDI%u: %02X %02X %02X\n", nCable,
+ (unsigned)pMessage[0], (unsigned)pMessage[1],
+ (unsigned)pMessage[2]);
break;
default:
- switch(pMessage[0])
+ switch (pMessage[0])
{
- case MIDI_SYSTEM_EXCLUSIVE_BEGIN:
- printf("MIDI%u: SysEx data length: [%d]:",nCable, uint16_t(nLength));
- for (uint16_t i = 0; i < nLength; i++)
- {
- if((i % 16) == 0)
- printf("\n%04d:",i);
- printf(" 0x%02x",pMessage[i]);
- }
- printf("\n");
- break;
- default:
- printf("MIDI%u: Unhandled MIDI event type %0x02x\n",nCable,pMessage[0]);
+ case MIDI_SYSTEM_EXCLUSIVE_BEGIN:
+ printf("MIDI%u: SysEx data length: [%d]:", nCable, uint16_t(nLength));
+ for (uint16_t i = 0; i < nLength; i++)
+ {
+ if ((i % 16) == 0)
+ printf("\n%04d:", i);
+ printf(" 0x%02x", pMessage[i]);
+ }
+ printf("\n");
+ break;
+ default:
+ printf("MIDI%u: Unhandled MIDI event type %0x02x\n", nCable, pMessage[0]);
}
break;
}
}
// Only for debugging:
-/*
- if(pMessage[0]==MIDI_SYSTEM_EXCLUSIVE_BEGIN)
- {
- printf("MIDI%u: SysEx data length: [%d]:",nCable, uint16_t(nLength));
- for (uint16_t i = 0; i < nLength; i++)
+ /*
+ if(pMessage[0]==MIDI_SYSTEM_EXCLUSIVE_BEGIN)
{
- if((i % 16) == 0)
- printf("\n%04d:",i);
- printf(" 0x%02x",pMessage[i]);
+ printf("MIDI%u: SysEx data length: [%d]:",nCable, uint16_t(nLength));
+ for (uint16_t i = 0; i < nLength; i++)
+ {
+ if((i % 16) == 0)
+ printf("\n%04d:",i);
+ printf(" 0x%02x",pMessage[i]);
+ }
+ printf("\n");
}
- printf("\n");
- }
-*/
+ */
// Handle MIDI Thru
- if (m_DeviceName.compare (m_pConfig->GetMIDIThruIn ()) == 0)
+ if (m_DeviceName.compare(m_pConfig->GetMIDIThruIn()) == 0)
{
TDeviceMap::const_iterator Iterator;
- Iterator = s_DeviceMap.find (m_pConfig->GetMIDIThruOut ());
- if (Iterator != s_DeviceMap.end ())
+ Iterator = s_DeviceMap.find(m_pConfig->GetMIDIThruOut());
+ if (Iterator != s_DeviceMap.end())
{
- Iterator->second->Send (pMessage, nLength, nCable);
+ Iterator->second->Send(pMessage, nLength, nCable);
}
}
@@ -168,17 +170,17 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
return;
}
- m_MIDISpinLock.Acquire ();
+ m_MIDISpinLock.Acquire();
- u8 ucStatus = pMessage[0];
+ u8 ucStatus = pMessage[0];
u8 ucChannel = ucStatus & 0x0F;
- u8 ucType = ucStatus >> 4;
+ u8 ucType = ucStatus >> 4;
// GLOBAL MIDI SYSEX
- if (pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && pMessage[3] == 0x04 && pMessage[4] == 0x01 && pMessage[nLength-1] == MIDI_SYSTEM_EXCLUSIVE_END) // MASTER VOLUME
+ if (pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && pMessage[3] == 0x04 && pMessage[4] == 0x01 && pMessage[nLength - 1] == MIDI_SYSTEM_EXCLUSIVE_END) // MASTER VOLUME
{
- float32_t nMasterVolume=((pMessage[5] & 0x7c) & ((pMessage[6] & 0x7c) <<7))/(1<<14);
- LOGNOTE("Master volume: %f",nMasterVolume);
+ float32_t nMasterVolume = ((pMessage[5] & 0x7c) & ((pMessage[6] & 0x7c) << 7)) / (1 << 14);
+ LOGNOTE("Master volume: %f", nMasterVolume);
m_pSynthesizer->setMasterVolume(nMasterVolume);
}
else
@@ -191,9 +193,9 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
case MIDI_NOTE_ON:
if (nLength < 3)
{
- break;
+ break;
}
- m_pUI->UIMIDICmdHandler (ucChannel, ucStatus & 0xF0, pMessage[1], pMessage[2]);
+ m_pUI->UIMIDICmdHandler(ucChannel, ucStatus & 0xF0, pMessage[1], pMessage[2]);
break;
}
@@ -206,14 +208,13 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
uint8_t ucSysExChannel = (pMessage[2] & 0x0F);
if (m_ChannelMap[nTG] == ucSysExChannel || m_ChannelMap[nTG] == OmniMode)
{
- LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u",m_ChannelMap[nTG],nLength,nTG);
+ LOGNOTE("MIDI-SYSEX: channel: %u, len: %u, TG: %u", m_ChannelMap[nTG], nLength, nTG);
HandleSystemExclusive(pMessage, nLength, nCable, nTG);
}
}
else
{
- if ( m_ChannelMap[nTG] == ucChannel
- || m_ChannelMap[nTG] == OmniMode)
+ if (m_ChannelMap[nTG] == ucChannel || m_ChannelMap[nTG] == OmniMode)
{
switch (ucType)
{
@@ -222,138 +223,156 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
{
break;
}
-
+
if (pMessage[2] > 0)
{
if (pMessage[2] <= 127)
{
- m_pSynthesizer->keydown (pMessage[1],
- pMessage[2], nTG);
+ m_pSynthesizer->keydown(pMessage[1],
+ pMessage[2], nTG);
}
}
else
{
- m_pSynthesizer->keyup (pMessage[1], nTG);
+ m_pSynthesizer->keyup(pMessage[1], nTG);
}
break;
-
+
case MIDI_NOTE_OFF:
if (nLength < 3)
{
break;
}
-
- m_pSynthesizer->keyup (pMessage[1], nTG);
+
+ m_pSynthesizer->keyup(pMessage[1], nTG);
break;
-
+
case MIDI_CHANNEL_AFTERTOUCH:
-
- m_pSynthesizer->setAftertouch (pMessage[1], nTG);
- m_pSynthesizer->ControllersRefresh (nTG);
+
+ m_pSynthesizer->setAftertouch(pMessage[1], nTG);
+ m_pSynthesizer->ControllersRefresh(nTG);
break;
-
+
case MIDI_CONTROL_CHANGE:
if (nLength < 3)
{
break;
}
-
+
switch (pMessage[1])
{
case MIDI_CC_MODULATION:
- m_pSynthesizer->setModWheel (pMessage[2], nTG);
- m_pSynthesizer->ControllersRefresh (nTG);
+ m_pSynthesizer->setModWheel(pMessage[2], nTG);
+ m_pSynthesizer->ControllersRefresh(nTG);
break;
-
+
case MIDI_CC_FOOT_PEDAL:
- m_pSynthesizer->setFootController (pMessage[2], nTG);
- m_pSynthesizer->ControllersRefresh (nTG);
+ m_pSynthesizer->setFootController(pMessage[2], nTG);
+ m_pSynthesizer->ControllersRefresh(nTG);
break;
case MIDI_CC_BREATH_CONTROLLER:
- m_pSynthesizer->setBreathController (pMessage[2], nTG);
- m_pSynthesizer->ControllersRefresh (nTG);
+ m_pSynthesizer->setBreathController(pMessage[2], nTG);
+ m_pSynthesizer->ControllersRefresh(nTG);
break;
-
+
case MIDI_CC_VOLUME:
- m_pSynthesizer->SetVolume (pMessage[2], nTG);
+ m_pSynthesizer->SetVolume(pMessage[2], nTG);
break;
-
+
case MIDI_CC_PAN_POSITION:
- m_pSynthesizer->SetPan (pMessage[2], nTG);
+ m_pSynthesizer->SetPan(pMessage[2], nTG);
break;
-
+
case MIDI_CC_BANK_SELECT_MSB:
- m_pSynthesizer->BankSelectMSB (pMessage[2], nTG);
+ m_pSynthesizer->BankSelectMSB(pMessage[2], nTG);
break;
-
+
case MIDI_CC_BANK_SELECT_LSB:
- m_pSynthesizer->BankSelectLSB (pMessage[2], nTG);
+ m_pSynthesizer->BankSelectLSB(pMessage[2], nTG);
break;
-
+
case MIDI_CC_BANK_SUSTAIN:
- m_pSynthesizer->setSustain (pMessage[2] >= 64, nTG);
+ m_pSynthesizer->setSustain(pMessage[2] >= 64, nTG);
break;
-
+
case MIDI_CC_RESONANCE:
- m_pSynthesizer->SetResonance (maplong (pMessage[2], 0, 127, 0, 99), nTG);
+ m_pSynthesizer->SetResonance(maplong(pMessage[2], 0, 127, 0, 99), nTG);
break;
-
+
case MIDI_CC_FREQUENCY_CUTOFF:
- m_pSynthesizer->SetCutoff (maplong (pMessage[2], 0, 127, 0, 99), nTG);
+ m_pSynthesizer->SetCutoff(maplong(pMessage[2], 0, 127, 0, 99), nTG);
break;
-
+
case MIDI_CC_REVERB_LEVEL:
- m_pSynthesizer->SetReverbSend (maplong (pMessage[2], 0, 127, 0, 99), nTG);
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->m_pSynthesizer->setMixingConsoleSendLevel(nTG, MixerOutput::FX_PlateReverb, maplong(pMessage[2], 0, 127, 0, 99));
+#elif defined(PLATE_REVERB_ENABLE)
+ m_pSynthesizer->SetReverbSend(maplong(pMessage[2], 0, 127, 0, 99), nTG);
+#endif
+ break;
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ case MIDI_CC_ORBITONE_LEVEL:
+ this->m_pSynthesizer->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Orbitone, maplong(pMessage[2], 0, 127, 0, 99));
break;
-
+ case MIDI_CC_CHORUS_LEVEL:
+ this->m_pSynthesizer->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Chorus, maplong(pMessage[2], 0, 127, 0, 99));
+ break;
+ case MIDI_CC_PHASER_LEVEL:
+ this->m_pSynthesizer->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Phaser, maplong(pMessage[2], 0, 127, 0, 99));
+ break;
+#endif
+
case MIDI_CC_DETUNE_LEVEL:
if (pMessage[2] == 0)
{
// "0 to 127, with 0 being no celeste (detune) effect applied at all."
- m_pSynthesizer->SetMasterTune (0, nTG);
+ m_pSynthesizer->SetMasterTune(0, nTG);
}
else
{
- m_pSynthesizer->SetMasterTune (maplong (pMessage[2], 1, 127, -99, 99), nTG);
+ m_pSynthesizer->SetMasterTune(maplong(pMessage[2], 1, 127, -99, 99), nTG);
}
break;
-
+
case MIDI_CC_ALL_SOUND_OFF:
- m_pSynthesizer->panic (pMessage[2], nTG);
+ m_pSynthesizer->panic(pMessage[2], nTG);
break;
-
+
case MIDI_CC_ALL_NOTES_OFF:
// As per "MIDI 1.0 Detailed Specification" v4.2
// From "ALL NOTES OFF" states:
// "Receivers should ignore an All Notes Off message while Omni is on (Modes 1 & 2)"
- if (!m_pConfig->GetIgnoreAllNotesOff () && m_ChannelMap[nTG] != OmniMode)
+ if (!m_pConfig->GetIgnoreAllNotesOff() && m_ChannelMap[nTG] != OmniMode)
{
- m_pSynthesizer->notesOff (pMessage[2], nTG);
+ m_pSynthesizer->notesOff(pMessage[2], nTG);
}
break;
}
break;
-
+
case MIDI_PROGRAM_CHANGE:
// do program change only if enabled in config
- if( m_pConfig->GetMIDIRXProgramChange() )
- m_pSynthesizer->ProgramChange (pMessage[1], nTG);
+ if (m_pConfig->GetMIDIRXProgramChange())
+ m_pSynthesizer->ProgramChange(pMessage[1], nTG);
break;
-
- case MIDI_PITCH_BEND: {
+
+ case MIDI_PITCH_BEND:
+ {
if (nLength < 3)
{
break;
}
-
+
s16 nValue = pMessage[1];
- nValue |= (s16) pMessage[2] << 7;
+ nValue |= (s16)pMessage[2] << 7;
nValue -= 0x2000;
-
- m_pSynthesizer->setPitchbend (nValue, nTG);
- } break;
-
+
+ m_pSynthesizer->setPitchbend(nValue, nTG);
+ }
+ break;
+
default:
break;
}
@@ -361,161 +380,161 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
}
}
}
- m_MIDISpinLock.Release ();
+ m_MIDISpinLock.Release();
}
-void CMIDIDevice::AddDevice (const char *pDeviceName)
+void CMIDIDevice::AddDevice(const char *pDeviceName)
{
- assert (pDeviceName);
+ assert(pDeviceName);
- assert (m_DeviceName.empty ());
+ assert(m_DeviceName.empty());
m_DeviceName = pDeviceName;
- assert (!m_DeviceName.empty ());
+ assert(!m_DeviceName.empty());
- s_DeviceMap.insert (std::pair (pDeviceName, this));
+ s_DeviceMap.insert(std::pair(pDeviceName, this));
}
-void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const unsigned nCable, const uint8_t nTG)
+void CMIDIDevice::HandleSystemExclusive(const uint8_t *pMessage, const size_t nLength, const unsigned nCable, const uint8_t nTG)
{
- int16_t sysex_return;
-
- sysex_return = m_pSynthesizer->checkSystemExclusive(pMessage, nLength, nTG);
- LOGDBG("SYSEX handler return value: %d", sysex_return);
-
- switch (sysex_return)
- {
- case -1:
- LOGERR("SysEx end status byte not detected.");
- break;
- case -2:
- LOGERR("SysEx vendor not Yamaha.");
- break;
- case -3:
- LOGERR("Unknown SysEx parameter change.");
- break;
- case -4:
- LOGERR("Unknown SysEx voice or function.");
- break;
- case -5:
- LOGERR("Not a SysEx voice bulk upload.");
- break;
- case -6:
- LOGERR("Wrong length for SysEx voice bulk upload (not 155).");
- break;
- case -7:
- LOGERR("Checksum error for one voice.");
- break;
- case -8:
- LOGERR("Not a SysEx bank bulk upload.");
- break;
- case -9:
- LOGERR("Wrong length for SysEx bank bulk upload (not 4096).");
- case -10:
- LOGERR("Checksum error for bank.");
- break;
- case -11:
- LOGERR("Unknown SysEx message.");
- break;
- case 64:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setMonoMode(pMessage[5],nTG);
- break;
- case 65:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setPitchbendRange(pMessage[5],nTG);
- break;
- case 66:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setPitchbendStep(pMessage[5],nTG);
- break;
- case 67:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setPortamentoMode(pMessage[5],nTG);
- break;
- case 68:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setPortamentoGlissando(pMessage[5],nTG);
- break;
- case 69:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setPortamentoTime(pMessage[5],nTG);
- break;
- case 70:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setModWheelRange(pMessage[5],nTG);
- break;
- case 71:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setModWheelTarget(pMessage[5],nTG);
- break;
- case 72:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setFootControllerRange(pMessage[5],nTG);
- break;
- case 73:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setFootControllerTarget(pMessage[5],nTG);
- break;
- case 74:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setBreathControllerRange(pMessage[5],nTG);
- break;
- case 75:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setBreathControllerTarget(pMessage[5],nTG);
- break;
- case 76:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setAftertouchRange(pMessage[5],nTG);
- break;
- case 77:
- LOGDBG("SysEx Function parameter change: %d Value %d",pMessage[4],pMessage[5]);
- m_pSynthesizer->setAftertouchTarget(pMessage[5],nTG);
- break;
- case 100:
- // load sysex-data into voice memory
- LOGDBG("One Voice bulk upload");
- m_pSynthesizer->loadVoiceParameters(pMessage,nTG);
- break;
- case 200:
- LOGDBG("Bank bulk upload.");
- //TODO: add code for storing a bank bulk upload
- LOGNOTE("Currently code for storing a bulk bank upload is missing!");
- break;
- default:
- if(sysex_return >= 300 && sysex_return < 500)
- {
- LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]);
- m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG);
- switch(pMessage[4] + ((pMessage[3] & 0x03) * 128))
- {
- case 134:
- m_pSynthesizer->notesOff(0,nTG);
- break;
- }
- }
- else if(sysex_return >= 500 && sysex_return < 600)
- {
- LOGDBG("SysEx send voice %u request",sysex_return-500);
- SendSystemExclusiveVoice(sysex_return-500, nCable, nTG);
- }
- break;
- }
+ int16_t sysex_return;
+
+ sysex_return = m_pSynthesizer->checkSystemExclusive(pMessage, nLength, nTG);
+ LOGDBG("SYSEX handler return value: %d", sysex_return);
+
+ switch (sysex_return)
+ {
+ case -1:
+ LOGERR("SysEx end status byte not detected.");
+ break;
+ case -2:
+ LOGERR("SysEx vendor not Yamaha.");
+ break;
+ case -3:
+ LOGERR("Unknown SysEx parameter change.");
+ break;
+ case -4:
+ LOGERR("Unknown SysEx voice or function.");
+ break;
+ case -5:
+ LOGERR("Not a SysEx voice bulk upload.");
+ break;
+ case -6:
+ LOGERR("Wrong length for SysEx voice bulk upload (not 155).");
+ break;
+ case -7:
+ LOGERR("Checksum error for one voice.");
+ break;
+ case -8:
+ LOGERR("Not a SysEx bank bulk upload.");
+ break;
+ case -9:
+ LOGERR("Wrong length for SysEx bank bulk upload (not 4096).");
+ case -10:
+ LOGERR("Checksum error for bank.");
+ break;
+ case -11:
+ LOGERR("Unknown SysEx message.");
+ break;
+ case 64:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setMonoMode(pMessage[5], nTG);
+ break;
+ case 65:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setPitchbendRange(pMessage[5], nTG);
+ break;
+ case 66:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setPitchbendStep(pMessage[5], nTG);
+ break;
+ case 67:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setPortamentoMode(pMessage[5], nTG);
+ break;
+ case 68:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setPortamentoGlissando(pMessage[5], nTG);
+ break;
+ case 69:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setPortamentoTime(pMessage[5], nTG);
+ break;
+ case 70:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setModWheelRange(pMessage[5], nTG);
+ break;
+ case 71:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setModWheelTarget(pMessage[5], nTG);
+ break;
+ case 72:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setFootControllerRange(pMessage[5], nTG);
+ break;
+ case 73:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setFootControllerTarget(pMessage[5], nTG);
+ break;
+ case 74:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setBreathControllerRange(pMessage[5], nTG);
+ break;
+ case 75:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setBreathControllerTarget(pMessage[5], nTG);
+ break;
+ case 76:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setAftertouchRange(pMessage[5], nTG);
+ break;
+ case 77:
+ LOGDBG("SysEx Function parameter change: %d Value %d", pMessage[4], pMessage[5]);
+ m_pSynthesizer->setAftertouchTarget(pMessage[5], nTG);
+ break;
+ case 100:
+ // load sysex-data into voice memory
+ LOGDBG("One Voice bulk upload");
+ m_pSynthesizer->loadVoiceParameters(pMessage, nTG);
+ break;
+ case 200:
+ LOGDBG("Bank bulk upload.");
+ // TODO: add code for storing a bank bulk upload
+ LOGNOTE("Currently code for storing a bulk bank upload is missing!");
+ break;
+ default:
+ if (sysex_return >= 300 && sysex_return < 500)
+ {
+ LOGDBG("SysEx voice parameter change: Parameter %d value: %d", pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]);
+ m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5], nTG);
+ switch (pMessage[4] + ((pMessage[3] & 0x03) * 128))
+ {
+ case 134:
+ m_pSynthesizer->notesOff(0, nTG);
+ break;
+ }
+ }
+ else if (sysex_return >= 500 && sysex_return < 600)
+ {
+ LOGDBG("SysEx send voice %u request", sysex_return - 500);
+ SendSystemExclusiveVoice(sysex_return - 500, nCable, nTG);
+ }
+ break;
+ }
}
void CMIDIDevice::SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable, uint8_t nTG)
{
- uint8_t voicedump[163];
+ uint8_t voicedump[163];
- // Get voice sysex dump from TG
- m_pSynthesizer->getSysExVoiceDump(voicedump, nTG);
+ // Get voice sysex dump from TG
+ m_pSynthesizer->getSysExVoiceDump(voicedump, nTG);
- TDeviceMap::const_iterator Iterator;
+ TDeviceMap::const_iterator Iterator;
- // send voice dump to all MIDI interfaces
- for(Iterator = s_DeviceMap.begin(); Iterator != s_DeviceMap.end(); ++Iterator)
- {
- Iterator->second->Send (voicedump, sizeof(voicedump)*sizeof(uint8_t));
- // LOGDBG("Send SYSEX voice dump %u to \"%s\"",nVoice,Iterator->first.c_str());
- }
-}
+ // send voice dump to all MIDI interfaces
+ for (Iterator = s_DeviceMap.begin(); Iterator != s_DeviceMap.end(); ++Iterator)
+ {
+ Iterator->second->Send(voicedump, sizeof(voicedump) * sizeof(uint8_t));
+ // LOGDBG("Send SYSEX voice dump %u to \"%s\"",nVoice,Iterator->first.c_str());
+ }
+}
diff --git a/src/minidexed.cpp b/src/minidexed.cpp
index db9254a..fdc2ae2 100644
--- a/src/minidexed.cpp
+++ b/src/minidexed.cpp
@@ -30,9 +30,13 @@
LOGMODULE ("minidexed");
-CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
- CGPIOManager *pGPIOManager, CI2CMaster *pI2CMaster, FATFS *pFileSystem)
-:
+CMiniDexed::CMiniDexed (
+ CConfig *pConfig,
+ CInterruptSystem *pInterrupt,
+ CGPIOManager *pGPIOManager,
+ CI2CMaster *pI2CMaster,
+ FATFS *pFileSystem
+) :
#ifdef ARM_ALLOW_MULTI_CORE
CMultiCoreSupport (CMemorySystem::Get ()),
#endif
@@ -47,8 +51,9 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
#ifdef ARM_ALLOW_MULTI_CORE
m_nActiveTGsLog2 (0),
#endif
- m_GetChunkTimer ("GetChunk",
- 1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()),
+
+
+ m_GetChunkTimer ("GetChunk", 1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()),
m_bProfileEnabled (m_pConfig->GetProfileEnabled ()),
m_bSavePerformance (false),
m_bSavePerformanceNewFile (false),
@@ -79,16 +84,29 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
m_nNoteLimitHigh[i] = 127;
m_nNoteShift[i] = 0;
- m_nModulationWheelRange[i]=99;
- m_nModulationWheelTarget[i]=7;
- m_nFootControlRange[i]=99;
- m_nFootControlTarget[i]=0;
- m_nBreathControlRange[i]=99;
- m_nBreathControlTarget[i]=0;
- m_nAftertouchRange[i]=99;
- m_nAftertouchTarget[i]=0;
-
+
+
+
+
+
+
+
+
+
+ m_nModulationWheelRange[i] = 99;
+ m_nModulationWheelTarget[i] = 7;
+ m_nFootControlRange[i] = 99;
+ m_nFootControlTarget[i] = 0;
+ m_nBreathControlRange[i] = 99;
+ m_nBreathControlTarget[i] = 0;
+ m_nAftertouchRange[i] = 99;
+ m_nAftertouchTarget[i] = 0;
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ memset(this->m_nTGSendLevel[i], 0, MixerOutput::kFXCount * sizeof(unsigned));
+#elif defined(PLATE_REVERB_ENABLE)
m_nReverbSend[i] = 0;
+#endif
m_uchOPMask[i] = 0b111111; // All operators on
m_pTG[i] = new CDexedAdapter (CConfig::MaxNotes, pConfig->GetSampleRate ());
@@ -97,6 +115,17 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
m_pTG[i]->activate ();
}
+#if defined(MIXING_CONSOLE_ENABLE)
+ for(size_t i = MixerOutput::FX_Tube; i < (MixerOutput::kFXCount - 1); ++i)
+ {
+ memset(this->m_nFXSendLevel[i], 0, MixerOutput::kFXCount * sizeof(unsigned));
+ }
+
+ this->m_nTGSendLevel[0][MixerOutput::MainOutput] = 99;
+ this->m_nTGSendLevel[0][MixerOutput::FX_PlateReverb] = 99;
+ this->m_nFXSendLevel[MixerOutput::FX_PlateReverb][MixerOutput::MainOutput] = 99;
+#endif
+
for (unsigned i = 0; i < CConfig::MaxUSBMIDIDevices; i++)
{
m_pMIDIKeyboard[i] = new CMIDIKeyboard (this, pConfig, &m_UI, i);
@@ -139,7 +168,69 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
}
#endif
- setMasterVolume(1.0);
+ this->setMasterVolume(1.0);
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->mixing_console_ = new Mixer(static_cast(pConfig->GetSampleRate()), CConfig::MaxChunkSize, this->m_bChannelsSwapped);
+ for (uint8_t i = 0; i < CConfig::ToneGenerators; i++)
+ {
+ memset(this->m_OutputLevel[i], 0, CConfig::MaxChunkSize * sizeof(float32_t));
+ this->mixing_console_->setInputSampleBuffer(i, this->m_OutputLevel[i]);
+ }
+
+ // Tube parameters
+ this->SetParameter(TParameter::ParameterFXTubeEnable, 1);
+ this->SetParameter(TParameter::ParameterFXTubeOverdrive, 25);
+
+ // Chorus parameters
+ this->SetParameter(TParameter::ParameterFXChorusEnable, 1);
+ this->SetParameter(TParameter::ParameterFXChorusRate, 50);
+ this->SetParameter(TParameter::ParameterFXChorusDepth, 50);
+
+ // Flanger parameters
+ this->SetParameter(TParameter::ParameterFXFlangerEnable, 1);
+ this->SetParameter(TParameter::ParameterFXFlangerRate, 3);
+ this->SetParameter(TParameter::ParameterFXFlangerDepth, 75);
+ this->SetParameter(TParameter::ParameterFXFlangerFeedback, 50);
+
+ // Orbitone parameters
+ this->SetParameter(TParameter::ParameterFXOrbitoneEnable, 1);
+ this->SetParameter(TParameter::ParameterFXOrbitoneRate, 40);
+ this->SetParameter(TParameter::ParameterFXOrbitoneDepth, 50);
+
+ // Phaser parameters
+ this->SetParameter(TParameter::ParameterFXPhaserEnable, 1);
+ this->SetParameter(TParameter::ParameterFXPhaserRate, 5);
+ this->SetParameter(TParameter::ParameterFXPhaserDepth, 99);
+ this->SetParameter(TParameter::ParameterFXPhaserFeedback, 50);
+ this->SetParameter(TParameter::ParameterFXPhaserNbStages, 12);
+
+ // Delay parameters
+ this->SetParameter(TParameter::ParameterFXDelayEnable, 1);
+ this->SetParameter(TParameter::ParameterFXDelayLeftDelayTime, 15);
+ this->SetParameter(TParameter::ParameterFXDelayRightDelayTime, 22);
+ this->SetParameter(TParameter::ParameterFXDelayFeedback, 35);
+
+ // AudioEffectPlateReverb parameters
+ this->SetParameter(TParameter::ParameterReverbEnable, 1);
+ this->SetParameter(TParameter::ParameterReverbSize, 70);
+ this->SetParameter(TParameter::ParameterReverbHighDamp, 50);
+ this->SetParameter(TParameter::ParameterReverbLowDamp, 50);
+ this->SetParameter(TParameter::ParameterReverbLowPass, 30);
+ this->SetParameter(TParameter::ParameterReverbDiffusion, 65);
+ this->SetParameter(TParameter::ParameterReverbLevel, 99);
+
+ // Reverberator parameters
+ this->SetParameter(TParameter::ParameterFXReverberatorEnable, 1);
+ this->SetParameter(TParameter::ParameterFXReverberatorInputGain, 99);
+ this->SetParameter(TParameter::ParameterFXReverberatorTime, 80);
+ this->SetParameter(TParameter::ParameterFXReverberatorDiffusion, 80);
+ this->SetParameter(TParameter::ParameterFXReverberatorLP, 70);
+
+ // Bypass
+ this->SetParameter(TParameter::ParameterFXBypass, 0);
+
+#elif defined(PLATE_REVERB_ENABLE)
// BEGIN setup tg_mixer
tg_mixer = new AudioStereoMixer(pConfig->GetChunkSize()/2);
@@ -148,73 +239,18 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
// BEGIN setup reverb
reverb_send_mixer = new AudioStereoMixer(pConfig->GetChunkSize()/2);
reverb = new AudioEffectPlateReverb(pConfig->GetSampleRate());
- SetParameter (ParameterReverbEnable, 1);
- SetParameter (ParameterReverbSize, 70);
- SetParameter (ParameterReverbHighDamp, 50);
- SetParameter (ParameterReverbLowDamp, 50);
- SetParameter (ParameterReverbLowPass, 30);
- SetParameter (ParameterReverbDiffusion, 65);
- SetParameter (ParameterReverbLevel, 99);
+ SetParameter (TParameter::ParameterReverbEnable, 1);
+ SetParameter (TParameter::ParameterReverbSize, 70);
+ SetParameter (TParameter::ParameterReverbHighDamp, 50);
+ SetParameter (TParameter::ParameterReverbLowDamp, 50);
+ SetParameter (TParameter::ParameterReverbLowPass, 30);
+ SetParameter (TParameter::ParameterReverbDiffusion, 65);
+ SetParameter (TParameter::ParameterReverbLevel, 99);
// END setup reverb
- SetParameter (ParameterCompressorEnable, 1);
-
- // BEGIN setup FXRack
- #ifdef FXRACK_ENABLE
- this->fx_rack = new FXRack(static_cast(pConfig->GetSampleRate()));
-
- // FXChain parameters
- this->SetParameter(ParameterFXChainEnable, 1);
- this->SetParameter(ParameterFXChainWet, 99);
-
- // FXChain > Tube parameters
- this->SetParameter(ParameterFXChainTubeEnable, 1);
- this->SetParameter(ParameterFXChainTubeWet, 50);
- this->SetParameter(ParameterFXChainTubeOverdrive, 10);
+#endif
- // FXChain > Chorus parameters
- this->SetParameter(ParameterFXChainChorusEnable, 1);
- this->SetParameter(ParameterFXChainChorusWet, 50);
- this->SetParameter(ParameterFXChainChorusRate, 50);
- this->SetParameter(ParameterFXChainChorusDepth, 50);
-
- // FXChain > Flanger parameters
- this->SetParameter(ParameterFXChainFlangerEnable, 1);
- this->SetParameter(ParameterFXChainFlangerWet, 50);
- this->SetParameter(ParameterFXChainFlangerRate, 3);
- this->SetParameter(ParameterFXChainFlangerDepth, 75);
- this->SetParameter(ParameterFXChainFlangerFeedback, 50);
-
- // FXChain > Orbitone parameters
- this->SetParameter(ParameterFXChainOrbitoneEnable, 1);
- this->SetParameter(ParameterFXChainOrbitoneWet, 80);
- this->SetParameter(ParameterFXChainOrbitoneRate, 40);
- this->SetParameter(ParameterFXChainOrbitoneDepth, 50);
-
- // FXChain > Phaser parameters
- this->SetParameter(ParameterFXChainPhaserEnable, 1);
- this->SetParameter(ParameterFXChainPhaserWet, 50);
- this->SetParameter(ParameterFXChainPhaserRate, 5);
- this->SetParameter(ParameterFXChainPhaserDepth, 99);
- this->SetParameter(ParameterFXChainPhaserFeedback, 50);
- this->SetParameter(ParameterFXChainPhaserNbStages, 12);
-
- // 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);
- this->SetParameter(ParameterFXChainShimmerReverbWet, 70);
- this->SetParameter(ParameterFXChainShimmerReverbInputGain, 99);
- this->SetParameter(ParameterFXChainShimmerReverbTime, 80);
- this->SetParameter(ParameterFXChainShimmerReverbDiffusion, 80);
- this->SetParameter(ParameterFXChainShimmerReverbLP, 70);
- #endif
- // END setup FXRack
+ this->SetParameter (TParameter::ParameterCompressorEnable, 1);
};
bool CMiniDexed::Initialize (void)
@@ -252,10 +288,21 @@ bool CMiniDexed::Initialize (void)
m_pTG[i]->setBCController (99, 1, 0);
m_pTG[i]->setATController (99, 1, 0);
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->mixing_console_->reset();
+ this->mixing_console_->setPan(i, this->m_nPan[i] / 127.0f);
+
+ this->mixing_console_->setSendLevel(i, MixerOutput::FX_PlateReverb, this->m_nTGSendLevel[i][MixerOutput::FX_PlateReverb] / 99.0f);
+ this->mixing_console_->setSendLevel(i, MixerOutput::MainOutput, this->m_nTGSendLevel[i][MixerOutput::MainOutput] / 99.0f);
+ this->mixing_console_->setFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::MainOutput, this->m_nFXSendLevel[MixerOutput::FX_PlateReverb][MixerOutput::FX_PlateReverb] / 99.0f);
+
+#elif defined(PLATE_REVERB_ENABLE)
+
tg_mixer->pan(i,mapfloat(m_nPan[i],0,127,0.0f,1.0f));
tg_mixer->gain(i,1.0f);
reverb_send_mixer->pan(i,mapfloat(m_nPan[i],0,127,0.0f,1.0f));
reverb_send_mixer->gain(i,mapfloat(m_nReverbSend[i],0,99,0.0f,1.0f));
+#endif
}
if (m_PerformanceConfig.Load ())
@@ -281,24 +328,26 @@ bool CMiniDexed::Initialize (void)
return false;
}
-#ifndef ARM_ALLOW_MULTI_CORE
- m_pSoundDevice->SetWriteFormat (SoundFormatSigned16, 1); // 16-bit Mono
-#else
+#if defined(ARM_ALLOW_MULTI_CORE)
+
+
m_pSoundDevice->SetWriteFormat (SoundFormatSigned16, 2); // 16-bit Stereo
+#else
+ m_pSoundDevice->SetWriteFormat (SoundFormatSigned16, 1); // 16-bit Mono
#endif
m_nQueueSizeFrames = m_pSoundDevice->GetQueueSizeFrames ();
m_pSoundDevice->Start ();
-#ifdef ARM_ALLOW_MULTI_CORE
+#if defined(ARM_ALLOW_MULTI_CORE)
// start secondary cores
if (!CMultiCoreSupport::Initialize ())
{
return false;
}
#endif
-
+
return true;
}
@@ -411,6 +460,10 @@ void CMiniDexed::Run (unsigned nCore)
{
assert (m_pTG[nTG]);
m_pTG[nTG]->getSamples (m_OutputLevel[nTG],m_nFramesToProcess);
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->mixing_console_->preProcessInputSampleBuffer(nTG, this->m_nFramesToProcess);
+#endif
}
}
}
@@ -525,6 +578,10 @@ void CMiniDexed::SetVolume (unsigned nVolume, unsigned nTG)
assert (m_pTG[nTG]);
m_pTG[nTG]->setGain (nVolume / 127.0f);
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->mixing_console_->setChannelLevel(nTG, nVolume == 0 ? 0.0f : 1.0f);
+#endif
+
m_UI.ParameterChanged ();
}
@@ -534,13 +591,52 @@ void CMiniDexed::SetPan (unsigned nPan, unsigned nTG)
assert (nTG < CConfig::ToneGenerators);
m_nPan[nTG] = nPan;
-
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->mixing_console_->setPan(nTG, nPan / 127.0f);
+
+#elif defined(PLATE_REVERB_ENABLE)
+
tg_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f));
reverb_send_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f));
+#endif
m_UI.ParameterChanged ();
}
+#if defined(MIXING_CONSOLE_ENABLE)
+
+unsigned CMiniDexed::getMixingConsoleSendLevel(unsigned nTG, MixerOutput fx) const
+{
+ assert (nTG < CConfig::ToneGenerators);
+ return this->m_nTGSendLevel[nTG][fx];
+}
+
+void CMiniDexed::setMixingConsoleSendLevel(unsigned nTG, MixerOutput fx, unsigned nFXSend)
+{
+ assert (nTG < CConfig::ToneGenerators);
+ nFXSend = constrain((int)nFXSend, 0, 99);
+
+ this->m_nTGSendLevel[nTG][fx] = nFXSend;
+ this->mixing_console_->setSendLevel(nTG, fx, nFXSend / 99.0f);
+
+ this->m_UI.ParameterChanged();
+}
+
+void CMiniDexed::setMixingConsoleFXSendLevel(MixerOutput fromFX, MixerOutput toFX, unsigned nFXSend)
+{
+ assert(fromFX < (MixerOutput::kFXCount - 1));
+ assert(toFX < MixerOutput::kFXCount);
+ if(fromFX != toFX)
+ {
+ nFXSend = constrain((int)nFXSend, 0, 99);
+ this->m_nFXSendLevel[fromFX][toFX] = nFXSend;
+ this->mixing_console_->setFXSendLevel(fromFX, toFX, nFXSend / 99.0f);
+ }
+}
+
+#elif defined(PLATE_REVERB_ENABLE)
+
void CMiniDexed::SetReverbSend (unsigned nReverbSend, unsigned nTG)
{
nReverbSend=constrain((int)nReverbSend,0,99);
@@ -553,6 +649,8 @@ void CMiniDexed::SetReverbSend (unsigned nReverbSend, unsigned nTG)
m_UI.ParameterChanged ();
}
+#endif
+
void CMiniDexed::SetMasterTune (int nMasterTune, unsigned nTG)
{
nMasterTune=constrain((int)nMasterTune,-99,99);
@@ -747,298 +845,688 @@ void CMiniDexed::ControllersRefresh (unsigned nTG)
void CMiniDexed::SetParameter (TParameter Parameter, int nValue)
{
- assert (reverb);
+
- assert (Parameter < ParameterUnknown);
+ assert(Parameter < TParameter::ParameterUnknown);
+
m_nParameter[Parameter] = nValue;
switch (Parameter)
{
- case ParameterCompressorEnable:
- for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
+ case TParameter::ParameterCompressorEnable:
+ for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; ++nTG)
{
- assert (m_pTG[nTG]);
+ assert(m_pTG[nTG]);
m_pTG[nTG]->setCompressor (!!nValue);
}
break;
- case ParameterReverbEnable:
- nValue=constrain((int)nValue,0,1);
- m_FXSpinLock.Acquire ();
- reverb->set_bypass (!nValue);
- m_FXSpinLock.Release ();
+#if defined(MIXING_CONSOLE_ENABLE)
+
+ // Tube parameters
+ case TParameter::ParameterFXTubeEnable:
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getTube()->setMute(!!!nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXTubeOverdrive:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getTube()->setOverdrive(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+
+ // Chorus parameters
+ case TParameter::ParameterFXChorusEnable:
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getChorus()->setMute(!!!nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXChorusRate:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getChorus()->setRate(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXChorusDepth:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getChorus()->setDepth(nValue / 9.9f);
+ this->m_FXSpinLock.Release();
+ break;
+
+ // Flanger parameters
+ case TParameter::ParameterFXFlangerEnable:
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getFlanger()->setMute(!!!nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXFlangerRate:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getFlanger()->setRate(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXFlangerDepth:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getFlanger()->setDepth(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXFlangerFeedback:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getFlanger()->setFeedback(mapfloat(nValue, 0, 99, 0.0f, 0.97f));
+ this->m_FXSpinLock.Release();
+ break;
+
+ // Orbitone parameters
+ case TParameter::ParameterFXOrbitoneEnable:
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getOrbitone()->setMute(!!!nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXOrbitoneRate:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getOrbitone()->setRate(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXOrbitoneDepth:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getOrbitone()->setDepth(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+
+ // Phaser parameters
+ case TParameter::ParameterFXPhaserEnable:
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getPhaser()->setMute(!!!nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaserRate:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getPhaser()->setRate(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaserDepth:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getPhaser()->setDepth(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaserFeedback:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getPhaser()->setFeedback(mapfloat(nValue, 0, 99, 0.0f, 0.97f));
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaserNbStages:
+ nValue = constrain((int)nValue, 2, MAX_NB_PHASES);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getPhaser()->setNbStages(nValue);
+ this->m_FXSpinLock.Release();
break;
- case ParameterReverbSize:
- nValue=constrain((int)nValue,0,99);
- m_FXSpinLock.Acquire ();
- reverb->size (nValue / 99.0f);
- m_FXSpinLock.Release ();
+ // Delay parameters
+ case TParameter::ParameterFXDelayEnable:
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getDelay()->setMute(!!!nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelayLeftDelayTime:
+ nValue = constrain((int)nValue, -99, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getDelay()->setLeftDelayTime(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelayRightDelayTime:
+ nValue = constrain((int)nValue, -99, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getDelay()->setRightDelayTime(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelayFeedback:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->getDelay()->setFeedback(nValue / 99.0f);
+ this->m_FXSpinLock.Release();
break;
- case ParameterReverbHighDamp:
+ // AudioEffectPlateReverb parameters
+ case TParameter::ParameterReverbEnable:
+ this->m_FXSpinLock.Acquire ();
+ this->mixing_console_->getPlateReverb()->set_bypass (!!!nValue);
+ this->m_FXSpinLock.Release ();
+ break;
+ case TParameter::ParameterReverbSize:
nValue=constrain((int)nValue,0,99);
- m_FXSpinLock.Acquire ();
- reverb->hidamp (nValue / 99.0f);
- m_FXSpinLock.Release ();
+ this->m_FXSpinLock.Acquire ();
+ this->mixing_console_->getPlateReverb()->size (nValue / 99.0f);
+ this->m_FXSpinLock.Release ();
break;
-
- case ParameterReverbLowDamp:
+ case TParameter::ParameterReverbHighDamp:
nValue=constrain((int)nValue,0,99);
- m_FXSpinLock.Acquire ();
- reverb->lodamp (nValue / 99.0f);
- m_FXSpinLock.Release ();
+ this->m_FXSpinLock.Acquire ();
+ this->mixing_console_->getPlateReverb()->hidamp (nValue / 99.0f);
+ this->m_FXSpinLock.Release ();
break;
-
- case ParameterReverbLowPass:
+ case TParameter::ParameterReverbLowDamp:
nValue=constrain((int)nValue,0,99);
- m_FXSpinLock.Acquire ();
- reverb->lowpass (nValue / 99.0f);
- m_FXSpinLock.Release ();
+ this->m_FXSpinLock.Acquire ();
+ this->mixing_console_->getPlateReverb()->lodamp (nValue / 99.0f);
+ this->m_FXSpinLock.Release ();
break;
-
- case ParameterReverbDiffusion:
+ case TParameter::ParameterReverbLowPass:
nValue=constrain((int)nValue,0,99);
- m_FXSpinLock.Acquire ();
- reverb->diffusion (nValue / 99.0f);
- m_FXSpinLock.Release ();
+ this->m_FXSpinLock.Acquire ();
+ this->mixing_console_->getPlateReverb()->lowpass (nValue / 99.0f);
+ this->m_FXSpinLock.Release ();
break;
-
- case ParameterReverbLevel:
+ case TParameter::ParameterReverbDiffusion:
nValue=constrain((int)nValue,0,99);
- m_FXSpinLock.Acquire ();
- reverb->level (nValue / 99.0f);
- m_FXSpinLock.Release ();
+ this->m_FXSpinLock.Acquire ();
+ this->mixing_console_->getPlateReverb()->diffusion (nValue / 99.0f);
+ this->m_FXSpinLock.Release ();
+ break;
+ case TParameter::ParameterReverbLevel:
+ nValue=constrain((int)nValue,0,99);
+ this->m_FXSpinLock.Acquire ();
+ this->mixing_console_->getPlateReverb()->level (nValue / 99.0f);
+ this->m_FXSpinLock.Release ();
break;
- // BEGIN FXChain parameters
- #ifdef FXRACK_ENABLE
- case ParameterFXChainEnable:
- nValue = constrain((int)nValue, 0, 1);
+ // Reverberator parameters
+ case TParameter::ParameterFXReverberatorEnable:
this->m_FXSpinLock.Acquire();
- this->fx_rack->setEnable(!!nValue);
+ this->mixing_console_->getReverberator()->setMute(!!!nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainWet:
+ case TParameter::ParameterFXReverberatorInputGain:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->setWetLevel(nValue / 99.0f);
+ this->mixing_console_->getReverberator()->setInputGain(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
-
- // FXChain > Tube parameters
- case ParameterFXChainTubeEnable:
- nValue = constrain((int)nValue, 0, 1);
+ case TParameter::ParameterFXReverberatorTime:
+ nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getTube()->setEnable(!!nValue);
+ this->mixing_console_->getReverberator()->setTime(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainTubeWet:
+ case TParameter::ParameterFXReverberatorDiffusion:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getTube()->setWetLevel(nValue / 99.0f);
+ this->mixing_console_->getReverberator()->setDiffusion(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainTubeOverdrive:
+ case TParameter::ParameterFXReverberatorLP:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getTube()->setOverdrive(nValue / 99.0f);
+ this->mixing_console_->getReverberator()->setLP(nValue / 99.0f);
this->m_FXSpinLock.Release();
break;
-
- // FXChain > Chorus parameters
- case ParameterFXChainChorusEnable:
- nValue = constrain((int)nValue, 0, 1);
+
+ // Tube Send parameters
+ case TParameter::ParameterFXTube_ChorusSend:
+ nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getChorus()->setEnable(!!nValue);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Chorus, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainChorusWet:
+ case TParameter::ParameterFXTube_FlangerSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getChorus()->setWetLevel(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Flanger, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainChorusRate:
+ case TParameter::ParameterFXTube_OrbitoneSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getChorus()->setRate(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Orbitone, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainChorusDepth:
+ case TParameter::ParameterFXTube_PhaserSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getChorus()->setDepth(nValue / 9.9f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Phaser, nValue);
this->m_FXSpinLock.Release();
break;
-
- // FXChain > Flanger parameters
- case ParameterFXChainFlangerEnable:
- nValue = constrain((int)nValue, 0, 1);
+ case TParameter::ParameterFXTube_DelaySend:
+ nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getFlanger()->setEnable(!!nValue);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Delay, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainFlangerWet:
+ case TParameter::ParameterFXTube_PlateReverbSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getFlanger()->setWetLevel(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_PlateReverb, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainFlangerRate:
+ case TParameter::ParameterFXTube_ReverberatorSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getFlanger()->setRate(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Reverberator, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainFlangerDepth:
+ case TParameter::ParameterFXTube_MainOutput:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getFlanger()->setDepth(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainFlangerFeedback:
+
+ // Chorus Send parameters
+ case TParameter::ParameterFXChorus_TubeSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getFlanger()->setFeedback(mapfloat(nValue, 0, 99, 0.0f, 0.97f));
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Tube, nValue);
this->m_FXSpinLock.Release();
break;
-
- // FXChain > Orbitone parameters
- case ParameterFXChainOrbitoneEnable:
- nValue = constrain((int)nValue, 0, 1);
+ case TParameter::ParameterFXChorus_FlangerSend:
+ nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getOrbitone()->setEnable(!!nValue);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Flanger, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainOrbitoneWet:
+ case TParameter::ParameterFXChorus_OrbitoneSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getOrbitone()->setWetLevel(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Orbitone, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainOrbitoneRate:
+ case TParameter::ParameterFXChorus_PhaserSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getOrbitone()->setRate(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Phaser, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainOrbitoneDepth:
+ case TParameter::ParameterFXChorus_DelaySend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getOrbitone()->setDepth(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Delay, nValue);
this->m_FXSpinLock.Release();
break;
-
- // FXChain > Phaser parameters
- case ParameterFXChainPhaserEnable:
- nValue = constrain((int)nValue, 0, 1);
+ case TParameter::ParameterFXChorus_PlateReverbSend:
+ nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getPhaser()->setEnable(!!nValue);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_PlateReverb, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainPhaserWet:
+ case TParameter::ParameterFXChorus_ReverberatorSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getPhaser()->setWetLevel(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Reverberator, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainPhaserRate:
+ case TParameter::ParameterFXChorus_MainOutput:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getPhaser()->setRate(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::MainOutput, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainPhaserDepth:
+
+ // Flanger Send parameters
+ case TParameter::ParameterFXFlanger_TubeSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getPhaser()->setDepth(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Tube, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainPhaserFeedback:
+ case TParameter::ParameterFXFlanger_ChorusSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getPhaser()->setFeedback(mapfloat(nValue, 0, 99, 0.0f, 0.97f));
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Chorus, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainPhaserNbStages:
- nValue = constrain((int)nValue, 2, MAX_NB_PHASES);
+ case TParameter::ParameterFXFlanger_OrbitoneSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Orbitone, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXFlanger_PhaserSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Phaser, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXFlanger_DelaySend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Delay, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXFlanger_PlateReverbSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_PlateReverb, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXFlanger_ReverberatorSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Reverberator, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXFlanger_MainOutput:
+ nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getPhaser()->setNbStages(nValue);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::MainOutput, nValue);
this->m_FXSpinLock.Release();
break;
- // FXChain > Delay parameters
- case ParameterFXChainDelayEnable:
- nValue = constrain((int)nValue, 0, 1);
+ // Orbitone Send parameters
+ case TParameter::ParameterFXOrbitone_TubeSend:
+ nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getDelay()->setEnable(!!nValue);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Tube, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainDelayWet:
+ case TParameter::ParameterFXOrbitone_ChorusSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getDelay()->setWetLevel(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Chorus, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainDelayLeftDelayTime:
+ case TParameter::ParameterFXOrbitone_FlangerSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getDelay()->setLeftDelayTime(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Flanger, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainDelayRightDelayTime:
+ case TParameter::ParameterFXOrbitone_PhaserSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getDelay()->setRightDelayTime(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Phaser, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainDelayFeedback:
+ case TParameter::ParameterFXOrbitone_DelaySend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getDelay()->setFeedback(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Delay, nValue);
this->m_FXSpinLock.Release();
break;
-
- // FXChain > ShimmerReverb parameters
- case ParameterFXChainShimmerReverbEnable:
- nValue = constrain((int)nValue, 0, 1);
+ case TParameter::ParameterFXOrbitone_PlateReverbSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_PlateReverb, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXOrbitone_ReverberatorSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Reverberator, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXOrbitone_MainOutput:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::MainOutput, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+
+ // Phaser Send parameters
+ case TParameter::ParameterFXPhaser_TubeSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Tube, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaser_ChorusSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Chorus, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaser_FlangerSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Flanger, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaser_OrbitoneSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Orbitone, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaser_DelaySend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Delay, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaser_PlateReverbSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_PlateReverb, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaser_ReverberatorSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Reverberator, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPhaser_MainOutput:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::MainOutput, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+
+ // Delay Send parameters
+ case TParameter::ParameterFXDelay_TubeSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Tube, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelay_ChorusSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Chorus, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelay_FlangerSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Flanger, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelay_OrbitoneSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Orbitone, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelay_PhaserSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Phaser, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelay_PlateReverbSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_PlateReverb, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelay_ReverberatorSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Reverberator, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXDelay_MainOutput:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Delay, MixerOutput::MainOutput, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+
+ // Reverb Send parameters
+ case TParameter::ParameterFXPlateReverb_TubeSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Tube, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPlateReverb_ChorusSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Chorus, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPlateReverb_FlangerSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Flanger, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPlateReverb_OrbitoneSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Orbitone, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPlateReverb_PhaserSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Phaser, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPlateReverb_DelaySend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Delay, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPlateReverb_ReverberatorSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Reverberator, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXPlateReverb_MainOutput:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::MainOutput, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+
+ // Reverberator Send parameters
+ case TParameter::ParameterFXReverberator_TubeSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Tube, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXReverberator_ChorusSend:
+ nValue = constrain((int)nValue, 0, 99);
+ this->m_FXSpinLock.Acquire();
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Chorus, nValue);
+ this->m_FXSpinLock.Release();
+ break;
+ case TParameter::ParameterFXReverberator_FlangerSend:
+ nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getReverberator()->setEnable(!!nValue);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Flanger, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainShimmerReverbWet:
+ case TParameter::ParameterFXReverberator_OrbitoneSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getReverberator()->setWetLevel(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Orbitone, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainShimmerReverbInputGain:
+ case TParameter::ParameterFXReverberator_PhaserSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getReverberator()->setInputGain(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Phaser, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainShimmerReverbTime:
+ case TParameter::ParameterFXReverberator_DelaySend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getReverberator()->setTime(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Delay, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainShimmerReverbDiffusion:
+ case TParameter::ParameterFXReverberator_PlateReverbSend:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getReverberator()->setDiffusion(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_PlateReverb, nValue);
this->m_FXSpinLock.Release();
break;
- case ParameterFXChainShimmerReverbLP:
+ case TParameter::ParameterFXReverberator_MainOutput:
nValue = constrain((int)nValue, 0, 99);
this->m_FXSpinLock.Acquire();
- this->fx_rack->getReverberator()->setLP(nValue / 99.0f);
+ this->setMixingConsoleFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, nValue);
this->m_FXSpinLock.Release();
break;
- #endif
- // END FXChain parameters
+
+ case TParameter::ParameterFXBypass:
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->bypass(!!nValue);
+ this->m_FXSpinLock.Release();
+ break;
+
+#elif defined(PLATE_REVERB_ENABLE)
+
+ case TParameter::ParameterReverbEnable:
+ nValue=constrain((int)nValue,0,1);
+ m_FXSpinLock.Acquire ();
+ reverb->set_bypass (!nValue);
+ m_FXSpinLock.Release ();
+ break;
+
+ case TParameter::ParameterReverbSize:
+ nValue=constrain((int)nValue,0,99);
+ m_FXSpinLock.Acquire ();
+ reverb->size (nValue / 99.0f);
+ m_FXSpinLock.Release ();
+ break;
+
+ case TParameter::ParameterReverbHighDamp:
+ nValue=constrain((int)nValue,0,99);
+ m_FXSpinLock.Acquire ();
+ reverb->hidamp (nValue / 99.0f);
+ m_FXSpinLock.Release ();
+ break;
+
+ case TParameter::ParameterReverbLowDamp:
+ nValue=constrain((int)nValue,0,99);
+ m_FXSpinLock.Acquire ();
+ reverb->lodamp (nValue / 99.0f);
+ m_FXSpinLock.Release ();
+ break;
+
+ case TParameter::ParameterReverbLowPass:
+ nValue=constrain((int)nValue,0,99);
+ m_FXSpinLock.Acquire ();
+ reverb->lowpass (nValue / 99.0f);
+ m_FXSpinLock.Release ();
+ break;
+
+ case TParameter::ParameterReverbDiffusion:
+ nValue=constrain((int)nValue,0,99);
+ m_FXSpinLock.Acquire ();
+ reverb->diffusion (nValue / 99.0f);
+ m_FXSpinLock.Release ();
+ break;
+
+ case TParameter::ParameterReverbLevel:
+ nValue=constrain((int)nValue,0,99);
+ m_FXSpinLock.Acquire ();
+ reverb->level (nValue / 99.0f);
+ m_FXSpinLock.Release ();
+ break;
+
+#endif
default:
assert (0);
@@ -1048,7 +1536,8 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue)
int CMiniDexed::GetParameter (TParameter Parameter)
{
- assert (Parameter < ParameterUnknown);
+ assert(Parameter < TParameter::ParameterUnknown);
+
return m_nParameter[Parameter];
}
@@ -1058,53 +1547,67 @@ void CMiniDexed::SetTGParameter (TTGParameter Parameter, int nValue, unsigned nT
switch (Parameter)
{
- case TGParameterVoiceBank: BankSelect (nValue, nTG); break;
- case TGParameterVoiceBankMSB: BankSelectMSB (nValue, nTG); break;
- case TGParameterVoiceBankLSB: BankSelectLSB (nValue, nTG); break;
- case TGParameterProgram: ProgramChange (nValue, nTG); break;
- case TGParameterVolume: SetVolume (nValue, nTG); break;
- case TGParameterPan: SetPan (nValue, nTG); break;
- case TGParameterMasterTune: SetMasterTune (nValue, nTG); break;
- case TGParameterCutoff: SetCutoff (nValue, nTG); break;
- case TGParameterResonance: SetResonance (nValue, nTG); break;
- case TGParameterPitchBendRange: setPitchbendRange (nValue, nTG); break;
- case TGParameterPitchBendStep: setPitchbendStep (nValue, nTG); break;
- case TGParameterPortamentoMode: setPortamentoMode (nValue, nTG); break;
- case TGParameterPortamentoGlissando: setPortamentoGlissando (nValue, nTG); break;
- case TGParameterPortamentoTime: setPortamentoTime (nValue, nTG); break;
- case TGParameterMonoMode: setMonoMode (nValue , nTG); break;
+ case TTGParameter::TGParameterVoiceBank: this->BankSelect (nValue, nTG); break;
+ case TTGParameter::TGParameterVoiceBankMSB: this->BankSelectMSB (nValue, nTG); break;
+ case TTGParameter::TGParameterVoiceBankLSB: this->BankSelectLSB (nValue, nTG); break;
+ case TTGParameter::TGParameterProgram: this->ProgramChange (nValue, nTG); break;
+ case TTGParameter::TGParameterVolume: this->SetVolume (nValue, nTG); break;
+ case TTGParameter::TGParameterPan: this->SetPan (nValue, nTG); break;
+ case TTGParameter::TGParameterMasterTune: this->SetMasterTune (nValue, nTG); break;
+ case TTGParameter::TGParameterCutoff: this->SetCutoff (nValue, nTG); break;
+ case TTGParameter::TGParameterResonance: this->SetResonance (nValue, nTG); break;
+ case TTGParameter::TGParameterPitchBendRange: this->setPitchbendRange (nValue, nTG); break;
+ case TTGParameter::TGParameterPitchBendStep: this->setPitchbendStep (nValue, nTG); break;
+ case TTGParameter::TGParameterPortamentoMode: this->setPortamentoMode (nValue, nTG); break;
+ case TTGParameter::TGParameterPortamentoGlissando: this->setPortamentoGlissando (nValue, nTG); break;
+ case TTGParameter::TGParameterPortamentoTime: this->setPortamentoTime (nValue, nTG); break;
+ case TTGParameter::TGParameterMonoMode: this->setMonoMode (nValue , nTG); break;
- case TGParameterMWRange: setModController(0, 0, nValue, nTG); break;
- case TGParameterMWPitch: setModController(0, 1, nValue, nTG); break;
- case TGParameterMWAmplitude: setModController(0, 2, nValue, nTG); break;
- case TGParameterMWEGBias: setModController(0, 3, nValue, nTG); break;
+ case TTGParameter::TGParameterMWRange: this->setModController(0, 0, nValue, nTG); break;
+ case TTGParameter::TGParameterMWPitch: this->setModController(0, 1, nValue, nTG); break;
+ case TTGParameter::TGParameterMWAmplitude: this->setModController(0, 2, nValue, nTG); break;
+ case TTGParameter::TGParameterMWEGBias: this->setModController(0, 3, nValue, nTG); break;
- case TGParameterFCRange: setModController(1, 0, nValue, nTG); break;
- case TGParameterFCPitch: setModController(1, 1, nValue, nTG); break;
- case TGParameterFCAmplitude: setModController(1, 2, nValue, nTG); break;
- case TGParameterFCEGBias: setModController(1, 3, nValue, nTG); break;
+ case TTGParameter::TGParameterFCRange: this->setModController(1, 0, nValue, nTG); break;
+ case TTGParameter::TGParameterFCPitch: this->setModController(1, 1, nValue, nTG); break;
+ case TTGParameter::TGParameterFCAmplitude: this->setModController(1, 2, nValue, nTG); break;
+ case TTGParameter::TGParameterFCEGBias: this->setModController(1, 3, nValue, nTG); break;
- case TGParameterBCRange: setModController(2, 0, nValue, nTG); break;
- case TGParameterBCPitch: setModController(2, 1, nValue, nTG); break;
- case TGParameterBCAmplitude: setModController(2, 2, nValue, nTG); break;
- case TGParameterBCEGBias: setModController(2, 3, nValue, nTG); break;
+ case TTGParameter::TGParameterBCRange: this->setModController(2, 0, nValue, nTG); break;
+ case TTGParameter::TGParameterBCPitch: this->setModController(2, 1, nValue, nTG); break;
+ case TTGParameter::TGParameterBCAmplitude: this->setModController(2, 2, nValue, nTG); break;
+ case TTGParameter::TGParameterBCEGBias: this->setModController(2, 3, nValue, nTG); break;
- case TGParameterATRange: setModController(3, 0, nValue, nTG); break;
- case TGParameterATPitch: setModController(3, 1, nValue, nTG); break;
- case TGParameterATAmplitude: setModController(3, 2, nValue, nTG); break;
- case TGParameterATEGBias: setModController(3, 3, nValue, nTG); break;
+ case TTGParameter::TGParameterATRange: this->setModController(3, 0, nValue, nTG); break;
+ case TTGParameter::TGParameterATPitch: this->setModController(3, 1, nValue, nTG); break;
+ case TTGParameter::TGParameterATAmplitude: this->setModController(3, 2, nValue, nTG); break;
+ case TTGParameter::TGParameterATEGBias: this->setModController(3, 3, nValue, nTG); break;
- case TGParameterMIDIChannel:
+ case TTGParameter::TGParameterMIDIChannel:
assert (0 <= nValue && nValue <= 255);
SetMIDIChannel ((uint8_t) nValue, nTG);
break;
- case TGParameterReverbSend: SetReverbSend (nValue, nTG); break;
+#if defined(MIXING_CONSOLE_ENABLE)
+ case TTGParameter::TGParameterMixingSendFXTube: this->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Tube, nValue); break;
+ case TTGParameter::TGParameterMixingSendFXChorus: this->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Chorus, nValue); break;
+ case TTGParameter::TGParameterMixingSendFXFlanger: this->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Flanger, nValue); break;
+ case TTGParameter::TGParameterMixingSendFXOrbitone: this->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Orbitone, nValue); break;
+ case TTGParameter::TGParameterMixingSendFXPhaser: this->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Phaser, nValue); break;
+ case TTGParameter::TGParameterMixingSendFXDelay: this->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Delay, nValue); break;
+ case TTGParameter::TGParameterMixingSendFXPlateReverb: this->setMixingConsoleSendLevel(nTG, MixerOutput::FX_PlateReverb, nValue); break;
+ case TTGParameter::TGParameterMixingSendFXReverberator: this->setMixingConsoleSendLevel(nTG, MixerOutput::FX_Reverberator, nValue); break;
+ case TTGParameter::TGParameterMixingSendFXMainOutput: this->setMixingConsoleSendLevel(nTG, MixerOutput::MainOutput, nValue); break;
+#elif defined(PLATE_REVERB_ENABLE)
+ case TTGParameter::TGParameterReverbSend: this->SetReverbSend (nValue, nTG); break;
+#endif // MIXING_CONSOLE_ENABLE
default:
assert (0);
break;
}
+
+ this->m_UI.ParameterChanged();
}
int CMiniDexed::GetTGParameter (TTGParameter Parameter, unsigned nTG)
@@ -1113,45 +1616,56 @@ int CMiniDexed::GetTGParameter (TTGParameter Parameter, unsigned nTG)
switch (Parameter)
{
- case TGParameterVoiceBank: return m_nVoiceBankID[nTG];
- case TGParameterVoiceBankMSB: return m_nVoiceBankID[nTG] >> 7;
- case TGParameterVoiceBankLSB: return m_nVoiceBankID[nTG] & 0x7F;
- case TGParameterProgram: return m_nProgram[nTG];
- case TGParameterVolume: return m_nVolume[nTG];
- case TGParameterPan: return m_nPan[nTG];
- case TGParameterMasterTune: return m_nMasterTune[nTG];
- case TGParameterCutoff: return m_nCutoff[nTG];
- case TGParameterResonance: return m_nResonance[nTG];
- case TGParameterMIDIChannel: return m_nMIDIChannel[nTG];
- case TGParameterReverbSend: return m_nReverbSend[nTG];
- case TGParameterPitchBendRange: return m_nPitchBendRange[nTG];
- case TGParameterPitchBendStep: return m_nPitchBendStep[nTG];
- case TGParameterPortamentoMode: return m_nPortamentoMode[nTG];
- case TGParameterPortamentoGlissando: return m_nPortamentoGlissando[nTG];
- case TGParameterPortamentoTime: return m_nPortamentoTime[nTG];
- case TGParameterMonoMode: return m_bMonoMode[nTG] ? 1 : 0;
-
- case TGParameterMWRange: return getModController(0, 0, nTG);
- case TGParameterMWPitch: return getModController(0, 1, nTG);
- case TGParameterMWAmplitude: return getModController(0, 2, nTG);
- case TGParameterMWEGBias: return getModController(0, 3, nTG);
-
- case TGParameterFCRange: return getModController(1, 0, nTG);
- case TGParameterFCPitch: return getModController(1, 1, nTG);
- case TGParameterFCAmplitude: return getModController(1, 2, nTG);
- case TGParameterFCEGBias: return getModController(1, 3, nTG);
+ case TTGParameter::TGParameterVoiceBank: return m_nVoiceBankID[nTG];
+ case TTGParameter::TGParameterVoiceBankMSB: return m_nVoiceBankID[nTG] >> 7;
+ case TTGParameter::TGParameterVoiceBankLSB: return m_nVoiceBankID[nTG] & 0x7F;
+ case TTGParameter::TGParameterProgram: return m_nProgram[nTG];
+ case TTGParameter::TGParameterVolume: return m_nVolume[nTG];
+ case TTGParameter::TGParameterPan: return m_nPan[nTG];
+ case TTGParameter::TGParameterMasterTune: return m_nMasterTune[nTG];
+ case TTGParameter::TGParameterCutoff: return m_nCutoff[nTG];
+ case TTGParameter::TGParameterResonance: return m_nResonance[nTG];
+ case TTGParameter::TGParameterMIDIChannel: return m_nMIDIChannel[nTG];
+#if defined(MIXING_CONSOLE_ENABLE)
+ case TTGParameter::TGParameterMixingSendFXTube: return this->getMixingConsoleSendLevel(nTG, MixerOutput::FX_Tube);
+ case TTGParameter::TGParameterMixingSendFXChorus: return this->getMixingConsoleSendLevel(nTG, MixerOutput::FX_Chorus);
+ case TTGParameter::TGParameterMixingSendFXFlanger: return this->getMixingConsoleSendLevel(nTG, MixerOutput::FX_Flanger);
+ case TTGParameter::TGParameterMixingSendFXOrbitone: return this->getMixingConsoleSendLevel(nTG, MixerOutput::FX_Orbitone);
+ case TTGParameter::TGParameterMixingSendFXPhaser: return this->getMixingConsoleSendLevel(nTG, MixerOutput::FX_Phaser);
+ case TTGParameter::TGParameterMixingSendFXDelay: return this->getMixingConsoleSendLevel(nTG, MixerOutput::FX_Delay);
+ case TTGParameter::TGParameterMixingSendFXPlateReverb: return this->getMixingConsoleSendLevel(nTG, MixerOutput::FX_PlateReverb);
+ case TTGParameter::TGParameterMixingSendFXReverberator: return this->getMixingConsoleSendLevel(nTG, MixerOutput::FX_Reverberator);
+ case TTGParameter::TGParameterMixingSendFXMainOutput: return this->getMixingConsoleSendLevel(nTG, MixerOutput::MainOutput);
+#elif defined(PLATE_REVERB_ENABLE)
+ case TTGParameter::TGParameterReverbSend: return m_nReverbSend[nTG];
+#endif
+ case TTGParameter::TGParameterPitchBendRange: return m_nPitchBendRange[nTG];
+ case TTGParameter::TGParameterPitchBendStep: return m_nPitchBendStep[nTG];
+ case TTGParameter::TGParameterPortamentoMode: return m_nPortamentoMode[nTG];
+ case TTGParameter::TGParameterPortamentoGlissando: return m_nPortamentoGlissando[nTG];
+ case TTGParameter::TGParameterPortamentoTime: return m_nPortamentoTime[nTG];
+ case TTGParameter::TGParameterMonoMode: return m_bMonoMode[nTG] ? 1 : 0;
- case TGParameterBCRange: return getModController(2, 0, nTG);
- case TGParameterBCPitch: return getModController(2, 1, nTG);
- case TGParameterBCAmplitude: return getModController(2, 2, nTG);
- case TGParameterBCEGBias: return getModController(2, 3, nTG);
+ case TTGParameter::TGParameterMWRange: return getModController(0, 0, nTG);
+ case TTGParameter::TGParameterMWPitch: return getModController(0, 1, nTG);
+ case TTGParameter::TGParameterMWAmplitude: return getModController(0, 2, nTG);
+ case TTGParameter::TGParameterMWEGBias: return getModController(0, 3, nTG);
- case TGParameterATRange: return getModController(3, 0, nTG);
- case TGParameterATPitch: return getModController(3, 1, nTG);
- case TGParameterATAmplitude: return getModController(3, 2, nTG);
- case TGParameterATEGBias: return getModController(3, 3, nTG);
+ case TTGParameter::TGParameterFCRange: return getModController(1, 0, nTG);
+ case TTGParameter::TGParameterFCPitch: return getModController(1, 1, nTG);
+ case TTGParameter::TGParameterFCAmplitude: return getModController(1, 2, nTG);
+ case TTGParameter::TGParameterFCEGBias: return getModController(1, 3, nTG);
+ case TTGParameter::TGParameterBCRange: return getModController(2, 0, nTG);
+ case TTGParameter::TGParameterBCPitch: return getModController(2, 1, nTG);
+ case TTGParameter::TGParameterBCAmplitude: return getModController(2, 2, nTG);
+ case TTGParameter::TGParameterBCEGBias: return getModController(2, 3, nTG);
+ case TTGParameter::TGParameterATRange: return getModController(3, 0, nTG);
+ case TTGParameter::TGParameterATPitch: return getModController(3, 1, nTG);
+ case TTGParameter::TGParameterATAmplitude: return getModController(3, 2, nTG);
+ case TTGParameter::TGParameterATEGBias: return getModController(3, 3, nTG);
+
default:
assert (0);
return 0;
@@ -1289,6 +1803,10 @@ void CMiniDexed::ProcessSound (void)
{
assert (m_pTG[i]);
m_pTG[i]->getSamples (m_OutputLevel[i], nFrames);
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->mixing_console_->preProcessInputSampleBuffer(i, nFrames);
+#endif
}
// wait for cores 2 and 3 to complete their work
@@ -1302,17 +1820,40 @@ void CMiniDexed::ProcessSound (void)
//
// Audio signal path after tone generators starts here
- //
+ int16_t tmp_int[nFrames * 2];
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ // BEGIN mixing
+ if(this->nMasterVolume > 0.0f)
+ {
+ // temp buffering and channel indexing
+ float32_t interlacedSampleBuffer[nFrames << 1];
- assert (CConfig::ToneGenerators == 8);
+ this->m_FXSpinLock.Acquire();
+ this->mixing_console_->process(interlacedSampleBuffer);
+ this->m_FXSpinLock.Release();
+
+ if(this->nMasterVolume < 1.0f)
+ {
+ arm_scale_f32(interlacedSampleBuffer, this->nMasterVolume, interlacedSampleBuffer, nFrames << 1);
+ }
+
+ // 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
+ {
+ arm_fill_q15(0, tmp_int, nFrames << 1);
+ }
+
+#elif defined(PLATE_REVERB_ENABLE)
uint8_t indexL=0, indexR=1;
// BEGIN TG mixing
float32_t tmp_float[nFrames*2];
- int16_t tmp_int[nFrames*2];
- if(nMasterVolume > 0.0)
+ if(nMasterVolume > 0.0f)
{
for (uint8_t i = 0; i < CConfig::ToneGenerators; i++)
{
@@ -1355,19 +1896,6 @@ void CMiniDexed::ProcessSound (void)
}
// END adding reverb
- // BEGIN adding FXRack
- #ifdef FXRACK_ENABLE
- if(this->fx_rack->isEnable() && this->fx_rack->getWetLevel() > 0.0f)
- {
- this->m_FXSpinLock.Acquire();
-
- this->fx_rack->process(SampleBuffer[indexL], SampleBuffer[indexR], SampleBuffer[indexL], SampleBuffer[indexR], nFrames);
-
- this->m_FXSpinLock.Release();
- }
- #endif
- // END adding FXRack
-
// swap stereo channels if needed prior to writing back out
if (m_bChannelsSwapped)
{
@@ -1393,15 +1921,16 @@ void CMiniDexed::ProcessSound (void)
}
else
arm_fill_q15(0, tmp_int, nFrames * 2);
+#endif
- if (m_pSoundDevice->Write (tmp_int, sizeof(tmp_int)) != (int) sizeof(tmp_int))
+ if(this->m_pSoundDevice->Write(tmp_int, sizeof(tmp_int)) != (int)sizeof(tmp_int))
{
LOGERR ("Sound data dropped");
}
- if (m_bProfileEnabled)
+ if(this->m_bProfileEnabled)
{
- m_GetChunkTimer.Stop ();
+ this->m_GetChunkTimer.Stop ();
}
}
}
@@ -1449,58 +1978,139 @@ bool CMiniDexed::DoSavePerformance (void)
m_PerformanceConfig.SetBreathControlTarget (m_nBreathControlTarget[nTG], nTG);
m_PerformanceConfig.SetAftertouchRange (m_nAftertouchRange[nTG], nTG);
m_PerformanceConfig.SetAftertouchTarget (m_nAftertouchTarget[nTG], nTG);
-
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ for(size_t fx = 0; fx < MixerOutput::kFXCount; ++fx)
+ {
+ this->m_PerformanceConfig.SetTGSendLevel(nTG, static_cast(fx), this->m_nTGSendLevel[nTG][fx]);
+ }
+#endif
+
+#if defined(PLATE_REVERB_ENABLE)
m_PerformanceConfig.SetReverbSend (m_nReverbSend[nTG], nTG);
+#endif
}
- m_PerformanceConfig.SetCompressorEnable (!!m_nParameter[ParameterCompressorEnable]);
- m_PerformanceConfig.SetReverbEnable (!!m_nParameter[ParameterReverbEnable]);
- m_PerformanceConfig.SetReverbSize (m_nParameter[ParameterReverbSize]);
- m_PerformanceConfig.SetReverbHighDamp (m_nParameter[ParameterReverbHighDamp]);
- m_PerformanceConfig.SetReverbLowDamp (m_nParameter[ParameterReverbLowDamp]);
- m_PerformanceConfig.SetReverbLowPass (m_nParameter[ParameterReverbLowPass]);
- m_PerformanceConfig.SetReverbDiffusion (m_nParameter[ParameterReverbDiffusion]);
- m_PerformanceConfig.SetReverbLevel (m_nParameter[ParameterReverbLevel]);
-
- // BEGIN FXRack parameters
- #ifdef FXRACK_ENABLE
- this->m_PerformanceConfig.SetFXChainEnable(!!this->m_nParameter[ParameterFXChainEnable]);
- this->m_PerformanceConfig.SetFXChainWet(this->m_nParameter[ParameterFXChainWet]);
- this->m_PerformanceConfig.SetFXChainTubeEnable(!!this->m_nParameter[ParameterFXChainTubeEnable]);
- this->m_PerformanceConfig.SetFXChainTubeWet(this->m_nParameter[ParameterFXChainTubeWet]);
- this->m_PerformanceConfig.SetFXChainTubeOverdrive(this->m_nParameter[ParameterFXChainTubeOverdrive]);
- this->m_PerformanceConfig.SetFXChainChorusEnable(!!this->m_nParameter[ParameterFXChainChorusEnable]);
- this->m_PerformanceConfig.SetFXChainChorusWet(this->m_nParameter[ParameterFXChainChorusWet]);
- this->m_PerformanceConfig.SetFXChainChorusRate(this->m_nParameter[ParameterFXChainChorusRate]);
- this->m_PerformanceConfig.SetFXChainChorusDepth(this->m_nParameter[ParameterFXChainChorusDepth]);
- this->m_PerformanceConfig.SetFXChainFlangerEnable(!!this->m_nParameter[ParameterFXChainFlangerEnable]);
- this->m_PerformanceConfig.SetFXChainFlangerWet(this->m_nParameter[ParameterFXChainFlangerWet]);
- this->m_PerformanceConfig.SetFXChainFlangerRate(this->m_nParameter[ParameterFXChainFlangerRate]);
- this->m_PerformanceConfig.SetFXChainFlangerDepth(this->m_nParameter[ParameterFXChainFlangerDepth]);
- this->m_PerformanceConfig.SetFXChainFlangerFeedback(this->m_nParameter[ParameterFXChainFlangerFeedback]);
- this->m_PerformanceConfig.SetFXChainOrbitoneEnable(!!this->m_nParameter[ParameterFXChainOrbitoneEnable]);
- this->m_PerformanceConfig.SetFXChainOrbitoneWet(this->m_nParameter[ParameterFXChainOrbitoneWet]);
- this->m_PerformanceConfig.SetFXChainOrbitoneRate(this->m_nParameter[ParameterFXChainOrbitoneRate]);
- this->m_PerformanceConfig.SetFXChainOrbitoneDepth(this->m_nParameter[ParameterFXChainOrbitoneDepth]);
- this->m_PerformanceConfig.SetFXChainPhaserEnable(!!this->m_nParameter[ParameterFXChainPhaserEnable]);
- this->m_PerformanceConfig.SetFXChainPhaserWet(this->m_nParameter[ParameterFXChainPhaserWet]);
- this->m_PerformanceConfig.SetFXChainPhaserRate(this->m_nParameter[ParameterFXChainPhaserRate]);
- this->m_PerformanceConfig.SetFXChainPhaserDepth(this->m_nParameter[ParameterFXChainPhaserDepth]);
- this->m_PerformanceConfig.SetFXChainPhaserFeedback(this->m_nParameter[ParameterFXChainPhaserFeedback]);
- this->m_PerformanceConfig.SetFXChainPhaserNbStages(this->m_nParameter[ParameterFXChainPhaserNbStages]);
- 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]);
- this->m_PerformanceConfig.SetFXChainShimmerReverbTime(this->m_nParameter[ParameterFXChainShimmerReverbTime]);
- this->m_PerformanceConfig.SetFXChainShimmerReverbDiffusion(this->m_nParameter[ParameterFXChainShimmerReverbDiffusion]);
- this->m_PerformanceConfig.SetFXChainShimmerReverbLP(this->m_nParameter[ParameterFXChainShimmerReverbLP]);
- #endif
- // END FXRack parameters
+ m_PerformanceConfig.SetCompressorEnable (!!m_nParameter[TParameter::ParameterCompressorEnable]);
+#if defined(MIXING_CONSOLE_ENABLE) || defined(PLATE_REVERB_ENABLE)
+ m_PerformanceConfig.SetReverbEnable (!!m_nParameter[TParameter::ParameterReverbEnable]);
+ m_PerformanceConfig.SetReverbSize (m_nParameter[TParameter::ParameterReverbSize]);
+ m_PerformanceConfig.SetReverbHighDamp (m_nParameter[TParameter::ParameterReverbHighDamp]);
+ m_PerformanceConfig.SetReverbLowDamp (m_nParameter[TParameter::ParameterReverbLowDamp]);
+ m_PerformanceConfig.SetReverbLowPass (m_nParameter[TParameter::ParameterReverbLowPass]);
+ m_PerformanceConfig.SetReverbDiffusion (m_nParameter[TParameter::ParameterReverbDiffusion]);
+ m_PerformanceConfig.SetReverbLevel (m_nParameter[TParameter::ParameterReverbLevel]);
+#endif
+
+#ifdef MIXING_CONSOLE_ENABLE
+ this->m_PerformanceConfig.SetFXTubeEnable(!!this->m_nParameter[TParameter::ParameterFXTubeEnable]);
+ this->m_PerformanceConfig.SetFXTubeOverdrive(this->m_nParameter[TParameter::ParameterFXTubeOverdrive]);
+
+ this->m_PerformanceConfig.SetFXChorusEnable(!!this->m_nParameter[TParameter::ParameterFXChorusEnable]);
+ this->m_PerformanceConfig.SetFXChorusRate(this->m_nParameter[TParameter::ParameterFXChorusRate]);
+ this->m_PerformanceConfig.SetFXChorusDepth(this->m_nParameter[TParameter::ParameterFXChorusDepth]);
+
+ this->m_PerformanceConfig.SetFXFlangerEnable(!!this->m_nParameter[TParameter::ParameterFXFlangerEnable]);
+ this->m_PerformanceConfig.SetFXFlangerRate(this->m_nParameter[TParameter::ParameterFXFlangerRate]);
+ this->m_PerformanceConfig.SetFXFlangerDepth(this->m_nParameter[TParameter::ParameterFXFlangerDepth]);
+ this->m_PerformanceConfig.SetFXFlangerFeedback(this->m_nParameter[TParameter::ParameterFXFlangerFeedback]);
+
+ this->m_PerformanceConfig.SetFXOrbitoneEnable(!!this->m_nParameter[TParameter::ParameterFXOrbitoneEnable]);
+ this->m_PerformanceConfig.SetFXOrbitoneRate(this->m_nParameter[TParameter::ParameterFXOrbitoneRate]);
+ this->m_PerformanceConfig.SetFXOrbitoneDepth(this->m_nParameter[TParameter::ParameterFXOrbitoneDepth]);
+
+ this->m_PerformanceConfig.SetFXPhaserEnable(!!this->m_nParameter[TParameter::ParameterFXPhaserEnable]);
+ this->m_PerformanceConfig.SetFXPhaserRate(this->m_nParameter[TParameter::ParameterFXPhaserRate]);
+ this->m_PerformanceConfig.SetFXPhaserDepth(this->m_nParameter[TParameter::ParameterFXPhaserDepth]);
+ this->m_PerformanceConfig.SetFXPhaserFeedback(this->m_nParameter[TParameter::ParameterFXPhaserFeedback]);
+ this->m_PerformanceConfig.SetFXPhaserNbStages(this->m_nParameter[TParameter::ParameterFXPhaserNbStages]);
+
+ this->m_PerformanceConfig.SetFXDelayEnable(!!this->m_nParameter[TParameter::ParameterFXDelayEnable]);
+ this->m_PerformanceConfig.SetFXDelayLeftDelayTime(this->m_nParameter[TParameter::ParameterFXDelayLeftDelayTime]);
+ this->m_PerformanceConfig.SetFXDelayRightDelayTime(this->m_nParameter[TParameter::ParameterFXDelayRightDelayTime]);
+ this->m_PerformanceConfig.SetFXDelayFeedback(this->m_nParameter[TParameter::ParameterFXDelayFeedback]);
+
+ this->m_PerformanceConfig.SetFXReverberatorEnable(!!this->m_nParameter[TParameter::ParameterFXReverberatorEnable]);
+ this->m_PerformanceConfig.SetFXReverberatorInputGain(this->m_nParameter[TParameter::ParameterFXReverberatorInputGain]);
+ this->m_PerformanceConfig.SetFXReverberatorTime(this->m_nParameter[TParameter::ParameterFXReverberatorTime]);
+ this->m_PerformanceConfig.SetFXReverberatorDiffusion(this->m_nParameter[TParameter::ParameterFXReverberatorDiffusion]);
+ this->m_PerformanceConfig.SetFXReverberatorLP(this->m_nParameter[TParameter::ParameterFXReverberatorLP]);
+
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Chorus, this->m_nParameter[TParameter::ParameterFXTube_ChorusSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Flanger, this->m_nParameter[TParameter::ParameterFXTube_FlangerSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Orbitone, this->m_nParameter[TParameter::ParameterFXTube_OrbitoneSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Phaser, this->m_nParameter[TParameter::ParameterFXTube_PhaserSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Delay, this->m_nParameter[TParameter::ParameterFXTube_DelaySend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_PlateReverb, this->m_nParameter[TParameter::ParameterFXTube_PlateReverbSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Reverberator, this->m_nParameter[TParameter::ParameterFXTube_ReverberatorSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput, this->m_nParameter[TParameter::ParameterFXTube_MainOutput]);
+
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Tube, this->m_nParameter[TParameter::ParameterFXChorus_TubeSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Flanger, this->m_nParameter[TParameter::ParameterFXChorus_FlangerSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Orbitone, this->m_nParameter[TParameter::ParameterFXChorus_OrbitoneSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Phaser, this->m_nParameter[TParameter::ParameterFXChorus_PhaserSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Delay, this->m_nParameter[TParameter::ParameterFXChorus_DelaySend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_PlateReverb, this->m_nParameter[TParameter::ParameterFXChorus_PlateReverbSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Reverberator, this->m_nParameter[TParameter::ParameterFXChorus_ReverberatorSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::MainOutput, this->m_nParameter[TParameter::ParameterFXChorus_MainOutput]);
+
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Tube, this->m_nParameter[TParameter::ParameterFXFlanger_TubeSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Chorus, this->m_nParameter[TParameter::ParameterFXFlanger_ChorusSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Orbitone, this->m_nParameter[TParameter::ParameterFXFlanger_OrbitoneSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Phaser, this->m_nParameter[TParameter::ParameterFXFlanger_PhaserSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Delay, this->m_nParameter[TParameter::ParameterFXFlanger_DelaySend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_PlateReverb, this->m_nParameter[TParameter::ParameterFXFlanger_PlateReverbSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Reverberator, this->m_nParameter[TParameter::ParameterFXFlanger_ReverberatorSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::MainOutput, this->m_nParameter[TParameter::ParameterFXFlanger_MainOutput]);
+
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Tube, this->m_nParameter[TParameter::ParameterFXOrbitone_TubeSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Chorus, this->m_nParameter[TParameter::ParameterFXOrbitone_ChorusSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Flanger, this->m_nParameter[TParameter::ParameterFXOrbitone_FlangerSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Phaser, this->m_nParameter[TParameter::ParameterFXOrbitone_PhaserSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Delay, this->m_nParameter[TParameter::ParameterFXOrbitone_DelaySend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_PlateReverb, this->m_nParameter[TParameter::ParameterFXOrbitone_PlateReverbSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Reverberator, this->m_nParameter[TParameter::ParameterFXOrbitone_ReverberatorSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::MainOutput, this->m_nParameter[TParameter::ParameterFXOrbitone_MainOutput]);
+
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Tube, this->m_nParameter[TParameter::ParameterFXPhaser_TubeSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Chorus, this->m_nParameter[TParameter::ParameterFXPhaser_ChorusSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Flanger, this->m_nParameter[TParameter::ParameterFXPhaser_FlangerSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Orbitone, this->m_nParameter[TParameter::ParameterFXPhaser_OrbitoneSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Delay, this->m_nParameter[TParameter::ParameterFXPhaser_DelaySend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_PlateReverb, this->m_nParameter[TParameter::ParameterFXPhaser_PlateReverbSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Reverberator, this->m_nParameter[TParameter::ParameterFXPhaser_ReverberatorSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::MainOutput, this->m_nParameter[TParameter::ParameterFXPhaser_MainOutput]);
+
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Tube, this->m_nParameter[TParameter::ParameterFXDelay_TubeSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Chorus, this->m_nParameter[TParameter::ParameterFXDelay_ChorusSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Flanger, this->m_nParameter[TParameter::ParameterFXDelay_FlangerSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Orbitone, this->m_nParameter[TParameter::ParameterFXDelay_OrbitoneSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Phaser, this->m_nParameter[TParameter::ParameterFXDelay_PhaserSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_PlateReverb, this->m_nParameter[TParameter::ParameterFXDelay_PlateReverbSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Reverberator, this->m_nParameter[TParameter::ParameterFXDelay_ReverberatorSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::MainOutput, this->m_nParameter[TParameter::ParameterFXDelay_MainOutput]);
+
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Tube, this->m_nParameter[TParameter::ParameterFXPlateReverb_TubeSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Chorus, this->m_nParameter[TParameter::ParameterFXPlateReverb_ChorusSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Flanger, this->m_nParameter[TParameter::ParameterFXPlateReverb_FlangerSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Orbitone, this->m_nParameter[TParameter::ParameterFXPlateReverb_OrbitoneSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Phaser, this->m_nParameter[TParameter::ParameterFXPlateReverb_PhaserSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Delay, this->m_nParameter[TParameter::ParameterFXPlateReverb_DelaySend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Reverberator, this->m_nParameter[TParameter::ParameterFXPlateReverb_ReverberatorSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::MainOutput, this->m_nParameter[TParameter::ParameterFXPlateReverb_MainOutput]);
+
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Tube, this->m_nParameter[TParameter::ParameterFXReverberator_TubeSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Chorus, this->m_nParameter[TParameter::ParameterFXReverberator_ChorusSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Flanger, this->m_nParameter[TParameter::ParameterFXReverberator_FlangerSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Orbitone, this->m_nParameter[TParameter::ParameterFXReverberator_OrbitoneSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Phaser, this->m_nParameter[TParameter::ParameterFXReverberator_PhaserSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Delay, this->m_nParameter[TParameter::ParameterFXReverberator_DelaySend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_PlateReverb, this->m_nParameter[TParameter::ParameterFXReverberator_PlateReverbSend]);
+ this->m_PerformanceConfig.SetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, this->m_nParameter[TParameter::ParameterFXReverberator_MainOutput]);
+
+ this->m_PerformanceConfig.SetFXBypass(this->mixing_console_->bypass());
+
+#endif
if(m_bSaveAsDeault)
{
@@ -1747,12 +2357,12 @@ void CMiniDexed::getSysExVoiceDump(uint8_t* dest, uint8_t nTG)
void CMiniDexed::setMasterVolume (float32_t vol)
{
- if(vol < 0.0)
- vol = 0.0;
- else if(vol > 1.0)
- vol = 1.0;
+ this->nMasterVolume = constrain(vol, 0.0f, 1.0f);
+
+
+
- nMasterVolume=vol;
+
}
std::string CMiniDexed::GetPerformanceFileName(unsigned nID)
@@ -1841,93 +2451,179 @@ bool CMiniDexed::DoSavePerformanceNewFile (void)
void CMiniDexed::LoadPerformanceParameters(void)
{
for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
+ {
+
+ BankSelect (m_PerformanceConfig.GetBankNumber (nTG), nTG);
+ ProgramChange (m_PerformanceConfig.GetVoiceNumber (nTG), nTG);
+ SetMIDIChannel (m_PerformanceConfig.GetMIDIChannel (nTG), nTG);
+ SetVolume (m_PerformanceConfig.GetVolume (nTG), nTG);
+ SetPan (m_PerformanceConfig.GetPan (nTG), nTG);
+ SetMasterTune (m_PerformanceConfig.GetDetune (nTG), nTG);
+ SetCutoff (m_PerformanceConfig.GetCutoff (nTG), nTG);
+ SetResonance (m_PerformanceConfig.GetResonance (nTG), nTG);
+ setPitchbendRange (m_PerformanceConfig.GetPitchBendRange (nTG), nTG);
+ setPitchbendStep (m_PerformanceConfig.GetPitchBendStep (nTG), nTG);
+ setPortamentoMode (m_PerformanceConfig.GetPortamentoMode (nTG), nTG);
+ setPortamentoGlissando (m_PerformanceConfig.GetPortamentoGlissando (nTG), nTG);
+ setPortamentoTime (m_PerformanceConfig.GetPortamentoTime (nTG), nTG);
+
+ m_nNoteLimitLow[nTG] = m_PerformanceConfig.GetNoteLimitLow (nTG);
+ m_nNoteLimitHigh[nTG] = m_PerformanceConfig.GetNoteLimitHigh (nTG);
+ m_nNoteShift[nTG] = m_PerformanceConfig.GetNoteShift (nTG);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if(m_PerformanceConfig.VoiceDataFilled(nTG))
{
+ uint8_t* tVoiceData = m_PerformanceConfig.GetVoiceDataFromTxt(nTG);
+ m_pTG[nTG]->loadVoiceParameters(tVoiceData);
+ }
+ setMonoMode(m_PerformanceConfig.GetMonoMode(nTG) ? 1 : 0, nTG);
- BankSelect (m_PerformanceConfig.GetBankNumber (nTG), nTG);
- ProgramChange (m_PerformanceConfig.GetVoiceNumber (nTG), nTG);
- SetMIDIChannel (m_PerformanceConfig.GetMIDIChannel (nTG), nTG);
- SetVolume (m_PerformanceConfig.GetVolume (nTG), nTG);
- SetPan (m_PerformanceConfig.GetPan (nTG), nTG);
- SetMasterTune (m_PerformanceConfig.GetDetune (nTG), nTG);
- SetCutoff (m_PerformanceConfig.GetCutoff (nTG), nTG);
- SetResonance (m_PerformanceConfig.GetResonance (nTG), nTG);
- setPitchbendRange (m_PerformanceConfig.GetPitchBendRange (nTG), nTG);
- setPitchbendStep (m_PerformanceConfig.GetPitchBendStep (nTG), nTG);
- setPortamentoMode (m_PerformanceConfig.GetPortamentoMode (nTG), nTG);
- setPortamentoGlissando (m_PerformanceConfig.GetPortamentoGlissando (nTG), nTG);
- setPortamentoTime (m_PerformanceConfig.GetPortamentoTime (nTG), nTG);
-
- m_nNoteLimitLow[nTG] = m_PerformanceConfig.GetNoteLimitLow (nTG);
- m_nNoteLimitHigh[nTG] = m_PerformanceConfig.GetNoteLimitHigh (nTG);
- m_nNoteShift[nTG] = m_PerformanceConfig.GetNoteShift (nTG);
-
- if(m_PerformanceConfig.VoiceDataFilled(nTG))
- {
- uint8_t* tVoiceData = m_PerformanceConfig.GetVoiceDataFromTxt(nTG);
- m_pTG[nTG]->loadVoiceParameters(tVoiceData);
- }
- setMonoMode(m_PerformanceConfig.GetMonoMode(nTG) ? 1 : 0, nTG);
- SetReverbSend (m_PerformanceConfig.GetReverbSend (nTG), nTG);
-
- setModWheelRange (m_PerformanceConfig.GetModulationWheelRange (nTG), nTG);
- setModWheelTarget (m_PerformanceConfig.GetModulationWheelTarget (nTG), nTG);
- setFootControllerRange (m_PerformanceConfig.GetFootControlRange (nTG), nTG);
- setFootControllerTarget (m_PerformanceConfig.GetFootControlTarget (nTG), nTG);
- setBreathControllerRange (m_PerformanceConfig.GetBreathControlRange (nTG), nTG);
- setBreathControllerTarget (m_PerformanceConfig.GetBreathControlTarget (nTG), nTG);
- setAftertouchRange (m_PerformanceConfig.GetAftertouchRange (nTG), nTG);
- setAftertouchTarget (m_PerformanceConfig.GetAftertouchTarget (nTG), nTG);
-
-
+ this->SetParameter(TParameter::ParameterCompressorEnable, this->m_PerformanceConfig.GetCompressorEnable());
+#if defined(MIXING_CONSOLE_ENABLE)
+ for(size_t fx = 0; fx < MixerOutput::kFXCount; ++fx)
+ {
+ this->setMixingConsoleSendLevel(nTG, static_cast(fx), this->m_PerformanceConfig.GetTGSendLevel(nTG, static_cast(fx)));
}
+#elif defined(PLATE_REVERB_ENABLE)
+ SetReverbSend (m_PerformanceConfig.GetReverbSend (nTG), nTG);
+#endif
+
+ setModWheelRange (m_PerformanceConfig.GetModulationWheelRange (nTG), nTG);
+ setModWheelTarget (m_PerformanceConfig.GetModulationWheelTarget (nTG), nTG);
+ setFootControllerRange (m_PerformanceConfig.GetFootControlRange (nTG), nTG);
+ setFootControllerTarget (m_PerformanceConfig.GetFootControlTarget (nTG), nTG);
+ setBreathControllerRange (m_PerformanceConfig.GetBreathControlRange (nTG), nTG);
+ setBreathControllerTarget (m_PerformanceConfig.GetBreathControlTarget (nTG), nTG);
+ setAftertouchRange (m_PerformanceConfig.GetAftertouchRange (nTG), nTG);
+ setAftertouchTarget (m_PerformanceConfig.GetAftertouchTarget (nTG), nTG);
+ }
- // Effects
- SetParameter (ParameterCompressorEnable, m_PerformanceConfig.GetCompressorEnable () ? 1 : 0);
- SetParameter (ParameterReverbEnable, m_PerformanceConfig.GetReverbEnable () ? 1 : 0);
- SetParameter (ParameterReverbSize, m_PerformanceConfig.GetReverbSize ());
- SetParameter (ParameterReverbHighDamp, m_PerformanceConfig.GetReverbHighDamp ());
- SetParameter (ParameterReverbLowDamp, m_PerformanceConfig.GetReverbLowDamp ());
- SetParameter (ParameterReverbLowPass, m_PerformanceConfig.GetReverbLowPass ());
- SetParameter (ParameterReverbDiffusion, m_PerformanceConfig.GetReverbDiffusion ());
- SetParameter (ParameterReverbLevel, m_PerformanceConfig.GetReverbLevel ());
-
- #ifdef FXRACK_ENABLE
- this->SetParameter(ParameterFXChainEnable, this->m_PerformanceConfig.GetFXChainEnable());
- this->SetParameter(ParameterFXChainWet, this->m_PerformanceConfig.GetFXChainWet());
- this->SetParameter(ParameterFXChainTubeEnable, this->m_PerformanceConfig.GetFXChainTubeEnable());
- this->SetParameter(ParameterFXChainTubeWet, this->m_PerformanceConfig.GetFXChainTubeWet());
- this->SetParameter(ParameterFXChainTubeOverdrive, this->m_PerformanceConfig.GetFXChainTubeOverdrive());
- this->SetParameter(ParameterFXChainChorusEnable, this->m_PerformanceConfig.GetFXChainChorusEnable());
- this->SetParameter(ParameterFXChainChorusWet, this->m_PerformanceConfig.GetFXChainChorusWet());
- this->SetParameter(ParameterFXChainChorusRate, this->m_PerformanceConfig.GetFXChainChorusRate());
- this->SetParameter(ParameterFXChainChorusDepth, this->m_PerformanceConfig.GetFXChainChorusDepth());
- this->SetParameter(ParameterFXChainFlangerEnable, this->m_PerformanceConfig.GetFXChainFlangerEnable());
- this->SetParameter(ParameterFXChainFlangerWet, this->m_PerformanceConfig.GetFXChainFlangerWet());
- this->SetParameter(ParameterFXChainFlangerRate, this->m_PerformanceConfig.GetFXChainFlangerRate());
- this->SetParameter(ParameterFXChainFlangerDepth, this->m_PerformanceConfig.GetFXChainFlangerDepth());
- this->SetParameter(ParameterFXChainFlangerFeedback, this->m_PerformanceConfig.GetFXChainFlangerFeedback());
- this->SetParameter(ParameterFXChainOrbitoneEnable, this->m_PerformanceConfig.GetFXChainOrbitoneEnable());
- this->SetParameter(ParameterFXChainOrbitoneWet, this->m_PerformanceConfig.GetFXChainOrbitoneWet());
- this->SetParameter(ParameterFXChainOrbitoneRate, this->m_PerformanceConfig.GetFXChainOrbitoneRate());
- this->SetParameter(ParameterFXChainOrbitoneDepth, this->m_PerformanceConfig.GetFXChainOrbitoneDepth());
- this->SetParameter(ParameterFXChainPhaserEnable, this->m_PerformanceConfig.GetFXChainPhaserEnable());
- this->SetParameter(ParameterFXChainPhaserWet, this->m_PerformanceConfig.GetFXChainPhaserWet());
- this->SetParameter(ParameterFXChainPhaserRate, this->m_PerformanceConfig.GetFXChainPhaserRate());
- this->SetParameter(ParameterFXChainPhaserDepth, this->m_PerformanceConfig.GetFXChainPhaserDepth());
- this->SetParameter(ParameterFXChainPhaserFeedback, this->m_PerformanceConfig.GetFXChainPhaserFeedback());
- this->SetParameter(ParameterFXChainPhaserNbStages, this->m_PerformanceConfig.GetFXChainPhaserNbStages());
- 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());
- this->SetParameter(ParameterFXChainShimmerReverbTime, this->m_PerformanceConfig.GetFXChainShimmerReverbTime());
- this->SetParameter(ParameterFXChainShimmerReverbDiffusion, this->m_PerformanceConfig.GetFXChainShimmerReverbDiffusion());
- this->SetParameter(ParameterFXChainShimmerReverbLP, this->m_PerformanceConfig.GetFXChainShimmerReverbLP());
- #endif
+#ifdef MIXING_CONSOLE_ENABLE
+ this->SetParameter(TParameter::ParameterFXTubeEnable, this->m_PerformanceConfig.GetFXTubeEnable());
+ this->SetParameter(TParameter::ParameterFXTubeOverdrive, this->m_PerformanceConfig.GetFXTubeOverdrive());
+
+ this->SetParameter(TParameter::ParameterFXChorusEnable, this->m_PerformanceConfig.GetFXChorusEnable());
+ this->SetParameter(TParameter::ParameterFXChorusRate, this->m_PerformanceConfig.GetFXChorusRate());
+ this->SetParameter(TParameter::ParameterFXChorusDepth, this->m_PerformanceConfig.GetFXChorusDepth());
+
+ this->SetParameter(TParameter::ParameterFXFlangerEnable, this->m_PerformanceConfig.GetFXFlangerEnable());
+ this->SetParameter(TParameter::ParameterFXFlangerRate, this->m_PerformanceConfig.GetFXFlangerRate());
+ this->SetParameter(TParameter::ParameterFXFlangerDepth, this->m_PerformanceConfig.GetFXFlangerDepth());
+ this->SetParameter(TParameter::ParameterFXFlangerFeedback, this->m_PerformanceConfig.GetFXFlangerFeedback());
+
+ this->SetParameter(TParameter::ParameterFXOrbitoneEnable, this->m_PerformanceConfig.GetFXOrbitoneEnable());
+ this->SetParameter(TParameter::ParameterFXOrbitoneRate, this->m_PerformanceConfig.GetFXOrbitoneRate());
+ this->SetParameter(TParameter::ParameterFXOrbitoneDepth, this->m_PerformanceConfig.GetFXOrbitoneDepth());
+
+ this->SetParameter(TParameter::ParameterFXPhaserEnable, this->m_PerformanceConfig.GetFXPhaserEnable());
+ this->SetParameter(TParameter::ParameterFXPhaserRate, this->m_PerformanceConfig.GetFXPhaserRate());
+ this->SetParameter(TParameter::ParameterFXPhaserDepth, this->m_PerformanceConfig.GetFXPhaserDepth());
+ this->SetParameter(TParameter::ParameterFXPhaserFeedback, this->m_PerformanceConfig.GetFXPhaserFeedback());
+ this->SetParameter(TParameter::ParameterFXPhaserNbStages, this->m_PerformanceConfig.GetFXPhaserNbStages());
+
+ this->SetParameter(TParameter::ParameterFXDelayEnable, this->m_PerformanceConfig.GetFXDelayEnable());
+ this->SetParameter(TParameter::ParameterFXDelayLeftDelayTime, this->m_PerformanceConfig.GetFXDelayLeftDelayTime());
+ this->SetParameter(TParameter::ParameterFXDelayRightDelayTime, this->m_PerformanceConfig.GetFXDelayRightDelayTime());
+ this->SetParameter(TParameter::ParameterFXDelayFeedback, this->m_PerformanceConfig.GetFXDelayFeedback());
+
+ this->SetParameter(TParameter::ParameterFXReverberatorEnable, this->m_PerformanceConfig.GetFXReverberatorEnable());
+ this->SetParameter(TParameter::ParameterFXReverberatorInputGain, this->m_PerformanceConfig.GetFXReverberatorInputGain());
+ this->SetParameter(TParameter::ParameterFXReverberatorTime, this->m_PerformanceConfig.GetFXReverberatorTime());
+ this->SetParameter(TParameter::ParameterFXReverberatorDiffusion, this->m_PerformanceConfig.GetFXReverberatorDiffusion());
+ this->SetParameter(TParameter::ParameterFXReverberatorLP, this->m_PerformanceConfig.GetFXReverberatorLP());
+
+ this->SetParameter(TParameter::ParameterFXTube_ChorusSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Chorus));
+ this->SetParameter(TParameter::ParameterFXTube_FlangerSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Flanger));
+ this->SetParameter(TParameter::ParameterFXTube_OrbitoneSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Orbitone));
+ this->SetParameter(TParameter::ParameterFXTube_PhaserSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Phaser));
+ this->SetParameter(TParameter::ParameterFXTube_DelaySend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Delay));
+ this->SetParameter(TParameter::ParameterFXTube_PlateReverbSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_PlateReverb));
+ this->SetParameter(TParameter::ParameterFXTube_ReverberatorSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Reverberator));
+ this->SetParameter(TParameter::ParameterFXTube_MainOutput, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput));
+
+ this->SetParameter(TParameter::ParameterFXChorus_TubeSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Tube));
+ this->SetParameter(TParameter::ParameterFXChorus_FlangerSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Flanger));
+ this->SetParameter(TParameter::ParameterFXChorus_OrbitoneSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Orbitone));
+ this->SetParameter(TParameter::ParameterFXChorus_PhaserSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Phaser));
+ this->SetParameter(TParameter::ParameterFXChorus_DelaySend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Delay));
+ this->SetParameter(TParameter::ParameterFXChorus_PlateReverbSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_PlateReverb));
+ this->SetParameter(TParameter::ParameterFXChorus_ReverberatorSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Reverberator));
+ this->SetParameter(TParameter::ParameterFXChorus_MainOutput, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::MainOutput));
+
+ this->SetParameter(TParameter::ParameterFXFlanger_TubeSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Tube));
+ this->SetParameter(TParameter::ParameterFXFlanger_ChorusSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Chorus));
+ this->SetParameter(TParameter::ParameterFXFlanger_OrbitoneSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Orbitone));
+ this->SetParameter(TParameter::ParameterFXFlanger_PhaserSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Phaser));
+ this->SetParameter(TParameter::ParameterFXFlanger_DelaySend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Delay));
+ this->SetParameter(TParameter::ParameterFXFlanger_PlateReverbSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_PlateReverb));
+ this->SetParameter(TParameter::ParameterFXFlanger_ReverberatorSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::FX_Reverberator));
+ this->SetParameter(TParameter::ParameterFXFlanger_MainOutput, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Flanger, MixerOutput::MainOutput));
+
+ this->SetParameter(TParameter::ParameterFXOrbitone_TubeSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Tube));
+ this->SetParameter(TParameter::ParameterFXOrbitone_ChorusSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Chorus));
+ this->SetParameter(TParameter::ParameterFXOrbitone_FlangerSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Flanger));
+ this->SetParameter(TParameter::ParameterFXOrbitone_PhaserSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Phaser));
+ this->SetParameter(TParameter::ParameterFXOrbitone_DelaySend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Delay));
+ this->SetParameter(TParameter::ParameterFXOrbitone_PlateReverbSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_PlateReverb));
+ this->SetParameter(TParameter::ParameterFXOrbitone_ReverberatorSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_Reverberator));
+ this->SetParameter(TParameter::ParameterFXOrbitone_MainOutput, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::MainOutput));
+
+ this->SetParameter(TParameter::ParameterFXPhaser_TubeSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Tube));
+ this->SetParameter(TParameter::ParameterFXPhaser_ChorusSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Chorus));
+ this->SetParameter(TParameter::ParameterFXPhaser_FlangerSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Flanger));
+ this->SetParameter(TParameter::ParameterFXPhaser_OrbitoneSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Orbitone));
+ this->SetParameter(TParameter::ParameterFXPhaser_DelaySend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Delay));
+ this->SetParameter(TParameter::ParameterFXPhaser_PlateReverbSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_PlateReverb));
+ this->SetParameter(TParameter::ParameterFXPhaser_ReverberatorSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Reverberator));
+ this->SetParameter(TParameter::ParameterFXPhaser_MainOutput, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::MainOutput));
+
+ this->SetParameter(TParameter::ParameterFXDelay_TubeSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Tube));
+ this->SetParameter(TParameter::ParameterFXDelay_ChorusSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Chorus));
+ this->SetParameter(TParameter::ParameterFXDelay_FlangerSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Flanger));
+ this->SetParameter(TParameter::ParameterFXDelay_OrbitoneSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Orbitone));
+ this->SetParameter(TParameter::ParameterFXDelay_PhaserSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Phaser));
+ this->SetParameter(TParameter::ParameterFXDelay_PlateReverbSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_PlateReverb));
+ this->SetParameter(TParameter::ParameterFXDelay_ReverberatorSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::FX_Reverberator));
+ this->SetParameter(TParameter::ParameterFXDelay_MainOutput, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Delay, MixerOutput::MainOutput));
+
+ this->SetParameter(TParameter::ParameterFXPlateReverb_TubeSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Tube));
+ this->SetParameter(TParameter::ParameterFXPlateReverb_ChorusSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Chorus));
+ this->SetParameter(TParameter::ParameterFXPlateReverb_FlangerSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Flanger));
+ this->SetParameter(TParameter::ParameterFXPlateReverb_OrbitoneSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Orbitone));
+ this->SetParameter(TParameter::ParameterFXPlateReverb_PhaserSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Phaser));
+ this->SetParameter(TParameter::ParameterFXPlateReverb_DelaySend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Delay));
+ this->SetParameter(TParameter::ParameterFXPlateReverb_ReverberatorSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::FX_Reverberator));
+ this->SetParameter(TParameter::ParameterFXPlateReverb_MainOutput, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::MainOutput));
+
+ this->SetParameter(TParameter::ParameterFXReverberator_TubeSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Tube));
+ this->SetParameter(TParameter::ParameterFXReverberator_ChorusSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Chorus));
+ this->SetParameter(TParameter::ParameterFXReverberator_FlangerSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Flanger));
+ this->SetParameter(TParameter::ParameterFXReverberator_OrbitoneSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Orbitone));
+ this->SetParameter(TParameter::ParameterFXReverberator_PhaserSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Phaser));
+ this->SetParameter(TParameter::ParameterFXReverberator_DelaySend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_Delay));
+ this->SetParameter(TParameter::ParameterFXReverberator_PlateReverbSend, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::FX_PlateReverb));
+ this->SetParameter(TParameter::ParameterFXReverberator_MainOutput, this->m_PerformanceConfig.GetFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput));
+
+ this->mixing_console_->bypass(this->m_PerformanceConfig.IsFXBypass());
+#endif
}
std::string CMiniDexed::GetNewPerformanceDefaultName(void)
@@ -2109,5 +2805,4 @@ unsigned CMiniDexed::getModController (unsigned controller, unsigned parameter,
return 0;
break;
}
-
}
diff --git a/src/minidexed.h b/src/minidexed.h
index d18035c..ed6e84d 100644
--- a/src/minidexed.h
+++ b/src/minidexed.h
@@ -45,8 +45,10 @@
#include "effect_platervbstereo.h"
#include "effect_compressor.h"
-#ifdef ARM_ALLOW_MULTI_CORE
-#include "fx_rack.h"
+#if defined(MIXING_CONSOLE_ENABLE)
+#include "mixing_console.hpp"
+
+typedef MixingConsole Mixer;
#endif
class CMiniDexed
@@ -55,8 +57,13 @@ class CMiniDexed
#endif
{
public:
- CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
- CGPIOManager *pGPIOManager, CI2CMaster *pI2CMaster, FATFS *pFileSystem);
+ CMiniDexed(
+ CConfig *pConfig,
+ CInterruptSystem *pInterrupt,
+ CGPIOManager *pGPIOManager,
+ CI2CMaster *pI2CMaster,
+ FATFS *pFileSystem
+ );
bool Initialize (void);
@@ -93,7 +100,13 @@ public:
void setBreathController (uint8_t value, unsigned nTG);
void setAftertouch (uint8_t value, unsigned nTG);
+#if defined(MIXING_CONSOLE_ENABLE)
+ unsigned getMixingConsoleSendLevel(unsigned nTG, MixerOutput fx) const;
+ void setMixingConsoleSendLevel(unsigned nTG, MixerOutput fx, unsigned nFXSend);
+ void setMixingConsoleFXSendLevel(MixerOutput fromFX, MixerOutput toFX, unsigned nFXReturn);
+#elif defined(PLATE_REVERB_ENABLE)
void SetReverbSend (unsigned nReverbSend, unsigned nTG); // 0 .. 127
+#endif
void setMonoMode(uint8_t mono, uint8_t nTG);
void setPitchbendRange(uint8_t range, uint8_t nTG);
@@ -135,6 +148,9 @@ public:
enum TParameter
{
ParameterCompressorEnable,
+
+ #if defined(PLATE_REVERB_ENABLE) || defined(MIXING_CONSOLE_ENABLE)
+ // Plate Reverb parameters
ParameterReverbEnable,
ParameterReverbSize,
ParameterReverbHighDamp,
@@ -142,61 +158,136 @@ public:
ParameterReverbLowPass,
ParameterReverbDiffusion,
ParameterReverbLevel,
+ #endif
+
+ // BEGIN FX global parameters definition
+ #if defined(MIXING_CONSOLE_ENABLE)
+
+ // Tube parameters
+ ParameterFXTubeEnable,
+ ParameterFXTubeOverdrive,
- // BEGIN FXRack global parameters definition
- #ifdef FXRACK_ENABLE
- // FXChain parameters
- ParameterFXChainEnable,
- ParameterFXChainWet,
-
- // FXChain > Tube parameters
- ParameterFXChainTubeEnable,
- ParameterFXChainTubeWet,
- ParameterFXChainTubeOverdrive,
-
- // FXChain > Chorus parameters
- ParameterFXChainChorusEnable,
- ParameterFXChainChorusWet,
- ParameterFXChainChorusRate,
- ParameterFXChainChorusDepth,
+ // Chorus parameters
+ ParameterFXChorusEnable,
+ ParameterFXChorusRate,
+ ParameterFXChorusDepth,
- // FXChain > Flanger parameters
- ParameterFXChainFlangerEnable,
- ParameterFXChainFlangerWet,
- ParameterFXChainFlangerRate,
- ParameterFXChainFlangerDepth,
- ParameterFXChainFlangerFeedback,
-
- // FXChain > Orbitone parameters
- ParameterFXChainOrbitoneEnable,
- ParameterFXChainOrbitoneWet,
- ParameterFXChainOrbitoneRate,
- ParameterFXChainOrbitoneDepth,
-
- // FXChain > Phaser parameters
- ParameterFXChainPhaserEnable,
- ParameterFXChainPhaserWet,
- ParameterFXChainPhaserRate,
- ParameterFXChainPhaserDepth,
- ParameterFXChainPhaserFeedback,
- ParameterFXChainPhaserNbStages,
-
- // FXChain > Delay parameters
- ParameterFXChainDelayEnable,
- ParameterFXChainDelayWet,
- ParameterFXChainDelayLeftDelayTime,
- ParameterFXChainDelayRightDelayTime,
- ParameterFXChainDelayFeedback,
-
- // FXChain > ShimmerReverb parameters
- ParameterFXChainShimmerReverbEnable,
- ParameterFXChainShimmerReverbWet,
- ParameterFXChainShimmerReverbInputGain,
- ParameterFXChainShimmerReverbTime,
- ParameterFXChainShimmerReverbDiffusion,
- ParameterFXChainShimmerReverbLP,
- #endif
- // END FXRack global parameters definition
+ // Flanger parameters
+ ParameterFXFlangerEnable,
+ ParameterFXFlangerRate,
+ ParameterFXFlangerDepth,
+ ParameterFXFlangerFeedback,
+
+ // Orbitone parameters
+ ParameterFXOrbitoneEnable,
+ ParameterFXOrbitoneRate,
+ ParameterFXOrbitoneDepth,
+
+ // Phaser parameters
+ ParameterFXPhaserEnable,
+ ParameterFXPhaserRate,
+ ParameterFXPhaserDepth,
+ ParameterFXPhaserFeedback,
+ ParameterFXPhaserNbStages,
+
+ // Delay parameters
+ ParameterFXDelayEnable,
+ ParameterFXDelayLeftDelayTime,
+ ParameterFXDelayRightDelayTime,
+ ParameterFXDelayFeedback,
+
+ // Reverberator parameters
+ ParameterFXReverberatorEnable,
+ ParameterFXReverberatorInputGain,
+ ParameterFXReverberatorTime,
+ ParameterFXReverberatorDiffusion,
+ ParameterFXReverberatorLP,
+
+ // Tube Return parameters
+ ParameterFXTube_ChorusSend,
+ ParameterFXTube_FlangerSend,
+ ParameterFXTube_OrbitoneSend,
+ ParameterFXTube_PhaserSend,
+ ParameterFXTube_DelaySend,
+ ParameterFXTube_PlateReverbSend,
+ ParameterFXTube_ReverberatorSend,
+ ParameterFXTube_MainOutput,
+
+ // Chorus Return parameters
+ ParameterFXChorus_TubeSend,
+ ParameterFXChorus_FlangerSend,
+ ParameterFXChorus_OrbitoneSend,
+ ParameterFXChorus_PhaserSend,
+ ParameterFXChorus_DelaySend,
+ ParameterFXChorus_PlateReverbSend,
+ ParameterFXChorus_ReverberatorSend,
+ ParameterFXChorus_MainOutput,
+
+ // Flanger Return parameters
+ ParameterFXFlanger_TubeSend,
+ ParameterFXFlanger_ChorusSend,
+ ParameterFXFlanger_OrbitoneSend,
+ ParameterFXFlanger_PhaserSend,
+ ParameterFXFlanger_DelaySend,
+ ParameterFXFlanger_PlateReverbSend,
+ ParameterFXFlanger_ReverberatorSend,
+ ParameterFXFlanger_MainOutput,
+
+ // Orbitone Return parameters
+ ParameterFXOrbitone_TubeSend,
+ ParameterFXOrbitone_ChorusSend,
+ ParameterFXOrbitone_FlangerSend,
+ ParameterFXOrbitone_PhaserSend,
+ ParameterFXOrbitone_DelaySend,
+ ParameterFXOrbitone_PlateReverbSend,
+ ParameterFXOrbitone_ReverberatorSend,
+ ParameterFXOrbitone_MainOutput,
+
+ // Phaser Return parameters
+ ParameterFXPhaser_TubeSend,
+ ParameterFXPhaser_ChorusSend,
+ ParameterFXPhaser_FlangerSend,
+ ParameterFXPhaser_OrbitoneSend,
+ ParameterFXPhaser_DelaySend,
+ ParameterFXPhaser_PlateReverbSend,
+ ParameterFXPhaser_ReverberatorSend,
+ ParameterFXPhaser_MainOutput,
+
+ // Delay Return parameters
+ ParameterFXDelay_TubeSend,
+ ParameterFXDelay_ChorusSend,
+ ParameterFXDelay_FlangerSend,
+ ParameterFXDelay_OrbitoneSend,
+ ParameterFXDelay_PhaserSend,
+ ParameterFXDelay_PlateReverbSend,
+ ParameterFXDelay_ReverberatorSend,
+ ParameterFXDelay_MainOutput,
+
+ // Plate Reverb Return parameters
+ ParameterFXPlateReverb_TubeSend,
+ ParameterFXPlateReverb_ChorusSend,
+ ParameterFXPlateReverb_FlangerSend,
+ ParameterFXPlateReverb_OrbitoneSend,
+ ParameterFXPlateReverb_PhaserSend,
+ ParameterFXPlateReverb_DelaySend,
+ ParameterFXPlateReverb_ReverberatorSend,
+ ParameterFXPlateReverb_MainOutput,
+
+ // Reverberator Return parameters
+ ParameterFXReverberator_TubeSend,
+ ParameterFXReverberator_ChorusSend,
+ ParameterFXReverberator_FlangerSend,
+ ParameterFXReverberator_OrbitoneSend,
+ ParameterFXReverberator_PhaserSend,
+ ParameterFXReverberator_DelaySend,
+ ParameterFXReverberator_PlateReverbSend,
+ ParameterFXReverberator_MainOutput,
+
+ // Bypass FX
+ ParameterFXBypass,
+
+ #endif
+ // END FX global parameters definition
ParameterUnknown
};
@@ -223,7 +314,9 @@ public:
TGParameterCutoff,
TGParameterResonance,
TGParameterMIDIChannel,
+#if defined(PLATE_REVERB_ENABLE)
TGParameterReverbSend,
+#endif
TGParameterPitchBendRange,
TGParameterPitchBendStep,
TGParameterPortamentoMode,
@@ -251,6 +344,18 @@ public:
TGParameterATAmplitude,
TGParameterATEGBias,
+#if defined(MIXING_CONSOLE_ENABLE)
+ TGParameterMixingSendFXTube,
+ TGParameterMixingSendFXChorus,
+ TGParameterMixingSendFXFlanger,
+ TGParameterMixingSendFXOrbitone,
+ TGParameterMixingSendFXPhaser,
+ TGParameterMixingSendFXDelay,
+ TGParameterMixingSendFXPlateReverb,
+ TGParameterMixingSendFXReverberator,
+ TGParameterMixingSendFXMainOutput,
+#endif // MIXING_CONSOLE_ENABLE
+
TGParameterUnknown
};
@@ -322,8 +427,13 @@ private:
unsigned m_nNoteLimitHigh[CConfig::ToneGenerators];
int m_nNoteShift[CConfig::ToneGenerators];
+#ifdef MIXING_CONSOLE_ENABLE
+ unsigned m_nTGSendLevel[CConfig::ToneGenerators][MixerOutput::kFXCount];
+ unsigned m_nFXSendLevel[MixerOutput::kFXCount - 1][MixerOutput::kFXCount];
+#elif defined(PLATE_REVERB_ENABLE)
unsigned m_nReverbSend[CConfig::ToneGenerators];
-
+#endif
+
uint8_t m_nRawVoiceData[156];
@@ -352,15 +462,16 @@ private:
CPerformanceTimer m_GetChunkTimer;
bool m_bProfileEnabled;
+#if defined(MIXING_CONSOLE_ENABLE)
+ Mixer* mixing_console_;
+#elif defined(PLATE_REVERB_ENABLE)
AudioEffectPlateReverb* reverb;
AudioStereoMixer* tg_mixer;
AudioStereoMixer* reverb_send_mixer;
+#endif
CSpinLock m_FXSpinLock;
-#ifdef FXRACK_ENABLE
- FXRack* fx_rack;
-#endif
bool m_bSavePerformance;
bool m_bSavePerformanceNewFile;
diff --git a/src/mixing_console.hpp b/src/mixing_console.hpp
new file mode 100644
index 0000000..af679fc
--- /dev/null
+++ b/src/mixing_console.hpp
@@ -0,0 +1,793 @@
+//
+// mixing_console.hpp
+//
+// MiniDexed - Dexed FM synthesizer for bare metal Raspberry Pi
+// Author: Vincent Gauché
+// Copyright (C) 2022 The MiniDexed Team
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+
+// Implementation of the MixingConsole class defined in mixing_console.h
+#pragma once
+
+#include "mixing_console_constants.h"
+#include "fx_tube.h"
+#include "fx_chorus.h"
+#include "fx_flanger.h"
+#include "fx_orbitone.h"
+#include "fx_phaser.h"
+#include "fx_delay.h"
+#include "effect_platervbstereo.h"
+#include "fx_reverberator.h"
+#include "fx_dry.h"
+#include "fx_unit2.hpp"
+
+template
+class MixingConsole : public FXBase
+{
+ DISALLOW_COPY_AND_ASSIGN(MixingConsole);
+
+public:
+ MixingConsole(float32_t sampling_rate, size_t buffer_size, bool swapStereoImage = false);
+ ~MixingConsole();
+
+ inline size_t getChannelNumber() const;
+
+ inline void bypass(bool bypass);
+ inline bool bypass() const;
+
+ // Send section
+ inline void setChannelLevel(size_t in, float32_t lvl);
+ 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 setInputSample(size_t in, float32_t sampleL, float32_t sampleR);
+ inline void setInputSampleBuffer(size_t in, float32_t* samples);
+
+ // Return section
+ inline void setFXSendLevel(MixerOutput fromFX, MixerOutput toFX, float32_t lvl);
+ inline void setReturnSample(MixerOutput ret, float32_t sampleL, float32_t sampleR);
+
+ // Get FX
+ inline FXElement* getFX(size_t fx);
+ inline FXUnit2* getTube();
+ inline FXUnit2* getChorus();
+ inline FXUnit2* getFlanger();
+ inline FXUnit2* getOrbitone();
+ inline FXUnit2* getPhaser();
+ inline FXUnit2* getDelay();
+ inline FXUnit2* getPlateReverb();
+ inline FXUnit2* getReverberator();
+ inline FXUnit2* getDry();
+
+ // Processing
+ inline void init();
+ inline void reset() override;
+ inline void preProcessInputSampleBuffer(size_t in, 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);
+ void process(float32_t* outL, float32_t* outR);
+ void process(float32_t* outLR);
+
+protected:
+ inline void updatePan(size_t in);
+ inline void setLevel(size_t in, MixerOutput fx, float32_t lvl);
+ inline void setSample(size_t in, float32_t sampleL, float32_t sampleR);
+
+private:
+ static inline float32_t weighted_sum(const float32_t* data, const float32_t* weights, size_t size);
+
+ const size_t BufferSize;
+
+ bool bypass_;
+
+ float32_t channel_level_[nb_inputs];
+ float32_t pan_[StereoChannels::kNumChannels + 1][nb_inputs];
+ bool swap_stereo_image_;
+ float32_t* tg_input_sample_buffer_[nb_inputs];
+ float32_t* input_sample_buffer_[StereoChannels::kNumChannels][nb_inputs];
+ float32_t input_samples_[StereoChannels::kNumChannels][nb_inputs + MixerOutput::kFXCount - 1];
+ float32_t levels_[MixerOutput::kFXCount][nb_inputs + MixerOutput::kFXCount - 1];
+ volatile size_t m_nSamples;
+
+ FXElement* fx_[MixerOutput::kFXCount];
+ FXUnit2* tube_;
+ FXUnit2* chorus_;
+ FXUnit2* flanger_;
+ FXUnit2* orbitone_;
+ FXUnit2* phaser_;
+ FXUnit2* delay_;
+ FXUnit2* plate_reverb_;
+ FXUnit2* reverberator_;
+ FXUnit2* dry_;
+
+ IMPLEMENT_DUMP(
+ const size_t space = 9;
+ const size_t precision = 5;
+
+ std::stringstream ss;
+
+ out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+
+ out << "\t" << "Input levels & Pan:" << std::endl;
+ {
+ SS_RESET(ss, precision, std::left);
+ SS_SPACE(ss, ' ', space, std::left, '|');
+ SS__TEXT(ss, ' ', space, std::left, '|', "Level");
+ SS__TEXT(ss, ' ', space, std::left, '|', "Pan L");
+ SS__TEXT(ss, ' ', space, std::left, '|', "Pan R");
+ SS__TEXT(ss, ' ', space, std::left, '|', "Pan");
+ out << "\t" << ss.str() << std::endl;
+
+ SS_RESET(ss, precision, 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;
+
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ std::stringstream s;
+ s << "* Input ";
+ s << (i + 1);
+
+ SS_RESET(ss, precision, std::left);
+ SS__TEXT(ss, ' ', space, std::left, '|', s.str());
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->channel_level_[i]);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->pan_[StereoChannels::Left][i]);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->pan_[StereoChannels::Right][i]);
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->pan_[StereoChannels::kNumChannels][i]);
+
+ out << "\t" << ss.str() << std::endl;
+ }
+ }
+ out << std::endl;
+
+ out << "\t" << "Mixing Console input samples:" << std::endl;
+ {
+ SS_RESET(ss, precision, std::left);
+ SS_SPACE(ss, ' ', space, std::left, '|');
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ std::stringstream s;
+ s << "Input ";
+ s << (i + 1);
+
+ SS__TEXT(ss, ' ', space, std::left, '|', s.str());
+ }
+ for(size_t i = 0; i < (MixerOutput::kFXCount - 1); ++i)
+ {
+ std::string s = toString(static_cast(i));
+ s.resize(space);
+ SS__TEXT(ss, ' ', space, std::left, '|', s.c_str());
+ }
+ out << "\t" << ss.str() << std::endl;
+
+ SS_RESET(ss, precision, std::left);
+ SS_SPACE(ss, '-', space, std::left, '+');
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ SS_SPACE(ss, '-', space, std::left, '+');
+ }
+ for(size_t i = 0; i < (MixerOutput::kFXCount - 1); ++i)
+ {
+ SS_SPACE(ss, '-', space, std::left, '+');
+ }
+ out << "\t" << ss.str() << std::endl;
+
+ const char* LR = "LR";
+ for(size_t c = 0; c < StereoChannels::kNumChannels; ++c)
+ {
+ std::stringstream s;
+ s << "* Input ";
+ s << LR[c];
+
+ SS_RESET(ss, precision, std::left);
+ SS__TEXT(ss, ' ', space, std::left, '|', s.str());
+ for(size_t i = 0; i < (nb_inputs + MixerOutput::kFXCount - 1); ++i)
+ {
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->input_samples_[c][i]);
+ }
+ out << "\t" << ss.str() << std::endl;
+ }
+ }
+ out << std::endl;
+
+ out << "\t" << "Mixing Console levels:" << std::endl;
+ {
+ SS_RESET(ss, precision, std::left);
+ SS_SPACE(ss, ' ', space, std::left, '|');
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ std::stringstream s;
+ s << "Input ";
+ s << (i + 1);
+
+ SS__TEXT(ss, ' ', space, std::left, '|', s.str());
+ }
+ for(size_t i = 0; i < (MixerOutput::kFXCount - 1); ++i)
+ {
+ std::string s = toString(static_cast(i));
+ s.resize(space);
+ SS__TEXT(ss, ' ', space, std::left, '|', s.c_str());
+ }
+ out << "\t" << ss.str() << std::endl;
+
+ SS_RESET(ss, precision, std::left);
+ SS_SPACE(ss, '-', space, std::left, '+');
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ SS_SPACE(ss, '-', space, std::left, '+');
+ }
+ for(size_t i = 0; i < (MixerOutput::kFXCount - 1); ++i)
+ {
+ SS_SPACE(ss, '-', space, std::left, '+');
+ }
+ out << "\t" << ss.str() << std::endl;
+
+ for(size_t c = 0; c < MixerOutput::kFXCount; ++c)
+ {
+ SS_RESET(ss, precision, std::left);
+ std::string s = toString(static_cast(c));
+ s.resize(space);
+ SS__TEXT(ss, ' ', space, std::left, '|', s.c_str());
+ for(size_t i = 0; i < (nb_inputs + MixerOutput::kFXCount - 1); ++i)
+ {
+ SS__TEXT(ss, ' ', space - 1, std::right, " |", this->levels_[c][i]);
+ }
+ out << "\t" << ss.str() << std::endl;
+ }
+ }
+ out << std::endl;
+
+ if(deepInspection)
+ {
+ this->tube_->dump(out, deepInspection, tag + ".tube_");
+ this->chorus_->dump(out, deepInspection, tag + ".chorus_");
+ this->flanger_->dump(out, deepInspection, tag + ".flanger_");
+ this->orbitone_->dump(out, deepInspection, tag + ".orbitone_");
+ this->phaser_->dump(out, deepInspection, tag + ".phaser_");
+ this->delay_->dump(out, deepInspection, tag + ".delay_");
+ this->plate_reverb_->dump(out, deepInspection, tag + ".plate_reverb_");
+ this->reverberator_->dump(out, deepInspection, tag + ".reverberator_");
+ this->dry_->dump(out, deepInspection, tag + ".dry_");
+ }
+
+ out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
+ )
+
+ IMPLEMENT_INSPECT(
+ size_t nb_errors = 0;
+
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ nb_errors += inspector(tag + ".level[ input #" + std::to_string(i) + " ]" , this->channel_level_[i], -1.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".pan[ L ][ input #" + std::to_string(i) + " ]", this->pan_[StereoChannels::Left][i], -1.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".pan[ R ][ input #" + std::to_string(i) + " ]", this->pan_[StereoChannels::Right][i], -1.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".pan[ input #" + std::to_string(i) + " ]", this->pan_[StereoChannels::kNumChannels][i], -1.0f, 1.0f, deepInspection);
+ }
+
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ nb_errors += inspector(tag + ".input[ L ][ input #" + std::to_string(i) + " ]", this->input_samples_[StereoChannels::Left ][i], -1.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".input[ R ][ input #" + std::to_string(i) + " ]", this->input_samples_[StereoChannels::Right][i], -1.0f, 1.0f, deepInspection);
+ }
+
+ for(size_t i = nb_inputs; i < (nb_inputs + MixerOutput::kFXCount - 1); ++i)
+ {
+ nb_errors += inspector(tag + ".input[ L ][ input " + toString(static_cast(i - nb_inputs)) + " ]", this->input_samples_[StereoChannels::Left ][i], -1.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".input[ R ][ input " + toString(static_cast(i - nb_inputs)) + " ]", this->input_samples_[StereoChannels::Right][i], -1.0f, 1.0f, deepInspection);
+ }
+
+ for(size_t c = 0; c < MixerOutput::kFXCount; ++c)
+ {
+ for(size_t i = 0; i < (nb_inputs + MixerOutput::kFXCount - 1); ++i)
+ {
+ nb_errors += inspector(tag + ".levels[ " + std::to_string(c) + " ][ " + std::to_string(i) + " ]", this->levels_[c][i], -1.0f, 1.0f, deepInspection);
+ }
+ }
+
+ if(deepInspection)
+ {
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ for(size_t k = 0; k < this->m_nSamples; ++k)
+ {
+ nb_errors += inspector(tag + ".input_sample_buffer_[ L ][ " + std::to_string(i) + " ][ " + std::to_string(k) +" ] ", this->input_sample_buffer_[StereoChannels::Left ][i][k], -1.0f, 1.0f, deepInspection);
+ nb_errors += inspector(tag + ".input_sample_buffer_[ R ][ " + std::to_string(i) + " ][ " + std::to_string(k) +" ] ", this->input_sample_buffer_[StereoChannels::Right][i][k], -1.0f, 1.0f, deepInspection);
+ }
+ }
+
+ nb_errors += this->tube_->inspect(inspector, deepInspection, tag + ".tube_");
+ nb_errors += this->chorus_->inspect(inspector, deepInspection, tag + ".chorus_");
+ nb_errors += this->flanger_->inspect(inspector, deepInspection, tag + ".flanger_");
+ nb_errors += this->orbitone_->inspect(inspector, deepInspection, tag + ".orbitone_");
+ nb_errors += this->phaser_->inspect(inspector, deepInspection, tag + ".phaser_");
+ nb_errors += this->delay_->inspect(inspector, deepInspection, tag + ".delay_");
+ nb_errors += this->plate_reverb_->inspect(inspector, deepInspection, tag + ".plate_reverb_");
+ nb_errors += this->reverberator_->inspect(inspector, deepInspection, tag + ".reverberator_");
+ nb_errors += this->dry_->inspect(inspector, deepInspection, tag + ".dry_");
+ }
+
+ return nb_errors;
+ )
+};
+
+template
+float32_t MixingConsole::weighted_sum(const float32_t* data, const float32_t* weights, size_t size)
+{
+ float32_t res = arm_weighted_sum_f32(data, weights, size);
+
+ return std::isnan(res) ? 0.0f : res;
+}
+
+template
+MixingConsole::MixingConsole(float32_t sampling_rate, size_t buffer_size, bool swapStereoImage) :
+ FXBase(sampling_rate),
+ BufferSize(buffer_size),
+ bypass_(true),
+ swap_stereo_image_(swapStereoImage),
+ m_nSamples(0)
+{
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ this->tg_input_sample_buffer_[i] = nullptr;
+ this->input_sample_buffer_[StereoChannels::Left ][i] = new float32_t[this->BufferSize];
+ this->input_sample_buffer_[StereoChannels::Right][i] = new float32_t[this->BufferSize];
+ memset(this->input_sample_buffer_[StereoChannels::Left ][i], 0, sizeof(float32_t) * this->BufferSize);
+ memset(this->input_sample_buffer_[StereoChannels::Right][i], 0, sizeof(float32_t) * this->BufferSize);
+ }
+
+ this->fx_[MixerOutput::FX_Tube] = this->tube_ = new FXUnit2(sampling_rate);
+ this->fx_[MixerOutput::FX_Chorus] = this->chorus_ = new FXUnit2(sampling_rate);
+ this->fx_[MixerOutput::FX_Flanger] = this->flanger_ = new FXUnit2(sampling_rate);
+ this->fx_[MixerOutput::FX_Orbitone] = this->orbitone_ = new FXUnit2(sampling_rate);
+ this->fx_[MixerOutput::FX_Phaser] = this->phaser_ = new FXUnit2(sampling_rate);
+ this->fx_[MixerOutput::FX_Delay] = this->delay_ = new FXUnit2(sampling_rate);
+ this->fx_[MixerOutput::FX_PlateReverb] = this->plate_reverb_ = new FXUnit2(sampling_rate);
+ this->fx_[MixerOutput::FX_Reverberator] = this->reverberator_ = new FXUnit2(sampling_rate);
+ this->fx_[MixerOutput::MainOutput] = this->dry_ = new FXUnit2(sampling_rate);
+
+ this->bypass(false);
+
+ this->init();
+}
+
+template
+MixingConsole::~MixingConsole()
+{
+ for(size_t i = 0; i < MixerOutput::kFXCount; ++i)
+ {
+ delete this->fx_[i];
+ }
+
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ delete[] this->input_sample_buffer_[StereoChannels::Left ][i];
+ delete[] this->input_sample_buffer_[StereoChannels::Right][i];
+
+ // The tg_input_sample_buffer_ buffers are not freed as MixingConsole is not the creator
+ // They must be freed by the creator of the buffers
+ this->tg_input_sample_buffer_[i] = nullptr;
+ }
+}
+
+template
+void MixingConsole::bypass(bool bypass)
+{
+ if(this->bypass_ != bypass)
+ {
+ this->bypass_ = bypass;
+
+ for(size_t fx = MixerOutput::FX_Tube; fx < MixerOutput::kFXCount; ++fx)
+ {
+ this->getFX(fx)->bypassFXProcess(bypass);
+ }
+
+ if(!bypass)
+ {
+ this->reset();
+ }
+ }
+}
+
+template
+bool MixingConsole::bypass() const
+{
+ return this->bypass_;
+}
+
+template
+size_t MixingConsole::getChannelNumber() const
+{
+ return nb_inputs;
+}
+
+// Send section
+template
+void MixingConsole::setChannelLevel(size_t in, float32_t lvl)
+{
+ assert(in < nb_inputs);
+
+ lvl = constrain(lvl, 0.0f, 1.0f);
+ if(lvl == this->channel_level_[in]) return;
+
+ this->channel_level_[in] = lvl;
+ this->updatePan(in);
+}
+
+template
+void MixingConsole::setPan(size_t in, float32_t pan)
+{
+ assert(in < nb_inputs);
+
+ pan = constrain(pan, 0.0f, 1.0f);
+
+ if(pan == this->pan_[StereoChannels::kNumChannels][in]) return;
+
+ this->pan_[StereoChannels::kNumChannels][in] = pan;
+ this->updatePan(in);
+}
+
+template
+void MixingConsole::swapStereoImage(bool swap)
+{
+ this->swap_stereo_image_ = swap;
+}
+
+template
+void MixingConsole::setSendLevel(size_t in, MixerOutput fx, float32_t lvl)
+{
+ assert(in < nb_inputs);
+ assert(fx < MixerOutput::kFXCount);
+
+ this->setLevel(in, fx, lvl);
+}
+
+template
+void MixingConsole::setInputSample(size_t in, float32_t sampleL, float32_t sampleR)
+{
+ assert(in < nb_inputs);
+
+ this->setSample(in, sampleL, sampleR);
+}
+
+template
+void MixingConsole::setInputSampleBuffer(size_t in, float32_t* samples)
+{
+ assert(in < nb_inputs);
+
+ this->tg_input_sample_buffer_[in] = samples;
+}
+
+// Return section
+template
+void MixingConsole::setFXSendLevel(MixerOutput fromFX, MixerOutput toFX, float32_t lvl)
+{
+ assert(fromFX < (MixerOutput::kFXCount - 1));
+ assert(toFX < MixerOutput::kFXCount);
+
+ if(fromFX == toFX)
+ {
+ // An FX cannot feedback on itself
+ return;
+ }
+
+ this->setLevel(nb_inputs + fromFX, toFX, lvl);
+}
+
+template
+void MixingConsole::setReturnSample(MixerOutput ret, float32_t sampleL, float32_t sampleR)
+{
+ assert(ret < (MixerOutput::kFXCount - 1));
+
+ this->setSample(nb_inputs + ret, sampleL, sampleR);
+}
+
+// Get FX
+template
+FXElement* MixingConsole::getFX(size_t fx)
+{
+ assert(fx < MixerOutput::kFXCount);
+ return this->fx_[fx];
+}
+
+template
+FXUnit2* MixingConsole::getTube()
+{
+ return this->tube_;
+}
+
+template
+FXUnit2* MixingConsole::getChorus()
+{
+ return this->chorus_;
+}
+
+template
+FXUnit2* MixingConsole::getFlanger()
+{
+ return this->flanger_;
+}
+
+template
+FXUnit2* MixingConsole::getOrbitone()
+{
+ return this->orbitone_;
+}
+
+template
+FXUnit2* MixingConsole::getPhaser()
+{
+ return this->phaser_;
+}
+
+template
+FXUnit2* MixingConsole::getDelay()
+{
+ return this->delay_;
+}
+
+template
+FXUnit2* MixingConsole::getPlateReverb()
+{
+ return this->plate_reverb_;
+}
+
+template
+FXUnit2* MixingConsole::getReverberator()
+{
+ return this->reverberator_;
+}
+
+template
+FXUnit2* MixingConsole::getDry()
+{
+ return this->dry_;
+}
+
+// Processing
+template
+void MixingConsole::init()
+{
+ memset(this->channel_level_, 0, nb_inputs * sizeof(float32_t));
+ for(size_t i = 0; i <= StereoChannels::kNumChannels; ++i) memset(this->pan_[i], 0, nb_inputs * sizeof(float32_t));
+
+ for(size_t i = 0; i < MixerOutput::kFXCount; ++i)
+ memset(this->levels_[i], 0, (nb_inputs + MixerOutput::kFXCount - 1) * sizeof(float32_t));
+
+ for(size_t i = 0; i < StereoChannels::kNumChannels; ++i)
+ memset(this->input_samples_[i], 0, (nb_inputs + MixerOutput::kFXCount - 1) * sizeof(float32_t));
+
+ this->reset();
+}
+
+template
+void MixingConsole::reset()
+{
+ for(size_t i = 0; i < nb_inputs; ++i)
+ {
+ memset(this->input_sample_buffer_[StereoChannels::Left ][i], 0, this->BufferSize * sizeof(float32_t));
+ memset(this->input_sample_buffer_[StereoChannels::Right][i], 0, this->BufferSize * sizeof(float32_t));
+ }
+
+ for(size_t i = 0; i < MixerOutput::kFXCount; ++i)
+ {
+ this->fx_[i]->reset();
+
+ if(i != MixerOutput::MainOutput)
+ {
+ this->setReturnSample(static_cast(i), 0.0f, 0.0f);
+ }
+ }
+}
+
+template
+void MixingConsole::injectInputSamples(size_t in, float32_t* samplesL, float32_t* samplesR, size_t nSamples)
+{
+ // Only used to input stereo samples
+ assert(in < nb_inputs);
+ this->m_nSamples = std::min(nSamples, this->BufferSize);
+ if(samplesL != nullptr)
+ {
+ memcpy(this->input_sample_buffer_[StereoChannels::Left ][in], samplesL, this->m_nSamples * sizeof(float32_t));
+ }
+ else
+ {
+ memset(this->input_sample_buffer_[StereoChannels::Left ][in], 0, this->m_nSamples * sizeof(float32_t));
+ }
+
+ if(samplesR != nullptr)
+ {
+ memcpy(this->input_sample_buffer_[StereoChannels::Right][in], samplesR, this->m_nSamples * sizeof(float32_t));
+ }
+ else
+ {
+ memset(this->input_sample_buffer_[StereoChannels::Right][in], 0, this->m_nSamples * sizeof(float32_t));
+ }
+}
+
+template
+void MixingConsole::preProcessInputSampleBuffer(size_t in, size_t nSamples)
+{
+ assert(in < nb_inputs);
+ assert(nSamples <= this->BufferSize);
+
+ float32_t* samples = this->tg_input_sample_buffer_[in];
+ if(samples == nullptr) return;
+
+ this->m_nSamples = nSamples;
+ if(nSamples > 0)
+ {
+ if(this->pan_[StereoChannels::Left ][in] != 0.0f)
+ {
+ arm_scale_f32(samples, this->pan_[StereoChannels::Left ][in], this->input_sample_buffer_[StereoChannels::Left ][in], nSamples);
+ }
+ else
+ {
+ memset(this->input_sample_buffer_[StereoChannels::Left ][in], 0, nSamples * sizeof(float32_t));
+ }
+
+ if(this->pan_[StereoChannels::Right][in] != 0.0f)
+ {
+ arm_scale_f32(samples, this->pan_[StereoChannels::Right][in], this->input_sample_buffer_[StereoChannels::Right][in], nSamples);
+ }
+ else
+ {
+ memset(this->input_sample_buffer_[StereoChannels::Right][in], 0, nSamples * sizeof(float32_t));
+ }
+ }
+ else
+ {
+ memset(this->input_sample_buffer_[StereoChannels::Left ][in], 0, this->BufferSize * sizeof(float32_t));
+ memset(this->input_sample_buffer_[StereoChannels::Right][in], 0, this->BufferSize * sizeof(float32_t));
+ }
+}
+
+template
+void MixingConsole::processSample(float32_t& outL, float32_t& outR)
+{
+ const size_t nBuffers = nb_inputs + MixerOutput::kFXCount - 1;
+
+ float32_t fx_input_[StereoChannels::kNumChannels];
+ float32_t fx_output_[StereoChannels::kNumChannels];
+ for(size_t fxId = 0; fxId < MixerOutput::kFXCount; ++fxId)
+ {
+ // Compute the samples that will feed the FX
+ fx_input_[StereoChannels::Left ] = MixingConsole::weighted_sum(this->input_samples_[StereoChannels::Left ], this->levels_[fxId], nBuffers);
+ fx_input_[StereoChannels::Right] = MixingConsole::weighted_sum(this->input_samples_[StereoChannels::Right], this->levels_[fxId], nBuffers);
+
+ // Process the FX
+ this->fx_[fxId]->processSample(
+ fx_input_[StereoChannels::Left ],
+ fx_input_[StereoChannels::Right],
+ fx_output_[StereoChannels::Left ],
+ fx_output_[StereoChannels::Right]
+ );
+
+ if(fxId != MixerOutput::MainOutput)
+ {
+ // Feedback the processed samples except for the main output
+ this->setReturnSample(
+ static_cast(fxId),
+ fx_output_[StereoChannels::Left],
+ fx_output_[StereoChannels::Right]
+ );
+ }
+ else
+ {
+ // Returns the main output sample
+ outL = fx_output_[StereoChannels::Left];
+ outR = fx_output_[StereoChannels::Right];
+ }
+ }
+}
+
+template
+void MixingConsole::process(float32_t* outL, float32_t* outR)
+{
+ 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(*outR, *outL);
+ }
+ else
+ {
+ this->processSample(*outL, *outR);
+ }
+
+ ++outL;
+ ++outR;
+ }
+
+ this->m_nSamples = 0;
+}
+
+template
+void MixingConsole::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
+void MixingConsole::updatePan(size_t in)
+{
+ float32_t pan = this->pan_[StereoChannels::kNumChannels][in] * Constants::MPI_2;
+ if(this->channel_level_[in] != 0.0f)
+ {
+ this->pan_[StereoChannels::Left ][in] = InterpolatedSineOscillator::Cos(pan) * this->channel_level_[in];
+ this->pan_[StereoChannels::Right][in] = InterpolatedSineOscillator::Sin(pan) * this->channel_level_[in];
+ }
+ else
+ {
+ this->pan_[StereoChannels::Left ][in] =
+ this->pan_[StereoChannels::Right][in] = 0.0f;
+ }
+}
+
+template
+void MixingConsole::setLevel(size_t in, MixerOutput fx, float32_t lvl)
+{
+ assert(in < (nb_inputs + MixerOutput::kFXCount - 1));
+ assert(fx < MixerOutput::kFXCount);
+
+ this->levels_[fx][in] = constrain(lvl, 0.0f, 1.0f);
+}
+
+template
+void MixingConsole::setSample(size_t in, float32_t sampleL, float32_t sampleR)
+{
+ assert(in < (nb_inputs + MixerOutput::kFXCount - 1));
+ this->input_samples_[StereoChannels::Left ][in] = sampleL;
+ this->input_samples_[StereoChannels::Right][in] = sampleR;
+}
diff --git a/src/mixing_console_constants.h b/src/mixing_console_constants.h
new file mode 100644
index 0000000..0257733
--- /dev/null
+++ b/src/mixing_console_constants.h
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "extra_features.h"
+
+#include
+#include
+#include
+
+enum MixerOutput
+{
+ OutputStart = 0,
+ FX_Tube = 0,
+ FX_Chorus,
+ FX_Flanger,
+ FX_Orbitone,
+ FX_Phaser,
+ FX_Delay,
+ FX_PlateReverb,
+ FX_Reverberator,
+ MainOutput,
+ kFXCount
+};
+
+inline std::string toString(MixerOutput enum_val)
+{
+ static const std::array names
+ {
+ "Tube",
+ "Chorus",
+ "Flanger",
+ "Orbitone",
+ "Phaser",
+ "Delay",
+ "PlateReverb",
+ "Reverberator",
+ "MainOutput"
+ };
+ static_assert(names.size() == MixerOutput::kFXCount, "Enum MixerOutput and string array size mismatch");
+
+ return std::string(names[static_cast(enum_val)]);
+}
+
+#define TO_INDEX_CHECK(str, fx) if(std::strcmp(str, toString(fx).c_str()) == 0) return fx;
+
+inline MixerOutput toIndex(const char* str)
+{
+ TO_INDEX_CHECK(str, MixerOutput::FX_Tube);
+ TO_INDEX_CHECK(str, MixerOutput::FX_Chorus);
+ TO_INDEX_CHECK(str, MixerOutput::FX_Flanger);
+ TO_INDEX_CHECK(str, MixerOutput::FX_Orbitone);
+ TO_INDEX_CHECK(str, MixerOutput::FX_Phaser);
+ TO_INDEX_CHECK(str, MixerOutput::FX_Delay);
+ TO_INDEX_CHECK(str, MixerOutput::FX_PlateReverb);
+ TO_INDEX_CHECK(str, MixerOutput::FX_Reverberator);
+ TO_INDEX_CHECK(str, MixerOutput::MainOutput);
+
+ throw std::invalid_argument("Invalid MixerOutput string");
+}
diff --git a/src/performance.ini b/src/performance.ini
index 7a61480..78a5cba 100644
--- a/src/performance.ini
+++ b/src/performance.ini
@@ -275,6 +275,7 @@ AftertouchTarget8=0
# Effects
CompressorEnable=1
+
ReverbEnable=1
ReverbSize=70
ReverbHighDamp=50
@@ -283,39 +284,190 @@ ReverbLowPass=30
ReverbDiffusion=65
ReverbLevel=99
-# FXRack
-FXChainEnable=1
-FXChainWet=99
-FXChainTubeEnable=0
-FXChainTubeWet=50
-FXChainTubeOverdrive=10
-FXChainChorusEnable=0
-FXChainChorusWet=50
-FXChainChorusRate=40
-FXChainChorusDepth=50
-FXChainFlangerEnable=0
-FXChainFlangerWet=50
-FXChainFlangerRate=3
-FXChainFlangerDepth=75
-FXChainFlangerFeedback=50
-FXChainOrbitoneEnable=0
-FXChainOrbitoneWet=80
-FXChainOrbitoneRate=40
-FXChainOrbitoneDepth=50
-FXChainPhaserEnable=0
-FXChainPhaserWet=50
-FXChainPhaserRate=5
-FXChainPhaserDepth=99
-FXChainPhaserFeedback=70
-FXChainPhaserNbStages=12
-FXChainDelayEnable=0
-FXChainDelayWet=50
-FXChainDelayLeftDelayTime=15
-FXChainDelayRightDelayTime=22
-FXChainDelayFeedback=35
-FXChainShimmerReverbEnable=1
-FXChainShimmerReverbWet=70
-FXChainShimmerReverbInputGain=55
-FXChainShimmerReverbTime=75
-FXChainShimmerReverbDiffusion=75
-FXChainShimmerReverbLP=80
+# Mixing Console
+FXTubeEnable=1
+FXTubeOverdrive=10
+
+FXChorusEnable=1
+FXChorusRate=40
+FXChorusDepth=50
+
+FXFlangerEnable=1
+FXFlangerRate=3
+FXFlangerDepth=75
+FXFlangerFeedback=50
+
+FXOrbitoneEnable=1
+FXOrbitoneRate=40
+FXOrbitoneDepth=50
+
+FXPhaserEnable=1
+FXPhaserRate=5
+FXPhaserDepth=99
+FXPhaserFeedback=70
+FXPhaserNbStages=12
+
+FXDelayEnable=1
+FXDelayLeftDelayTime=15
+FXDelayRightDelayTime=22
+FXDelayFeedback=35
+FXDelayFlutterRate=0
+FXDelayFlutterAmount=0
+
+FXReverberatorEnable=1
+FXReverberatorInputGain=55
+FXReverberatorTime=75
+FXReverberatorDiffusion=75
+FXReverberatorLP=80
+
+FXSend_TG0_to_Tube=0
+FXSend_TG0_to_Chorus=0
+FXSend_TG0_to_Flanger=0
+FXSend_TG0_to_Orbitone=0
+FXSend_TG0_to_Phaser=0
+FXSend_TG0_to_Delay=0
+FXSend_TG0_to_PlateReverb=99
+FXSend_TG0_to_Reverberator=0
+FXSend_TG0_to_MainOutput=99
+
+FXSend_TG1_to_Tube=0
+FXSend_TG1_to_Chorus=0
+FXSend_TG1_to_Flanger=0
+FXSend_TG1_to_Orbitone=0
+FXSend_TG1_to_Phaser=0
+FXSend_TG1_to_Delay=0
+FXSend_TG1_to_PlateReverb=0
+FXSend_TG1_to_Reverberator=0
+FXSend_TG1_to_MainOutput=0
+
+FXSend_TG2_to_Tube=0
+FXSend_TG2_to_Chorus=0
+FXSend_TG2_to_Flanger=0
+FXSend_TG2_to_Orbitone=0
+FXSend_TG2_to_Phaser=0
+FXSend_TG2_to_Delay=0
+FXSend_TG2_to_PlateReverb=0
+FXSend_TG2_to_Reverberator=0
+FXSend_TG2_to_MainOutput=0
+
+FXSend_TG3_to_Tube=0
+FXSend_TG3_to_Chorus=0
+FXSend_TG3_to_Flanger=0
+FXSend_TG3_to_Orbitone=0
+FXSend_TG3_to_Phaser=0
+FXSend_TG3_to_Delay=0
+FXSend_TG3_to_PlateReverb=0
+FXSend_TG3_to_Reverberator=0
+FXSend_TG3_to_MainOutput=0
+
+FXSend_TG4_to_Tube=0
+FXSend_TG4_to_Chorus=0
+FXSend_TG4_to_Flanger=0
+FXSend_TG4_to_Orbitone=0
+FXSend_TG4_to_Phaser=0
+FXSend_TG4_to_Delay=0
+FXSend_TG4_to_PlateReverb=0
+FXSend_TG4_to_Reverberator=0
+FXSend_TG4_to_MainOutput=0
+
+FXSend_TG5_to_Tube=0
+FXSend_TG5_to_Chorus=0
+FXSend_TG5_to_Flanger=0
+FXSend_TG5_to_Orbitone=0
+FXSend_TG5_to_Phaser=0
+FXSend_TG5_to_Delay=0
+FXSend_TG5_to_PlateReverb=0
+FXSend_TG5_to_Reverberator=0
+FXSend_TG5_to_MainOutput=0
+
+FXSend_TG6_to_Tube=0
+FXSend_TG6_to_Chorus=0
+FXSend_TG6_to_Flanger=0
+FXSend_TG6_to_Orbitone=0
+FXSend_TG6_to_Phaser=0
+FXSend_TG6_to_Delay=0
+FXSend_TG6_to_PlateReverb=0
+FXSend_TG6_to_Reverberator=0
+FXSend_TG6_to_MainOutput=0
+
+FXSend_TG7_to_Tube=0
+FXSend_TG7_to_Chorus=0
+FXSend_TG7_to_Flanger=0
+FXSend_TG7_to_Orbitone=0
+FXSend_TG7_to_Phaser=0
+FXSend_TG7_to_Delay=0
+FXSend_TG7_to_PlateReverb=0
+FXSend_TG7_to_Reverberator=0
+FXSend_TG7_to_MainOutput=0
+
+FXSend_Tube_to_Chorus=0
+FXSend_Tube_to_Flanger=0
+FXSend_Tube_to_Orbitone=0
+FXSend_Tube_to_Phaser=0
+FXSend_Tube_to_Delay=0
+FXSend_Tube_to_PlateReverb=0
+FXSend_Tube_to_Reverberator=0
+FXSend_Tube_to_MainOutput=0
+
+FXSend_Chorus_to_Tube=0
+FXSend_Chorus_to_Flanger=0
+FXSend_Chorus_to_Orbitone=0
+FXSend_Chorus_to_Phaser=0
+FXSend_Chorus_to_Delay=0
+FXSend_Chorus_to_PlateReverb=0
+FXSend_Chorus_to_Reverberator=0
+FXSend_Chorus_to_MainOutput=0
+
+FXSend_Flanger_to_Tube=0
+FXSend_Flanger_to_Chorus=0
+FXSend_Flanger_to_Orbitone=0
+FXSend_Flanger_to_Phaser=0
+FXSend_Flanger_to_Delay=0
+FXSend_Flanger_to_PlateReverb=0
+FXSend_Flanger_to_Reverberator=0
+FXSend_Flanger_to_MainOutput=0
+
+FXSend_Orbitone_to_Tube=0
+FXSend_Orbitone_to_Chorus=0
+FXSend_Orbitone_to_Flanger=0
+FXSend_Orbitone_to_Phaser=0
+FXSend_Orbitone_to_Delay=0
+FXSend_Orbitone_to_PlateReverb=0
+FXSend_Orbitone_to_Reverberator=0
+FXSend_Orbitone_to_MainOutput=0
+
+FXSend_Phaser_to_Tube=0
+FXSend_Phaser_to_Chorus=0
+FXSend_Phaser_to_Flanger=0
+FXSend_Phaser_to_Orbitone=0
+FXSend_Phaser_to_Delay=0
+FXSend_Phaser_to_PlateReverb=0
+FXSend_Phaser_to_Reverberator=0
+FXSend_Phaser_to_MainOutput=0
+
+FXSend_Delay_to_Tube=0
+FXSend_Delay_to_Chorus=0
+FXSend_Delay_to_Flanger=0
+FXSend_Delay_to_Orbitone=0
+FXSend_Delay_to_Phaser=0
+FXSend_Delay_to_PlateReverb=0
+FXSend_Delay_to_Reverberator=0
+FXSend_Delay_to_MainOutput=0
+
+FXSend_PlateReverb_to_Tube=0
+FXSend_PlateReverb_to_Chorus=0
+FXSend_PlateReverb_to_Flanger=0
+FXSend_PlateReverb_to_Orbitone=0
+FXSend_PlateReverb_to_Phaser=0
+FXSend_PlateReverb_to_Delay=0
+FXSend_PlateReverb_to_Reverberator=0
+FXSend_PlateReverb_to_MainOutput=99
+
+FXSend_Reverberator_to_Tube=0
+FXSend_Reverberator_to_Chorus=0
+FXSend_Reverberator_to_Flanger=0
+FXSend_Reverberator_to_Orbitone=0
+FXSend_Reverberator_to_Phaser=0
+FXSend_Reverberator_to_Delay=0
+FXSend_Reverberator_to_PlateReverb=0
+FXSend_Reverberator_to_MainOutput=0
diff --git a/src/performanceconfig.cpp b/src/performanceconfig.cpp
index cdc52bf..574a664 100644
--- a/src/performanceconfig.cpp
+++ b/src/performanceconfig.cpp
@@ -102,9 +102,11 @@ bool CPerformanceConfig::Load (void)
PropertyName.Format ("NoteShift%u", nTG+1);
m_nNoteShift[nTG] = m_Properties.GetSignedNumber (PropertyName, 0);
+#if defined(PLATE_REVERB_ENABLE)
PropertyName.Format ("ReverbSend%u", nTG+1);
m_nReverbSend[nTG] = m_Properties.GetNumber (PropertyName, 50);
-
+#endif
+
PropertyName.Format ("PitchBendRange%u", nTG+1);
m_nPitchBendRange[nTG] = m_Properties.GetNumber (PropertyName, 2);
@@ -150,54 +152,90 @@ bool CPerformanceConfig::Load (void)
PropertyName.Format ("AftertouchTarget%u", nTG+1);
m_nAftertouchTarget[nTG] = m_Properties.GetNumber (PropertyName, 0);
- }
+ }
m_bCompressorEnable = m_Properties.GetNumber ("CompressorEnable", 1) != 0;
- m_bReverbEnable = m_Properties.GetNumber ("ReverbEnable", 1) != 0;
- m_nReverbSize = m_Properties.GetNumber ("ReverbSize", 70);
- m_nReverbHighDamp = m_Properties.GetNumber ("ReverbHighDamp", 50);
- m_nReverbLowDamp = m_Properties.GetNumber ("ReverbLowDamp", 50);
- m_nReverbLowPass = m_Properties.GetNumber ("ReverbLowPass", 30);
- m_nReverbDiffusion = m_Properties.GetNumber ("ReverbDiffusion", 65);
- m_nReverbLevel = m_Properties.GetNumber ("ReverbLevel", 99);
-
-#ifdef ARM_ALLOW_MULTI_CORE
- this->m_bFXChainEnable = this->m_Properties.GetNumber("FXChainEnable", 1);
- this->m_nFXChainWet = this->m_Properties.GetNumber("FXChainWet", 99);
- this->m_bFXChainTubeEnable = this->m_Properties.GetNumber("FXChainTubeEnable", 1);
- this->m_nFXChainTubeWet = this->m_Properties.GetNumber("FXChainTubeWet", 50);
- this->m_nFXChainTubeOverdrive = this->m_Properties.GetNumber("FXChainTubeOverdrive", 10);
- this->m_bFXChainChorusEnable = this->m_Properties.GetNumber("FXChainChorusEnable", 1);
- this->m_nFXChainChorusWet = this->m_Properties.GetNumber("FXChainChorusWet", 50);
- this->m_nFXChainChorusRate = this->m_Properties.GetNumber("FXChainChorusRate", 50);
- this->m_nFXChainChorusDepth = this->m_Properties.GetNumber("FXChainChorusDepth", 50);
- this->m_bFXChainFlangerEnable = this->m_Properties.GetNumber("FXChainFlangerEnable", 1);
- this->m_nFXChainFlangerWet = this->m_Properties.GetNumber("FXChainFlangerWet", 50);
- this->m_nFXChainFlangerRate = this->m_Properties.GetNumber("FXChainFlangerRate", 15);
- this->m_nFXChainFlangerDepth = this->m_Properties.GetNumber("FXChainFlangerDepth", 10);
- this->m_nFXChainFlangerFeedback = this->m_Properties.GetNumber("FXChainFlangerFeedback", 20);
- this->m_bFXChainOrbitoneEnable = this->m_Properties.GetNumber("FXChainOrbitoneEnable", 1);
- this->m_nFXChainOrbitoneWet = this->m_Properties.GetNumber("FXChainOrbitoneWet", 80);
- this->m_nFXChainOrbitoneRate = this->m_Properties.GetNumber("FXChainOrbitoneRate", 40);
- this->m_nFXChainOrbitoneDepth = this->m_Properties.GetNumber("FXChainOrbitoneDepth", 50);
- this->m_bFXChainPhaserEnable = this->m_Properties.GetNumber("FXChainPhaserEnable", 1);
- this->m_nFXChainPhaserWet = this->m_Properties.GetNumber("FXChainPhaserWet", 50);
- this->m_nFXChainPhaserRate = this->m_Properties.GetNumber("FXChainPhaserRate", 5);
- this->m_nFXChainPhaserDepth = this->m_Properties.GetNumber("FXChainPhaserDepth", 99);
- this->m_nFXChainPhaserFeedback = this->m_Properties.GetNumber("FXChainPhaserFeedback", 50);
- this->m_nFXChainPhaserNbStages = this->m_Properties.GetNumber("FXChainPhaserNbStages", 12);
- 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);
- this->m_nFXChainShimmerReverbTime = this->m_Properties.GetNumber("FXChainShimmerReverbTime", 30);
- this->m_nFXChainShimmerReverbDiffusion = this->m_Properties.GetNumber("FXChainShimmerReverbDiffusion", 30);
- this->m_nFXChainShimmerReverbLP = this->m_Properties.GetNumber("FXChainShimmerReverbLP", 99);
+#if defined(PLATE_REVERB_ENABLE) || defined(MIXING_CONSOLE_ENABLE)
+ this->m_bReverbEnable = this->m_Properties.GetNumber ("ReverbEnable", 1) != 0;
+ this->m_nReverbSize = this->m_Properties.GetNumber ("ReverbSize", 70);
+ this->m_nReverbHighDamp = this->m_Properties.GetNumber ("ReverbHighDamp", 50);
+ this->m_nReverbLowDamp = this->m_Properties.GetNumber ("ReverbLowDamp", 50);
+ this->m_nReverbLowPass = this->m_Properties.GetNumber ("ReverbLowPass", 30);
+ this->m_nReverbDiffusion = this->m_Properties.GetNumber ("ReverbDiffusion", 65);
+ this->m_nReverbLevel = this->m_Properties.GetNumber ("ReverbLevel", 99);
+#endif
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->m_bFXTubeEnable = this->m_Properties.GetNumber("FXTubeEnable", 1);
+ this->m_nFXTubeOverdrive = this->m_Properties.GetNumber("FXTubeOverdrive", 10);
+
+ this->m_bFXChorusEnable = this->m_Properties.GetNumber("FXChorusEnable", 1);
+ this->m_nFXChorusRate = this->m_Properties.GetNumber("FXChorusRate", 50);
+ this->m_nFXChorusDepth = this->m_Properties.GetNumber("FXChorusDepth", 50);
+
+ this->m_bFXFlangerEnable = this->m_Properties.GetNumber("FXFlangerEnable", 1);
+ this->m_nFXFlangerRate = this->m_Properties.GetNumber("FXFlangerRate", 15);
+ this->m_nFXFlangerDepth = this->m_Properties.GetNumber("FXFlangerDepth", 10);
+ this->m_nFXFlangerFeedback = this->m_Properties.GetNumber("FXFlangerFeedback", 20);
+
+ this->m_bFXOrbitoneEnable = this->m_Properties.GetNumber("FXOrbitoneEnable", 1);
+ this->m_nFXOrbitoneRate = this->m_Properties.GetNumber("FXOrbitoneRate", 40);
+ this->m_nFXOrbitoneDepth = this->m_Properties.GetNumber("FXOrbitoneDepth", 50);
+
+ this->m_bFXPhaserEnable = this->m_Properties.GetNumber("FXPhaserEnable", 1);
+ this->m_nFXPhaserRate = this->m_Properties.GetNumber("FXPhaserRate", 5);
+ this->m_nFXPhaserDepth = this->m_Properties.GetNumber("FXPhaserDepth", 99);
+ this->m_nFXPhaserFeedback = this->m_Properties.GetNumber("FXPhaserFeedback", 50);
+ this->m_nFXPhaserNbStages = this->m_Properties.GetNumber("FXPhaserNbStages", 12);
+
+ this->m_bFXDelayEnable = this->m_Properties.GetNumber("FXDelayEnable", 1);
+ this->m_nFXDelayLeftDelayTime = this->m_Properties.GetNumber("FXDelayLeftDelayTime", 15);
+ this->m_nFXDelayRightDelayTime = this->m_Properties.GetNumber("FXDelayRightDelayTime", 22);
+ this->m_nFXDelayFeedback = this->m_Properties.GetNumber("FXDelayFeedback", 35);
+
+ this->m_bFXReverberatorEnable = this->m_Properties.GetNumber("FXReverberatorEnable", 1);
+ this->m_nFXReverberatorInputGain = this->m_Properties.GetNumber("FXReverberatorInputGain", 30);
+ this->m_nFXReverberatorTime = this->m_Properties.GetNumber("FXReverberatorTime", 30);
+ this->m_nFXReverberatorDiffusion = this->m_Properties.GetNumber("FXReverberatorDiffusion", 30);
+ this->m_nFXReverberatorLP = this->m_Properties.GetNumber("FXReverberatorLP", 99);
+
+ bool revUsed = false;
+ for(unsigned nTG = 0; nTG < CConfig::ToneGenerators; ++nTG)
+ {
+ CString reverbSendProp;
+ reverbSendProp.Format ("ReverbSend%u", nTG + 1);
+ unsigned reverbSend = m_Properties.GetNumber(reverbSendProp, 50);
+ revUsed |= (reverbSend > 0);
+
+ for(unsigned toFX = 0; toFX < MixerOutput::kFXCount; ++toFX)
+ {
+ CString propertyName;
+ propertyName.Format("FXSend_TG%u_to_%s", nTG + 1, toString(static_cast(toFX)).c_str());
+ unsigned defaultLevel = 0;
+ if(nTG == 0)
+ {
+ if(toFX == MixerOutput::FX_PlateReverb) defaultLevel = reverbSend;
+ else if(toFX == MixerOutput::MainOutput) defaultLevel = 99 - reverbSend;
+ }
+ this->m_nTGSendLevel[nTG][toFX] = this->m_Properties.GetNumber(propertyName, defaultLevel);
+ }
+ }
+
+ size_t end = MixerOutput::kFXCount - 1;
+ for(size_t fromFX = 0; fromFX < end; ++fromFX)
+ {
+ for(size_t toFX = 0; toFX < MixerOutput::kFXCount; ++toFX)
+ {
+ CString propertyName;
+ propertyName.Format("FXSend_%s_to_%s", toString(static_cast(fromFX)).c_str(), toString(static_cast(toFX)).c_str());
+ unsigned defaultLevel = 0;
+ if(fromFX == MixerOutput::FX_PlateReverb && toFX == MixerOutput::MainOutput) defaultLevel = revUsed ? 99 : 0;
+ this->m_nFXSendLevel[fromFX][toFX] = this->m_Properties.GetNumber(propertyName, defaultLevel);
+ }
+ }
+
+ this->m_bFXBypass = this->m_Properties.GetNumber("FXBypass", 0);
#endif
return bResult;
@@ -257,9 +295,11 @@ bool CPerformanceConfig::Save (void)
PropertyName.Format ("NoteShift%u", nTG+1);
m_Properties.SetSignedNumber (PropertyName, m_nNoteShift[nTG]);
+#if defined(PLATE_REVERB_ENABLE)
PropertyName.Format ("ReverbSend%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nReverbSend[nTG]);
-
+#endif
+
PropertyName.Format ("PitchBendRange%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nPitchBendRange[nTG]);
@@ -310,6 +350,7 @@ bool CPerformanceConfig::Save (void)
m_Properties.SetNumber ("CompressorEnable", m_bCompressorEnable ? 1 : 0);
+#if defined(PLATE_REVERB_ENABLE) || defined(MIXING_CONSOLE_ENABLE)
m_Properties.SetNumber ("ReverbEnable", m_bReverbEnable ? 1 : 0);
m_Properties.SetNumber ("ReverbSize", m_nReverbSize);
m_Properties.SetNumber ("ReverbHighDamp", m_nReverbHighDamp);
@@ -317,43 +358,64 @@ bool CPerformanceConfig::Save (void)
m_Properties.SetNumber ("ReverbLowPass", m_nReverbLowPass);
m_Properties.SetNumber ("ReverbDiffusion", m_nReverbDiffusion);
m_Properties.SetNumber ("ReverbLevel", m_nReverbLevel);
+#endif
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ this->m_Properties.SetNumber("FXTubeEnable", this->m_bFXTubeEnable ? 1 : 0);
+ this->m_Properties.SetNumber("FXTubeOverdrive", this->m_nFXTubeOverdrive);
+
+ this->m_Properties.SetNumber("FXChorusEnable", this->m_bFXChorusEnable ? 1 : 0);
+ this->m_Properties.SetNumber("FXChorusRate", this->m_nFXChorusRate);
+ this->m_Properties.SetNumber("FXChorusDepth", this->m_nFXChorusDepth);
+
+ this->m_Properties.SetNumber("FXFlangerEnable", this->m_bFXFlangerEnable ? 1 : 0);
+ this->m_Properties.SetNumber("FXFlangerRate", this->m_nFXFlangerRate);
+ this->m_Properties.SetNumber("FXFlangerDepth", this->m_nFXFlangerDepth);
+ this->m_Properties.SetNumber("FXFlangerFeedback", this->m_nFXFlangerFeedback);
+
+ this->m_Properties.SetNumber("FXOrbitoneEnable", this->m_bFXOrbitoneEnable ? 1 : 0);
+ this->m_Properties.SetNumber("FXOrbitoneRate", this->m_nFXOrbitoneRate);
+ this->m_Properties.SetNumber("FXOrbitoneDepth", this->m_nFXOrbitoneDepth);
+
+ this->m_Properties.SetNumber("FXPhaserEnable", this->m_bFXPhaserEnable ? 1 : 0);
+ this->m_Properties.SetNumber("FXPhaserRate", this->m_nFXPhaserRate);
+ this->m_Properties.SetNumber("FXPhaserDepth", this->m_nFXPhaserDepth);
+ this->m_Properties.SetNumber("FXPhaserFeedback", this->m_nFXPhaserFeedback);
+ this->m_Properties.SetNumber("FXPhaserNbStages", this->m_nFXPhaserNbStages);
+
+ this->m_Properties.SetNumber("FXDelayEnable", this->m_bFXDelayEnable ? 1 : 0);
+ this->m_Properties.SetNumber("FXDelayLeftDelayTime", this->m_nFXDelayLeftDelayTime);
+ this->m_Properties.SetNumber("FXDelayRightDelayTime", this->m_nFXDelayRightDelayTime);
+ this->m_Properties.SetNumber("FXDelayFeedback", this->m_nFXDelayFeedback);
+
+ this->m_Properties.SetNumber("FXReverberatorEnable", this->m_bFXReverberatorEnable ? 1 : 0);
+ this->m_Properties.SetNumber("FXReverberatorInputGain", this->m_nFXReverberatorInputGain);
+ this->m_Properties.SetNumber("FXReverberatorTime", this->m_nFXReverberatorTime);
+ this->m_Properties.SetNumber("FXReverberatorDiffusion", this->m_nFXReverberatorDiffusion);
+ this->m_Properties.SetNumber("FXReverberatorLP", this->m_nFXReverberatorLP);
+
+ for(unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
+ {
+ for(size_t toFX = 0; toFX < MixerOutput::kFXCount; ++toFX)
+ {
+ CString propertyName;
+ propertyName.Format("FXSend_TG%u_to_%s", nTG + 1, toString(static_cast(toFX)).c_str());
+ this->m_Properties.SetNumber(propertyName, this->m_nTGSendLevel[nTG][toFX]);
+ }
+ }
-#ifdef ARM_ALLOW_MULTI_CORE
- this->m_Properties.SetNumber("FXChainEnable", m_bFXChainEnable ? 1 : 0);
- this->m_Properties.SetNumber("FXChainWet", m_nFXChainWet);
- this->m_Properties.SetNumber("FXChainTubeEnable", m_bFXChainTubeEnable ? 1 : 0);
- this->m_Properties.SetNumber("FXChainTubeWet", m_nFXChainTubeWet);
- this->m_Properties.SetNumber("FXChainTubeOverdrive", m_nFXChainTubeOverdrive);
- this->m_Properties.SetNumber("FXChainChorusEnable", m_bFXChainChorusEnable ? 1 : 0);
- this->m_Properties.SetNumber("FXChainChorusWet", m_nFXChainChorusWet);
- this->m_Properties.SetNumber("FXChainChorusRate", m_nFXChainChorusRate);
- this->m_Properties.SetNumber("FXChainChorusDepth", m_nFXChainChorusDepth);
- this->m_Properties.SetNumber("FXChainFlangerEnable", m_bFXChainFlangerEnable ? 1 : 0);
- this->m_Properties.SetNumber("FXChainFlangerWet", m_nFXChainFlangerWet);
- this->m_Properties.SetNumber("FXChainFlangerRate", m_nFXChainFlangerRate);
- this->m_Properties.SetNumber("FXChainFlangerDepth", m_nFXChainFlangerDepth);
- this->m_Properties.SetNumber("FXChainFlangerFeedback", m_nFXChainFlangerFeedback);
- this->m_Properties.SetNumber("FXChainOrbitoneEnable", m_bFXChainOrbitoneEnable ? 1 : 0);
- this->m_Properties.SetNumber("FXChainOrbitoneWet", m_nFXChainOrbitoneWet);
- this->m_Properties.SetNumber("FXChainOrbitoneRate", m_nFXChainOrbitoneRate);
- this->m_Properties.SetNumber("FXChainOrbitoneDepth", m_nFXChainOrbitoneDepth);
- this->m_Properties.SetNumber("FXChainPhaserEnable", m_bFXChainPhaserEnable ? 1 : 0);
- this->m_Properties.SetNumber("FXChainPhaserWet", m_nFXChainPhaserWet);
- this->m_Properties.SetNumber("FXChainPhaserRate", m_nFXChainPhaserRate);
- this->m_Properties.SetNumber("FXChainPhaserDepth", m_nFXChainPhaserDepth);
- this->m_Properties.SetNumber("FXChainPhaserFeedback", m_nFXChainPhaserFeedback);
- this->m_Properties.SetNumber("FXChainPhaserNbStages", m_nFXChainPhaserNbStages);
- 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);
- this->m_Properties.SetNumber("FXChainShimmerReverbTime", m_nFXChainShimmerReverbTime);
- this->m_Properties.SetNumber("FXChainShimmerReverbDiffusion", m_nFXChainShimmerReverbDiffusion);
- this->m_Properties.SetNumber("FXChainShimmerReverbLP", m_nFXChainShimmerReverbLP);
+ size_t end = MixerOutput::kFXCount - 1;
+ for(size_t fromFX = 0; fromFX < end; ++fromFX)
+ {
+ for(size_t toFX = 0; toFX < MixerOutput::kFXCount; ++toFX)
+ {
+ CString propertyName;
+ propertyName.Format("FXSend_%s_to_%s", toString(static_cast(fromFX)).c_str(), toString(static_cast(toFX)).c_str());
+ this->m_Properties.SetNumber(propertyName, this->m_nFXSendLevel[fromFX][toFX]);
+ }
+ }
+
+ this->m_Properties.SetNumber("FXBypass", this->m_bFXBypass ? 1 : 0);
#endif
return m_Properties.Save ();
@@ -425,11 +487,13 @@ int CPerformanceConfig::GetNoteShift (unsigned nTG) const
return m_nNoteShift[nTG];
}
+#if defined(PLATE_REVERB_ENABLE)
unsigned CPerformanceConfig::GetReverbSend (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nReverbSend[nTG];
}
+#endif
void CPerformanceConfig::SetBankNumber (unsigned nValue, unsigned nTG)
{
@@ -497,11 +561,13 @@ void CPerformanceConfig::SetNoteShift (int nValue, unsigned nTG)
m_nNoteShift[nTG] = nValue;
}
+#if defined(PLATE_REVERB_ENABLE)
void CPerformanceConfig::SetReverbSend (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nReverbSend[nTG] = nValue;
}
+#endif
bool CPerformanceConfig::GetCompressorEnable (void) const
{
@@ -927,9 +993,12 @@ bool CPerformanceConfig::ListPerformances()
Result = f_findfirst (&Directory, &FileInfo, "SD:/" PERFORMANCE_DIR, "*.ini");
for (unsigned i = 0; Result == FR_OK && FileInfo.fname[0]; i++)
{
- if (nLastPerformance >= NUM_PERFORMANCES) {
+ if (nLastPerformance >= NUM_PERFORMANCES)
+ {
LOGNOTE ("Skipping performance %s", FileInfo.fname);
- } else {
+ }
+ else
+ {
if (!(FileInfo.fattrib & (AM_HID | AM_SYS)))
{
std::string FileName = FileInfo.fname;
@@ -941,9 +1010,9 @@ bool CPerformanceConfig::ListPerformances()
{
nLastFileIndex=nPIndex;
}
-
+
m_nPerformanceFileName[nLastPerformance++]= FileName;
- }
+ }
}
}
@@ -952,15 +1021,14 @@ bool CPerformanceConfig::ListPerformances()
// sort by performance number-name
if (nLastPerformance > 2)
{
- sort (m_nPerformanceFileName+1, m_nPerformanceFileName + nLastPerformance); // default is always on first place. %%%%%%%%%%%%%%%%
+ sort (m_nPerformanceFileName+1, m_nPerformanceFileName + nLastPerformance); // default is always on first place. %%%%%%%%%%%%%%%%
}
}
LOGNOTE ("Number of Performances: %d", nLastPerformance);
-
+
return nInternalFolderOk;
}
-
void CPerformanceConfig::SetNewPerformance (unsigned nID)
{
@@ -1028,355 +1096,304 @@ bool CPerformanceConfig::DeletePerformance(unsigned nID)
return bOK;
}
-#ifdef ARM_ALLOW_MULTI_CORE
-bool CPerformanceConfig::GetFXChainEnable(void) const
-{
- return this->m_bFXChainEnable;
-}
-
-unsigned CPerformanceConfig::GetFXChainWet(void) const
-{
- return this->m_nFXChainWet;
-}
-
-bool CPerformanceConfig::GetFXChainTubeEnable(void) const
-{
- return this->m_bFXChainTubeEnable;
-}
-
-unsigned CPerformanceConfig::GetFXChainTubeWet(void) const
-{
- return this->m_nFXChainTubeWet;
-}
-
-unsigned CPerformanceConfig::GetFXChainTubeOverdrive(void) const
-{
- return this->m_nFXChainTubeOverdrive;
-}
-
-bool CPerformanceConfig::GetFXChainChorusEnable(void) const
-{
- return this->m_bFXChainChorusEnable;
-}
-
-unsigned CPerformanceConfig::GetFXChainChorusWet(void) const
-{
- return this->m_nFXChainChorusWet;
-}
-
-unsigned CPerformanceConfig::GetFXChainChorusRate(void) const
-{
- return this->m_nFXChainChorusRate;
-}
-
-unsigned CPerformanceConfig::GetFXChainChorusDepth(void) const
-{
- return this->m_nFXChainChorusDepth;
-}
-
-bool CPerformanceConfig::GetFXChainFlangerEnable(void) const
-{
- return this->m_bFXChainFlangerEnable;
-}
-
-unsigned CPerformanceConfig::GetFXChainFlangerWet(void) const
-{
- return this->m_nFXChainFlangerWet;
-}
-
-unsigned CPerformanceConfig::GetFXChainFlangerRate(void) const
-{
- return this->m_nFXChainFlangerRate;
-}
+#ifdef MIXING_CONSOLE_ENABLE
-unsigned CPerformanceConfig::GetFXChainFlangerDepth(void) const
+bool CPerformanceConfig::GetFXTubeEnable(void) const
{
- return this->m_nFXChainFlangerDepth;
+ return this->m_bFXTubeEnable;
}
-unsigned CPerformanceConfig::GetFXChainFlangerFeedback(void) const
+unsigned CPerformanceConfig::GetFXTubeOverdrive(void) const
{
- return this->m_nFXChainFlangerFeedback;
+ return this->m_nFXTubeOverdrive;
}
-bool CPerformanceConfig::GetFXChainOrbitoneEnable(void) const
+bool CPerformanceConfig::GetFXChorusEnable(void) const
{
- return this->m_bFXChainOrbitoneEnable;
+ return this->m_bFXChorusEnable;
}
-unsigned CPerformanceConfig::GetFXChainOrbitoneWet(void) const
+unsigned CPerformanceConfig::GetFXChorusRate(void) const
{
- return this->m_nFXChainOrbitoneWet;
+ return this->m_nFXChorusRate;
}
-unsigned CPerformanceConfig::GetFXChainOrbitoneRate(void) const
+unsigned CPerformanceConfig::GetFXChorusDepth(void) const
{
- return this->m_nFXChainOrbitoneRate;
+ return this->m_nFXChorusDepth;
}
-unsigned CPerformanceConfig::GetFXChainOrbitoneDepth(void) const
+bool CPerformanceConfig::GetFXFlangerEnable(void) const
{
- return this->m_nFXChainOrbitoneDepth;
+ return this->m_bFXFlangerEnable;
}
-bool CPerformanceConfig::GetFXChainPhaserEnable(void) const
+unsigned CPerformanceConfig::GetFXFlangerRate(void) const
{
- return this->m_bFXChainPhaserEnable;
+ return this->m_nFXFlangerRate;
}
-unsigned CPerformanceConfig::GetFXChainPhaserWet(void) const
+unsigned CPerformanceConfig::GetFXFlangerDepth(void) const
{
- return this->m_nFXChainPhaserWet;
+ return this->m_nFXFlangerDepth;
}
-unsigned CPerformanceConfig::GetFXChainPhaserRate(void) const
+unsigned CPerformanceConfig::GetFXFlangerFeedback(void) const
{
- return this->m_nFXChainPhaserRate;
+ return this->m_nFXFlangerFeedback;
}
-unsigned CPerformanceConfig::GetFXChainPhaserDepth(void) const
+bool CPerformanceConfig::GetFXOrbitoneEnable(void) const
{
- return this->m_nFXChainPhaserDepth;
+ return this->m_bFXOrbitoneEnable;
}
-unsigned CPerformanceConfig::GetFXChainPhaserFeedback(void) const
+unsigned CPerformanceConfig::GetFXOrbitoneRate(void) const
{
- return this->m_nFXChainPhaserFeedback;
+ return this->m_nFXOrbitoneRate;
}
-unsigned CPerformanceConfig::GetFXChainPhaserNbStages(void) const
+unsigned CPerformanceConfig::GetFXOrbitoneDepth(void) const
{
- return this->m_nFXChainPhaserNbStages;
+ return this->m_nFXOrbitoneDepth;
}
-bool CPerformanceConfig::GetFXChainDelayEnable(void) const
+bool CPerformanceConfig::GetFXPhaserEnable(void) const
{
- return this->m_bFXChainDelayEnable;
+ return this->m_bFXPhaserEnable;
}
-unsigned CPerformanceConfig::GetFXChainDelayWet(void) const
+unsigned CPerformanceConfig::GetFXPhaserRate(void) const
{
- return this->m_nFXChainDelayWet;
+ return this->m_nFXPhaserRate;
}
-unsigned CPerformanceConfig::GetFXChainDelayLeftDelayTime(void) const
+unsigned CPerformanceConfig::GetFXPhaserDepth(void) const
{
- return this->m_nFXChainDelayLeftDelayTime;
+ return this->m_nFXPhaserDepth;
}
-unsigned CPerformanceConfig::GetFXChainDelayRightDelayTime(void) const
+unsigned CPerformanceConfig::GetFXPhaserFeedback(void) const
{
- return this->m_nFXChainDelayRightDelayTime;
+ return this->m_nFXPhaserFeedback;
}
-unsigned CPerformanceConfig::GetFXChainDelayFeedback(void) const
+unsigned CPerformanceConfig::GetFXPhaserNbStages(void) const
{
- return this->m_nFXChainDelayFeedback;
+ return this->m_nFXPhaserNbStages;
}
-bool CPerformanceConfig::GetFXChainShimmerReverbEnable(void) const
+bool CPerformanceConfig::GetFXDelayEnable(void) const
{
- return this->m_bFXChainShimmerReverbEnable;
+ return this->m_bFXDelayEnable;
}
-unsigned CPerformanceConfig::GetFXChainShimmerReverbWet(void) const
+unsigned CPerformanceConfig::GetFXDelayLeftDelayTime(void) const
{
- return this->m_nFXChainShimmerReverbWet;
+ return this->m_nFXDelayLeftDelayTime;
}
-unsigned CPerformanceConfig::GetFXChainShimmerReverbInputGain(void) const
+unsigned CPerformanceConfig::GetFXDelayRightDelayTime(void) const
{
- return this->m_nFXChainShimmerReverbInputGain;
+ return this->m_nFXDelayRightDelayTime;
}
-unsigned CPerformanceConfig::GetFXChainShimmerReverbTime(void) const
+unsigned CPerformanceConfig::GetFXDelayFeedback(void) const
{
- return this->m_nFXChainShimmerReverbTime;
+ return this->m_nFXDelayFeedback;
}
-unsigned CPerformanceConfig::GetFXChainShimmerReverbDiffusion(void) const
+bool CPerformanceConfig::GetFXReverberatorEnable(void) const
{
- return this->m_nFXChainShimmerReverbDiffusion;
+ return this->m_bFXReverberatorEnable;
}
-unsigned CPerformanceConfig::GetFXChainShimmerReverbLP(void) const
+unsigned CPerformanceConfig::GetFXReverberatorInputGain(void) const
{
- return this->m_nFXChainShimmerReverbLP;
+ return this->m_nFXReverberatorInputGain;
}
-void CPerformanceConfig::SetFXChainEnable(bool bValue)
+unsigned CPerformanceConfig::GetFXReverberatorTime(void) const
{
- this->m_bFXChainEnable = bValue;
+ return this->m_nFXReverberatorTime;
}
-void CPerformanceConfig::SetFXChainWet(unsigned nValue)
+unsigned CPerformanceConfig::GetFXReverberatorDiffusion(void) const
{
- this->m_nFXChainWet = nValue;
+ return this->m_nFXReverberatorDiffusion;
}
-void CPerformanceConfig::SetFXChainTubeEnable(bool bValue)
+unsigned CPerformanceConfig::GetFXReverberatorLP(void) const
{
- this->m_bFXChainTubeEnable = bValue;
+ return this->m_nFXReverberatorLP;
}
-void CPerformanceConfig::SetFXChainTubeWet(unsigned nValue)
+unsigned CPerformanceConfig::GetTGSendLevel(unsigned in, MixerOutput fx) const
{
- this->m_nFXChainTubeWet = nValue;
+ assert(in < CConfig::ToneGenerators);
+ assert(fx < MixerOutput::kFXCount);
+ return this->m_nTGSendLevel[in][fx];
}
-void CPerformanceConfig::SetFXChainTubeOverdrive(unsigned nValue)
+unsigned CPerformanceConfig::GetFXSendLevel(MixerOutput fromFX, MixerOutput toFX) const
{
- this->m_nFXChainTubeOverdrive = nValue;
+ assert(fromFX < (MixerOutput::kFXCount - 1));
+ assert(toFX < MixerOutput::kFXCount);
+ return (fromFX == toFX) ? 0 : this->m_nFXSendLevel[fromFX][toFX];
}
-void CPerformanceConfig::SetFXChainChorusEnable(bool bValue)
+void CPerformanceConfig::SetFXTubeEnable(bool bValue)
{
- this->m_bFXChainChorusEnable = bValue;
+ this->m_bFXTubeEnable = bValue;
}
-void CPerformanceConfig::SetFXChainChorusWet(unsigned nValue)
+void CPerformanceConfig::SetFXTubeOverdrive(unsigned nValue)
{
- this->m_nFXChainChorusWet = nValue;
+ this->m_nFXTubeOverdrive = nValue;
}
-void CPerformanceConfig::SetFXChainChorusRate(unsigned nValue)
+void CPerformanceConfig::SetFXChorusEnable(bool bValue)
{
- this->m_nFXChainChorusRate = nValue;
+ this->m_bFXChorusEnable = bValue;
}
-void CPerformanceConfig::SetFXChainChorusDepth(unsigned nValue)
+void CPerformanceConfig::SetFXChorusRate(unsigned nValue)
{
- this->m_nFXChainChorusDepth = nValue;
+ this->m_nFXChorusRate = nValue;
}
-void CPerformanceConfig::SetFXChainFlangerEnable(bool bValue)
+void CPerformanceConfig::SetFXChorusDepth(unsigned nValue)
{
- this->m_bFXChainFlangerEnable = bValue;
+ this->m_nFXChorusDepth = nValue;
}
-void CPerformanceConfig::SetFXChainFlangerWet(unsigned nValue)
+void CPerformanceConfig::SetFXFlangerEnable(bool bValue)
{
- this->m_nFXChainFlangerWet = nValue;
+ this->m_bFXFlangerEnable = bValue;
}
-void CPerformanceConfig::SetFXChainFlangerRate(unsigned nValue)
+void CPerformanceConfig::SetFXFlangerRate(unsigned nValue)
{
- this->m_nFXChainFlangerRate = nValue;
+ this->m_nFXFlangerRate = nValue;
}
-void CPerformanceConfig::SetFXChainFlangerDepth(unsigned nValue)
+void CPerformanceConfig::SetFXFlangerDepth(unsigned nValue)
{
- this->m_nFXChainFlangerDepth = nValue;
+ this->m_nFXFlangerDepth = nValue;
}
-void CPerformanceConfig::SetFXChainFlangerFeedback(unsigned nValue)
+void CPerformanceConfig::SetFXFlangerFeedback(unsigned nValue)
{
- this->m_nFXChainFlangerFeedback = nValue;
+ this->m_nFXFlangerFeedback = nValue;
}
-void CPerformanceConfig::SetFXChainOrbitoneEnable(bool bValue)
+void CPerformanceConfig::SetFXOrbitoneEnable(bool bValue)
{
- this->m_bFXChainOrbitoneEnable = bValue;
+ this->m_bFXOrbitoneEnable = bValue;
}
-void CPerformanceConfig::SetFXChainOrbitoneWet(unsigned nValue)
+void CPerformanceConfig::SetFXOrbitoneRate(unsigned nValue)
{
- this->m_nFXChainOrbitoneWet = nValue;
+ this->m_nFXOrbitoneRate = nValue;
}
-void CPerformanceConfig::SetFXChainOrbitoneRate(unsigned nValue)
+void CPerformanceConfig::SetFXOrbitoneDepth(unsigned nValue)
{
- this->m_nFXChainOrbitoneRate = nValue;
+ this->m_nFXOrbitoneDepth = nValue;
}
-void CPerformanceConfig::SetFXChainOrbitoneDepth(unsigned nValue)
+void CPerformanceConfig::SetFXPhaserEnable(bool bValue)
{
- this->m_nFXChainOrbitoneDepth = nValue;
+ this->m_bFXPhaserEnable = bValue;
}
-void CPerformanceConfig::SetFXChainPhaserEnable(bool bValue)
+void CPerformanceConfig::SetFXPhaserRate(unsigned nValue)
{
- this->m_bFXChainPhaserEnable = bValue;
+ this->m_nFXPhaserRate = nValue;
}
-void CPerformanceConfig::SetFXChainPhaserWet(unsigned nValue)
+void CPerformanceConfig::SetFXPhaserDepth(unsigned nValue)
{
- this->m_nFXChainPhaserWet = nValue;
+ this->m_nFXPhaserDepth = nValue;
}
-void CPerformanceConfig::SetFXChainPhaserRate(unsigned nValue)
+void CPerformanceConfig::SetFXPhaserFeedback(unsigned nValue)
{
- this->m_nFXChainPhaserRate = nValue;
+ this->m_nFXPhaserFeedback = nValue;
}
-void CPerformanceConfig::SetFXChainPhaserDepth(unsigned nValue)
+void CPerformanceConfig::SetFXPhaserNbStages(unsigned nValue)
{
- this->m_nFXChainPhaserDepth = nValue;
+ this->m_nFXPhaserNbStages = nValue;
}
-void CPerformanceConfig::SetFXChainPhaserFeedback(unsigned nValue)
+void CPerformanceConfig::SetFXDelayEnable(unsigned bValue)
{
- this->m_nFXChainPhaserFeedback = nValue;
+ this->m_bFXDelayEnable = bValue;
}
-void CPerformanceConfig::SetFXChainPhaserNbStages(unsigned nValue)
+void CPerformanceConfig::SetFXDelayLeftDelayTime(unsigned nValue)
{
- this->m_nFXChainPhaserNbStages = nValue;
+ this->m_nFXDelayLeftDelayTime = nValue;
}
-void CPerformanceConfig::SetFXChainDelayEnable(unsigned bValue)
+void CPerformanceConfig::SetFXDelayRightDelayTime(unsigned nValue)
{
- this->m_bFXChainDelayEnable = bValue;
+ this->m_nFXDelayRightDelayTime = nValue;
}
-void CPerformanceConfig::SetFXChainDelayWet(unsigned nValue)
+void CPerformanceConfig::SetFXDelayFeedback(unsigned nValue)
{
- this->m_nFXChainDelayWet = nValue;
+ this->m_nFXDelayFeedback = nValue;
}
-void CPerformanceConfig::SetFXChainDelayLeftDelayTime(unsigned nValue)
+void CPerformanceConfig::SetFXReverberatorEnable(unsigned bValue)
{
- this->m_nFXChainDelayLeftDelayTime = nValue;
+ this->m_bFXReverberatorEnable = bValue;
}
-void CPerformanceConfig::SetFXChainDelayRightDelayTime(unsigned nValue)
+void CPerformanceConfig::SetFXReverberatorInputGain(unsigned nValue)
{
- this->m_nFXChainDelayRightDelayTime = nValue;
+ this->m_nFXReverberatorInputGain = nValue;
}
-void CPerformanceConfig::SetFXChainDelayFeedback(unsigned nValue)
+void CPerformanceConfig::SetFXReverberatorTime(unsigned nValue)
{
- this->m_nFXChainDelayFeedback = nValue;
+ this->m_nFXReverberatorTime = nValue;
}
-void CPerformanceConfig::SetFXChainShimmerReverbEnable(unsigned bValue)
+void CPerformanceConfig::SetFXReverberatorDiffusion(unsigned nValue)
{
- this->m_bFXChainShimmerReverbEnable = bValue;
+ this->m_nFXReverberatorDiffusion = nValue;
}
-void CPerformanceConfig::SetFXChainShimmerReverbWet(unsigned nValue)
+void CPerformanceConfig::SetFXReverberatorLP(unsigned nValue)
{
- this->m_nFXChainShimmerReverbWet = nValue;
+ this->m_nFXReverberatorLP = nValue;
}
-void CPerformanceConfig::SetFXChainShimmerReverbInputGain(unsigned nValue)
+void CPerformanceConfig::SetTGSendLevel(unsigned in, MixerOutput fx, unsigned nValue)
{
- this->m_nFXChainShimmerReverbInputGain = nValue;
+ assert(in < CConfig::ToneGenerators);
+ assert(fx < MixerOutput::kFXCount);
+ this->m_nTGSendLevel[in][fx] = nValue;
}
-void CPerformanceConfig::SetFXChainShimmerReverbTime(unsigned nValue)
+void CPerformanceConfig::SetFXSendLevel(MixerOutput fromFX, MixerOutput toFX, unsigned nValue)
{
- this->m_nFXChainShimmerReverbTime = nValue;
+ assert(fromFX < (MixerOutput::kFXCount - 1));
+ assert(toFX < MixerOutput::kFXCount);
+ this->m_nFXSendLevel[fromFX][toFX] = (fromFX == toFX) ? 0 : nValue;
}
-void CPerformanceConfig::SetFXChainShimmerReverbDiffusion(unsigned nValue)
+void CPerformanceConfig::SetFXBypass(bool bypass)
{
- this->m_nFXChainShimmerReverbDiffusion = nValue;
+ this->m_bFXBypass = bypass;
}
-void CPerformanceConfig::SetFXChainShimmerReverbLP(unsigned nValue)
+bool CPerformanceConfig::IsFXBypass() const
{
- this->m_nFXChainShimmerReverbLP = nValue;
+ return this->m_bFXBypass;
}
#endif
diff --git a/src/performanceconfig.h b/src/performanceconfig.h
index fd373f4..5e308f3 100644
--- a/src/performanceconfig.h
+++ b/src/performanceconfig.h
@@ -24,6 +24,7 @@
#define _performanceconfig_h
#include "config.h"
+#include "mixing_console_constants.h"
#include
#include
#define NUM_VOICE_PARAM 156
@@ -52,7 +53,9 @@ public:
unsigned GetNoteLimitLow (unsigned nTG) const; // 0 .. 127
unsigned GetNoteLimitHigh (unsigned nTG) const; // 0 .. 127
int GetNoteShift (unsigned nTG) const; // -24 .. 24
+#if defined(PLATE_REVERB_ENABLE)
unsigned GetReverbSend (unsigned nTG) const; // 0 .. 127
+#endif
unsigned GetPitchBendRange (unsigned nTG) const; // 0 .. 12
unsigned GetPitchBendStep (unsigned nTG) const; // 0 .. 12
unsigned GetPortamentoMode (unsigned nTG) const; // 0 .. 1
@@ -80,7 +83,9 @@ public:
void SetNoteLimitLow (unsigned nValue, unsigned nTG);
void SetNoteLimitHigh (unsigned nValue, unsigned nTG);
void SetNoteShift (int nValue, unsigned nTG);
+#if defined(PLATE_REVERB_ENABLE)
void SetReverbSend (unsigned nValue, unsigned nTG);
+#endif
void SetPitchBendRange (unsigned nValue, unsigned nTG);
void SetPitchBendStep (unsigned nValue, unsigned nTG);
void SetPortamentoMode (unsigned nValue, unsigned nTG);
@@ -118,78 +123,80 @@ public:
void SetReverbDiffusion (unsigned nValue);
void SetReverbLevel (unsigned nValue);
-#ifdef ARM_ALLOW_MULTI_CORE
- bool GetFXChainEnable(void) const;
- unsigned GetFXChainWet(void) const;
- bool GetFXChainTubeEnable(void) const;
- unsigned GetFXChainTubeWet(void) const;
- unsigned GetFXChainTubeOverdrive(void) const;
- bool GetFXChainChorusEnable(void) const;
- unsigned GetFXChainChorusWet(void) const;
- unsigned GetFXChainChorusRate(void) const;
- unsigned GetFXChainChorusDepth(void) const;
- bool GetFXChainFlangerEnable(void) const;
- unsigned GetFXChainFlangerWet(void) const;
- unsigned GetFXChainFlangerRate(void) const;
- unsigned GetFXChainFlangerDepth(void) const;
- unsigned GetFXChainFlangerFeedback(void) const;
- bool GetFXChainOrbitoneEnable(void) const;
- unsigned GetFXChainOrbitoneWet(void) const;
- unsigned GetFXChainOrbitoneRate(void) const;
- unsigned GetFXChainOrbitoneDepth(void) const;
- bool GetFXChainPhaserEnable(void) const;
- unsigned GetFXChainPhaserWet(void) const;
- unsigned GetFXChainPhaserRate(void) const;
- unsigned GetFXChainPhaserDepth(void) const;
- unsigned GetFXChainPhaserFeedback(void) const;
- unsigned GetFXChainPhaserNbStages(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;
- unsigned GetFXChainShimmerReverbTime(void) const;
- unsigned GetFXChainShimmerReverbDiffusion(void) const;
- unsigned GetFXChainShimmerReverbLP(void) const;
-
- void SetFXChainEnable(bool bValue);
- void SetFXChainWet(unsigned nValue);
- void SetFXChainTubeEnable(bool bValue);
- void SetFXChainTubeWet(unsigned nValue);
- void SetFXChainTubeOverdrive(unsigned nValue);
- void SetFXChainChorusEnable(bool bValue);
- void SetFXChainChorusWet(unsigned nValue);
- void SetFXChainChorusRate(unsigned nValue);
- void SetFXChainChorusDepth(unsigned nValue);
- void SetFXChainFlangerEnable(bool bValue);
- void SetFXChainFlangerWet(unsigned nValue);
- void SetFXChainFlangerRate(unsigned nValue);
- void SetFXChainFlangerDepth(unsigned nValue);
- void SetFXChainFlangerFeedback(unsigned nValue);
- void SetFXChainOrbitoneEnable(bool bValue);
- void SetFXChainOrbitoneWet(unsigned nValue);
- void SetFXChainOrbitoneRate(unsigned nValue);
- void SetFXChainOrbitoneDepth(unsigned nValue);
- void SetFXChainPhaserEnable(bool bValue);
- void SetFXChainPhaserWet(unsigned nValue);
- void SetFXChainPhaserRate(unsigned nValue);
- void SetFXChainPhaserDepth(unsigned nValue);
- void SetFXChainPhaserFeedback(unsigned nValue);
- void SetFXChainPhaserNbStages(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);
- void SetFXChainShimmerReverbTime(unsigned nValue);
- void SetFXChainShimmerReverbDiffusion(unsigned nValue);
- void SetFXChainShimmerReverbLP(unsigned nValue);
+#ifdef MIXING_CONSOLE_ENABLE
+ bool GetFXTubeEnable(void) const;
+ unsigned GetFXTubeOverdrive(void) const;
+
+ bool GetFXChorusEnable(void) const;
+ unsigned GetFXChorusRate(void) const;
+ unsigned GetFXChorusDepth(void) const;
+
+ bool GetFXFlangerEnable(void) const;
+ unsigned GetFXFlangerRate(void) const;
+ unsigned GetFXFlangerDepth(void) const;
+ unsigned GetFXFlangerFeedback(void) const;
+
+ bool GetFXOrbitoneEnable(void) const;
+ unsigned GetFXOrbitoneRate(void) const;
+ unsigned GetFXOrbitoneDepth(void) const;
+
+ bool GetFXPhaserEnable(void) const;
+ unsigned GetFXPhaserRate(void) const;
+ unsigned GetFXPhaserDepth(void) const;
+ unsigned GetFXPhaserFeedback(void) const;
+ unsigned GetFXPhaserNbStages(void) const;
+
+ bool GetFXDelayEnable(void) const;
+ unsigned GetFXDelayLeftDelayTime(void) const;
+ unsigned GetFXDelayRightDelayTime(void) const;
+ unsigned GetFXDelayFeedback(void) const;
+
+ bool GetFXReverberatorEnable(void) const;
+ unsigned GetFXReverberatorInputGain(void) const;
+ unsigned GetFXReverberatorTime(void) const;
+ unsigned GetFXReverberatorDiffusion(void) const;
+ unsigned GetFXReverberatorLP(void) const;
+ unsigned GetTGSendLevel(unsigned in, MixerOutput fx) const;
+ unsigned GetFXSendLevel(MixerOutput ret, MixerOutput fx) const;
+
+ void SetFXTubeEnable(bool bValue);
+ void SetFXTubeOverdrive(unsigned nValue);
+
+ void SetFXChorusEnable(bool bValue);
+ void SetFXChorusRate(unsigned nValue);
+ void SetFXChorusDepth(unsigned nValue);
+
+ void SetFXFlangerEnable(bool bValue);
+ void SetFXFlangerRate(unsigned nValue);
+ void SetFXFlangerDepth(unsigned nValue);
+ void SetFXFlangerFeedback(unsigned nValue);
+
+ void SetFXOrbitoneEnable(bool bValue);
+ void SetFXOrbitoneRate(unsigned nValue);
+ void SetFXOrbitoneDepth(unsigned nValue);
+
+ void SetFXPhaserEnable(bool bValue);
+ void SetFXPhaserRate(unsigned nValue);
+ void SetFXPhaserDepth(unsigned nValue);
+ void SetFXPhaserFeedback(unsigned nValue);
+ void SetFXPhaserNbStages(unsigned nValue);
+
+ void SetFXDelayEnable(unsigned nValue);
+ void SetFXDelayLeftDelayTime(unsigned nValue);
+ void SetFXDelayRightDelayTime(unsigned nValue);
+ void SetFXDelayFeedback(unsigned nValue);
+
+ void SetFXReverberatorEnable(unsigned nValue);
+ void SetFXReverberatorInputGain(unsigned nValue);
+ void SetFXReverberatorTime(unsigned nValue);
+ void SetFXReverberatorDiffusion(unsigned nValue);
+ void SetFXReverberatorLP(unsigned nValue);
+
+ void SetTGSendLevel(unsigned in, MixerOutput fx, unsigned nValue);
+ void SetFXSendLevel(MixerOutput fromFX, MixerOutput toFX, unsigned nValue);
+
+ void SetFXBypass(bool bypass);
+ bool IsFXBypass() const;
#endif
bool VoiceDataFilled(unsigned nTG);
@@ -222,7 +229,9 @@ private:
unsigned m_nNoteLimitLow[CConfig::ToneGenerators];
unsigned m_nNoteLimitHigh[CConfig::ToneGenerators];
int m_nNoteShift[CConfig::ToneGenerators];
+#if defined(PLATE_REVERB_ENABLE)
int m_nReverbSend[CConfig::ToneGenerators];
+#endif
unsigned m_nPitchBendRange[CConfig::ToneGenerators];
unsigned m_nPitchBendStep[CConfig::ToneGenerators];
unsigned m_nPortamentoMode[CConfig::ToneGenerators];
@@ -260,42 +269,46 @@ private:
unsigned m_nReverbDiffusion;
unsigned m_nReverbLevel;
-#ifdef ARM_ALLOW_MULTI_CORE
- bool m_bFXChainEnable;
- unsigned m_nFXChainWet;
- bool m_bFXChainTubeEnable;
- unsigned m_nFXChainTubeWet;
- unsigned m_nFXChainTubeOverdrive;
- bool m_bFXChainChorusEnable;
- unsigned m_nFXChainChorusWet;
- unsigned m_nFXChainChorusRate;
- unsigned m_nFXChainChorusDepth;
- bool m_bFXChainFlangerEnable;
- unsigned m_nFXChainFlangerWet;
- unsigned m_nFXChainFlangerRate;
- unsigned m_nFXChainFlangerDepth;
- unsigned m_nFXChainFlangerFeedback;
- bool m_bFXChainOrbitoneEnable;
- unsigned m_nFXChainOrbitoneWet;
- unsigned m_nFXChainOrbitoneRate;
- unsigned m_nFXChainOrbitoneDepth;
- bool m_bFXChainPhaserEnable;
- unsigned m_nFXChainPhaserWet;
- unsigned m_nFXChainPhaserRate;
- unsigned m_nFXChainPhaserDepth;
- unsigned m_nFXChainPhaserFeedback;
- unsigned m_nFXChainPhaserNbStages;
- bool m_bFXChainDelayEnable;
- unsigned m_nFXChainDelayWet;
- unsigned m_nFXChainDelayLeftDelayTime;
- unsigned m_nFXChainDelayRightDelayTime;
- unsigned m_nFXChainDelayFeedback;
- bool m_bFXChainShimmerReverbEnable;
- unsigned m_nFXChainShimmerReverbWet;
- unsigned m_nFXChainShimmerReverbInputGain;
- unsigned m_nFXChainShimmerReverbTime;
- unsigned m_nFXChainShimmerReverbDiffusion;
- unsigned m_nFXChainShimmerReverbLP;
+#if defined(MIXING_CONSOLE_ENABLE)
+ bool m_bFXTubeEnable;
+ unsigned m_nFXTubeWet;
+ unsigned m_nFXTubeOverdrive;
+
+ bool m_bFXChorusEnable;
+ unsigned m_nFXChorusRate;
+ unsigned m_nFXChorusDepth;
+
+ bool m_bFXFlangerEnable;
+ unsigned m_nFXFlangerRate;
+ unsigned m_nFXFlangerDepth;
+ unsigned m_nFXFlangerFeedback;
+
+ bool m_bFXOrbitoneEnable;
+ unsigned m_nFXOrbitoneRate;
+ unsigned m_nFXOrbitoneDepth;
+
+ bool m_bFXPhaserEnable;
+ unsigned m_nFXPhaserRate;
+ unsigned m_nFXPhaserDepth;
+ unsigned m_nFXPhaserFeedback;
+ unsigned m_nFXPhaserNbStages;
+
+ bool m_bFXDelayEnable;
+ unsigned m_nFXDelayLeftDelayTime;
+ unsigned m_nFXDelayRightDelayTime;
+ unsigned m_nFXDelayFeedback;
+
+ bool m_bFXReverberatorEnable;
+ unsigned m_nFXReverberatorInputGain;
+ unsigned m_nFXReverberatorTime;
+ unsigned m_nFXReverberatorDiffusion;
+ unsigned m_nFXReverberatorLP;
+
+ unsigned m_nTGSendLevel[CConfig::ToneGenerators + MixerOutput::kFXCount - 1][MixerOutput::kFXCount];
+ unsigned m_nFXSendLevel[MixerOutput::kFXCount - 1][MixerOutput::kFXCount];
+
+ bool m_bFXBypass;
+
#endif
};
diff --git a/src/test/Makefile b/src/test/Makefile
index c001e86..e308e22 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -6,8 +6,23 @@ EXE := $(BINDIR)/all_tests.bin
BETA := $(BINDIR)/beta.bin
CXX = g++
-CXXFLAGS = -g -Wall -std=c++20 -MMD -MP
-DEFINES = -DCPU=x86 -DDEBUG -DOUTPUT_FOLDER="\"$(OUTPUT_FOLDER)\""
+CXXFLAGS = -g -std=c++20 -MMD -MP -Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wmissing-declarations -Winline -Wundef -Wno-unused-parameter
+DEFINES = -DCPU=x86 -DOUTPUT_FOLDER="\"$(OUTPUT_FOLDER)\""
+
+ifeq ($(shell echo $(MODE) | tr '[:upper:]' '[:lower:]'), release)
+
+# RELEASE
+CXXFLAGS += -O3
+DEFINES += -DNDEBUG
+
+else
+
+# DEBUG
+CXXFLAGS += -g3
+DEFINES += -DDEBUG
+
+endif
+
INCLUDES = -I../../CMSIS_5/CMSIS/DSP/Include/ \
-I../../CMSIS_5/CMSIS/Core/Include/ \
-I../../Synth_Dexed/src/
@@ -34,7 +49,12 @@ FX__SRCS += ../fx_orbitone.cpp
FX__SRCS += ../fx_flanger.cpp
FX__SRCS += ../fx_delay.cpp
FX__SRCS += ../effect_platervbstereo.cpp
+FX__SRCS += ../fx_shimmer_helper.cpp
+FX__SRCS += ../fx_diffuser.cpp
+FX__SRCS += ../fx_pitch_shifter.cpp
FX__SRCS += ../fx_reverberator.cpp
+FX__SRCS += ../fx_shimmer_reverb.cpp
+FX__SRCS += ../fx_dry.cpp
FX__SRCS += ../fx_rack.cpp
TST_SRCS := $(filter-out waveplay.cpp $(wildcard beta*.cpp), $(wildcard *.cpp))
diff --git a/src/test/arm_functions.cpp b/src/test/arm_functions.cpp
index 2964f48..61a5f0d 100644
--- a/src/test/arm_functions.cpp
+++ b/src/test/arm_functions.cpp
@@ -35,9 +35,16 @@ void arm_fill_f32(float32_t value, float32_t *pDst, uint32_t blockSize)
float32_t arm_weighted_sum_f32(const float32_t *in, const float32_t *weights, uint32_t blockSize)
{
- float32_t m = 0.0f;
- for(size_t i = 0; i < blockSize; ++i) m += in[i] * weights[i];
- return m;
+ float32_t s = 0.0f;
+ float32_t w = 0.0f;
+
+ for(size_t i = 0; i < blockSize; ++i)
+ {
+ s += in[i] * weights[i];
+ w += weights[i];
+ }
+
+ return s / w;
}
void arm_clip_f32(const float32_t *pSrc, float32_t *pDst, float32_t low, float32_t high, uint32_t numSamples)
diff --git a/src/test/beta.cpp b/src/test/beta.cpp
new file mode 100644
index 0000000..3adea7e
--- /dev/null
+++ b/src/test/beta.cpp
@@ -0,0 +1,390 @@
+#include "test_fx_helper.h"
+
+#include
+#include
+#include
+
+class FastLFODebugger
+{
+public:
+ FastLFODebugger(float32_t sampling_rate, float32_t min_frequency, float32_t max_frequency, float32_t initial_phase, bool centered) :
+ SamplingFrequency(sampling_rate),
+ InitialPhase(initial_phase),
+ min_frequency_(min_frequency),
+ max_frequency_(max_frequency),
+ centered_(centered),
+ frequency_(0.0f),
+ nb_sub_increment_(1),
+ sub_increment_(0),
+ y0_(0.0f),
+ y1_(0.0f),
+ iir_coefficient_(0.0f),
+ initial_amplitude_(0.0f)
+ {
+ assert(this->min_frequency_ <= this->max_frequency_);
+ assert(this->max_frequency_ < sampling_rate / 2.0f);
+
+ this->setFrequency(this->min_frequency_);
+ }
+
+ ~FastLFODebugger()
+ {
+ }
+
+ inline float32_t getSamplingRate() const
+ {
+ return this->SamplingFrequency;
+ }
+
+ void setNormalizedFrequency(float32_t normalized_frequency)
+ {
+ normalized_frequency = constrain(normalized_frequency, 0.0f, 1.0f);
+ if(this->normalized_frequency_ != normalized_frequency)
+ {
+ float32_t frequency = mapfloat(normalized_frequency, 0.0f, 1.0f, this->min_frequency_, this->max_frequency_);
+ this->normalized_frequency_ = normalized_frequency;
+ this->frequency_ = frequency;
+ this->unitary_frequency_ = this->frequency_ / this->getSamplingRate();
+
+ this->nb_sub_increment_ = (frequency >= 3.0f ? 1 : 300);
+ this->unitary_frequency_ *= this->nb_sub_increment_;
+
+ this->updateCoefficient(1.0f);
+ }
+ }
+
+ float32_t getNormalizedFrequency() const
+ {
+ return this->normalized_frequency_;
+ }
+
+ void setFrequency(float32_t frequency)
+ {
+ frequency = constrain(frequency, this->min_frequency_, this->max_frequency_);
+ if(this->frequency_ != frequency)
+ {
+ float32_t normalized_frequency = mapfloat(frequency, this->min_frequency_, this->max_frequency_, 0.0f, 1.0f);
+ this->normalized_frequency_ = normalized_frequency;
+ this->frequency_ = frequency;
+ this->unitary_frequency_ = this->frequency_ / this->getSamplingRate();
+
+ this->nb_sub_increment_ = (frequency >= 3.0f ? 1 : 300);
+ this->unitary_frequency_ *= this->nb_sub_increment_;
+
+ this->updateCoefficient(1.0f);
+ }
+ }
+
+ float32_t getFrequency() const
+ {
+ return this->frequency_;
+ }
+
+ void updateCoefficient(float32_t correction_ratio)
+ {
+ float32_t frequency = this->unitary_frequency_ * correction_ratio;
+
+ float32_t sign = 16.0f;
+ frequency -= 0.25f;
+ if(frequency < 0.0f)
+ {
+ frequency = -frequency;
+ }
+ else
+ {
+ if(frequency > 0.5f)
+ {
+ frequency -= 0.5f;
+ }
+ else
+ {
+ sign = -16.0f;
+ }
+ }
+
+ this->iir_coefficient_ = sign * frequency * (1.0f - 2.0f * frequency);
+ this->initial_amplitude_ = this->iir_coefficient_ * 0.25f;
+
+ this->reset(correction_ratio);
+ }
+
+ void reset(float32_t correction_ratio = 1.0f)
+ {
+ // static const float32_t epsilon = 1e-7;
+
+ this->sub_increment_ = 0.0f;
+
+ // computing cos(0) = sin(-PI/2)
+ this->y1_ = this->initial_amplitude_;
+ this->y0_ = 0.5f;
+
+ // if(this->unitary_frequency_ == 0.0f)
+ // {
+ // return;
+ // }
+
+ // float32_t p_i = 2.0f * PI * this->unitary_frequency_ * correction_ratio / static_cast(this->nb_sub_increment_);
+ // float32_t p = PI / 2.0f;
+ // float32_t t_p = this->InitialPhase;
+ // if(t_p < p)
+ // {
+ // p -= 2.0f* PI;
+ // }
+ // float32_t current = 3.0f;
+ // while(abs(current, sin(this->InitialPhase)) > epsilon)
+ // {
+ // std::cout << "phase: " << p << std::endl;
+ // this->process();
+ // p += p_i;
+ // if(p > (6.0f * PI))
+ // cout << "ERROR: FLO is not precise enough" <<
+ // return;
+ // }
+ }
+
+ float32_t process()
+ {
+ float32_t temp = this->y0_;
+ float32_t current = temp + 0.5f;
+ if(this->centered_)
+ {
+ current = current * 2.0f - 1.0f;
+ }
+
+ if(this->sub_increment_ == 0)
+ {
+ this->y0_ = this->iir_coefficient_ * this->y0_ - this->y1_;
+ this->y1_ = temp;
+ this->current_ = current;
+ return current;
+ }
+
+ this->sub_increment_++;
+ if(this->sub_increment_ >= this->nb_sub_increment_)
+ {
+ this->sub_increment_ = 0;
+ }
+
+ return mapfloat(this->sub_increment_, 0, this->nb_sub_increment_, this->current_, current);
+ }
+
+ float32_t current() const
+ {
+ return this->current_;
+ }
+
+private:
+ const float32_t SamplingFrequency;
+ const float32_t InitialPhase;
+ const float32_t min_frequency_;
+ const float32_t max_frequency_;
+ const bool centered_;
+ float32_t frequency_;
+ float32_t normalized_frequency_;
+ float32_t unitary_frequency_;
+ size_t nb_sub_increment_;
+ size_t sub_increment_;
+
+ float32_t y0_;
+ float32_t y1_;
+ float32_t iir_coefficient_;
+ float32_t initial_amplitude_;
+ float32_t current_;
+};
+
+void updateCorrectionStep(float32_t& sign, float32_t& correction_ratio_step, int direction)
+{
+ if(sign == direction)
+ {
+ // does nothing
+ }
+ else if(sign == -direction)
+ {
+ sign = static_cast(direction);
+ correction_ratio_step /= 2.0f;
+ }
+ else
+ {
+ sign = static_cast(direction);
+ }
+
+ if(direction > 0)
+ {
+ std::cout << "LFO is too slow - correction ratio step becomes: " << (sign * correction_ratio_step);
+ }
+ else if(direction < 0)
+ {
+ std::cout << "LFO is too fast - correction ratio step becomes: " << (sign * correction_ratio_step);
+ }
+}
+
+TEST(BetaTesta, FastLFO)
+{
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ size_t NB = static_cast(1.0f * SAMPLING_FREQUENCY);
+ const float32_t freq = 1.5f;
+ const float32_t init_phase = PI / 2.0f;
+ float32_t correction_ratio = 1.0f;
+ float32_t correction_ratio_step = 8.0f/ SAMPLING_FREQUENCY;
+
+ FastLFODebugger lfo1(SAMPLING_FREQUENCY, freq, 440.0f, init_phase, true);
+ lfo1.setFrequency(freq);
+
+ const float32_t epsilon = 1e-3;
+
+ int nbTrials = 100000;
+ float32_t maxDiff;
+ float32_t sign = 0.0f;
+ float32_t phase;
+ float32_t phase_increment;
+ size_t maxOK = 0;
+ float32_t best_correction = correction_ratio;
+ while(nbTrials > 0)
+ {
+ maxDiff = 0.0f;
+ phase = init_phase;
+ correction_ratio += sign * correction_ratio_step;
+ std::cout << std::setprecision(9) << std::fixed << " - Testing correction_ratio: " << correction_ratio << std::endl;
+ lfo1.updateCoefficient(correction_ratio);
+ phase_increment = freq / SAMPLING_FREQUENCY;
+
+ for(size_t i = 0; i < NB; ++i)
+ {
+ float32_t v1 = lfo1.process();
+ float32_t v2 = sin(phase);
+ // std::cout << std::setprecision(9) << std::fixed << " + phase: " << phase << " // v1: " << v1 << " / v2: " << v2 << " => diff: " << (v2 - v1);
+
+ float32_t diff = abs(v1 - v2);
+ if(diff > maxDiff) maxDiff = diff;
+
+ // std::cout << " - OK: " << ((diff < epsilon) ? "Yes" : "No") << std::endl;
+
+ if(diff > epsilon)
+ {
+ if(maxOK < i)
+ {
+ maxOK = i + 1;
+ best_correction = correction_ratio;
+ }
+
+ int quater = 0;
+ if(phase > (PI / 2.0f)) ++quater;
+ if(phase > PI) ++quater;
+ if(phase > (3.0f * PI / 2.0f)) ++quater;
+
+ if(v1 < v2)
+ {
+ switch (quater)
+ {
+ case 0:
+ case 4:
+ // Sinus phase [0, PI / 2] => [0.00, 1.00]
+ // Sinus phase [3 * PI / 2, 2 * PI] => [-1.00, 0.00]
+ // lfo1 is too slow
+ updateCorrectionStep(sign, correction_ratio_step, +1);
+ break;
+
+ case 1:
+ case 3:
+ // Sinus phase [PI / 2, PI] => [1.00, 0.00]
+ // Sinus phase [PI, 3 * PI / 2] => [0.00, -1.00]
+ // lfo1 is too fast
+ updateCorrectionStep(sign, correction_ratio_step, -1);
+ break;
+
+ default:
+ FAIL() << "Issue on phase: " << phase;
+ break;
+ }
+ break;
+ }
+ else
+ {
+ switch (quater)
+ {
+ case 0:
+ case 4:
+ // Sinus phase [0, PI / 2] => [0.00, 1.00]
+ // Sinus phase [3 * PI / 2, 2 * PI] => [-1.00, 0.00]
+ // lfo1 is too fast
+ updateCorrectionStep(sign, correction_ratio_step, -1);
+ break;
+
+ case 1:
+ case 3:
+ // Sinus phase [PI / 2, PI] => [1.00, 0.00]
+ // Sinus phase [PI, 3 * PI / 2] => [0.00, -1.00]
+ // lfo1 is too slow
+ updateCorrectionStep(sign, correction_ratio_step, +1);
+ break;
+
+ default:
+ FAIL() << "Issue on phase: " << phase;
+ break;
+ }
+ break;
+ }
+ }
+
+ if(correction_ratio_step < 1e-9) FAIL() << "correction_ratio_step became too small. maxOK = " << maxOK << " with best_correction = " << best_correction;
+
+ phase += phase_increment;
+ if(phase > 2.0f * PI) phase -= 2.0f * PI;
+ }
+
+ --nbTrials;
+ }
+ if(nbTrials > -2)
+ std::cout << "Correct correction ratio = " << correction_ratio << " with maxDiff = " << maxDiff << std::endl;
+ else
+ std::cout << "No matching correction ratio" << std::endl;
+
+ std::cout << "maxOK = " << maxOK << " with best_correction = " << best_correction << std::endl;;
+
+
+ // std::stringstream ssFst;
+ // std::stringstream ssSin;
+
+ // for(size_t i = 0; i < NB; ++i)
+ // {
+ // ssFst << lfo1.process() << (i == (NB - 1) ? "" : ", ");
+ // ssSin << sin(2.0f * PI * freq * i / SAMPLING_FREQUENCY + init_phase) << (i == (NB - 1) ? "" : ", ");
+ // }
+
+ // std::ofstream _fst(getResultFile(full_test_name + ".fst.data", true));
+ // _fst << ssFst.str();
+ // _fst.close();
+
+ // std::ofstream _sin(getResultFile(full_test_name + ".sin.data", true));
+ // _sin << ssSin.str();
+ // _sin.close();
+
+
+ // std::ofstream out(getResultFile(full_test_name + ".data.m", true));
+ // out << "# m file to tune FastLFO component" << std::endl << std::endl;
+ // out << "# Parameters:" << std::endl
+ // << "# + frequency: " << freq << "Hz" << std::endl
+ // << "# + # samples: " << NB << std::endl << std::endl;
+
+ // out << "time = 0 : " << (NB - 1) << ";" << std::endl;
+ // out << "fst_lfo = load(\"-ascii\", \"" << full_test_name << ".fst.data\");" << std::endl;
+ // out << "sin_lfo = load(\"-ascii\", \"" << full_test_name << ".sin.data\");" << std::endl;
+
+ // out << std::endl << std::endl;
+
+ // out << "plot(time, fst_lfo, '-', time, sin_lfo, '-');" << std::endl;
+ // out << "title('LFO tuning');" << std::endl;
+ // out << "legend('FastLFODebugger', 'Sinus');" << std::endl;
+
+ // out.close();
+}
+
+int main(int argc, char **argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/test/test_fxLevelTuning.cpp b/src/test/test_fxLevelTuning.cpp
index 38571ed..90f2328 100644
--- a/src/test/test_fxLevelTuning.cpp
+++ b/src/test/test_fxLevelTuning.cpp
@@ -177,8 +177,6 @@ TEST(LevelTuning, Delay)
fx.setLeftDelayTime(0.15f);
fx.setLeftDelayTime(0.2f);
fx.setFeedback(0.35f);
- fx.setFlutterRate(0.0f);
- fx.setFlutterAmount(0.0f);
PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
float32_t sumIn = 0.0f;
diff --git a/src/test/test_fx_components.cpp b/src/test/test_fx_components.cpp
index 6c23d75..e812a19 100644
--- a/src/test/test_fx_components.cpp
+++ b/src/test/test_fx_components.cpp
@@ -12,6 +12,8 @@
#define MAX_SVF_SAMPLES 10000000
#define MAX_NB_ERRORS 100
+void testFastLFOPrecision(std::string file, float32_t freq, float32_t init_phase);
+
TEST(FXComponent, LFO)
{
const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
@@ -141,10 +143,10 @@ void testFastLFOPrecision(std::string file, float32_t freq, float32_t init_phase
lfo1.setFrequency(freq);
lfo2.setFrequency(freq);
- std::string file0 = std::string("data/") + file + ".ComplexLFO." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data";
- std::string file1 = std::string("data/") + file + ".FastLFO." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data";
- std::string file2 = std::string("data/") + file + ".FastLFO2." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data";
- std::string file3 = std::string(file + ".") + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data.m";
+ std::string file0 = string("data/") + file + ".ComplexLFO." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data";
+ std::string file1 = string("data/") + file + ".FastLFO." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data";
+ std::string file2 = string("data/") + file + ".FastLFO2." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data";
+ std::string file3 = string(file + ".") + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data.m";
std::ofstream _lfo0(getResultFile(file0, true));
std::ofstream _lfo1(getResultFile(file1, true));
@@ -180,7 +182,7 @@ void testFastLFOPrecision(std::string file, float32_t freq, float32_t init_phase
_m << "fast_lfo = load(\"-ascii\", \"" << file1 << "\");" << std::endl;
_m << "fast_lfo2 = load(\"-ascii\", \"" << file2 << "\");" << std::endl;
_m << "plot(time, cplx_lfo, '-b', 'LineWidth', 6, time, fast_lfo, '-r', 'LineWidth', 4, time, fast_lfo2, '-o', 'LineWidth', 4);" << std::endl;
- _m << "title('LFO tuning @ " << freq << "Hz / " << init_phase_deg << "�');" << std::endl;
+ _m << "title('LFO tuning @ " << freq << "Hz / " << init_phase_deg << "°');" << std::endl;
_m << "legend('ComplexLFO', 'FastLFO');" << std::endl;
_m.close();
diff --git a/src/test/test_fx_helper.h b/src/test/test_fx_helper.h
index 66fd41e..b574fc8 100644
--- a/src/test/test_fx_helper.h
+++ b/src/test/test_fx_helper.h
@@ -1,3 +1,22 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//
+// test_fx_helper.h
+//
+// Set og helpers dedicated to code rationalization for the elaboration on unit tests.
+// Author: Vincent Gauché
+//
#pragma once
#include
diff --git a/src/test/test_fx_mixing_console.cpp b/src/test/test_fx_mixing_console.cpp
new file mode 100644
index 0000000..d08deba
--- /dev/null
+++ b/src/test/test_fx_mixing_console.cpp
@@ -0,0 +1,565 @@
+#include
+#include
+
+#include "test_fx_helper.h"
+#include "wave.h"
+
+#include "../mixing_console.hpp"
+
+#define NB_MIXER_CHANNELS 8
+
+class MixingConsoleScenarioTest : public testing::TestWithParam {};
+
+typedef MixingConsole Mixer;
+
+void setupMixingConsoleFX(Mixer* mixer);
+void setupMixingConsoleFX(Mixer* mixer, int scenarioId, size_t channel = 0);
+
+TEST_P(MixingConsoleScenarioTest, MixerOutputTest)
+{
+ MixerOutput v = this->GetParam();
+ std::string str = toString(v);
+ MixerOutput mo = toIndex(str.c_str());
+ ASSERT_EQ(v, mo);
+}
+
+INSTANTIATE_TEST_SUITE_P(MixerOutputTest, MixingConsoleScenarioTest, testing::Range(MixerOutput::OutputStart, MixerOutput::kFXCount));
+
+void setupMixingConsoleFX(Mixer* mixer)
+{
+ mixer->setChannelLevel(0, 1.0f);
+ mixer->setPan(0, 0.5f);
+
+ mixer->getTube()->setMute(false);
+ mixer->getTube()->setOverdrive(0.85f);
+
+ mixer->getChorus()->setMute(false);
+ mixer->getChorus()->setRate(0.4f);
+ mixer->getChorus()->setDepth(0.7f);
+
+ mixer->getFlanger()->setMute(false);
+ mixer->getFlanger()->setRate(0.03f);
+ mixer->getFlanger()->setDepth(0.75f);
+ mixer->getFlanger()->setFeedback(0.7f);
+
+ mixer->getOrbitone()->setMute(false);
+ mixer->getOrbitone()->setRate(0.4f);
+ mixer->getOrbitone()->setDepth(0.8f);
+
+ mixer->getPhaser()->setMute(false);
+ mixer->getPhaser()->setRate(0.1f);
+ mixer->getPhaser()->setDepth(1.0f);
+ mixer->getPhaser()->setFeedback(0.7f);
+ mixer->getPhaser()->setNbStages(12);
+
+ mixer->getDelay()->setMute(false);
+ mixer->getDelay()->setLeftDelayTime(0.15f);
+ mixer->getDelay()->setLeftDelayTime(0.20f);
+ mixer->getDelay()->setFeedback(0.7f);
+
+ mixer->getPlateReverb()->setMute(false);
+ mixer->getPlateReverb()->set_bypass(false);
+ mixer->getPlateReverb()->size(0.7f);
+ mixer->getPlateReverb()->hidamp(0.5f);
+ mixer->getPlateReverb()->lodamp(0.5f);
+ mixer->getPlateReverb()->lowpass(0.3f);
+ mixer->getPlateReverb()->diffusion(0.65f);
+ mixer->getPlateReverb()->level(1.0f);
+
+ mixer->getReverberator()->setMute(false);
+ mixer->getReverberator()->setInputGain(0.65f);
+ mixer->getReverberator()->setTime(0.89f);
+ mixer->getReverberator()->setDiffusion(0.75f);
+ mixer->getReverberator()->setLP(0.8f);
+}
+
+#define ACTIVE_FX(activity, scenarioId, fx) activity[MixerOutput::fx] = ((scenarioId & (1 << MixerOutput::fx)) == (1 << MixerOutput::fx))
+
+void setupMixingConsoleFX(Mixer* mixer, int scenarioId, size_t channel)
+{
+ mixer->setChannelLevel(channel, 1.0f);
+ mixer->setPan(channel, 0.5f);
+
+ bool fxActivity[MixerOutput::kFXCount - 1];
+ ACTIVE_FX(fxActivity, scenarioId, FX_Tube);
+ ACTIVE_FX(fxActivity, scenarioId, FX_Chorus);
+ ACTIVE_FX(fxActivity, scenarioId, FX_Flanger);
+ ACTIVE_FX(fxActivity, scenarioId, FX_Orbitone);
+ ACTIVE_FX(fxActivity, scenarioId, FX_Phaser);
+ ACTIVE_FX(fxActivity, scenarioId, FX_Delay);
+ ACTIVE_FX(fxActivity, scenarioId, FX_PlateReverb);
+ ACTIVE_FX(fxActivity, scenarioId, FX_Reverberator);
+
+ size_t nbActiveFX = 0;
+ MixerOutput previousActivatedFX = MixerOutput::MainOutput;
+
+ for(size_t i = 0; i < (MixerOutput::kFXCount - 1); ++i)
+ {
+ if(fxActivity[i])
+ {
+ nbActiveFX++;
+ if(nbActiveFX == 1)
+ {
+ mixer->setSendLevel(channel, static_cast(i), 1.0f);
+ }
+ else
+ {
+ mixer->setFXSendLevel(previousActivatedFX, static_cast(i), 1.0f);
+ }
+ previousActivatedFX = static_cast(i);
+ }
+ }
+
+ if(previousActivatedFX == MixerOutput::MainOutput)
+ {
+ mixer->setSendLevel(channel, MixerOutput::MainOutput, 1.0f);
+ }
+ else
+ {
+ mixer->setSendLevel(channel, MixerOutput::MainOutput, 0.25f);
+ mixer->setFXSendLevel(previousActivatedFX, MixerOutput::MainOutput, 0.75f);
+ }
+}
+
+TEST(MixingConsole, ZeroSamplesTest)
+{
+ static const size_t length = 4;
+
+ Mixer mixer(SAMPLING_FREQUENCY, length);
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+
+ mixer.reset();
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+
+ setupMixingConsoleFX(&mixer);
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+
+ mixer.setChannelLevel(0, 1.0f);
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+
+ mixer.setPan(0, 0.5f);
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+
+ float32_t samples[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ mixer.setInputSampleBuffer(0, samples);
+ mixer.preProcessInputSampleBuffer(0, 4);
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+
+ mixer.setSendLevel(0, MixerOutput::MainOutput, 1.0f);
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+
+ float32_t outL[4];
+ float32_t outR[4];
+ mixer.process(outL, outR);
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+
+ mixer.setSendLevel(0, MixerOutput::FX_Tube, 1.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Delay, 1.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_PlateReverb, 1.0f);
+
+ mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Orbitone, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::MainOutput, 0.5f);
+ mixer.setFXSendLevel(MixerOutput::FX_Orbitone, MixerOutput::FX_PlateReverb, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Delay, MixerOutput::MainOutput, 0.5f);
+ mixer.setFXSendLevel(MixerOutput::FX_PlateReverb, MixerOutput::MainOutput, 0.5f);
+ ASSERT_EQ(0, FULL_INSPECT((&mixer), true));
+}
+
+TEST(MixingConsole, DryProcessing)
+{
+ static const float32_t epsilon = 1e-4;
+ static const size_t length = 2;
+
+ Mixer mixer(SAMPLING_FREQUENCY, length);
+ mixer.reset();
+ mixer.setChannelLevel(0, 1.0f);
+ mixer.setPan(0, 0.5f);
+
+ mixer.setSendLevel(0, MixerOutput::FX_Tube, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Chorus, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Flanger, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Orbitone, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Phaser, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Delay, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_PlateReverb, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Reverberator, 0.0f);
+
+ for(size_t i = MixerOutput::OutputStart; i < (MixerOutput::kFXCount - 1); ++i)
+ {
+ mixer.setFXSendLevel(static_cast(i), MixerOutput::MainOutput, 0.0f);
+ }
+
+ mixer.setSendLevel(0, MixerOutput::MainOutput, 1.0f);
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ float32_t in[length] = {0.1, 0.2};
+ float32_t out[StereoChannels::kNumChannels][length];
+ for(size_t i = 0; i < StereoChannels::kNumChannels; ++i) memset(out[i], 0, length * sizeof(float32_t));
+
+ mixer.setInputSampleBuffer(0, in);
+ mixer.preProcessInputSampleBuffer(0, 2);
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ mixer.process(
+ out[StereoChannels::Left ],
+ out[StereoChannels::Right]
+ );
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ EXPECT_FLOAT_EQ(out[StereoChannels::Left ][0], out[StereoChannels::Right][0]);
+ EXPECT_FLOAT_EQ(out[StereoChannels::Left ][1], out[StereoChannels::Right][1]);
+ EXPECT_NEAR(out[StereoChannels::Left ][0], sqrt(2.0f) / 20.0f, epsilon);
+ EXPECT_NEAR(out[StereoChannels::Left ][1], sqrt(2.0f) / 10.0f, epsilon);
+}
+
+TEST(MixingConsole, ReverberatorProcessing)
+{
+ static const float32_t epsilon = 1e-7;
+ static const size_t length = 2;
+
+ Mixer mixer(SAMPLING_FREQUENCY, length);
+ mixer.reset();
+ mixer.setChannelLevel(0, 1.0f);
+ mixer.setPan(0, 0.5f);
+
+ mixer.setSendLevel(0, MixerOutput::MainOutput, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Reverberator, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, 1.0f);
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ float32_t in[length] = {0.1, 0.2};
+ float32_t out1[StereoChannels::kNumChannels][length];
+ for(size_t i = 0; i < StereoChannels::kNumChannels; ++i) memset(out1[i], 0, length * sizeof(float32_t));
+
+ mixer.setInputSampleBuffer(0, in);
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ mixer.process(
+ out1[StereoChannels::Left ],
+ out1[StereoChannels::Right]
+ );
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ mixer.reset();
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ float32_t out2[StereoChannels::kNumChannels][length];
+ mixer.setInputSampleBuffer(0, in);
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ mixer.process(
+ out2[StereoChannels::Left ],
+ out2[StereoChannels::Right]
+ );
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ EXPECT_NEAR(out1[StereoChannels::Left ][0], out2[StereoChannels::Left ][0], epsilon);
+ EXPECT_NEAR(out1[StereoChannels::Right][0], out2[StereoChannels::Right][0], epsilon);
+ EXPECT_NEAR(out1[StereoChannels::Left ][1], out2[StereoChannels::Left ][1], epsilon);
+ EXPECT_NEAR(out1[StereoChannels::Right][1], out2[StereoChannels::Right][1], epsilon);
+}
+
+TEST(MixingConsole, ReverberatorNoiseProcessing)
+{
+ static const size_t length = 1024;
+
+ Mixer mixer(SAMPLING_FREQUENCY, length);
+ mixer.reset();
+ mixer.setChannelLevel(0, 1.0f);
+ mixer.setPan(0, 0.5f);
+
+ mixer.setSendLevel(0, MixerOutput::MainOutput, 0.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Reverberator, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, 1.0f);
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ float32_t in[length];
+ for(size_t i = 0; i < length; ++i) in[i] = getRandomValue();
+
+ float32_t out[StereoChannels::kNumChannels][length];
+ for(size_t i = 0; i < StereoChannels::kNumChannels; ++i) memset(out[i], 0, length * sizeof(float32_t));
+
+ mixer.setInputSampleBuffer(0, in);
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ mixer.process(
+ out[StereoChannels::Left ],
+ out[StereoChannels::Right]
+ );
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+}
+
+TEST(MixingConsole, StandardUsageProcessingByInjection)
+{
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+
+ Mixer mixer(SAMPLING_FREQUENCY, size);
+ setupMixingConsoleFX(&mixer);
+
+ mixer.getTube()->setOverdrive(0.15f);
+
+ mixer.setSendLevel(0, MixerOutput::FX_Tube, 1.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Phaser, 1.0f);
+ // mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput, 1.0f);
+ // mixer.setSendLevel(0, MixerOutput::FX_Chorus, 1.0f);
+ // mixer.setSendLevel(0, MixerOutput::FX_Reverberator, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Chorus, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Reverberator, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Delay, 1.0f);
+
+ mixer.setSendLevel(0, MixerOutput::MainOutput, 0.25f);
+ mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput, 0.1f);
+ mixer.setFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::MainOutput, 0.15f);
+ mixer.setFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, 0.3f);
+ mixer.setFXSendLevel(MixerOutput::FX_Delay, MixerOutput::MainOutput, 0.3f);
+
+ mixer.injectInputSamples(0, inSamples[StereoChannels::Left], inSamples[StereoChannels::Right], size);
+ mixer.process(outSamples[0], outSamples[1]);
+ ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamples[0], outSamples[1], size, static_cast(SAMPLING_FREQUENCY), 16);
+
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
+
+TEST(MixingConsole, StandardUsageProcessing)
+{
+ static const size_t MAX_BUFFER_SIZE = 4096;
+ static const size_t BUFFER_SIZE = 256;
+
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+
+ Mixer mixer(SAMPLING_FREQUENCY, MAX_BUFFER_SIZE);
+
+ float32_t channelBuffer[MAX_BUFFER_SIZE];
+ memset(channelBuffer, 0, MAX_BUFFER_SIZE * sizeof(float32_t));
+ mixer.setInputSampleBuffer(0, channelBuffer);
+
+ setupMixingConsoleFX(&mixer);
+
+ mixer.getTube()->setOverdrive(0.15f);
+
+ mixer.setSendLevel(0, MixerOutput::FX_Tube, 1.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Phaser, 1.0f);
+ // mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput, 1.0f);
+ // mixer.setSendLevel(0, MixerOutput::FX_Chorus, 1.0f);
+ // mixer.setSendLevel(0, MixerOutput::FX_Reverberator, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Chorus, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Reverberator, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Delay, 1.0f);
+
+ mixer.setSendLevel(0, MixerOutput::MainOutput, 0.25f);
+ mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput, 0.1f);
+ mixer.setFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::MainOutput, 0.15f);
+ mixer.setFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, 0.3f);
+ mixer.setFXSendLevel(MixerOutput::FX_Delay, MixerOutput::MainOutput, 0.3f);
+
+ float32_t* inS = inSamples[StereoChannels::Left];
+ float32_t* outS[StereoChannels::kNumChannels];
+ outS[StereoChannels::Left ] = outSamples[StereoChannels::Left ];
+ outS[StereoChannels::Right] = outSamples[StereoChannels::Right];
+ size_t s = size;
+
+ while(s > 0)
+ {
+ size_t nb = (s > BUFFER_SIZE) ? BUFFER_SIZE : s;
+
+ memcpy(channelBuffer, inS, nb * sizeof(float32_t));
+
+ mixer.preProcessInputSampleBuffer(0, nb);
+ mixer.process(outS[StereoChannels::Left ], outS[StereoChannels::Right]);
+ // ASSERT_EQ(0, INSPECT((&mixer), fullInspector));
+
+ inS += nb;
+ outS[StereoChannels::Left ] += nb;
+ outS[StereoChannels::Right] += nb;
+ s -= nb;
+ }
+
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamples[0], outSamples[1], size, static_cast(SAMPLING_FREQUENCY), 16);
+
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
+
+TEST(MixingConsole, StandardUsageProcessingAllMixerChannels)
+{
+ static const size_t MAX_BUFFER_SIZE = 4096;
+ static const size_t BUFFER_SIZE = 256;
+
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+
+ Mixer mixer(SAMPLING_FREQUENCY, MAX_BUFFER_SIZE);
+
+ float32_t channelBuffer[NB_MIXER_CHANNELS][MAX_BUFFER_SIZE];
+ for(size_t i = 0; i < NB_MIXER_CHANNELS; ++i)
+ {
+ memset(channelBuffer[i], 0, MAX_BUFFER_SIZE * sizeof(float32_t));
+ mixer.setInputSampleBuffer(i, channelBuffer[i]);
+ }
+
+ setupMixingConsoleFX(&mixer);
+
+ mixer.getTube()->setOverdrive(0.15f);
+
+ mixer.setSendLevel(0, MixerOutput::FX_Tube, 1.0f);
+ mixer.setSendLevel(0, MixerOutput::FX_Phaser, 1.0f);
+ // mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput, 1.0f);
+ // mixer.setSendLevel(0, MixerOutput::FX_Chorus, 1.0f);
+ // mixer.setSendLevel(0, MixerOutput::FX_Reverberator, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::FX_Chorus, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::FX_Reverberator, 1.0f);
+ mixer.setFXSendLevel(MixerOutput::FX_Phaser, MixerOutput::FX_Delay, 1.0f);
+
+ mixer.setSendLevel(0, MixerOutput::MainOutput, 0.25f);
+ mixer.setFXSendLevel(MixerOutput::FX_Tube, MixerOutput::MainOutput, 0.1f);
+ mixer.setFXSendLevel(MixerOutput::FX_Chorus, MixerOutput::MainOutput, 0.15f);
+ mixer.setFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, 0.3f);
+ mixer.setFXSendLevel(MixerOutput::FX_Delay, MixerOutput::MainOutput, 0.3f);
+
+ float32_t* inS = inSamples[StereoChannels::Left];
+ float32_t* outS[StereoChannels::kNumChannels];
+ outS[StereoChannels::Left ] = outSamples[StereoChannels::Left ];
+ outS[StereoChannels::Right] = outSamples[StereoChannels::Right];
+ size_t s = size;
+
+ while(s > 0)
+ {
+ size_t nb = (s > BUFFER_SIZE) ? BUFFER_SIZE : s;
+
+ memcpy(channelBuffer[0], inS, nb * sizeof(float32_t));
+
+ for(size_t i = 0; i < mixer.getChannelNumber(); ++i)
+ {
+ mixer.preProcessInputSampleBuffer(i, nb);
+ }
+ mixer.process(outS[StereoChannels::Left ], outS[StereoChannels::Right]);
+
+ inS += nb;
+ outS[StereoChannels::Left ] += nb;
+ outS[StereoChannels::Right] += nb;
+ s -= nb;
+ }
+
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamples[0], outSamples[1], size, static_cast(SAMPLING_FREQUENCY), 16);
+
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
+
+TEST(MixingConsole, StandardUsageProcessingAllMixerChannels2)
+{
+ static const size_t MAX_BUFFER_SIZE = 4096;
+ static const size_t BUFFER_SIZE = 256;
+
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+
+ Mixer mixer(SAMPLING_FREQUENCY, MAX_BUFFER_SIZE);
+
+ float32_t channelBuffer[NB_MIXER_CHANNELS][MAX_BUFFER_SIZE];
+ for(size_t i = 0; i < NB_MIXER_CHANNELS; ++i)
+ {
+ memset(channelBuffer[i], 0, MAX_BUFFER_SIZE * sizeof(float32_t));
+ mixer.setInputSampleBuffer(i, channelBuffer[i]);
+ }
+
+ setupMixingConsoleFX(&mixer);
+
+ for(size_t i = 0; i < NB_MIXER_CHANNELS; ++i)
+ {
+ mixer.setSendLevel(i, static_cast(i), 1.0f);
+ mixer.setFXSendLevel(static_cast(i), MixerOutput::MainOutput, 0.5f);
+ mixer.setSendLevel(i, MixerOutput::MainOutput, 0.5f);
+ }
+
+ float32_t* inS = inSamples[StereoChannels::Left];
+ float32_t* outS[StereoChannels::kNumChannels];
+ outS[StereoChannels::Left ] = outSamples[StereoChannels::Left ];
+ outS[StereoChannels::Right] = outSamples[StereoChannels::Right];
+ size_t s = size;
+
+ while(s > 0)
+ {
+ size_t nb = (s > BUFFER_SIZE) ? BUFFER_SIZE : s;
+
+ for(size_t i = 0; i < mixer.getChannelNumber(); ++i)
+ {
+ memcpy(channelBuffer[i], inS, nb * sizeof(float32_t));
+ mixer.preProcessInputSampleBuffer(i, nb);
+ }
+ mixer.process(outS[StereoChannels::Left ], outS[StereoChannels::Right]);
+
+ inS += nb;
+ outS[StereoChannels::Left ] += nb;
+ outS[StereoChannels::Right] += nb;
+ s -= nb;
+ }
+
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamples[0], outSamples[1], size, static_cast(SAMPLING_FREQUENCY), 16);
+
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
+
+TEST_P(FXScenarioTest, FXProcessingScenario)
+{
+ static const size_t MAX_BUFFER_SIZE = 4096;
+ static const size_t BUFFER_SIZE = 256;
+
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+
+ Mixer mixer(SAMPLING_FREQUENCY, MAX_BUFFER_SIZE);
+
+ float32_t channelBuffer[NB_MIXER_CHANNELS][MAX_BUFFER_SIZE];
+ for(size_t i = 0; i < NB_MIXER_CHANNELS; ++i)
+ {
+ memset(channelBuffer[i], 0, MAX_BUFFER_SIZE * sizeof(float32_t));
+ mixer.setInputSampleBuffer(i, channelBuffer[i]);
+ }
+
+ setupMixingConsoleFX(&mixer);
+
+ int scenarioId = this->GetParam();
+ setupMixingConsoleFX((&mixer), scenarioId);
+
+ float32_t* inS = inSamples[StereoChannels::Left];
+ float32_t* outS[StereoChannels::kNumChannels];
+ outS[StereoChannels::Left ] = outSamples[StereoChannels::Left ];
+ outS[StereoChannels::Right] = outSamples[StereoChannels::Right];
+ size_t s = size;
+
+ while(s > 0)
+ {
+ size_t nb = (s > BUFFER_SIZE) ? BUFFER_SIZE : s;
+
+ for(size_t i = 0; i < mixer.getChannelNumber(); ++i)
+ {
+ memcpy(channelBuffer[i], inS, nb * sizeof(float32_t));
+ mixer.preProcessInputSampleBuffer(i, nb);
+ }
+ mixer.process(outS[StereoChannels::Left ], outS[StereoChannels::Right]);
+
+ inS += nb;
+ outS[StereoChannels::Left ] += nb;
+ outS[StereoChannels::Right] += nb;
+ s -= nb;
+ }
+
+ std::string filename = "";
+ for(size_t i = 0; i < (MixerOutput::kFXCount - 1); ++i)
+ {
+ int k = 1 << i;
+ if((scenarioId & k) == 0)
+ {
+ continue;
+ }
+
+ if(filename.size() > 0)
+ {
+ filename += ", ";
+ }
+ filename += toString(static_cast(i));
+ }
+
+ saveWaveFile(getResultFile(full_test_name + " mixing-console[ " + filename + " ].wav", true), outSamples[0], outSamples[1], size, static_cast(SAMPLING_FREQUENCY), 16);
+
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
+
+INSTANTIATE_TEST_SUITE_P(MixingConsole, FXScenarioTest, testing::Range(0, 1 << (MixerOutput::kFXCount - 1)));
diff --git a/src/test/test_fx_mixing_console_unitary.cpp b/src/test/test_fx_mixing_console_unitary.cpp
new file mode 100644
index 0000000..313d040
--- /dev/null
+++ b/src/test/test_fx_mixing_console_unitary.cpp
@@ -0,0 +1,187 @@
+#include "test_fx_helper.h"
+
+#include "../mixing_console.hpp"
+
+typedef MixingConsole<1> Mixer;
+
+TEST(MixingConsole, ShortBuffer)
+{
+ static const float32_t SINPI_4 = std::sqrt(2.0f) / 2.0f;
+ static const float32_t epsilon = 1e-4;
+
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ const size_t size = 10;
+ Mixer* mixer = new Mixer(SAMPLING_FREQUENCY, size);
+ mixer->reset();
+ mixer->setChannelLevel(0, 1.0f);
+ mixer->setPan(0, 0.5f);
+
+ mixer->setSendLevel(0, MixerOutput::MainOutput, 1.0f);
+
+ float32_t inSamples[size];
+ for(size_t s = 0; s < size; ++s) inSamples[s] = getRandomValue();
+ float32_t outSamples[2][size];
+ memset(outSamples[0], 0, size * sizeof(float32_t));
+ memset(outSamples[1], 0, size * sizeof(float32_t));
+
+ mixer->setInputSampleBuffer(0, inSamples);
+ mixer->preProcessInputSampleBuffer(0, size);
+ ASSERT_EQ(0, FULL_INSPECT(mixer, true)) << full_test_name << " Mixer.setInputSampleBuffer";
+
+ mixer->process(outSamples[0], outSamples[1]);
+ ASSERT_EQ(0, FULL_INSPECT(mixer, true)) << full_test_name << " Mixer.process";
+ for(size_t s = 0; s < size; ++s)
+ {
+ EXPECT_NEAR(outSamples[0][s], outSamples[1][s], epsilon);
+ EXPECT_NEAR(outSamples[0][s], inSamples[s] * SINPI_4, epsilon);
+ }
+
+ delete mixer;
+}
+
+TEST(MixingConsole, ReverberatorShortBuffer)
+{
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ const size_t size = 10;
+ Mixer* mixer = new Mixer(SAMPLING_FREQUENCY, size);
+ mixer->reset();
+ mixer->setChannelLevel(0, 1.0f);
+ mixer->setPan(0, 0.5f);
+
+ mixer->getReverberator()->setInputGain(0.35f);
+ mixer->getReverberator()->setTime(0.69f);
+ mixer->getReverberator()->setDiffusion(0.7f);
+ mixer->getReverberator()->setLP(0.8f);
+
+ mixer->setSendLevel(0, MixerOutput::MainOutput, 0.4f);
+ mixer->setSendLevel(0, MixerOutput::FX_Reverberator, 1.0f);
+ mixer->setFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, 0.6f);
+
+ float32_t inSamples[size];
+ for(size_t s = 0; s < size; ++s) inSamples[s] = getRandomValue();
+ float32_t outSamples[2][size];
+ memset(outSamples[0], 0, size * sizeof(float32_t));
+ memset(outSamples[1], 0, size * sizeof(float32_t));
+
+ mixer->setInputSampleBuffer(0, inSamples);
+ mixer->preProcessInputSampleBuffer(0, size);
+ ASSERT_EQ(0, FULL_INSPECT(mixer, true)) << full_test_name << " Mixer.setInputSampleBuffer";
+
+ mixer->process(outSamples[0], outSamples[1]);
+ ASSERT_EQ(0, FULL_INSPECT(mixer, true)) << full_test_name << " Mixer.process";
+
+ delete mixer;
+}
+
+TEST(MixingConsole, DrySamplesBoundariesTest)
+{
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ size_t size;
+ float32_t** inSamples = readWaveFile(AUDIO_SOURCE_FILE, size);
+
+ Mixer* mixer = new Mixer(SAMPLING_FREQUENCY, size);
+ mixer->reset();
+ FULL_INSPECT2(mixer, true, "Mixer.reset");
+
+ mixer->setChannelLevel(0, 1.0f);
+ mixer->setPan(0, 0.5f);
+ mixer->setSendLevel(0, MixerOutput::MainOutput, 1.0f);
+
+ mixer->setInputSampleBuffer(0, inSamples[0]);
+ mixer->preProcessInputSampleBuffer(0, size);
+
+ float32_t** outSamples = new float32_t*[2];
+ outSamples[0] = new float32_t[size];
+ outSamples[1] = new float32_t[size];
+ memset(outSamples[0], 0, size * sizeof(float32_t));
+ memset(outSamples[1], 0, size * sizeof(float32_t));
+
+ mixer->process(outSamples[0], outSamples[1]);
+
+ size_t nb_errors = 0;
+ for(size_t i = 0; i < size; ++i)
+ {
+ nb_errors += fullInspector(full_test_name + ".outputSampleTest", inSamples[0][i], -1.0f, 1.0f, true);
+ nb_errors += fullInspector(full_test_name + ".outputSampleTest", inSamples[1][i], -1.0f, 1.0f, true);
+ }
+ ASSERT_EQ(0, nb_errors) << full_test_name << ".outputSampleTest";
+
+ delete[] inSamples[0];
+ delete[] inSamples[1];
+ delete[] inSamples;
+
+ delete[] outSamples[0];
+ delete[] outSamples[1];
+ delete[] outSamples;
+
+ delete mixer;
+}
+
+TEST(MixingConsole, ReverberatorSamplesBoundariesTest)
+{
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ size_t size;
+ float32_t** inSamples = readWaveFile(AUDIO_SOURCE_FILE, size);
+
+ float32_t** outSamples = new float32_t*[2];
+ outSamples[0] = new float32_t[size];
+ outSamples[1] = new float32_t[size];
+ memset(outSamples[0], 0, size * sizeof(float32_t));
+ memset(outSamples[1], 0, size * sizeof(float32_t));
+
+ Mixer* mixer = new Mixer(SAMPLING_FREQUENCY, size);
+ mixer->reset();
+ mixer->setChannelLevel(0, 1.0f);
+ mixer->setPan(0, 0.5f);
+
+ mixer->setSendLevel(0, MixerOutput::MainOutput, 0.4f);
+ mixer->setSendLevel(0, MixerOutput::FX_Reverberator, 1.0f);
+ mixer->setFXSendLevel(MixerOutput::FX_Reverberator, MixerOutput::MainOutput, 0.6f);
+
+ mixer->getReverberator()->setMute(false);
+ mixer->getReverberator()->setInputGain(0.35);
+ mixer->getReverberator()->setTime(0.65);
+ mixer->getReverberator()->setDiffusion(0.8);
+ mixer->getReverberator()->setLP(0.7f);
+
+ mixer->setInputSampleBuffer(0, inSamples[0]);
+ mixer->preProcessInputSampleBuffer(0, size);
+ mixer->process(outSamples[0], outSamples[1]);
+ ASSERT_EQ(0, FULL_INSPECT2(mixer, true, full_test_name + "Mixer.process")) << full_test_name << " Mixer.process";
+
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamples[0], outSamples[1], size, static_cast(SAMPLING_FREQUENCY), 16);
+
+ size_t nb_errors = 0;
+ for(size_t i = 0; i < size; ++i)
+ {
+ nb_errors += fullInspector(full_test_name + ".outputSampleTest", inSamples[0][i], -1.0f, 1.0f, true);
+ nb_errors += fullInspector(full_test_name + ".outputSampleTest", inSamples[1][i], -1.0f, 1.0f, true);
+ }
+ ASSERT_EQ(0, nb_errors) << full_test_name << ".outputSampleTest";
+
+ delete[] inSamples[0];
+ delete[] inSamples[1];
+ delete[] inSamples;
+
+ delete[] outSamples[0];
+ delete[] outSamples[1];
+ delete[] outSamples;
+
+ delete mixer;
+}
diff --git a/src/test/test_fx_rack.cpp b/src/test/test_fx_rack.cpp
index 8d38dd5..53306a9 100644
--- a/src/test/test_fx_rack.cpp
+++ b/src/test/test_fx_rack.cpp
@@ -7,13 +7,15 @@ using namespace std;
#define MAX_SVF_SAMPLES 10000000
#define MAX_NB_ERRORS 100
+void setupRack(FXRack* rack, int scenario);
+
void setupRack(FXRack* rack, int scenario)
{
rack->setWetLevel(1.0f);
rack->getTube()->setEnable(Active(scenario, FXSwitch::FX__Tube));
rack->getTube()->setWetLevel(0.25f);
- rack->getTube()->setOverdrive(0.25f);
+ rack->getTube()->setOverdrive(0.5f);
rack->getChorus()->setEnable(Active(scenario, FXSwitch::FX__Chorus));
rack->getChorus()->setWetLevel(0.5f);
@@ -43,8 +45,6 @@ void setupRack(FXRack* rack, int scenario)
rack->getDelay()->setLeftDelayTime(0.05f);
rack->getDelay()->setLeftDelayTime(0.07f);
rack->getDelay()->setFeedback(0.35f);
- rack->getDelay()->setFlutterRate(0.0f);
- rack->getDelay()->setFlutterAmount(0.0f);
rack->getReverberator()->setEnable(Active(scenario, FXSwitch::FX__Reverberator));
rack->getReverberator()->setWetLevel(0.5f);
diff --git a/src/test/test_fx_shimmer_reverb.cpp b/src/test/test_fx_shimmer_reverb.cpp
new file mode 100644
index 0000000..272ce94
--- /dev/null
+++ b/src/test/test_fx_shimmer_reverb.cpp
@@ -0,0 +1,182 @@
+#include
+
+#include "test_fx_helper.h"
+#include "../fx_reverberator.h"
+
+TEST(FXShimmer, TransientSilence)
+{
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ const size_t size = static_cast(SAMPLING_FREQUENCY);
+ float32_t* inSamples = new float32_t[size];
+ memset(inSamples, 0, size * sizeof(float32_t));
+
+ float32_t* outSamplesL = new float32_t[size];
+ float32_t* outSamplesR = new float32_t[size];
+ memset(outSamplesL, 0, size * sizeof(float32_t));
+ memset(outSamplesR, 0, size * sizeof(float32_t));
+
+ Reverberator* shimmer = new Reverberator(SAMPLING_FREQUENCY);
+
+ shimmer->setInputGain(0.55f);
+ shimmer->setTime(0.75f);
+ shimmer->setDiffusion(0.8f);
+ shimmer->setLP(0.7f);
+
+ shimmer->reset();
+ for(size_t i = 0; i < size; ++i)
+ {
+ shimmer->processSample(
+ inSamples[i],
+ inSamples[i],
+ outSamplesL[i],
+ outSamplesR[i]
+ );
+ }
+
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamplesL, outSamplesR, size, SAMPLING_FREQUENCY, 16);
+
+ delete shimmer;
+
+ delete[] inSamples;
+
+ delete[] outSamplesL;
+ delete[] outSamplesR;
+}
+
+TEST(FXShimmer, TransientSilenceWithDirac)
+{
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ const size_t size = 4 * static_cast(SAMPLING_FREQUENCY);
+ float32_t* inSamples = new float32_t[size];
+ memset(inSamples, 0, size * sizeof(float32_t));
+ inSamples[0] = 1.0f;
+
+ float32_t* outSamplesL = new float32_t[size];
+ float32_t* outSamplesR = new float32_t[size];
+ memset(outSamplesL, 0, size * sizeof(float32_t));
+ memset(outSamplesR, 0, size * sizeof(float32_t));
+
+ Reverberator* shimmer = new Reverberator(SAMPLING_FREQUENCY);
+
+ shimmer->setInputGain(0.55f);
+ shimmer->setTime(0.75f);
+ shimmer->setDiffusion(0.8f);
+ shimmer->setLP(0.7f);
+
+ shimmer->reset();
+ for(size_t i = 0; i < size; ++i)
+ {
+ shimmer->processSample(
+ inSamples[i],
+ inSamples[i],
+ outSamplesL[i],
+ outSamplesR[i]
+ );
+ }
+
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamplesL, outSamplesR, size, SAMPLING_FREQUENCY, 16);
+
+ delete shimmer;
+
+ delete[] inSamples;
+
+ delete[] outSamplesL;
+ delete[] outSamplesR;
+}
+
+TEST(FXShimmer, TransientNoise)
+{
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ const size_t size = static_cast(SAMPLING_FREQUENCY);
+ float32_t* inSamples = new float32_t[size];
+ for(size_t i = 0; i < size; ++i) inSamples[i] = getRandomValue();
+
+ float32_t* outSamplesL = new float32_t[size];
+ float32_t* outSamplesR = new float32_t[size];
+ memset(outSamplesL, 0, size * sizeof(float32_t));
+ memset(outSamplesR, 0, size * sizeof(float32_t));
+
+ Reverberator* shimmer = new Reverberator(SAMPLING_FREQUENCY);
+
+ shimmer->setInputGain(0.55f);
+ shimmer->setTime(0.75f);
+ shimmer->setDiffusion(0.8f);
+ shimmer->setLP(0.7f);
+
+ shimmer->reset();
+ for(size_t i = 0; i < size; ++i)
+ {
+ shimmer->processSample(
+ inSamples[i],
+ inSamples[i],
+ outSamplesL[i],
+ outSamplesR[i]
+ );
+ }
+
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamplesL, outSamplesR, size, SAMPLING_FREQUENCY, 16);
+
+ delete shimmer;
+
+ delete[] inSamples;
+
+ delete[] outSamplesL;
+ delete[] outSamplesR;
+}
+
+TEST(FXShimmer, TransientMusic)
+{
+ const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info();
+ std::string full_test_name = test_info->test_case_name();
+ full_test_name += ".";
+ full_test_name += test_info->name();
+
+ size_t size;
+ float32_t** inSamples = readWaveFile(AUDIO_SOURCE_FILE, size);
+
+ float32_t* outSamplesL = new float32_t[size];
+ float32_t* outSamplesR = new float32_t[size];
+ memset(outSamplesL, 0, size * sizeof(float32_t));
+ memset(outSamplesR, 0, size * sizeof(float32_t));
+
+ Reverberator* shimmer = new Reverberator(SAMPLING_FREQUENCY);
+
+ shimmer->setInputGain(0.55f);
+ shimmer->setTime(0.75f);
+ shimmer->setDiffusion(0.8f);
+ shimmer->setLP(0.7f);
+
+ shimmer->reset();
+ for(size_t i = 0; i < size; ++i)
+ {
+ shimmer->processSample(
+ inSamples[0][i],
+ inSamples[1][i],
+ outSamplesL[i],
+ outSamplesR[i]
+ );
+ }
+
+ saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamplesL, outSamplesR, size, SAMPLING_FREQUENCY, 16);
+
+ delete shimmer;
+
+ delete[] inSamples[0];
+ delete[] inSamples[1];
+ delete[] inSamples;
+
+ delete[] outSamplesL;
+ delete[] outSamplesR;
+}
diff --git a/src/test/test_unitFXTuning.cpp b/src/test/test_unitFXTuning.cpp
index 6abc9ab..f6e87b9 100644
--- a/src/test/test_unitFXTuning.cpp
+++ b/src/test/test_unitFXTuning.cpp
@@ -1,5 +1,6 @@
#include "test_fx_helper.h"
+#include "../fx_dry.h"
#include "../fx_tube.h"
#include "../fx_chorus.h"
#include "../fx_flanger.h"
@@ -7,7 +8,20 @@
#include "../fx_phaser.h"
#include "../fx_delay.h"
#include "../effect_platervbstereo.h"
+#include "../fx_diffuser.h"
+#include "../fx_pitch_shifter.h"
#include "../fx_reverberator.h"
+#include "../fx_shimmer_reverb.h"
+
+TEST(UnitFXTuning, Dry)
+{
+ Dry fx(SAMPLING_FREQUENCY);
+
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+ SIMPLE_AUDIO_LOOP(inSamples, outSamples, size, inL, inR, outL, outR, fx);
+ SAVE_AUDIO_RESULTS(full_test_name, outSamples, size);
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
TEST(UnitFXTuning, Tube)
{
@@ -77,8 +91,6 @@ TEST(UnitFXTuning, Delay)
fx.setLeftDelayTime(0.25f);
fx.setLeftDelayTime(0.40f);
fx.setFeedback(0.55f);
- fx.setFlutterRate(0.01f);
- fx.setFlutterAmount(0.05f);
PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
SIMPLE_AUDIO_LOOP(inSamples, outSamples, size, inL, inR, outL, outR, fx);
@@ -103,6 +115,28 @@ TEST(UnitFXTuning, PlateReverb)
CLEANUP_AUDIO_TEST(inSamples, outSamples);
}
+TEST(UnitFXTuning, Diffuser)
+{
+ Diffuser fx(SAMPLING_FREQUENCY);
+
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+ SIMPLE_AUDIO_LOOP(inSamples, outSamples, size, inL, inR, outL, outR, fx);
+ SAVE_AUDIO_RESULTS(full_test_name, outSamples, size);
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
+
+TEST(UnitFXTuning, PitchShifter)
+{
+ PitchShifter fx(SAMPLING_FREQUENCY);
+ fx.setSize(0.5f);
+ fx.setTranspose(12.0f);
+
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+ SIMPLE_AUDIO_LOOP(inSamples, outSamples, size, inL, inR, outL, outR, fx);
+ SAVE_AUDIO_RESULTS(full_test_name, outSamples, size);
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
+
TEST(UnitFXTuning, Reverberator)
{
Reverberator fx(SAMPLING_FREQUENCY);
@@ -116,3 +150,20 @@ TEST(UnitFXTuning, Reverberator)
SAVE_AUDIO_RESULTS(full_test_name, outSamples, size);
CLEANUP_AUDIO_TEST(inSamples, outSamples);
}
+
+TEST(UnitFXTuning, ShimmerReverb)
+{
+ const float32_t amount = 0.6f;
+
+ ShimmerReverb fx(SAMPLING_FREQUENCY);
+ fx.setInputGain(0.2f);
+ fx.setReverbAmount(amount);
+ fx.setDiffusion(0.7f);
+ fx.setFeedback(0.8f);
+
+ PREPARE_AUDIO_TEST(size, inSamples, outSamples, full_test_name);
+ SIMPLE_AUDIO_LOOP(inSamples, outSamples, size, inL, inR, outL, outR, fx);
+ SAVE_AUDIO_RESULTS(full_test_name, outSamples, size);
+ CLEANUP_AUDIO_TEST(inSamples, outSamples);
+}
+
diff --git a/src/test/wave.h b/src/test/wave.h
index 918a4ce..08834b7 100644
--- a/src/test/wave.h
+++ b/src/test/wave.h
@@ -1,3 +1,22 @@
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+//
+// wave.h
+//
+// Set of helpers to manipulate RIFF Wave files. These helpers are used in the unit tests.
+// Author: Vincent Gauché
+//
#pragma once
#include
diff --git a/src/uimenu.cpp b/src/uimenu.cpp
index 9cf319c..f16cf21 100644
--- a/src/uimenu.cpp
+++ b/src/uimenu.cpp
@@ -34,193 +34,521 @@ using namespace std;
const CUIMenu::TMenuItem CUIMenu::s_MenuRoot[] =
{
- {"MiniDexed", MenuHandler, s_MainMenu},
+ {"MiniDexed", CUIMenu::MenuHandler, CUIMenu::s_MainMenu},
{0}
};
// inserting menu items before "TG1" affect TGShortcutHandler()
const CUIMenu::TMenuItem CUIMenu::s_MainMenu[] =
{
- {"TG1", MenuHandler, s_TGMenu, 0},
+ {"TG1", CUIMenu::MenuHandler, CUIMenu::s_TGMenu, 0},
#ifdef ARM_ALLOW_MULTI_CORE
- {"TG2", MenuHandler, s_TGMenu, 1},
- {"TG3", MenuHandler, s_TGMenu, 2},
- {"TG4", MenuHandler, s_TGMenu, 3},
- {"TG5", MenuHandler, s_TGMenu, 4},
- {"TG6", MenuHandler, s_TGMenu, 5},
- {"TG7", MenuHandler, s_TGMenu, 6},
- {"TG8", MenuHandler, s_TGMenu, 7},
+ {"TG2", CUIMenu::MenuHandler, CUIMenu::s_TGMenu, 1},
+ {"TG3", CUIMenu::MenuHandler, CUIMenu::s_TGMenu, 2},
+ {"TG4", CUIMenu::MenuHandler, CUIMenu::s_TGMenu, 3},
+ {"TG5", CUIMenu::MenuHandler, CUIMenu::s_TGMenu, 4},
+ {"TG6", CUIMenu::MenuHandler, CUIMenu::s_TGMenu, 5},
+ {"TG7", CUIMenu::MenuHandler, CUIMenu::s_TGMenu, 6},
+ {"TG8", CUIMenu::MenuHandler, CUIMenu::s_TGMenu, 7},
#endif
- {"Effects", MenuHandler, s_EffectsMenu},
- {"Performance", MenuHandler, s_PerformanceMenu},
+ {"Effects", CUIMenu::MenuHandler, CUIMenu::s_EffectsMenu},
+ {"Performance", CUIMenu::MenuHandler, CUIMenu::s_PerformanceMenu},
{0}
};
+#if defined(MIXING_CONSOLE_ENABLE)
+const CUIMenu::TMenuItem CUIMenu::s_TGFXMenu[] =
+{
+ {"> Tub", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+ {"> ChR", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
+ {"> Flg", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+ {"> Orb", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+ {"> PhR", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+ {"> Dly", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+ {"> Plt", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+ {"> Rev", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+ {"> Main", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+ {0}
+};
+#endif
+
const CUIMenu::TMenuItem CUIMenu::s_TGMenu[] =
{
- {"Voice", EditProgramNumber},
- {"Bank", EditVoiceBankNumber},
- {"Volume", EditTGParameter, 0, CMiniDexed::TGParameterVolume},
+ {"Voice", CUIMenu::EditProgramNumber},
+ {"Bank", CUIMenu::EditVoiceBankNumber},
+ {"Volume", CUIMenu::EditTGParameter, 0, CMiniDexed::TTGParameter::TGParameterVolume},
#ifdef ARM_ALLOW_MULTI_CORE
- {"Pan", EditTGParameter, 0, CMiniDexed::TGParameterPan},
+ {"Pan", CUIMenu::EditTGParameter, 0, CMiniDexed::TTGParameter::TGParameterPan},
#endif
- {"Reverb-Send", EditTGParameter, 0, CMiniDexed::TGParameterReverbSend},
- {"Detune", EditTGParameter, 0, CMiniDexed::TGParameterMasterTune},
- {"Cutoff", EditTGParameter, 0, CMiniDexed::TGParameterCutoff},
- {"Resonance", EditTGParameter, 0, CMiniDexed::TGParameterResonance},
- {"Pitch Bend", MenuHandler, s_EditPitchBendMenu},
- {"Portamento", MenuHandler, s_EditPortamentoMenu},
- {"Poly/Mono", EditTGParameter, 0, CMiniDexed::TGParameterMonoMode},
- {"Modulation", MenuHandler, s_ModulationMenu},
- {"Channel", EditTGParameter, 0, CMiniDexed::TGParameterMIDIChannel},
- {"Edit Voice", MenuHandler, s_EditVoiceMenu},
+#if defined(MIXING_CONSOLE_ENABLE)
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_TGFXMenu},
+#elif defined(PLATE_REVERB_ENABLE)
+ {"Reverb-Send", CUIMenu::EditTGParameter, 0, CMiniDexed::TTGParameter::TGParameterReverbSend},
+#endif
+ {"Detune", CUIMenu::EditTGParameter, 0, CMiniDexed::TTGParameter::TGParameterMasterTune},
+ {"Cutoff", CUIMenu::EditTGParameter, 0, CMiniDexed::TTGParameter::TGParameterCutoff},
+ {"Resonance", CUIMenu::EditTGParameter, 0, CMiniDexed::TTGParameter::TGParameterResonance},
+ {"Pitch Bend", CUIMenu::MenuHandler, CUIMenu::s_EditPitchBendMenu},
+ {"Portamento", CUIMenu::MenuHandler, CUIMenu::s_EditPortamentoMenu},
+ {"Poly/Mono", CUIMenu::EditTGParameter, 0, CMiniDexed::TTGParameter::TGParameterMonoMode},
+ {"Modulation", CUIMenu::MenuHandler, CUIMenu::s_ModulationMenu},
+ {"Channel", CUIMenu::EditTGParameter, 0, CMiniDexed::TTGParameter::TGParameterMIDIChannel},
+ {"Edit Voice", CUIMenu::MenuHandler, CUIMenu::s_EditVoiceMenu},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_EffectsMenu[] =
{
- {"Compress", EditGlobalParameter, 0, CMiniDexed::ParameterCompressorEnable},
-#ifdef ARM_ALLOW_MULTI_CORE
- {"Reverb", MenuHandler, s_ReverbMenu},
+ {"Compress",CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterCompressorEnable},
+#if defined(MIXING_CONSOLE_ENABLE)
+ {"Tube", CUIMenu::MenuHandler, CUIMenu::s_FXTube},
+ {"Chorus", CUIMenu::MenuHandler, CUIMenu::s_FXChorus},
+ {"FlangR", CUIMenu::MenuHandler, CUIMenu::s_FXFlanger},
+ {"Orb", CUIMenu::MenuHandler, CUIMenu::s_FXOrbitone},
+ {"PhasR", CUIMenu::MenuHandler, CUIMenu::s_FXPhaser},
+ {"Delay", CUIMenu::MenuHandler, CUIMenu::s_FXDelay},
#endif
-#ifdef FXRACK_ENABLE
- {"FXChain", MenuHandler, s_FXChainMenu},
+#if defined(PLATE_REVERB_ENABLE)
+ {"Reverb", CUIMenu::MenuHandler, CUIMenu::s_FXPlateReverb},
+#elif defined(MIXING_CONSOLE_ENABLE)
+ {"Plt Rvb", CUIMenu::MenuHandler, CUIMenu::s_FXPlateReverb},
+ {"Rvbrtor", CUIMenu::MenuHandler, CUIMenu::s_FXReverberator},
+ {"MainOut", CUIMenu::MenuHandler, CUIMenu::s_FXMainOutputLevels},
+ {"Bypass", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXBypass},
#endif
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_EditPitchBendMenu[] =
{
- {"Bend Range", EditTGParameter2, 0, CMiniDexed::TGParameterPitchBendRange},
- {"Bend Step", EditTGParameter2, 0, CMiniDexed::TGParameterPitchBendStep},
+ {"Bend Range", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterPitchBendRange},
+ {"Bend Step", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterPitchBendStep},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_EditPortamentoMenu[] =
{
- {"Mode", EditTGParameter2, 0, CMiniDexed::TGParameterPortamentoMode},
- {"Glissando", EditTGParameter2, 0, CMiniDexed::TGParameterPortamentoGlissando},
- {"Time", EditTGParameter2, 0, CMiniDexed::TGParameterPortamentoTime},
+ {"Mode", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterPortamentoMode},
+ {"Glissando", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterPortamentoGlissando},
+ {"Time", CUIMenu::EditTGParameter2, 0, CMiniDexed::TTGParameter::TGParameterPortamentoTime},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_ModulationMenu[] =
{
- {"Mod. Wheel", MenuHandler, s_ModulationMenuParameters, CMiniDexed::TGParameterMWRange},
- {"Foot Control", MenuHandler, s_ModulationMenuParameters, CMiniDexed::TGParameterFCRange},
- {"Breath Control", MenuHandler, s_ModulationMenuParameters, CMiniDexed::TGParameterBCRange},
- {"Aftertouch", MenuHandler, s_ModulationMenuParameters, CMiniDexed::TGParameterATRange},
+ {"Mod. Wheel", CUIMenu::MenuHandler, CUIMenu::s_ModulationMenuParameters, CMiniDexed::TTGParameter::TGParameterMWRange},
+ {"Foot Control", CUIMenu::MenuHandler, CUIMenu::s_ModulationMenuParameters, CMiniDexed::TTGParameter::TGParameterFCRange},
+ {"Breath Control", CUIMenu::MenuHandler, CUIMenu::s_ModulationMenuParameters, CMiniDexed::TTGParameter::TGParameterBCRange},
+ {"Aftertouch", CUIMenu::MenuHandler, CUIMenu::s_ModulationMenuParameters, CMiniDexed::TTGParameter::TGParameterATRange},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_ModulationMenuParameters[] =
{
- {"Range", EditTGParameterModulation, 0, 0},
- {"Pitch", EditTGParameterModulation, 0, 1},
- {"Amplitude", EditTGParameterModulation, 0, 2},
- {"EG Bias", EditTGParameterModulation, 0, 3},
+ {"Range", CUIMenu::EditTGParameterModulation, 0, 0},
+ {"Pitch", CUIMenu::EditTGParameterModulation, 0, 1},
+ {"Amplitude", CUIMenu::EditTGParameterModulation, 0, 2},
+ {"EG Bias", CUIMenu::EditTGParameterModulation, 0, 3},
{0}
};
-#ifdef ARM_ALLOW_MULTI_CORE
+#if defined(PLATE_REVERB_ENABLE) || defined(MIXING_CONSOLE_ENABLE)
+
+const CUIMenu::TMenuItem CUIMenu::s_FXPlateReverb[] =
+{
+ {"Enable", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterReverbEnable},
+ {"Size", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterReverbSize},
+ {"High damp", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterReverbHighDamp},
+ {"Low damp", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterReverbLowDamp},
+ {"Low pass", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterReverbLowPass},
+ {"Diffusion", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterReverbDiffusion},
+ {"Level", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterReverbLevel},
+#if defined(MIXING_CONSOLE_ENABLE)
+ {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXPlateReverbLevels},
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXPlateReverbSend},
+#endif
+ {0}
+};
+
+#endif
+
+#if defined(MIXING_CONSOLE_ENABLE)
+
+const CUIMenu::TMenuItem CUIMenu::s_FXTube[] =
+{
+ {"Enable", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTubeEnable},
+ {"Overdrv", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTubeOverdrive},
+ {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXTubeLevels},
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXTubeSend},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXChorus[] =
+{
+ {"Enable", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorusEnable},
+ {"Rate", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorusRate},
+ {"Depth", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorusDepth},
+ {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXChorusLevels},
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXChorusSend},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXFlanger[] =
+{
+ {"Enable", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlangerEnable},
+ {"Rate", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlangerRate},
+ {"Depth", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlangerDepth},
+ {"Feedbck", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlangerFeedback},
+ {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXFlangerLevels},
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXFlangerSend},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXOrbitone[] =
+{
+ {"Enable", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitoneEnable},
+ {"Rate", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitoneRate},
+ {"Depth", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitoneDepth},
+ {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXOrbitoneLevels},
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXOrbitoneSend},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXPhaser[] =
+{
+ {"Enable", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaserEnable},
+ {"Rate", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaserRate},
+ {"Depth", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaserDepth},
+ {"Feedbck", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaserFeedback},
+ {"Stages", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaserNbStages},
+ {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXPhaserLevels},
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXPhaserSend},
+ {0}
+};
-const CUIMenu::TMenuItem CUIMenu::s_ReverbMenu[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXDelay[] =
{
- {"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterReverbEnable},
- {"Size", EditGlobalParameter, 0, CMiniDexed::ParameterReverbSize},
- {"High damp", EditGlobalParameter, 0, CMiniDexed::ParameterReverbHighDamp},
- {"Low damp", EditGlobalParameter, 0, CMiniDexed::ParameterReverbLowDamp},
- {"Low pass", EditGlobalParameter, 0, CMiniDexed::ParameterReverbLowPass},
- {"Diffusion", EditGlobalParameter, 0, CMiniDexed::ParameterReverbDiffusion},
- {"Level", EditGlobalParameter, 0, CMiniDexed::ParameterReverbLevel},
+ {"Enable", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayEnable},
+ {"L Delay", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayLeftDelayTime},
+ {"R Delay", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayRightDelayTime},
+ {"Feedbck", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelayFeedback},
+ {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXDelayLevels},
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXDelaySend},
{0}
};
+const CUIMenu::TMenuItem CUIMenu::s_FXReverberator[] =
+{
+ {"Enable", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberatorEnable},
+ {"Gain", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberatorInputGain},
+ {"Time", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberatorTime},
+ {"Diffusion", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberatorDiffusion},
+ {"Low pass", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberatorLP},
+ {"Levels", CUIMenu::MenuHandler, CUIMenu::s_FXReverberatorLevels},
+ {"FX-Send", CUIMenu::MenuHandler, CUIMenu::s_FXReverberatorSend},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXTubeLevels[] =
+{
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXTube},
+#endif
+ {"ChR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_TubeSend},
+ {"Flg >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_TubeSend},
+ {"Orb >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_TubeSend},
+ {"PhR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_TubeSend},
+ {"Dly >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_TubeSend},
+ {"Plt >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_TubeSend},
+ {"Rev >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_TubeSend},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXTubeSend[] =
+{
+ {"> ChR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_ChorusSend},
+ {"> Flg", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_FlangerSend},
+ {"> Orb", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_OrbitoneSend},
+ {"> PhR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_PhaserSend},
+ {"> Dly", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_DelaySend},
+ {"> Plt", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_PlateReverbSend},
+ {"> Rev", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_ReverberatorSend},
+ {"> Main", CUIMenu::EditGlobalParameter, 0, CMiniDexed::ParameterFXTube_MainOutput},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXChorusLevels[] =
+{
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXChorus},
#endif
+ {"Tub >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_ChorusSend},
+ {"Flg >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_ChorusSend},
+ {"Orb >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_ChorusSend},
+ {"PhR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_ChorusSend},
+ {"Dly >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_ChorusSend},
+ {"Plt >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_ChorusSend},
+ {"Rev >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_ChorusSend},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXChorusSend[] =
+{
+ {"> Tub", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_TubeSend},
+ {"> Flg", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_FlangerSend},
+ {"> Orb", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_OrbitoneSend},
+ {"> PhR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_PhaserSend},
+ {"> Dly", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_DelaySend},
+ {"> Plt", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_PlateReverbSend},
+ {"> Rev", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_ReverberatorSend},
+ {"> Main", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_MainOutput},
+ {0}
+};
-#ifdef FXRACK_ENABLE
+const CUIMenu::TMenuItem CUIMenu::s_FXFlangerLevels[] =
+{
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXFlanger},
+#endif
+ {"Tub >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_FlangerSend},
+ {"ChR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_FlangerSend},
+ {"Orb >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_FlangerSend},
+ {"PhR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_FlangerSend},
+ {"Dly >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_FlangerSend},
+ {"Plt >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_FlangerSend},
+ {"Rev >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_FlangerSend},
+ {0}
+};
-const CUIMenu::TMenuItem CUIMenu::s_FXChainMenu[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXFlangerSend[] =
{
- // FXChain
- {"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainEnable},
- {"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainWet},
+ {"> Tub", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_TubeSend},
+ {"> ChR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_ChorusSend},
+ {"> Orb", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_OrbitoneSend},
+ {"> PhR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_PhaserSend},
+ {"> Dly", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_DelaySend},
+ {"> Plt", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_PlateReverbSend},
+ {"> Rev", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_ReverberatorSend},
+ {"> Main", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_MainOutput},
+ {0}
+};
- {"Tube", MenuHandler, s_FXChainTube},
- {"Chorus", MenuHandler, s_FXChainChorus},
- {"FlangR", MenuHandler, s_FXChainFlanger},
- {"Orb", MenuHandler, s_FXChainOrbitone},
- {"PhasR", MenuHandler, s_FXChainPhaser},
- {"Delay", MenuHandler, s_FXChainDelay},
- {"Shimmer", MenuHandler, s_FXChainShimmerReverb},
+const CUIMenu::TMenuItem CUIMenu::s_FXOrbitoneLevels[] =
+{
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXOrbitone},
+#endif
+ {"Tub >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_OrbitoneSend},
+ {"ChR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_OrbitoneSend},
+ {"Flg >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_OrbitoneSend},
+ {"PhR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_OrbitoneSend},
+ {"Dly >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_OrbitoneSend},
+ {"Plt >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_OrbitoneSend},
+ {"Rev >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_OrbitoneSend},
{0}
};
-const CUIMenu::TMenuItem CUIMenu::s_FXChainTube[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXOrbitoneSend[] =
{
- {"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTubeEnable},
- {"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTubeWet},
- {"Overdrv", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainTubeOverdrive},
+ {"> Tub", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_TubeSend},
+ {"> ChR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_ChorusSend},
+ {"> Flg", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_FlangerSend},
+ {"> PhR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_PhaserSend},
+ {"> Dly", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_DelaySend},
+ {"> Plt", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_PlateReverbSend},
+ {"> Rev", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_ReverberatorSend},
+ {"> Main", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_MainOutput},
{0}
};
-const CUIMenu::TMenuItem CUIMenu::s_FXChainChorus[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXPhaserLevels[] =
{
- {"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainChorusEnable},
- {"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainChorusWet},
- {"Rate", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainChorusRate},
- {"Depth", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainChorusDepth},
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPhaser},
+#endif
+ {"Tub >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_PhaserSend},
+ {"ChR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_PhaserSend},
+ {"Flg >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_PhaserSend},
+ {"Orb >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_PhaserSend},
+ {"Dly >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_PhaserSend},
+ {"Plt >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_PhaserSend},
+ {"Rev >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_PhaserSend},
{0}
};
-const CUIMenu::TMenuItem CUIMenu::s_FXChainFlanger[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXPhaserSend[] =
{
- {"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainFlangerEnable},
- {"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainFlangerWet},
- {"Rate", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainFlangerRate},
- {"Depth", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainFlangerDepth},
- {"Feedbck", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainFlangerFeedback},
+ {"> Tub", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_TubeSend},
+ {"> ChR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_ChorusSend},
+ {"> Flg", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_FlangerSend},
+ {"> Orb", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_OrbitoneSend},
+ {"> Dly", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_DelaySend},
+ {"> Plt", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_PlateReverbSend},
+ {"> Rev", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_ReverberatorSend},
+ {"> Main", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_MainOutput},
{0}
};
-const CUIMenu::TMenuItem CUIMenu::s_FXChainOrbitone[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXDelayLevels[] =
{
- {"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainOrbitoneEnable},
- {"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainOrbitoneWet},
- {"Rate", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainOrbitoneRate},
- {"Depth", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainOrbitoneDepth},
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXDelay},
+#endif
+ {"Tub >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_DelaySend},
+ {"ChR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_DelaySend},
+ {"Flg >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_DelaySend},
+ {"Orb >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_DelaySend},
+ {"PhR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_DelaySend},
+ {"Plt >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_DelaySend},
+ {"Rev >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_DelaySend},
{0}
};
-const CUIMenu::TMenuItem CUIMenu::s_FXChainPhaser[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXDelaySend[] =
{
- {"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainPhaserEnable},
- {"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainPhaserWet},
- {"Rate", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainPhaserRate},
- {"Depth", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainPhaserDepth},
- {"Feedbck", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainPhaserFeedback},
- {"Stages", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainPhaserNbStages},
+ {"> Tub", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_TubeSend},
+ {"> ChR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_ChorusSend},
+ {"> Flg", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_FlangerSend},
+ {"> Orb", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_OrbitoneSend},
+ {"> PhR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_PhaserSend},
+ {"> Plt", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_PlateReverbSend},
+ {"> Rev", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_ReverberatorSend},
+ {"> Main", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_MainOutput},
{0}
};
-const CUIMenu::TMenuItem CUIMenu::s_FXChainDelay[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXPlateReverbLevels[] =
{
- {"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},
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXPlateReverb},
+#endif
+ {"Tub >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_PlateReverbSend},
+ {"ChR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_PlateReverbSend},
+ {"Flg >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_PlateReverbSend},
+ {"Orb >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_PlateReverbSend},
+ {"PhR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_PlateReverbSend},
+ {"Dly >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_PlateReverbSend},
+ {"Rev >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_PlateReverbSend},
{0}
};
-const CUIMenu::TMenuItem CUIMenu::s_FXChainShimmerReverb[] =
+const CUIMenu::TMenuItem CUIMenu::s_FXPlateReverbSend[] =
{
- {"Enable", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainShimmerReverbEnable},
- {"Wet Lvl", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainShimmerReverbWet},
- {"Gain", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainShimmerReverbInputGain},
- {"Time", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainShimmerReverbTime},
- {"Diffus", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainShimmerReverbDiffusion},
- {"LowPass", EditGlobalParameter, 0, CMiniDexed::ParameterFXChainShimmerReverbLP},
+ {"> Tub", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_TubeSend},
+ {"> ChR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_ChorusSend},
+ {"> Flg", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_FlangerSend},
+ {"> Orb", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_OrbitoneSend},
+ {"> PhR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_PhaserSend},
+ {"> Dly", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_DelaySend},
+ {"> Rev", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_ReverberatorSend},
+ {"> Main", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_MainOutput},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXReverberatorLevels[] =
+{
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXReverberator},
+#endif
+ {"Tub >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_ReverberatorSend},
+ {"ChR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_ReverberatorSend},
+ {"Flg >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_ReverberatorSend},
+ {"Orb >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_ReverberatorSend},
+ {"PhR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_ReverberatorSend},
+ {"Dly >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_ReverberatorSend},
+ {"Plt >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_ReverberatorSend},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXReverberatorSend[] =
+{
+ {"> Tub", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_TubeSend},
+ {"> ChR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_ChorusSend},
+ {"> Flg", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_FlangerSend},
+ {"> Orb", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_OrbitoneSend},
+ {"> PhR", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_PhaserSend},
+ {"> Dly", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_DelaySend},
+ {"> Plt", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_PlateReverbSend},
+ {"> Main", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_MainOutput},
+ {0}
+};
+
+const CUIMenu::TMenuItem CUIMenu::s_FXMainOutputLevels[] =
+{
+ {"TG1 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+#if defined(ARM_ALLOW_MULTI_CORE)
+ {"TG2 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+ {"TG3 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+ {"TG4 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+ {"TG5 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+ {"TG6 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+ {"TG7 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+ {"TG8 >", CUIMenu::EditTGParameter3, 0, CMiniDexed::TTGParameter::TGParameterMixingSendFXMainOutput},
+#endif
+ {"Tub >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXTube_MainOutput},
+ {"ChR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXChorus_MainOutput},
+ {"Flg >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXFlanger_MainOutput},
+ {"Orb >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXOrbitone_MainOutput},
+ {"PhR >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPhaser_MainOutput},
+ {"Dly >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXDelay_MainOutput},
+ {"Plt >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXPlateReverb_MainOutput},
+ {"Rev >", CUIMenu::EditGlobalParameter, 0, CMiniDexed::TParameter::ParameterFXReverberator_MainOutput},
{0}
};
@@ -229,74 +557,77 @@ const CUIMenu::TMenuItem CUIMenu::s_FXChainShimmerReverb[] =
// inserting menu items before "OP1" affect OPShortcutHandler()
const CUIMenu::TMenuItem CUIMenu::s_EditVoiceMenu[] =
{
- {"OP1", MenuHandler, s_OperatorMenu, 0},
- {"OP2", MenuHandler, s_OperatorMenu, 1},
- {"OP3", MenuHandler, s_OperatorMenu, 2},
- {"OP4", MenuHandler, s_OperatorMenu, 3},
- {"OP5", MenuHandler, s_OperatorMenu, 4},
- {"OP6", MenuHandler, s_OperatorMenu, 5},
- {"Algorithm", EditVoiceParameter, 0, DEXED_ALGORITHM},
- {"Feedback", EditVoiceParameter, 0, DEXED_FEEDBACK},
- {"P EG Rate 1", EditVoiceParameter, 0, DEXED_PITCH_EG_R1},
- {"P EG Rate 2", EditVoiceParameter, 0, DEXED_PITCH_EG_R2},
- {"P EG Rate 3", EditVoiceParameter, 0, DEXED_PITCH_EG_R3},
- {"P EG Rate 4", EditVoiceParameter, 0, DEXED_PITCH_EG_R4},
- {"P EG Level 1",EditVoiceParameter, 0, DEXED_PITCH_EG_L1},
- {"P EG Level 2",EditVoiceParameter, 0, DEXED_PITCH_EG_L2},
- {"P EG Level 3",EditVoiceParameter, 0, DEXED_PITCH_EG_L3},
- {"P EG Level 4",EditVoiceParameter, 0, DEXED_PITCH_EG_L4},
- {"Osc Key Sync",EditVoiceParameter, 0, DEXED_OSC_KEY_SYNC},
- {"LFO Speed", EditVoiceParameter, 0, DEXED_LFO_SPEED},
- {"LFO Delay", EditVoiceParameter, 0, DEXED_LFO_DELAY},
- {"LFO PMD", EditVoiceParameter, 0, DEXED_LFO_PITCH_MOD_DEP},
- {"LFO AMD", EditVoiceParameter, 0, DEXED_LFO_AMP_MOD_DEP},
- {"LFO Sync", EditVoiceParameter, 0, DEXED_LFO_SYNC},
- {"LFO Wave", EditVoiceParameter, 0, DEXED_LFO_WAVE},
- {"P Mod Sens.", EditVoiceParameter, 0, DEXED_LFO_PITCH_MOD_SENS},
- {"Transpose", EditVoiceParameter, 0, DEXED_TRANSPOSE},
- {"Name", InputTxt,0 , 3},
+ {"OP1", CUIMenu::MenuHandler, CUIMenu::s_OperatorMenu, 0},
+ {"OP2", CUIMenu::MenuHandler, CUIMenu::s_OperatorMenu, 1},
+ {"OP3", CUIMenu::MenuHandler, CUIMenu::s_OperatorMenu, 2},
+ {"OP4", CUIMenu::MenuHandler, CUIMenu::s_OperatorMenu, 3},
+ {"OP5", CUIMenu::MenuHandler, CUIMenu::s_OperatorMenu, 4},
+ {"OP6", CUIMenu::MenuHandler, CUIMenu::s_OperatorMenu, 5},
+ {"Algorithm", CUIMenu::EditVoiceParameter, 0, DEXED_ALGORITHM},
+ {"Feedback", CUIMenu::EditVoiceParameter, 0, DEXED_FEEDBACK},
+ {"P EG Rate 1", CUIMenu::EditVoiceParameter, 0, DEXED_PITCH_EG_R1},
+ {"P EG Rate 2", CUIMenu::EditVoiceParameter, 0, DEXED_PITCH_EG_R2},
+ {"P EG Rate 3", CUIMenu::EditVoiceParameter, 0, DEXED_PITCH_EG_R3},
+ {"P EG Rate 4", CUIMenu::EditVoiceParameter, 0, DEXED_PITCH_EG_R4},
+ {"P EG Level 1",CUIMenu::EditVoiceParameter, 0, DEXED_PITCH_EG_L1},
+ {"P EG Level 2",CUIMenu::EditVoiceParameter, 0, DEXED_PITCH_EG_L2},
+ {"P EG Level 3",CUIMenu::EditVoiceParameter, 0, DEXED_PITCH_EG_L3},
+ {"P EG Level 4",CUIMenu::EditVoiceParameter, 0, DEXED_PITCH_EG_L4},
+ {"Osc Key Sync",CUIMenu::EditVoiceParameter, 0, DEXED_OSC_KEY_SYNC},
+ {"LFO Speed", CUIMenu::EditVoiceParameter, 0, DEXED_LFO_SPEED},
+ {"LFO Delay", CUIMenu::EditVoiceParameter, 0, DEXED_LFO_DELAY},
+ {"LFO PMD", CUIMenu::EditVoiceParameter, 0, DEXED_LFO_PITCH_MOD_DEP},
+ {"LFO AMD", CUIMenu::EditVoiceParameter, 0, DEXED_LFO_AMP_MOD_DEP},
+ {"LFO Sync", CUIMenu::EditVoiceParameter, 0, DEXED_LFO_SYNC},
+ {"LFO Wave", CUIMenu::EditVoiceParameter, 0, DEXED_LFO_WAVE},
+ {"P Mod Sens.", CUIMenu::EditVoiceParameter, 0, DEXED_LFO_PITCH_MOD_SENS},
+ {"Transpose", CUIMenu::EditVoiceParameter, 0, DEXED_TRANSPOSE},
+ {"Name", CUIMenu::InputTxt, 0, 3},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_OperatorMenu[] =
{
- {"Output Level",EditOPParameter, 0, DEXED_OP_OUTPUT_LEV},
- {"Freq Coarse", EditOPParameter, 0, DEXED_OP_FREQ_COARSE},
- {"Freq Fine", EditOPParameter, 0, DEXED_OP_FREQ_FINE},
- {"Osc Detune", EditOPParameter, 0, DEXED_OP_OSC_DETUNE},
- {"Osc Mode", EditOPParameter, 0, DEXED_OP_OSC_MODE},
- {"EG Rate 1", EditOPParameter, 0, DEXED_OP_EG_R1},
- {"EG Rate 2", EditOPParameter, 0, DEXED_OP_EG_R2},
- {"EG Rate 3", EditOPParameter, 0, DEXED_OP_EG_R3},
- {"EG Rate 4", EditOPParameter, 0, DEXED_OP_EG_R4},
- {"EG Level 1", EditOPParameter, 0, DEXED_OP_EG_L1},
- {"EG Level 2", EditOPParameter, 0, DEXED_OP_EG_L2},
- {"EG Level 3", EditOPParameter, 0, DEXED_OP_EG_L3},
- {"EG Level 4", EditOPParameter, 0, DEXED_OP_EG_L4},
- {"Break Point", EditOPParameter, 0, DEXED_OP_LEV_SCL_BRK_PT},
- {"L Key Depth", EditOPParameter, 0, DEXED_OP_SCL_LEFT_DEPTH},
- {"R Key Depth", EditOPParameter, 0, DEXED_OP_SCL_RGHT_DEPTH},
- {"L Key Scale", EditOPParameter, 0, DEXED_OP_SCL_LEFT_CURVE},
- {"R Key Scale", EditOPParameter, 0, DEXED_OP_SCL_RGHT_CURVE},
- {"Rate Scaling",EditOPParameter, 0, DEXED_OP_OSC_RATE_SCALE},
- {"A Mod Sens.", EditOPParameter, 0, DEXED_OP_AMP_MOD_SENS},
- {"K Vel. Sens.",EditOPParameter, 0, DEXED_OP_KEY_VEL_SENS},
- {"Enable", EditOPParameter, 0, DEXED_OP_ENABLE},
+ {"Output Level",CUIMenu::EditOPParameter, 0, DEXED_OP_OUTPUT_LEV},
+ {"Freq Coarse", CUIMenu::EditOPParameter, 0, DEXED_OP_FREQ_COARSE},
+ {"Freq Fine", CUIMenu::EditOPParameter, 0, DEXED_OP_FREQ_FINE},
+ {"Osc Detune", CUIMenu::EditOPParameter, 0, DEXED_OP_OSC_DETUNE},
+ {"Osc Mode", CUIMenu::EditOPParameter, 0, DEXED_OP_OSC_MODE},
+ {"EG Rate 1", CUIMenu::EditOPParameter, 0, DEXED_OP_EG_R1},
+ {"EG Rate 2", CUIMenu::EditOPParameter, 0, DEXED_OP_EG_R2},
+ {"EG Rate 3", CUIMenu::EditOPParameter, 0, DEXED_OP_EG_R3},
+ {"EG Rate 4", CUIMenu::EditOPParameter, 0, DEXED_OP_EG_R4},
+ {"EG Level 1", CUIMenu::EditOPParameter, 0, DEXED_OP_EG_L1},
+ {"EG Level 2", CUIMenu::EditOPParameter, 0, DEXED_OP_EG_L2},
+ {"EG Level 3", CUIMenu::EditOPParameter, 0, DEXED_OP_EG_L3},
+ {"EG Level 4", CUIMenu::EditOPParameter, 0, DEXED_OP_EG_L4},
+ {"Break Point", CUIMenu::EditOPParameter, 0, DEXED_OP_LEV_SCL_BRK_PT},
+ {"L Key Depth", CUIMenu::EditOPParameter, 0, DEXED_OP_SCL_LEFT_DEPTH},
+ {"R Key Depth", CUIMenu::EditOPParameter, 0, DEXED_OP_SCL_RGHT_DEPTH},
+ {"L Key Scale", CUIMenu::EditOPParameter, 0, DEXED_OP_SCL_LEFT_CURVE},
+ {"R Key Scale", CUIMenu::EditOPParameter, 0, DEXED_OP_SCL_RGHT_CURVE},
+ {"Rate Scaling",CUIMenu::EditOPParameter, 0, DEXED_OP_OSC_RATE_SCALE},
+ {"A Mod Sens.", CUIMenu::EditOPParameter, 0, DEXED_OP_AMP_MOD_SENS},
+ {"K Vel. Sens.",CUIMenu::EditOPParameter, 0, DEXED_OP_KEY_VEL_SENS},
+ {"Enable", CUIMenu::EditOPParameter, 0, DEXED_OP_ENABLE},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_SaveMenu[] =
{
- {"Overwrite", SavePerformance, 0, 0},
- {"New", InputTxt,0 , 1},
- {"Save as default", SavePerformance, 0, 1},
+ {"Overwrite", CUIMenu::SavePerformance, 0, 0},
+ {"New", CUIMenu::InputTxt, 0, 1},
+ {"Save as default", CUIMenu::SavePerformance, 0, 1},
{0}
};
// must match CMiniDexed::TParameter
-const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::ParameterUnknown] =
+const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::TParameter::ParameterUnknown] =
{
- {0, 1, 1, ToOnOff}, // ParameterCompessorEnable
+ {0, 1, 1, ToOnOff} // ParameterCompressorEnable
+
+#if defined(PLATE_REVERB_ENABLE) || defined(MIXING_CONSOLE_ENABLE)
+ ,
{0, 1, 1, ToOnOff}, // ParameterReverbEnable
{0, 99, 1}, // ParameterReverbSize
{0, 99, 1}, // ParameterReverbHighDamp
@@ -304,154 +635,240 @@ const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::ParameterUnknow
{0, 99, 1}, // ParameterReverbLowPass
{0, 99, 1}, // ParameterReverbDiffusion
{0, 99, 1} // ParameterReverbLevel
+#endif
- // BEGIN FXRack global parameters mapping definition
- #ifdef FXRACK_ENABLE
+// BEGIN FX global parameters mapping definition
+#if defined(MIXING_CONSOLE_ENABLE)
,
- // FXChain parameters
- {0, 1, 1, ToOnOff}, // ParameterFXChainEnable
- {0, 99, 1}, // ParameterFXChainWet
-
- // FXChain > Tube parameters
- {0, 1, 1, ToOnOff}, // ParameterFXChainTubeEnable
- {0, 99, 1}, // ParameterFXChainTubeWet
- {0, 99, 1}, // ParameterFXChainTubeOverdrive
-
- // FXChain > Chorus parameters
- {0, 1, 1, ToOnOff}, // ParameterFXChainChorusEnable
- {0, 99, 1}, // ParameterFXChainChorusWet
- {0, 99, 1}, // ParameterFXChainChorusRate
- {0, 99, 1}, // ParameterFXChainChorusDepth
-
- // FXChain > Flanger parameters
- {0, 1, 1, ToOnOff}, // ParameterFXChainFlangerEnable
- {0, 99, 1}, // ParameterFXChainFlangerWet
- {0, 99, 1}, // ParameterFXChainFlangerRate
- {0, 99, 1}, // ParameterFXChainFlangerDepth
- {0, 99, 1}, // ParameterFXChainFlangerFeedback
-
- // FXChain > Orbitone parameters
- {0, 1, 1, ToOnOff}, // ParameterFXChainOrbitoneEnable
- {0, 99, 1}, // ParameterFXChainOrbitoneWet
- {0, 99, 1}, // ParameterFXChainOrbitoneRate
- {0, 99, 1}, // ParameterFXChainOrbitoneDepth
-
- // FXChain > Phaser parameters
- {0, 1, 1, ToOnOff}, // ParameterFXChainPhaserEnable
- {0, 99, 1}, // ParameterFXChainPhaserWet
- {0, 99, 1}, // ParameterFXChainPhaserRate
- {0, 99, 1}, // ParameterFXChainPhaserDepth
- {0, 99, 1}, // ParameterFXChainPhaserFeedback
- {2, MAX_NB_PHASES, 1}, // ParameterFXChainPhaserNbStages
-
- // 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
- {0, 99, 1}, // ParameterFXChainShimmerReverbWet
- {0, 99, 1}, // ParameterFXChainShimmerReverbInputGain
- {0, 99, 1}, // ParameterFXChainShimmerReverbTime
- {0, 99, 1}, // ParameterFXChainShimmerReverbDiffusion
- {0, 99, 1}, // ParameterFXChainShimmerReverbLP
-
- #endif
- // END FXRack global parameters mapping definition
-
+ // FX > Tube parameters
+ {0, 1, 1, ToOnOff}, // ParameterFXTubeEnable
+ {0, 99 ,1}, // ParameterFXTubeOverdrive
+
+ // FX > Chorus parameters
+ {0, 1, 1, ToOnOff}, // ParameterFXChorusEnable
+ {0, 99, 1}, // ParameterFXChorusRate
+ {0, 99, 1}, // ParameterFXChorusDepth
+
+ // FX > Flanger parameters
+ {0, 1, 1, ToOnOff}, // ParameterFXFlangerEnable
+ {0, 99, 1}, // ParameterFXFlangerRate
+ {0, 99, 1}, // ParameterFXFlangerDepth
+ {0, 99, 1}, // ParameterFXFlangerFeedback
+
+ // FX > Orbitone parameters
+ {0, 1, 1, ToOnOff}, // ParameterFXOrbitoneEnable
+ {0, 99, 1}, // ParameterFXOrbitoneRate
+ {0, 99, 1}, // ParameterFXOrbitoneDepth
+
+ // FX > Phaser parameters
+ {0, 1, 1, ToOnOff}, // ParameterFXPhaserEnable
+ {0, 99, 1}, // ParameterFXPhaserRate
+ {0, 99, 1}, // ParameterFXPhaserDepth
+ {0, 99, 1}, // ParameterFXPhaserFeedback
+ {2, MAX_NB_PHASES, 1}, // ParameterFXPhaserNbStages
+
+ // FX > Delay parameters
+ {0, 1, 1, ToOnOff}, // ParameterFXDelayEnable
+ {-99, 99, 1}, // ParameterFXDelayLeftDelayTime
+ {-99, 99, 1}, // ParameterFXDelayRightDelayTime
+ {0, 99, 1}, // ParameterFXDelayFeedback
+
+ // FX > Reverberator parameters
+ {0, 1, 1, ToOnOff}, // ParameterFXReverberatorEnable
+ {0, 99, 1}, // ParameterFXReverberatorInputGain
+ {0, 99, 1}, // ParameterFXReverberatorTime
+ {0, 99, 1}, // ParameterFXReverberatorDiffusion
+ {0, 99, 1}, // ParameterFXReverberatorLP
+
+ // FX > Tube Return parameters
+ {0, 99, 1}, // ParameterFXTube_ChorusSend
+ {0, 99, 1}, // ParameterFXTube_FlangerSend
+ {0, 99, 1}, // ParameterFXTube_OrbitoneSend
+ {0, 99, 1}, // ParameterFXTube_PhaserSend
+ {0, 99, 1}, // ParameterFXTube_DelaySend
+ {0, 99, 1}, // ParameterFXTube_PlateReverbSend
+ {0, 99, 1}, // ParameterFXTube_ReverberatorSend
+ {0, 99, 1}, // ParameterFXTube_MainOutput
+
+ // FX > Chorus Return parameters
+ {0, 99, 1}, // ParameterFXChorus_TubeSend
+ {0, 99, 1}, // ParameterFXChorus_FlangerSend
+ {0, 99, 1}, // ParameterFXChorus_OrbitoneSend
+ {0, 99, 1}, // ParameterFXChorus_PhaserSend
+ {0, 99, 1}, // ParameterFXChorus_DelaySend
+ {0, 99, 1}, // ParameterFXChorus_PlateReverbSend
+ {0, 99, 1}, // ParameterFXChorus_ReverberatorSend
+ {0, 99, 1}, // ParameterFXChorus_MainOutput
+
+ // FX > Flanger Return parameters
+ {0, 99, 1}, // ParameterFXFlanger_TubeSend
+ {0, 99, 1}, // ParameterFXFlanger_ChorusSend
+ {0, 99, 1}, // ParameterFXFlanger_OrbitoneSend
+ {0, 99, 1}, // ParameterFXFlanger_PhaserSend
+ {0, 99, 1}, // ParameterFXFlanger_DelaySend
+ {0, 99, 1}, // ParameterFXFlanger_PlateReverbSend
+ {0, 99, 1}, // ParameterFXFlanger_ReverberatorSend
+ {0, 99, 1}, // ParameterFXFlanger_MainOutput
+
+ // FX > Orbitone Return parameters
+ {0, 99, 1}, // ParameterFXOrbitone_TubeSend
+ {0, 99, 1}, // ParameterFXOrbitone_ChorusSend
+ {0, 99, 1}, // ParameterFXOrbitone_FlangerSend
+ {0, 99, 1}, // ParameterFXOrbitone_PhaserSend
+ {0, 99, 1}, // ParameterFXOrbitone_DelaySend
+ {0, 99, 1}, // ParameterFXOrbitone_PlateReverbSend
+ {0, 99, 1}, // ParameterFXOrbitone_ReverberatorSend
+ {0, 99, 1}, // ParameterFXOrbitone_MainOutput
+
+ // FX > Phaser Return parameters
+ {0, 99, 1}, // ParameterFXPhaser_TubeSend
+ {0, 99, 1}, // ParameterFXPhaser_ChorusSend
+ {0, 99, 1}, // ParameterFXPhaser_FlangerSend
+ {0, 99, 1}, // ParameterFXPhaser_OrbitoneSend
+ {0, 99, 1}, // ParameterFXPhaser_DelaySend
+ {0, 99, 1}, // ParameterFXPhaser_PlateReverbSend
+ {0, 99, 1}, // ParameterFXPhaser_ReverberatorSend
+ {0, 99, 1}, // ParameterFXPhaser_MainOutput
+
+ // FX > Delay Return parameters
+ {0, 99, 1}, // ParameterFXDelay_TubeSend
+ {0, 99, 1}, // ParameterFXDelay_ChorusSend
+ {0, 99, 1}, // ParameterFXDelay_FlangerSend
+ {0, 99, 1}, // ParameterFXDelay_OrbitoneSend
+ {0, 99, 1}, // ParameterFXDelay_PhaserSend
+ {0, 99, 1}, // ParameterFXDelay_PlateReverbSend
+ {0, 99, 1}, // ParameterFXDelay_ReverberatorSend
+ {0, 99, 1}, // ParameterFXDelay_MainOutput
+
+ // FX > Reverb Return parameters
+ {0, 99, 1}, // ParameterFXPlateReverb_TubeSend
+ {0, 99, 1}, // ParameterFXPlateReverb_ChorusSend
+ {0, 99, 1}, // ParameterFXPlateReverb_FlangerSend
+ {0, 99, 1}, // ParameterFXPlateReverb_OrbitoneSend
+ {0, 99, 1}, // ParameterFXPlateReverb_PhaserSend
+ {0, 99, 1}, // ParameterFXPlateReverb_DelaySend
+ {0, 99, 1}, // ParameterFXPlateReverb_ReverberatorSend
+ {0, 99, 1}, // ParameterFXPlateReverb_MainOutput
+
+ // FX > Reverberator Return parameters
+ {0, 99, 1}, // ParameterFXReverberator_TubeSend
+ {0, 99, 1}, // ParameterFXReverberator_ChorusSend
+ {0, 99, 1}, // ParameterFXReverberator_FlangerSend
+ {0, 99, 1}, // ParameterFXReverberator_OrbitoneSend
+ {0, 99, 1}, // ParameterFXReverberator_PhaserSend
+ {0, 99, 1}, // ParameterFXReverberator_DelaySend
+ {0, 99, 1}, // ParameterFXReverberator_PlateReverbSend
+ {0, 99, 1}, // ParameterFXReverberator_MainOutput
+
+ {0, 1, 1, ToOnOff} // ParameterFXBypass
+#endif
+// END FX global parameters mapping definition
};
// must match CMiniDexed::TTGParameter
-const CUIMenu::TParameter CUIMenu::s_TGParameter[CMiniDexed::TGParameterUnknown] =
-{
- {0, CSysExFileLoader::MaxVoiceBankID, 1}, // TGParameterVoiceBank
- {0, 0, 0}, // TGParameterVoiceBankMSB (not used in menus)
- {0, 0, 0}, // TGParameterVoiceBankLSB (not used in menus)
- {0, CSysExFileLoader::VoicesPerBank-1, 1}, // TGParameterProgram
- {0, 127, 8, ToVolume}, // TGParameterVolume
- {0, 127, 8, ToPan}, // TGParameterPan
- {-99, 99, 1}, // TGParameterMasterTune
- {0, 99, 1}, // TGParameterCutoff
- {0, 99, 1}, // TGParameterResonance
- {0, CMIDIDevice::ChannelUnknown-1, 1, ToMIDIChannel}, // TGParameterMIDIChannel
- {0, 99, 1}, // TGParameterReverbSend
- {0, 12, 1}, // TGParameterPitchBendRange
- {0, 12, 1}, // TGParameterPitchBendStep
- {0, 1, 1, ToPortaMode}, // TGParameterPortamentoMode
- {0, 1, 1, ToPortaGlissando}, // TGParameterPortamentoGlissando
- {0, 99, 1}, // TGParameterPortamentoTime
- {0, 1, 1, ToPolyMono}, // TGParameterMonoMode
- {0, 99, 1}, //MW Range
- {0, 1, 1, ToOnOff}, //MW Pitch
- {0, 1, 1, ToOnOff}, //MW Amp
- {0, 1, 1, ToOnOff}, //MW EGBias
- {0, 99, 1}, //FC Range
- {0, 1, 1, ToOnOff}, //FC Pitch
- {0, 1, 1, ToOnOff}, //FC Amp
- {0, 1, 1, ToOnOff}, //FC EGBias
- {0, 99, 1}, //BC Range
- {0, 1, 1, ToOnOff}, //BC Pitch
- {0, 1, 1, ToOnOff}, //BC Amp
- {0, 1, 1, ToOnOff}, //BC EGBias
- {0, 99, 1}, //AT Range
- {0, 1, 1, ToOnOff}, //AT Pitch
- {0, 1, 1, ToOnOff}, //AT Amp
- {0, 1, 1, ToOnOff} //AT EGBias
+const CUIMenu::TParameter CUIMenu::s_TGParameter[CMiniDexed::TTGParameter::TGParameterUnknown] =
+{
+ {0, CSysExFileLoader::MaxVoiceBankID, 1}, // TGParameterVoiceBank
+ {0, 0, 0}, // TGParameterVoiceBankMSB (not used in menus)
+ {0, 0, 0}, // TGParameterVoiceBankLSB (not used in menus)
+ {0, CSysExFileLoader::VoicesPerBank-1, 1}, // TGParameterProgram
+ {0, 127, 8, ToVolume}, // TGParameterVolume
+ {0, 127, 8, ToPan}, // TGParameterPan
+ {-99, 99, 1}, // TGParameterMasterTune
+ {0, 99, 1}, // TGParameterCutoff
+ {0, 99, 1}, // TGParameterResonance
+ {0, CMIDIDevice::ChannelUnknown-1, 1, ToMIDIChannel}, // TGParameterMIDIChannel
+#if defined(PLATE_REVERB_ENABLE)
+ {0, 99, 1}, // TGParameterReverbSend
+#endif
+ {0, 12, 1}, // TGParameterPitchBendRange
+ {0, 12, 1}, // TGParameterPitchBendStep
+ {0, 1, 1, ToPortaMode}, // TGParameterPortamentoMode
+ {0, 1, 1, ToPortaGlissando}, // TGParameterPortamentoGlissando
+ {0, 99, 1}, // TGParameterPortamentoTime
+ {0, 1, 1, ToPolyMono}, // TGParameterMonoMode
+ {0, 99, 1}, // MW Range
+ {0, 1, 1, ToOnOff}, // MW Pitch
+ {0, 1, 1, ToOnOff}, // MW Amp
+ {0, 1, 1, ToOnOff}, // MW EGBias
+ {0, 99, 1}, // FC Range
+ {0, 1, 1, ToOnOff}, // FC Pitch
+ {0, 1, 1, ToOnOff}, // FC Amp
+ {0, 1, 1, ToOnOff}, // FC EGBias
+ {0, 99, 1}, // BC Range
+ {0, 1, 1, ToOnOff}, // BC Pitch
+ {0, 1, 1, ToOnOff}, // BC Amp
+ {0, 1, 1, ToOnOff}, // BC EGBias
+ {0, 99, 1}, // AT Range
+ {0, 1, 1, ToOnOff}, // AT Pitch
+ {0, 1, 1, ToOnOff}, // AT Amp
+ {0, 1, 1, ToOnOff} // AT EGBias
+
+#if defined(MIXING_CONSOLE_ENABLE)
+ ,
+ {0, 99, 1}, // TGParameterMixingSendFXTube
+ {0, 99, 1}, // TGParameterMixingSendFXChorus
+ {0, 99, 1}, // TGParameterMixingSendFXFlanger
+ {0, 99, 1}, // TGParameterMixingSendFXOrbittone
+ {0, 99, 1}, // TGParameterMixingSendFXPhaser
+ {0, 99, 1}, // TGParameterMixingSendFXDelay
+ {0, 99, 1}, // TGParameterMixingSendFXPlateReverb
+ {0, 99, 1}, // TGParameterMixingSendFXReverberator
+ {0, 99, 1} // TGParameterMixingSendFXMainOutput
+
+#endif // MIXING_CONSOLE_ENABLE
};
// must match DexedVoiceParameters in Synth_Dexed
const CUIMenu::TParameter CUIMenu::s_VoiceParameter[] =
{
- {0, 99, 1}, // DEXED_PITCH_EG_R1
- {0, 99, 1}, // DEXED_PITCH_EG_R2
- {0, 99, 1}, // DEXED_PITCH_EG_R3
- {0, 99, 1}, // DEXED_PITCH_EG_R4
- {0, 99, 1}, // DEXED_PITCH_EG_L1
- {0, 99, 1}, // DEXED_PITCH_EG_L2
- {0, 99, 1}, // DEXED_PITCH_EG_L3
- {0, 99, 1}, // DEXED_PITCH_EG_L4
- {0, 31, 1, ToAlgorithm}, // DEXED_ALGORITHM
- {0, 7, 1}, // DEXED_FEEDBACK
- {0, 1, 1, ToOnOff}, // DEXED_OSC_KEY_SYNC
- {0, 99, 1}, // DEXED_LFO_SPEED
- {0, 99, 1}, // DEXED_LFO_DELAY
- {0, 99, 1}, // DEXED_LFO_PITCH_MOD_DEP
- {0, 99, 1}, // DEXED_LFO_AMP_MOD_DEP
- {0, 1, 1, ToOnOff}, // DEXED_LFO_SYNC
- {0, 5, 1, ToLFOWaveform}, // DEXED_LFO_WAVE
- {0, 7, 1}, // DEXED_LFO_PITCH_MOD_SENS
- {0, 48, 1, ToTransposeNote}, // DEXED_TRANSPOSE
- {0, 1, 1} // Voice Name - Dummy parameters for in case new item would be added in future
+ {0, 99, 1}, // DEXED_PITCH_EG_R1
+ {0, 99, 1}, // DEXED_PITCH_EG_R2
+ {0, 99, 1}, // DEXED_PITCH_EG_R3
+ {0, 99, 1}, // DEXED_PITCH_EG_R4
+ {0, 99, 1}, // DEXED_PITCH_EG_L1
+ {0, 99, 1}, // DEXED_PITCH_EG_L2
+ {0, 99, 1}, // DEXED_PITCH_EG_L3
+ {0, 99, 1}, // DEXED_PITCH_EG_L4
+ {0, 31, 1, ToAlgorithm}, // DEXED_ALGORITHM
+ {0, 7, 1}, // DEXED_FEEDBACK
+ {0, 1, 1, ToOnOff}, // DEXED_OSC_KEY_SYNC
+ {0, 99, 1}, // DEXED_LFO_SPEED
+ {0, 99, 1}, // DEXED_LFO_DELAY
+ {0, 99, 1}, // DEXED_LFO_PITCH_MOD_DEP
+ {0, 99, 1}, // DEXED_LFO_AMP_MOD_DEP
+ {0, 1, 1, ToOnOff}, // DEXED_LFO_SYNC
+ {0, 5, 1, ToLFOWaveform}, // DEXED_LFO_WAVE
+ {0, 7, 1}, // DEXED_LFO_PITCH_MOD_SENS
+ {0, 48, 1, ToTransposeNote}, // DEXED_TRANSPOSE
+ {0, 1, 1} // Voice Name - Dummy parameters for in case new item would be added in future
};
// must match DexedVoiceOPParameters in Synth_Dexed
const CUIMenu::TParameter CUIMenu::s_OPParameter[] =
{
- {0, 99, 1}, // DEXED_OP_EG_R1
- {0, 99, 1}, // DEXED_OP_EG_R2
- {0, 99, 1}, // DEXED_OP_EG_R3
- {0, 99, 1}, // DEXED_OP_EG_R4
- {0, 99, 1}, // DEXED_OP_EG_L1
- {0, 99, 1}, // DEXED_OP_EG_L2
- {0, 99, 1}, // DEXED_OP_EG_L3
- {0, 99, 1}, // DEXED_OP_EG_L4
- {0, 99, 1, ToBreakpointNote}, // DEXED_OP_LEV_SCL_BRK_PT
- {0, 99, 1}, // DEXED_OP_SCL_LEFT_DEPTH
- {0, 99, 1}, // DEXED_OP_SCL_RGHT_DEPTH
- {0, 3, 1, ToKeyboardCurve}, // DEXED_OP_SCL_LEFT_CURVE
- {0, 3, 1, ToKeyboardCurve}, // DEXED_OP_SCL_RGHT_CURVE
- {0, 7, 1}, // DEXED_OP_OSC_RATE_SCALE
- {0, 3, 1}, // DEXED_OP_AMP_MOD_SENS
- {0, 7, 1}, // DEXED_OP_KEY_VEL_SENS
- {0, 99, 1}, // DEXED_OP_OUTPUT_LEV
- {0, 1, 1, ToOscillatorMode}, // DEXED_OP_OSC_MODE
- {0, 31, 1}, // DEXED_OP_FREQ_COARSE
- {0, 99, 1}, // DEXED_OP_FREQ_FINE
- {0, 14, 1, ToOscillatorDetune}, // DEXED_OP_OSC_DETUNE
- {0, 1, 1, ToOnOff} // DEXED_OP_ENABLE
+ {0, 99, 1}, // DEXED_OP_EG_R1
+ {0, 99, 1}, // DEXED_OP_EG_R2
+ {0, 99, 1}, // DEXED_OP_EG_R3
+ {0, 99, 1}, // DEXED_OP_EG_R4
+ {0, 99, 1}, // DEXED_OP_EG_L1
+ {0, 99, 1}, // DEXED_OP_EG_L2
+ {0, 99, 1}, // DEXED_OP_EG_L3
+ {0, 99, 1}, // DEXED_OP_EG_L4
+ {0, 99, 1, ToBreakpointNote}, // DEXED_OP_LEV_SCL_BRK_PT
+ {0, 99, 1}, // DEXED_OP_SCL_LEFT_DEPTH
+ {0, 99, 1}, // DEXED_OP_SCL_RGHT_DEPTH
+ {0, 3, 1, ToKeyboardCurve}, // DEXED_OP_SCL_LEFT_CURVE
+ {0, 3, 1, ToKeyboardCurve}, // DEXED_OP_SCL_RGHT_CURVE
+ {0, 7, 1}, // DEXED_OP_OSC_RATE_SCALE
+ {0, 3, 1}, // DEXED_OP_AMP_MOD_SENS
+ {0, 7, 1}, // DEXED_OP_KEY_VEL_SENS
+ {0, 99, 1}, // DEXED_OP_OUTPUT_LEV
+ {0, 1, 1, ToOscillatorMode}, // DEXED_OP_OSC_MODE
+ {0, 31, 1}, // DEXED_OP_FREQ_COARSE
+ {0, 99, 1}, // DEXED_OP_FREQ_FINE
+ {0, 14, 1, ToOscillatorDetune}, // DEXED_OP_OSC_DETUNE
+ {0, 1, 1, ToOnOff} // DEXED_OP_ENABLE
};
const char CUIMenu::s_NoteName[100][4] =
@@ -470,15 +887,15 @@ static const unsigned NoteC3 = 27;
const CUIMenu::TMenuItem CUIMenu::s_PerformanceMenu[] =
{
- {"Load", PerformanceMenu, 0, 0},
- {"Save", MenuHandler, s_SaveMenu},
- {"Delete", PerformanceMenu, 0, 1},
+ {"Load", CUIMenu::PerformanceMenu, 0, 0},
+ {"Save", CUIMenu::MenuHandler, s_SaveMenu},
+ {"Delete", CUIMenu::PerformanceMenu, 0, 1},
{0}
};
-CUIMenu::CUIMenu (CUserInterface *pUI, CMiniDexed *pMiniDexed)
-: m_pUI (pUI),
+CUIMenu::CUIMenu (CUserInterface *pUI, CMiniDexed *pMiniDexed) :
+ m_pUI (pUI),
m_pMiniDexed (pMiniDexed),
m_pParentMenu (s_MenuRoot),
m_pCurrentMenu (s_MainMenu),
@@ -487,6 +904,7 @@ CUIMenu::CUIMenu (CUserInterface *pUI, CMiniDexed *pMiniDexed)
m_nCurrentParameter (0),
m_nCurrentMenuDepth (0)
{
+ assert(pMiniDexed);
#ifndef ARM_ALLOW_MULTI_CORE
// If there is just one core, then there is only a single
// tone generator so start on the TG1 menu...
@@ -566,23 +984,23 @@ void CUIMenu::MenuHandler (CUIMenu *pUIMenu, TMenuEvent Event)
case MenuEventSelect: // push menu
assert (pUIMenu->m_nCurrentMenuDepth < MaxMenuDepth);
- pUIMenu->m_MenuStackParent[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_pParentMenu;
- pUIMenu->m_MenuStackMenu[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_pCurrentMenu;
- pUIMenu->m_nMenuStackItem[pUIMenu->m_nCurrentMenuDepth]
- = pUIMenu->m_nCurrentMenuItem;
- pUIMenu->m_nMenuStackSelection[pUIMenu->m_nCurrentMenuDepth]
- = pUIMenu->m_nCurrentSelection;
- pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth]
- = pUIMenu->m_nCurrentParameter;
+ pUIMenu->m_MenuStackParent[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_pParentMenu;
+ pUIMenu->m_MenuStackMenu[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_pCurrentMenu;
+ pUIMenu->m_nMenuStackItem[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_nCurrentMenuItem;
+
+ pUIMenu->m_nMenuStackSelection[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_nCurrentSelection;
+
+ pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_nCurrentParameter;
+
pUIMenu->m_nCurrentMenuDepth++;
- pUIMenu->m_pParentMenu = pUIMenu->m_pCurrentMenu;
- pUIMenu->m_nCurrentParameter =
- pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].Parameter;
- pUIMenu->m_pCurrentMenu =
- pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].MenuItem;
- pUIMenu->m_nCurrentMenuItem = pUIMenu->m_nCurrentSelection;
- pUIMenu->m_nCurrentSelection = 0;
+ pUIMenu->m_pParentMenu = pUIMenu->m_pCurrentMenu;
+
+ pUIMenu->m_nCurrentParameter = pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].Parameter;
+
+ pUIMenu->m_pCurrentMenu = pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].MenuItem;
+ pUIMenu->m_nCurrentMenuItem = pUIMenu->m_nCurrentSelection;
+ pUIMenu->m_nCurrentSelection = 0;
break;
case MenuEventStepDown:
@@ -669,7 +1087,7 @@ void CUIMenu::EditVoiceBankNumber (CUIMenu *pUIMenu, TMenuEvent Event)
{
unsigned nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-1];
- int nValue = pUIMenu->m_pMiniDexed->GetTGParameter (CMiniDexed::TGParameterVoiceBank, nTG);
+ int nValue = pUIMenu->m_pMiniDexed->GetTGParameter (CMiniDexed::TTGParameter::TGParameterVoiceBank, nTG);
switch (Event)
{
@@ -679,13 +1097,13 @@ void CUIMenu::EditVoiceBankNumber (CUIMenu *pUIMenu, TMenuEvent Event)
case MenuEventStepDown:
nValue = pUIMenu->m_pMiniDexed->GetSysExFileLoader ()->GetNextBankDown(nValue);
pUIMenu->m_pMiniDexed->SetTGParameter (
- CMiniDexed::TGParameterVoiceBank, nValue, nTG);
+ CMiniDexed::TTGParameter::TGParameterVoiceBank, nValue, nTG);
break;
case MenuEventStepUp:
nValue = pUIMenu->m_pMiniDexed->GetSysExFileLoader ()->GetNextBankUp(nValue);
pUIMenu->m_pMiniDexed->SetTGParameter (
- CMiniDexed::TGParameterVoiceBank, nValue, nTG);
+ CMiniDexed::TTGParameter::TGParameterVoiceBank, nValue, nTG);
break;
case MenuEventPressAndStepDown:
@@ -713,7 +1131,7 @@ void CUIMenu::EditProgramNumber (CUIMenu *pUIMenu, TMenuEvent Event)
{
unsigned nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-1];
- int nValue = pUIMenu->m_pMiniDexed->GetTGParameter (CMiniDexed::TGParameterProgram, nTG);
+ int nValue = pUIMenu->m_pMiniDexed->GetTGParameter (CMiniDexed::TTGParameter::TGParameterProgram, nTG);
switch (Event)
{
@@ -725,11 +1143,11 @@ void CUIMenu::EditProgramNumber (CUIMenu *pUIMenu, TMenuEvent Event)
{
// Switch down a voice bank and set to the last voice
nValue = CSysExFileLoader::VoicesPerBank-1;
- int nVB = pUIMenu->m_pMiniDexed->GetTGParameter(CMiniDexed::TGParameterVoiceBank, nTG);
+ int nVB = pUIMenu->m_pMiniDexed->GetTGParameter(CMiniDexed::TTGParameter::TGParameterVoiceBank, nTG);
nVB = pUIMenu->m_pMiniDexed->GetSysExFileLoader ()->GetNextBankDown(nVB);
- pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TGParameterVoiceBank, nVB, nTG);
+ pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TTGParameter::TGParameterVoiceBank, nVB, nTG);
}
- pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TGParameterProgram, nValue, nTG);
+ pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TTGParameter::TGParameterProgram, nValue, nTG);
break;
case MenuEventStepUp:
@@ -737,11 +1155,11 @@ void CUIMenu::EditProgramNumber (CUIMenu *pUIMenu, TMenuEvent Event)
{
// Switch up a voice bank and reset to voice 0
nValue = 0;
- int nVB = pUIMenu->m_pMiniDexed->GetTGParameter(CMiniDexed::TGParameterVoiceBank, nTG);
+ int nVB = pUIMenu->m_pMiniDexed->GetTGParameter(CMiniDexed::TTGParameter::TGParameterVoiceBank, nTG);
nVB = pUIMenu->m_pMiniDexed->GetSysExFileLoader ()->GetNextBankUp(nVB);
- pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TGParameterVoiceBank, nVB, nTG);
+ pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TTGParameter::TGParameterVoiceBank, nVB, nTG);
}
- pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TGParameterProgram, nValue, nTG);
+ pUIMenu->m_pMiniDexed->SetTGParameter (CMiniDexed::TTGParameter::TGParameterProgram, nValue, nTG);
break;
case MenuEventPressAndStepDown:
@@ -884,6 +1302,60 @@ void CUIMenu::EditTGParameter2 (CUIMenu *pUIMenu, TMenuEvent Event) // second me
}
+void CUIMenu::EditTGParameter3(CUIMenu *pUIMenu, TMenuEvent Event)
+{
+ unsigned nTG = pUIMenu->m_nCurrentMenuItem;
+
+ CMiniDexed::TTGParameter Param = (CMiniDexed::TTGParameter) pUIMenu->m_nCurrentParameter;
+
+ const TParameter &rParam = s_TGParameter[Param];
+
+ int nValue = pUIMenu->m_pMiniDexed->GetTGParameter (Param, nTG);
+
+ switch (Event)
+ {
+ case MenuEventUpdate:
+ break;
+
+ case MenuEventStepDown:
+ nValue -= rParam.Increment;
+ if (nValue < rParam.Minimum)
+ {
+ nValue = rParam.Minimum;
+ }
+ pUIMenu->m_pMiniDexed->SetTGParameter (Param, nValue, nTG);
+ break;
+
+ case MenuEventStepUp:
+ nValue += rParam.Increment;
+ if (nValue > rParam.Maximum)
+ {
+ nValue = rParam.Maximum;
+ }
+ pUIMenu->m_pMiniDexed->SetTGParameter (Param, nValue, nTG);
+ break;
+
+ case MenuEventPressAndStepDown:
+ case MenuEventPressAndStepUp:
+ pUIMenu->TGShortcutHandler (Event);
+ return;
+
+ default:
+ return;
+ }
+
+ string TG ("TG");
+ TG += to_string (nTG+1);
+
+ string Value = GetTGValueString (Param, pUIMenu->m_pMiniDexed->GetTGParameter (Param, nTG));
+
+ pUIMenu->m_pUI->DisplayWrite (TG.c_str (),
+ pUIMenu->m_pParentMenu[pUIMenu->m_nCurrentMenuItem].Name,
+ Value.c_str (),
+ nValue > rParam.Minimum, nValue < rParam.Maximum);
+
+}
+
void CUIMenu::EditVoiceParameter (CUIMenu *pUIMenu, TMenuEvent Event)
{
unsigned nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-2];
@@ -1702,5 +2174,3 @@ void CUIMenu::EditTGParameterModulation (CUIMenu *pUIMenu, TMenuEvent Event)
nValue > rParam.Minimum, nValue < rParam.Maximum);
}
-
-
diff --git a/src/uimenu.h b/src/uimenu.h
index e8448c5..9cd8693 100644
--- a/src/uimenu.h
+++ b/src/uimenu.h
@@ -85,6 +85,7 @@ private:
static void EditOPParameter (CUIMenu *pUIMenu, TMenuEvent Event);
static void SavePerformance (CUIMenu *pUIMenu, TMenuEvent Event);
static void EditTGParameter2 (CUIMenu *pUIMenu, TMenuEvent Event);
+ static void EditTGParameter3 (CUIMenu *pUIMenu, TMenuEvent Event);
static void EditTGParameterModulation (CUIMenu *pUIMenu, TMenuEvent Event);
static void PerformanceMenu (CUIMenu *pUIMenu, TMenuEvent Event);
static void SavePerformanceNewFile (CUIMenu *pUIMenu, TMenuEvent Event);
@@ -139,18 +140,37 @@ private:
static const TMenuItem s_MainMenu[];
static const TMenuItem s_TGMenu[];
static const TMenuItem s_EffectsMenu[];
-#ifdef ARM_ALLOW_MULTI_CORE
- static const TMenuItem s_ReverbMenu[];
+#if defined(MIXING_CONSOLE_ENABLE)
+ static const TMenuItem s_TGFXMenu[];
+ static const TMenuItem s_FXTube[];
+ static const TMenuItem s_FXTubeLevels[];
+ static const TMenuItem s_FXTubeSend[];
+ static const TMenuItem s_FXChorus[];
+ static const TMenuItem s_FXChorusLevels[];
+ static const TMenuItem s_FXChorusSend[];
+ static const TMenuItem s_FXFlanger[];
+ static const TMenuItem s_FXFlangerLevels[];
+ static const TMenuItem s_FXFlangerSend[];
+ static const TMenuItem s_FXOrbitone[];
+ static const TMenuItem s_FXOrbitoneLevels[];
+ static const TMenuItem s_FXOrbitoneSend[];
+ static const TMenuItem s_FXPhaser[];
+ static const TMenuItem s_FXPhaserLevels[];
+ static const TMenuItem s_FXPhaserSend[];
+ static const TMenuItem s_FXDelay[];
+ static const TMenuItem s_FXDelayLevels[];
+ static const TMenuItem s_FXDelaySend[];
#endif
-#ifdef FXRACK_ENABLE
- static const TMenuItem s_FXChainMenu[];
- static const TMenuItem s_FXChainTube[];
- static const TMenuItem s_FXChainChorus[];
- static const TMenuItem s_FXChainFlanger[];
- static const TMenuItem s_FXChainOrbitone[];
- static const TMenuItem s_FXChainPhaser[];
- static const TMenuItem s_FXChainDelay[];
- static const TMenuItem s_FXChainShimmerReverb[];
+#if defined(PLATE_REVERB_ENABLE) || defined(MIXING_CONSOLE_ENABLE)
+ static const TMenuItem s_FXPlateReverb[];
+#endif
+#if defined(MIXING_CONSOLE_ENABLE)
+ static const TMenuItem s_FXPlateReverbLevels[];
+ static const TMenuItem s_FXPlateReverbSend[];
+ static const TMenuItem s_FXReverberator[];
+ static const TMenuItem s_FXReverberatorLevels[];
+ static const TMenuItem s_FXReverberatorSend[];
+ static const TMenuItem s_FXMainOutputLevels[];
#endif
static const TMenuItem s_EditVoiceMenu[];
static const TMenuItem s_OperatorMenu[];
diff --git a/wiki-update/Chorus--Channel.png b/wiki-update/Chorus--Channel.png
new file mode 100644
index 0000000..65d3e98
Binary files /dev/null and b/wiki-update/Chorus--Channel.png differ
diff --git a/wiki-update/Delay--Channel.png b/wiki-update/Delay--Channel.png
new file mode 100644
index 0000000..11beb5a
Binary files /dev/null and b/wiki-update/Delay--Channel.png differ
diff --git a/wiki-update/Flanger--Channel.png b/wiki-update/Flanger--Channel.png
new file mode 100644
index 0000000..775bd0a
Binary files /dev/null and b/wiki-update/Flanger--Channel.png differ
diff --git a/wiki-update/Orbitone--Channel.png b/wiki-update/Orbitone--Channel.png
new file mode 100644
index 0000000..eb43aa9
Binary files /dev/null and b/wiki-update/Orbitone--Channel.png differ
diff --git a/wiki-update/Phaser--Channel.png b/wiki-update/Phaser--Channel.png
new file mode 100644
index 0000000..8d2a6a7
Binary files /dev/null and b/wiki-update/Phaser--Channel.png differ
diff --git a/wiki-update/PlateReverb--Channel.png b/wiki-update/PlateReverb--Channel.png
new file mode 100644
index 0000000..822ed16
Binary files /dev/null and b/wiki-update/PlateReverb--Channel.png differ
diff --git a/wiki-update/Reverberator--Channel.png b/wiki-update/Reverberator--Channel.png
new file mode 100644
index 0000000..2044fe1
Binary files /dev/null and b/wiki-update/Reverberator--Channel.png differ
diff --git a/wiki-update/Tube--Channel.png b/wiki-update/Tube--Channel.png
new file mode 100644
index 0000000..b680ce6
Binary files /dev/null and b/wiki-update/Tube--Channel.png differ
diff --git a/wiki-update/Tube--overdrive-response.png b/wiki-update/Tube--overdrive-response.png
new file mode 100644
index 0000000..db5bef1
Binary files /dev/null and b/wiki-update/Tube--overdrive-response.png differ
diff --git a/wiki-update/fx-page.md b/wiki-update/fx-page.md
new file mode 100644
index 0000000..bb651d4
--- /dev/null
+++ b/wiki-update/fx-page.md
@@ -0,0 +1,470 @@
+# Mixing Console & Audio Effect
+
+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:
+
+
+
+Each FX has the possibility to return to any other Audio FX unit as well as Main Output.
+
+The diagram below shows the synopsis of this Mixing Console.
+
+
+
+## The Audio FX
+
+The following audio FX are available:
+
+* **Tube:** an amplifier that mimmic the response of valve based amplifier.
+
+
+
+ * ***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)
+
+
+
+
+* **Chorus:** this effect is an audio signal processing technique that creates a richer, thicker sound by duplicating the original signal and slightly delaying and modulating the duplicated signal in pitch and time. The modulated and delayed signals are then mixed back together with the original signal, creating a sound that seems to be coming from multiple sources or voices.
+The result of a chorus effect is a distinctive "shimmering" or "swirling" sound, similar to the sound of a choir or a group of instruments playing together. Chorus effects are commonly used in music production to add depth and complexity to a sound, particularly for guitars, keyboards, and vocals. They are also used in some audio equipment, such as guitar pedals and synthesizers, to produce a chorus effect in real-time.
+This implementation is a standard Chorus FX that is based on 4 LFO:
+ | LFO | Min. freq. | Max. freq. | Phase |
+ |-----|------------|------------|-------|
+ | 1 | 0.0 Hz | 0.25 Hz | 0° |
+ | 2 | 0.0 Hz | 0.25 Hz | 90° |
+ | 3 | 0.0 Hz | 0.35 Hz | 0° |
+ | 4 | 0.0 Hz | 0.35 Hz | 90° |
+
+
+
+ * ***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).
+ * ***Depth [0 - 99]:*** the level of modulation of the FX. The higher the value the more prononced the audio processing is.
+
+
+
+
+* **Flanger:** this effect is an audio signal processing technique that creates a sweeping, swirling sound by mixing a delayed copy of an audio signal with the original signal. The delay time of the copied signal is varied over time, creating a series of peaks and troughs in the frequency spectrum of the combined signal.
+The resulting sound is similar to a chorus effect, but with a more pronounced "swooshing" or "jet engine" effect, as the peaks and troughs of the frequency spectrum sweep up and down in a cyclic pattern. Flangers are often used in music production to create an "otherworldly" or psychedelic effect, particularly on guitars and keyboards.
+The name "flanger" comes from the original method of creating the effect, which involved using two tape recorders to play back the same signal simultaneously, while a finger was used to slightly slow down or speed up the flange (rim) of one of the reels, causing the delayed signal to vary in time. Today, flanger effects are typically created digitally, using specialized signal processing algorithms in software or hardware devices such as guitar pedals or studio processors.
+This implementation is based on 2 LFO:
+ | LFO | Min. freq. | Max. freq. | Phase |
+ |-----|------------|------------|-------|
+ | 1 | 0.1 Hz | 5.0 Hz | 0° |
+ | 2 | 0.1 Hz | 5.0 Hz | 90° |
+
+
+
+ * ***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).
+ * ***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.
+
+
+
+
+* ***Orbitone:*** this is an ensemble effect that is an audio signal processing technique that creates the impression of multiple instruments or voices playing together. It is similar to a chorus effect in that it involves duplicating and modulating an audio signal, but with some differences in the way it is applied.
+In an ensemble effect, the duplicated signals are modulated with a low-frequency oscillator (LFO) that varies the pitch and amplitude of the signals over time. The modulated signals are then mixed with the original signal, creating a sound that is thicker and richer, as if several instruments or voices were playing in unison.
+The resulting sound can be used to add depth and character to a musical performance, particularly for string, brass, or vocal sounds. Ensemble effects are often used in music production to create a sense of warmth, depth, and movement in a mix.
+This implementation is based on 4 LFO:
+ | LFO | Min. freq. | Max. freq. | Phase |
+ |-----|------------|------------|-------|
+ | 1 | 0.0 Hz | 1.0 Hz | 0° |
+ | 2 | 0.0 Hz | 1.0 Hz | 120° |
+ | 3 | 0.0 Hz | 1.0 Hz | 240° |
+ | 4 | 0.0 Hz | 8.8 Hz | 0° |
+ | 5 | 0.0 Hz | 8.8 Hz | 120° |
+ | 6 | 0.0 Hz | 8.8 Hz | 240° |
+
+
+
+ * ***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).
+ * ***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.
+
+
+
+
+* ***Phaser:*** a phaser or phase shifter effect is an audio signal processing technique that creates a sweeping, "whooshing" sound by altering the phase relationship between two identical signals. This is achieved by splitting the audio signal into two parts, delaying one of them slightly, and then combining them again. The delay time is varied over time, causing certain frequencies in the audio signal to be boosted and others to be attenuated.
+The resulting sound is characterized by a series of peaks and troughs in the frequency spectrum, which move up and down in a sweeping pattern. The phaser effect is often used in music production to create a sense of movement and space in a mix, and is particularly effective on guitars, keyboards, and other melodic instruments.
+This implementation is based on 2 LFO:
+ | LFO | Min. freq. | Max. freq. | Phase |
+ |-----|------------|------------|-------|
+ | 1 | 0.0 Hz | 2.5 Hz | 0° |
+ | 2 | 0.0 Hz | 2.5 Hz | 90° |
+
+
+
+ * ***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).
+ * ***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.
+ * ***Nb Stages [2 - 24]:*** The number of state variable filter stages that the audio signal will traverse.
+
+
+
+
+* **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 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, drums and other melodic instruments.
+The implemention of this delay accept negative values for both left and right delay. Negative values will echo sound reversed.
+
+
+
+ * ***Enable [Off - On]:*** Enable / disable the FX unit.
+ * **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.
+
+
+
+
+* **Plate Reverb:** A plate reverb effect is an audio signal processing technique that simulates the sound of a large, metallic plate vibrating in response to an audio signal. It is one of the most iconic and widely used types of artificial reverberation in music production.
+The plate reverb effect is created by passing an audio signal through a transducer that causes a large metal plate to vibrate in response. The vibrations of the plate are then picked up by one or more microphones and mixed back with the original signal. The sound of the plate reverb is characterized by a smooth decay and a diffuse, ambient quality that can add warmth and depth to a mix.
+Plate reverb effects are often used in music production to add space, depth, and character to a mix. They are particularly effective on vocals, drums, and other percussive sounds, and can be used to create a sense of space and distance in a recording. The effect can be adjusted to achieve varying degrees of intensity, decay time, and other parameters.
+
+
+
+ * ***Enable [Off - On]:*** Enable / disable the FX unit.
+ * ***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.
+ * ***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 Pass [0 - 99]:*** the low pass parameter of a plate reverb refers to a filter that is applied to the reverb signal to attenuate or cut off frequencies above a certain threshold.
+ A low pass filter can be used to create a darker, more mellow sound by reducing or removing high-frequency content from the reverb effect. This can be useful when trying to create a more vintage or retro sound, or when trying to soften harsh or bright sounds in a mix.
+ * ***Diffusion [0 - 99]:*** the diffusion parameter of a plate reverb 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 reverb effect sounds and how the individual reflections blend together.
+ A higher diffusion parameter means that the reflections in the reverb decay will be more widely dispersed, resulting in a more "washed out" or diffuse sound. This can be useful when trying to create a sense of space or depth in a mix, or when trying to create a more ambient or atmospheric effect.
+ Conversely, a lower diffusion parameter means that the reflections in the reverb decay will be more closely spaced, resulting in a more defined and focused sound. This can be useful when trying to create a more natural-sounding reverb effect, or when trying to highlight the details of a particular instrument or sound in a mix.
+ * ***Level [0 - 99]:*** the level parameter of a plate reverb refers to the overall level or amplitude of the reverb effect. It determines how loud the reverb signal is in relation to the dry or unprocessed signal.
+
+
+
+
+* **Reverberator:** the reverberator effect, commonly known as reverb, is an audio processing effect that simulates the sound reflections and acoustic environment of a physical space.
+When a sound is produced in a physical space, it travels through the air and reflects off the walls, floors, and other surfaces in the environment. These reflections create a sense of space and depth, and contribute to the character and quality of the sound.
+A reverberator effect works by simulating these reflections, and can be used to create a wide range of sonic environments, from small and intimate spaces like a bedroom or bathroom, to large and expansive spaces like a concert hall or cathedral.
+Reverberator can be applied to individual tracks or to a mix, and can be adjusted in various ways, such as changing the decay time or "size" of the simulated space, adjusting the frequency content of the reverb, and adjusting the level or balance of the reverb effect in relation to the dry or unprocessed signal.
+Reverberator is a common effect used in many genres of music, as well as in film, television, and other forms of audio production. It can be used to create a sense of realism, depth, and immersion, or to add a sense of ambiance, texture, or mood to a recording or production.
+This implementation pushes the reverberation to reach almost the shimmer effect.
+
+
+
+ * ***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.
+ * **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.
+ A higher diffusion parameter means that the reflections in the reverb decay will be more widely dispersed, resulting in a more "washed out" or diffuse sound. This can be useful when trying to create a sense of space or depth in a mix, or when trying to create a more ambient or atmospheric effect.
+ Conversely, a lower diffusion parameter means that the reflections in the reverberator decay will be more closely spaced, resulting in a more defined and focused sound. This can be useful when trying to create a more natural-sounding reverberator effect, or when trying to highlight the details of a particular instrument or sound in a mix.
+ * **Low Pass [0 - 99]:** the low pass parameter of a plate reverb refers to a filter that is applied to the reverb signal to attenuate or cut off frequencies above a certain threshold.
+ A low pass filter can be used to create a darker, more mellow sound by reducing or removing high-frequency content from the reverb effect. This can be useful when trying to create a more vintage or retro sound, or when trying to soften harsh or bright sounds in a mix.
+
+## The Menu structure
+
+* *MiniDexed*
+ * *TG1*
+ * *Voice*
+ * *Bank*
+ * *Volume*
+ * *Pan*
+ * **FX-Send**
+ * **> Tub** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Tube FX Unit.
+ * **> ChR** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Chorus FX Unit.
+ * **> Flg** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Flanger FX Unit.
+ * **> Orb** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Orbitone FX Unit.
+ * **> PhR** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Phaser FX Unit.
+ * **> Dly** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Delay FX Unit.
+ * **> Plt** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Plate Reverb FX Unit.
+ * **> Rev** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Reverberator FX Unit.
+ * **> Main** *[0 - 99]*: the amount of the Tone Generator signal that will be send to the Main output hence dry.
+ * *Detune*
+ * *Cutoff*
+ * *Resonance*
+ * *Pitch Bend*
+ * *Portamento*
+ * *Poly/Mono*
+ * *Modulation*
+ * *Channel*
+ * *Edit Voice:*
+ * ...
+ * *TG2*
+ * ... *similar to TG1 sub-menu* ...
+ * *TG3*
+ * ... *similar to TG1 sub-menu* ...
+ * *TG4*
+ * ... *similar to TG1 sub-menu* ...
+ * *TG5*
+ * ... *similar to TG1 sub-menu* ...
+ * *TG6*
+ * ... *similar to TG1 sub-menu* ...
+ * *TG7*
+ * ... *similar to TG1 sub-menu* ...
+ * *TG8*
+ * ... *similar to TG1 sub-menu* ...
+ * **Effects**
+ * Compress *[on - off]*: Enable / disable the FX unit for all Tone Generators.
+ * **Tube**
+ * **Enable** *[on - off]*: Enable / disable the FX unit.
+ * **Overdrv** *[0 - 99]*: The overdrive amount of the FX unit.
+ * **Levels**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Tub]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Tub]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> Tub]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> Tub]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> Tub]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> Tub]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> Tub]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> Tub]
+ * **ChR >** *[0 - 99]* - shortcut to [Effects] >> [Chorus] >> [> Tub]
+ * **Flg >** *[0 - 99]* - shortcut to [Effects] >> [FlangR] >> [> Tub]
+ * **Orb >** *[0 - 99]* - shortcut to [Effects] >> [Orb] >> [> Tub]
+ * **PhR >** *[0 - 99]* - shortcut to [Effects] >> [PhasR] >> [> Tub]
+ * **Dly >** *[0 - 99]* - shortcut to [Effects] >> [Delay] >> [> Tub]
+ * **Plt >** *[0 - 99]* - shortcut to [Effects] >> [Plt Rvb] >> [> Tub]
+ * **Rev >** *[0 - 99]* - shortcut to [Effects] >> [Rvbrtor] >> [> Tub]
+ * **FX-Send**
+ * **> ChR** *[0 - 99]*: The amount of signal processed by the Tube FX unit that will be sent to the Chorus FX unit.
+ * **> Flg** *[0 - 99]*: The amount of signal processed by the Tube FX unit that will be sent to the Flanger FX unit.
+ * **> Orb** *[0 - 99]*: The amount of signal processed by the Tube FX unit that will be sent to the Orbitone FX unit.
+ * **> PhR** *[0 - 99]*: The amount of signal processed by the Tube FX unit that will be sent to the Phaser FX unit.
+ * **> Dly** *[0 - 99]*: The amount of signal processed by the Tube FX unit that will be sent to the Delay FX unit.
+ * **> Plt** *[0 - 99]*: The amount of signal processed by the Tube FX unit that will be sent to the Plate Reverb FX unit.
+ * **> Rev** *[0 - 99]*: The amount of signal processed by the Tube FX unit that will be sent to the Reverberator FX unit.
+ * **> Main** *[0 - 99]*: The amount of signal processed by the Tube FX unit that will be sent to the Main output.
+ * **Chorus**
+ * **Enable** *[on - off]*: Enable / disable the FX unit.
+ * **Rate** *[0 - 99]*: The speed of the LFO of the FX unit.
+ * **Depth** *[0 - 99]*: The amount of effect that is applied to the input signal.
+ * **Levels**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> ChR]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> ChR]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> ChR]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> ChR]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> ChR]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> ChR]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> ChR]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> ChR]
+ * **Tub >** *[0 - 99]* - shortcut to [Effects] >> [Tube] >> [> ChR]
+ * **Flg >** *[0 - 99]* - shortcut to [Effects] >> [FlangR] >> [> ChR]
+ * **Orb >** *[0 - 99]* - shortcut to [Effects] >> [Orb] >> [> ChR]
+ * **PhR >** *[0 - 99]* - shortcut to [Effects] >> [PhasR] >> [> ChR]
+ * **Dly >** *[0 - 99]* - shortcut to [Effects] >> [Delay] >> [> ChR]
+ * **Plt >** *[0 - 99]* - shortcut to [Effects] >> [Plt Rvb] >> [> ChR]
+ * **Rev >** *[0 - 99]* - shortcut to [Effects] >> [Rvbrtor] >> [> ChR]
+ * **FX-Send**
+ * **> Tub** *[0 - 99]*: The amount of signal processed by the Chorus FX unit that will be sent to the Tube FX unit.
+ * **> Flg** *[0 - 99]*: The amount of signal processed by the Chorus FX unit that will be sent to the Flanger FX unit.
+ * **> Orb** *[0 - 99]*: The amount of signal processed by the Chorus FX unit that will be sent to the Orbitone FX unit.
+ * **> PhR** *[0 - 99]*: The amount of signal processed by the Chorus FX unit that will be sent to the Phaser FX unit.
+ * **> Dly** *[0 - 99]*: The amount of signal processed by the Chorus FX unit that will be sent to the Delay FX unit.
+ * **> Plt** *[0 - 99]*: The amount of signal processed by the Chorus FX unit that will be sent to the Plate Reverb FX unit.
+ * **> Rev** *[0 - 99]*: The amount of signal processed by the Chorus FX unit that will be sent to the Reverberator FX unit.
+ * **> Main** *[0 - 99]*: The amount of signal processed by the Chorus FX unit that will be sent to the Main output.
+ * **FlangR**
+ * **Enable** *[on - off]*: Enable / disable the FX unit.
+ * **Rate** *[0 - 99]*: The speed of the LFO of the FX unit.
+ * **Depth** *[0 - 99]*: The amount of effect that is applied to the input signal.
+ * **Feedbck** *[0 - 99]*: The amount of processed signal that will be reinjected at the input.
+ * **Levels**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Flg]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Flg]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> Flg]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> Flg]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> Flg]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> Flg]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> Flg]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> Flg]
+ * **Tub >** *[0 - 99]* - shortcut to [Effects] >> [Tube] >> [> Flg]
+ * **ChR >** *[0 - 99]* - shortcut to [Effects] >> [Chorus] >> [> Flg]
+ * **Orb >** *[0 - 99]* - shortcut to [Effects] >> [Orb] >> [> Flg]
+ * **PhR >** *[0 - 99]* - shortcut to [Effects] >> [PhasR] >> [> Flg]
+ * **Dly >** *[0 - 99]* - shortcut to [Effects] >> [Delay] >> [> Flg]
+ * **Plt >** *[0 - 99]* - shortcut to [Effects] >> [Plt Rvb] >> [> Flg]
+ * **Rev >** *[0 - 99]* - shortcut to [Effects] >> [Rvbrtor] >> [> Flg]
+ * **FX-Send**
+ * **> Tub** *[0 - 99]*: The amount of signal processed by the Flanger FX unit that will be sent to the Tube FX unit.
+ * **> ChR** *[0 - 99]*: The amount of signal processed by the Flanger FX unit that will be sent to the Chorus FX unit.
+ * **> Orb** *[0 - 99]*: The amount of signal processed by the Flanger FX unit that will be sent to the Orbitone FX unit.
+ * **> PhR** *[0 - 99]*: The amount of signal processed by the Flanger FX unit that will be sent to the Phaser FX unit.
+ * **> Dly** *[0 - 99]*: The amount of signal processed by the Flanger FX unit that will be sent to the Delay FX unit.
+ * **> Plt** *[0 - 99]*: The amount of signal processed by the Flanger FX unit that will be sent to the Plate Reverb FX unit.
+ * **> Rev** *[0 - 99]*: The amount of signal processed by the Flanger FX unit that will be sent to the Reverberator FX unit.
+ * **> Main** *[0 - 99]*: The amount of signal processed by the Flanger FX unit that will be sent to the Main output.
+ * **Orb**
+ * **Enable** *[on - off]*: Enable / disable the FX unit.
+ * **Rate** *[0 - 99]*: The speed of the LFO of the FX unit.
+ * **Depth** *[0 - 99]*: The amount of effect that is applied to the input signal.
+ * **Levels**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Orb]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Orb]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> Orb]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> Orb]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> Orb]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> Orb]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> Orb]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> Orb]
+ * **Tub >** *[0 - 99]* - shortcut to [Effects] >> [Tube] >> [> Orb]
+ * **ChR >** *[0 - 99]* - shortcut to [Effects] >> [Chorus] >> [> Orb]
+ * **Flg >** *[0 - 99]* - shortcut to [Effects] >> [FlangR] >> [> Orb]
+ * **PhR >** *[0 - 99]* - shortcut to [Effects] >> [PhasR] >> [> Orb]
+ * **Dly >** *[0 - 99]* - shortcut to [Effects] >> [Delay] >> [> Orb]
+ * **Plt >** *[0 - 99]* - shortcut to [Effects] >> [Plt Rvb] >> [> Orb]
+ * **Rev >** *[0 - 99]* - shortcut to [Effects] >> [Rvbrtor] >> [> Orb]
+ * **FX-Send**
+ * **> Tub** *[0 - 99]*: The amount of signal processed by the Orbitone FX unit that will be sent to the Tube FX unit.
+ * **> ChR** *[0 - 99]*: The amount of signal processed by the Orbitone FX unit that will be sent to the Chorus FX unit.
+ * **> Flg** *[0 - 99]*: The amount of signal processed by the Orbitone FX unit that will be sent to the Flanger FX unit.
+ * **> PhR** *[0 - 99]*: The amount of signal processed by the Orbitone FX unit that will be sent to the Phaser FX unit.
+ * **> Dly** *[0 - 99]*: The amount of signal processed by the Orbitone FX unit that will be sent to the Delay FX unit.
+ * **> Plt** *[0 - 99]*: The amount of signal processed by the Orbitone FX unit that will be sent to the Plate Reverb FX unit.
+ * **> Rev** *[0 - 99]*: The amount of signal processed by the Orbitone FX unit that will be sent to the Reverberator FX unit.
+ * **> Main** *[0 - 99]*: The amount of signal processed by the Orbitone FX unit that will be sent to the Main output.
+ * **PhasR**
+ * **Enable** *[on - off]*: Enable / disable the FX unit.
+ * **Rate** *[0 - 99]*: The speed of the LFO of the FX unit.
+ * **Depth** *[0 - 99]*: The amount of effect that is applied to the input signal.
+ * **Feedbck** *[0 - 99]*: The amount of processed signal that will be reinjected at the input.
+ * **Stages** *[2 - 24]*: The number of processing phasing stages.
+ * **Levels**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> PhR]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> PhR]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> PhR]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> PhR]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> PhR]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> PhR]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> PhR]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> PhR]
+ * **Tub >** *[0 - 99]* - shortcut to [Effects] >> [Tube] >> [> PhR]
+ * **ChR >** *[0 - 99]* - shortcut to [Effects] >> [Chorus] >> [> PhR]
+ * **Flg >** *[0 - 99]* - shortcut to [Effects] >> [FlangR] >> [> PhR]
+ * **Orb >** *[0 - 99]* - shortcut to [Effects] >> [Orb] >> [> PhR]
+ * **Dly >** *[0 - 99]* - shortcut to [Effects] >> [Delay] >> [> PhR]
+ * **Plt >** *[0 - 99]* - shortcut to [Effects] >> [Plt Rvb] >> [> PhR]
+ * **Rev >** *[0 - 99]* - shortcut to [Effects] >> [Rvbrtor] >> [> PhR]
+ * **FX-Send**
+ * **> Tub** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Tube FX unit.
+ * **> ChR** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Chorus FX unit.
+ * **> Flg** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Flanger FX unit.
+ * **> Orb** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Orbitone FX unit.
+ * **> Dly** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Delay FX unit.
+ * **> Plt** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Plate Reverb FX unit.
+ * **> Rev** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Reverberator FX unit.
+ * **> Main** *[0 - 99]*: The amount of signal processed by the Phaser FX unit that will be sent to the Main output.
+ * **Delay**
+ * **Enable** *[on - off]*: Enable / disable the FX unit.
+ * **L Delay** *[-99 - 99]*: The delay time for the Left channel. Negtive values play the echoed part of the processed sound reversed.
+ * **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.
+ * **Levels**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Dly]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Dly]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> Dly]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> Dly]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> Dly]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> Dly]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> Dly]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> Dly]
+ * **Tub >** *[0 - 99]* - shortcut to [Effects] >> [Tube] >> [> Dly]
+ * **ChR >** *[0 - 99]* - shortcut to [Effects] >> [Chorus] >> [> Dly]
+ * **Flg >** *[0 - 99]* - shortcut to [Effects] >> [FlangR] >> [> Dly]
+ * **Orb >** *[0 - 99]* - shortcut to [Effects] >> [Orb] >> [> Dly]
+ * **PhR >** *[0 - 99]* - shortcut to [Effects] >> [PhasR] >> [> Dly]
+ * **Plt >** *[0 - 99]* - shortcut to [Effects] >> [Plt Rvb] >> [> Dly]
+ * **Rev >** *[0 - 99]* - shortcut to [Effects] >> [Rvbrtor] >> [> Dly]
+ * **FX-Send**
+ * **> Tub** *[0 - 99]*: The amount of signal processed by the Delay FX unit that will be sent to the Tube FX unit.
+ * **> ChR** *[0 - 99]*: The amount of signal processed by the Delay FX unit that will be sent to the Chorus FX unit.
+ * **> Flg** *[0 - 99]*: The amount of signal processed by the Delay FX unit that will be sent to the Flanger FX unit.
+ * **> Orb** *[0 - 99]*: The amount of signal processed by the Delay FX unit that will be sent to the Orbitone FX unit.
+ * **> PhR** *[0 - 99]*: The amount of signal processed by the Delay FX unit that will be sent to the Phaser FX unit.
+ * **> Plt** *[0 - 99]*: The amount of signal processed by the Delay FX unit that will be sent to the Plate Reverb FX unit.
+ * **> Rev** *[0 - 99]*: The amount of signal processed by the Delay FX unit that will be sent to the Reverberator FX unit.
+ * **> Main** *[0 - 99]*: The amount of signal processed by the Delay FX unit that will be sent to the Main output.
+ * **Plt Rvb**
+ * **Enable** *[on - off]*: Enable / disable the FX unit.
+ * **Size** *[0 - 99]*: The size of the plate that simulate the size of the reverberating room.
+ * **High damp** *[0 - 99]*: The amount of high-frequency attenuation.
+ * **Low damp** *[0 - 99]*: The amount of low-frequency attenuation.
+ * **Low pass** *[0 - 99]*: The low pass cutoff frequency.
+ * **Diffusion** *[0 - 99]*: The degree to which the reflections in the reverb decay are dispersed or spread out in time and space.
+ * **Level** *[0 - 99]*: The overall level or amplitude of the reverb effect.
+ * **Levels**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Plt]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Plt]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> Plt]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> Plt]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> Plt]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> Plt]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> Plt]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> Plt]
+ * **Tub >** *[0 - 99]* - shortcut to [Effects] >> [Tube] >> [> Plt]
+ * **ChR >** *[0 - 99]* - shortcut to [Effects] >> [Chorus] >> [> Plt]
+ * **Flg >** *[0 - 99]* - shortcut to [Effects] >> [FlangR] >> [> Plt]
+ * **Orb >** *[0 - 99]* - shortcut to [Effects] >> [Orb] >> [> Plt]
+ * **PhR >** *[0 - 99]* - shortcut to [Effects] >> [PhasR] >> [> Plt]
+ * **Dly >** *[0 - 99]* - shortcut to [Effects] >> [Delay] >> [> Plt]
+ * **Rev >** *[0 - 99]* - shortcut to [Effects] >> [Rvbrtor] >> [> Plt]
+ * **FX-Send**
+ * **> Tub** *[0 - 99]*: The amount of signal processed by the Plate Reverb FX unit that will be sent to the Tube FX unit.
+ * **> ChR** *[0 - 99]*: The amount of signal processed by the Plate Reverb FX unit that will be sent to the Chorus FX unit.
+ * **> Flg** *[0 - 99]*: The amount of signal processed by the Plate Reverb FX unit that will be sent to the Flanger FX unit.
+ * **> Orb** *[0 - 99]*: The amount of signal processed by the Plate Reverb FX unit that will be sent to the Orbitone FX unit.
+ * **> PhR** *[0 - 99]*: The amount of signal processed by the Plate Reverb FX unit that will be sent to the Phaser FX unit.
+ * **> Dly** *[0 - 99]*: The amount of signal processed by the Plate Reverb FX unit that will be sent to the Delay FX unit.
+ * **> Rev** *[0 - 99]*: The amount of signal processed by the Plate Reverb FX unit that will be sent to the Reverberator FX unit.
+ * **> Main** *[0 - 99]*: The amount of signal processed by the Plate Reverb FX unit that will be sent to the Main output.
+ * **Rvbrtor**
+ * **Enable** *[on - off]*: Enable / disable the FX unit.
+ * **Gain** *[0 - 99]*: The overall level or amplitude of the FX.
+ * **Time** *[0 - 99]*: The time determines the size of the simulated reverberating space.
+ * **Diffusion** *[0 - 99]*: The degree to which the reflections in the reverb decay are dispersed or spread out in time and space.
+ * **Low pass** *[0 - 99]*: The low pass cutoff frequency.
+ * **Levels**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Rev]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Rev]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> Rev]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> Rev]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> Rev]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> Rev]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> Rev]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> Rev]
+ * **Tub >** *[0 - 99]* - shortcut to [Effects] >> [Tube] >> [> Rev]
+ * **ChR >** *[0 - 99]* - shortcut to [Effects] >> [Chorus] >> [> Rev]
+ * **Flg >** *[0 - 99]* - shortcut to [Effects] >> [FlangR] >> [> Rev]
+ * **Orb >** *[0 - 99]* - shortcut to [Effects] >> [Orb] >> [> Rev]
+ * **PhR >** *[0 - 99]* - shortcut to [Effects] >> [PhasR] >> [> Rev]
+ * **Dly >** *[0 - 99]* - shortcut to [Effects] >> [Delay] >> [> Rev]
+ * **Plt >** *[0 - 99]* - shortcut to [Effects] >> [Plt Rvb] >> [> Rev]
+ * **FX-Send**
+ * **> Tub** *[0 - 99]*: The amount of signal processed by the Reverberator FX unit that will be sent to the Tube FX unit.
+ * **> ChR** *[0 - 99]*: The amount of signal processed by the Reverberator FX unit that will be sent to the Chorus FX unit.
+ * **> Flg** *[0 - 99]*: The amount of signal processed by the Reverberator FX unit that will be sent to the Flanger FX unit.
+ * **> Orb** *[0 - 99]*: The amount of signal processed by the Reverberator FX unit that will be sent to the Orbitone FX unit.
+ * **> PhR** *[0 - 99]*: The amount of signal processed by the Reverberator FX unit that will be sent to the Phaser FX unit.
+ * **> Dly** *[0 - 99]*: The amount of signal processed by the Reverberator FX unit that will be sent to the Delay FX unit.
+ * **> Plt** *[0 - 99]*: The amount of signal processed by the Reverberator FX unit that will be sent to the Plate Reverb FX unit.
+ * **> Main** *[0 - 99]*: The amount of signal processed by the Reverberator FX unit that will be sent to the Main output.
+ * **MainOut**
+ * **TG1 >** *[0 - 99]* - shortcut to [TG1] >> [FX-Send] >> [> Main]
+ * **TG2 >** *[0 - 99]* - shortcut to [TG2] >> [FX-Send] >> [> Main]
+ * **TG3 >** *[0 - 99]* - shortcut to [TG3] >> [FX-Send] >> [> Main]
+ * **TG4 >** *[0 - 99]* - shortcut to [TG4] >> [FX-Send] >> [> Main]
+ * **TG5 >** *[0 - 99]* - shortcut to [TG5] >> [FX-Send] >> [> Main]
+ * **TG6 >** *[0 - 99]* - shortcut to [TG6] >> [FX-Send] >> [> Main]
+ * **TG7 >** *[0 - 99]* - shortcut to [TG7] >> [FX-Send] >> [> Main]
+ * **TG8 >** *[0 - 99]* - shortcut to [TG8] >> [FX-Send] >> [> Main]
+ * **Tub >** *[0 - 99]* - shortcut to [Effects] >> [Tube] >> [> Main]
+ * **ChR >** *[0 - 99]* - shortcut to [Effects] >> [Chorus] >> [> Main]
+ * **Flg >** *[0 - 99]* - shortcut to [Effects] >> [FlangR] >> [> Main]
+ * **Orb >** *[0 - 99]* - shortcut to [Effects] >> [Orb] >> [> Main]
+ * **PhR >** *[0 - 99]* - shortcut to [Effects] >> [PhasR] >> [> Main]
+ * **Dly >** *[0 - 99]* - shortcut to [Effects] >> [Delay] >> [> Main]
+ * **Plt >** *[0 - 99]* - shortcut to [Effects] >> [Plt Rvb] >> [> Main]
+ * **Rev >** *[0 - 99]* - shortcut to [Effects] >> [Rvbrtor] >> [> Main]
+ * *Performance*
+ * *Load*
+ * ...
+ * *Save*
+ * ...
+ * *Delete*
+ * ...
diff --git a/wiki-update/mixing-console--TG-Channel.png b/wiki-update/mixing-console--TG-Channel.png
new file mode 100644
index 0000000..e8efcc6
Binary files /dev/null and b/wiki-update/mixing-console--TG-Channel.png differ
diff --git a/wiki-update/mixing-console-overview.png b/wiki-update/mixing-console-overview.png
new file mode 100644
index 0000000..8e229f3
Binary files /dev/null and b/wiki-update/mixing-console-overview.png differ