diff --git a/src/extra_features.h b/src/extra_features.h index 14792a8..d982388 100644 --- a/src/extra_features.h +++ b/src/extra_features.h @@ -71,4 +71,4 @@ inline long long int getElapseTime(std::string marker = "") #define LAP_TIME(marker) #define LOG_LAP_TIME(marker) -#endif \ No newline at end of file +#endif diff --git a/src/fx.cpp b/src/fx.cpp index f879cc8..fd828b3 100644 --- a/src/fx.cpp +++ b/src/fx.cpp @@ -32,8 +32,3 @@ FX::FX(float32_t sampling_rate) : FX::~FX() { } - -void FXBase::prepare() -{ - // does nothing by default -} diff --git a/src/fx.h b/src/fx.h index ec23ad5..e3cef1d 100644 --- a/src/fx.h +++ b/src/fx.h @@ -22,7 +22,7 @@ #include #include "common.h" -#include "extra_features.h" +#include "fx_base.h" class FXBase { @@ -30,13 +30,13 @@ class FXBase protected: FXBase(float32_t sampling_rate); - virtual ~FXBase(); public: + virtual ~FXBase(); + float32_t getSamplingRate() const; virtual void reset() = 0; - virtual void prepare(); private: const float32_t SamplingRate; diff --git a/src/fx_base.h b/src/fx_base.h new file mode 100644 index 0000000..ec6f135 --- /dev/null +++ b/src/fx_base.h @@ -0,0 +1,10 @@ +#pragma once + +#include "extra_features.h" + +enum StereoChannels +{ + Left = 0, + Right, + kNumChannels +}; diff --git a/src/fx_chorus.cpp b/src/fx_chorus.cpp index edfa683..6fc1687 100644 --- a/src/fx_chorus.cpp +++ b/src/fx_chorus.cpp @@ -44,7 +44,7 @@ void Chorus::reset() void Chorus::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) { typedef Engine::Reserve<2047> Memory; - Engine::DelayLine line; + static Engine::DelayLine line; Engine::Context c; this->engine_.start(&c); diff --git a/src/fx_dry.cpp b/src/fx_dry.cpp index 5274d91..1c49794 100644 --- a/src/fx_dry.cpp +++ b/src/fx_dry.cpp @@ -11,7 +11,7 @@ Dry::~Dry() void Dry::reset() { - // does nothing + // nothing to be done } void Dry::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) diff --git a/src/fx_engine.hpp b/src/fx_engine.hpp index 662ca01..2827ff4 100644 --- a/src/fx_engine.hpp +++ b/src/fx_engine.hpp @@ -1,21 +1,22 @@ #pragma once -#include "fx_components.h" +#if defined(DEBUG) +#include +#include +#endif #include #include #include -#define MAKE_INTEGRAL_FRACTIONAL(x) \ - int32_t x ## _integral = static_cast(x); \ - float32_t x ## _fractional = x - static_cast(x ## _integral); +#include "fx_components.h" enum Format { - FORMAT_FLOAT32, FORMAT_12_BIT, FORMAT_16_BIT, - FORMAT_32_BIT + FORMAT_32_BIT, + FORMAT_FLOAT32 }; template @@ -39,66 +40,66 @@ inline int16_t clip16(int32_t x) } template <> -struct DataType +struct DataType { - typedef float32_t T; + typedef uint16_t T; static inline float32_t decompress(T value) { - return value; + return static_cast(static_cast(value)) / 4096.0f; } static inline T compress(float32_t value) { - return constrain(value, -1.0f, 1.0f); + return clip16(static_cast(value * 4096.0f)); } }; template <> -struct DataType +struct DataType { - typedef uint16_t T; + typedef uint32_t T; static inline float32_t decompress(T value) { - return static_cast(static_cast(value)) / 4096.0f; + return static_cast(static_cast(value)) / 65536.0f; } static inline T compress(float32_t value) { - return clip16(static_cast(value * 4096.0f)); + return clip16(static_cast(value * 65536.0f)); } }; template <> -struct DataType +struct DataType { typedef uint32_t T; static inline float32_t decompress(T value) { - return static_cast(static_cast(value)) / 65536.0f; + return static_cast(static_cast(value)) / static_cast(UINT32_MAX); } static inline T compress(float32_t value) { - return clip16(static_cast(value * 65536.0f)); + return value * static_cast(INT32_MAX); } }; template <> -struct DataType +struct DataType { - typedef uint32_t T; + typedef float32_t T; static inline float32_t decompress(T value) { - return static_cast(static_cast(value)) / static_cast(UINT32_MAX); + return value; } static inline T compress(float32_t value) { - return value * static_cast(INT32_MAX); + return constrain(value, -1.0f, 1.0f); } }; @@ -307,10 +308,14 @@ public: inline void interpolate(D& d, float32_t offset, float32_t scale) { assert((D::base + D::length) <= size); - MAKE_INTEGRAL_FRACTIONAL(offset); + + int32_t offset_integral = static_cast(offset); + float32_t offset_fractional = offset - static_cast(offset_integral); + float32_t a = DataType::decompress(this->buffer_[(this->write_ptr_ + offset_integral + D::base) & MASK]); float32_t b = DataType::decompress(this->buffer_[(this->write_ptr_ + offset_integral + D::base + 1) & MASK]); float32_t x = a + (b - a) * offset_fractional; + this->previous_read_ = x; this->accumulator_ += x * scale; } @@ -318,15 +323,9 @@ public: template inline void interpolate(D& d, float32_t offset, LFOIndex index, float32_t amplitude, float32_t scale) { - assert((D::base + D::length) <= size); assert(index < LFOIndex::kLFOCount); - offset += amplitude * this->lfo_value_[index]; - MAKE_INTEGRAL_FRACTIONAL(offset); - float32_t a = DataType::decompress(this->buffer_[(this->write_ptr_ + offset_integral + D::base) & MASK]); - float32_t b = DataType::decompress(this->buffer_[(this->write_ptr_ + offset_integral + D::base + 1) & MASK]); - float32_t x = a + (b - a) * offset_fractional; - this->previous_read_ = x; - this->accumulator_ += x * scale; + + this->interpolate(d, offset + amplitude * this->lfo_value_[index], scale); } private: @@ -355,7 +354,7 @@ public: } } - inline void start(Context *c) + inline void start(Context* c) { --this->write_ptr_; if(this->write_ptr_ < 0) diff --git a/src/fx_flanger.cpp b/src/fx_flanger.cpp index 8b53970..67aff97 100644 --- a/src/fx_flanger.cpp +++ b/src/fx_flanger.cpp @@ -25,8 +25,10 @@ Flanger::~Flanger() delete[] this->delay_lineL_; delete[] this->delay_lineR_; - delete this->lfo_[LFOIndex::LFO_L]; - delete this->lfo_[LFOIndex::LFO_R]; + for(unsigned i = 0; i < LFOIndex::kLFOCount; ++i) + { + delete this->lfo_[i]; + } } inline float32_t linearIterpolationnterp(float32_t inX, float32_t inY, float32_t inPhase) @@ -41,8 +43,10 @@ void Flanger::reset() memset(this->feedback_samples_, 0, 2 * sizeof(float32_t)); this->write_index_ = 0; - this->lfo_[LFOIndex::LFO_L]->reset(); - this->lfo_[LFOIndex::LFO_R]->reset(); + for(unsigned i = 0; i < LFOIndex::kLFOCount; ++i) + { + this->lfo_[i]->reset(); + } } void Flanger::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) @@ -58,8 +62,8 @@ void Flanger::processSample(float32_t inL, float32_t inR, float32_t& outL, float } // Configure LFO for effect processing - float32_t lfo_l = this->lfo_[LFO_L]->process() * this->depth_; - float32_t lfo_r = this->lfo_[LFO_R]->process() * this->depth_; + float32_t lfo_l = this->lfo_[LFOIndex::LFO_L]->process() * this->depth_; + float32_t lfo_r = this->lfo_[LFOIndex::LFO_R]->process() * this->depth_; // Map LFO range to millisecond range according to Chorus or Flanger effect float32_t lfoMappedL = mapfloat(lfo_l, -1.0f, 1.0f, 0.001f, 0.005f); @@ -104,8 +108,8 @@ void Flanger::processSample(float32_t inL, float32_t inR, float32_t& outL, float float32_t delay_sample_r = linearIterpolationnterp(this->delay_lineR_[currentR], this->delay_lineR_[nextR], fractionR); // Store delayed samples as feedback - this->feedback_samples_[0] = delay_sample_l * this->feedback_; - this->feedback_samples_[1] = delay_sample_r * this->feedback_; + this->feedback_samples_[StereoChannels::Left ] = delay_sample_l * this->feedback_; + this->feedback_samples_[StereoChannels::Right] = delay_sample_r * this->feedback_; outL = delay_sample_l; outR = delay_sample_r; diff --git a/src/fx_flanger.h b/src/fx_flanger.h index c0b3fb9..a8a6025 100644 --- a/src/fx_flanger.h +++ b/src/fx_flanger.h @@ -30,7 +30,8 @@ public: enum LFOIndex { LFO_L = 0, - LFO_R + LFO_R, + kLFOCount }; Flanger(float32_t sampling_rate, float32_t rate = 0.5f, float32_t depth = 0.5f, float32_t feedback = 0.0f); @@ -53,9 +54,9 @@ private: float32_t* delay_lineL_; float32_t* delay_lineR_; unsigned write_index_; - float32_t feedback_samples_[2]; + float32_t feedback_samples_[StereoChannels::kNumChannels]; - LFO* lfo_[2]; + LFO* lfo_[LFOIndex::kLFOCount]; float32_t depth_; // Depth of the flanger effect in milliseconds (0.0 - 10.0) float32_t feedback_; // Amount of feedback to apply to the delay line }; \ No newline at end of file diff --git a/src/fx_orbitone.h b/src/fx_orbitone.h index 986c0df..06ab899 100644 --- a/src/fx_orbitone.h +++ b/src/fx_orbitone.h @@ -58,4 +58,4 @@ private: float32_t fullscale_depth_; LFO* lfo_[LFOIndex::kLFOCount]; -}; \ No newline at end of file +}; diff --git a/src/fx_phaser.cpp b/src/fx_phaser.cpp index 06d5ea3..389d344 100644 --- a/src/fx_phaser.cpp +++ b/src/fx_phaser.cpp @@ -80,8 +80,8 @@ void Phaser::processSample(float32_t inL, float32_t inR, float32_t& outL, float3 this->z_[0] = sampleL; this->z_[1] = sampleR; - outL = inL + this->z_[0] * this->depth_; - outR = inR + this->z_[1] * this->depth_; + outL = inL + this->z_[StereoChannels::Left ] * this->depth_; + outR = inR + this->z_[StereoChannels::Right] * this->depth_; } void Phaser::setFrequencyRange(float32_t min_frequency, float32_t max_frequency) diff --git a/src/fx_phaser.h b/src/fx_phaser.h index 0391379..ce04570 100644 --- a/src/fx_phaser.h +++ b/src/fx_phaser.h @@ -42,7 +42,7 @@ public: private: float32_t a1_; - float32_t z_[2]; + float32_t z_[StereoChannels::kNumChannels]; }; Phaser(float32_t sampling_rate, float32_t rate = 0.5f, float32_t depth = 1.0f, float32_t feedback = 0.7f, unsigned nb_stages = 12); @@ -73,5 +73,5 @@ private: float32_t dmax_; unsigned nb_stages_; AllpassDelay stages_[MAX_NB_PHASES]; - float32_t z_[2]; + float32_t z_[StereoChannels::kNumChannels]; }; \ No newline at end of file diff --git a/src/fx_rack.cpp b/src/fx_rack.cpp index 8ddbc70..b08e964 100644 --- a/src/fx_rack.cpp +++ b/src/fx_rack.cpp @@ -50,7 +50,7 @@ inline void FXRack::reset() inline void FXRack::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) { - auto end = this->fx_chain_.end(); + FXChain::iterator end = this->fx_chain_.end(); for(FXChain::iterator it = this->fx_chain_.begin(); it != end; it++) { (*it)->processSample(inL, inR, outL, outR); @@ -60,19 +60,8 @@ inline void FXRack::processSample(float32_t inL, float32_t inR, float32_t& outL, } } -void FXRack::prepare() -{ - auto end = this->fx_chain_.end(); - for(FXChain::iterator it = this->fx_chain_.begin(); it != end; it++) - { - (*it)->prepare(); - } -} - void FXRack::process(float32_t* left_input, float32_t* right_input, float32_t* left_output, float32_t* right_output, size_t nSamples) { - this->prepare(); - float32_t sampleInL; float32_t sampleInR; float32_t sampleOutL; diff --git a/src/fx_rack.h b/src/fx_rack.h index 5def0f5..859a96a 100644 --- a/src/fx_rack.h +++ b/src/fx_rack.h @@ -19,7 +19,6 @@ #pragma once #include "fx.h" -#include "fx_unit.hpp" #include "fx_tube.h" #include "fx_chorus.h" #include "fx_flanger.h" @@ -27,6 +26,7 @@ #include "fx_phaser.h" #include "fx_delay.h" #include "fx_shimmer_reverb.h" +#include "fx_unit.hpp" #include @@ -42,7 +42,6 @@ public: virtual void reset() override; virtual inline void processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) override; - virtual void prepare() override; virtual void process(float32_t* left_input, float32_t* right_input, float32_t* left_output, float32_t* right_output, size_t nSamples) override; void setEnable(bool enable = true); diff --git a/src/fx_svf.h b/src/fx_svf.h index 8866a6e..b340451 100644 --- a/src/fx_svf.h +++ b/src/fx_svf.h @@ -19,7 +19,6 @@ // #include "fx.h" -#include "mixing_console_constants.h" class StateVariableFilter : public FXElement { diff --git a/src/fx_tube.cpp b/src/fx_tube.cpp index 69b2775..d01fd96 100644 --- a/src/fx_tube.cpp +++ b/src/fx_tube.cpp @@ -17,7 +17,7 @@ Tube::~Tube() void Tube::reset() { - // does nothing + // nothing to be done } void Tube::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) diff --git a/src/mixing_console.hpp b/src/mixing_console.hpp index 03896a5..0dd0bcb 100644 --- a/src/mixing_console.hpp +++ b/src/mixing_console.hpp @@ -34,7 +34,7 @@ #include "fx_unit2.hpp" #if defined(DEBUG) -typedef void (*ValueInpector)(const std::string&, size_t, const float32_t); +typedef size_t (*ValueInpector)(const std::string&, size_t, const float32_t); #endif template @@ -47,40 +47,39 @@ public: ~MixingConsole(); // Send section - void setChannelLevel(size_t in, float32_t lvl); - void setPan(size_t in, float32_t pan); - void setSendLevel(size_t in, MixerOutput fx, float32_t lvl); - void setInputSample(size_t in, float32_t sampleL, float32_t sampleR); - void setInputSampleBuffer(size_t in, float32_t* samples); - void setInputSampleBuffer(size_t in, float32_t* samplesL, float32_t* samplesR); + inline void setChannelLevel(size_t in, float32_t lvl); + inline void setPan(size_t in, float32_t pan); + 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); + inline void setInputSampleBuffer(size_t in, float32_t* samplesL, float32_t* samplesR); // Return section - void setReturnLevel(MixerOutput ret, MixerOutput dest, float32_t lvl); - void setReturnSample(MixerOutput ret, float32_t sampleL, float32_t sampleR); + inline void setReturnLevel(MixerOutput ret, MixerOutput dest, float32_t lvl); + inline void setReturnSample(MixerOutput ret, float32_t sampleL, float32_t sampleR); // Get FX - FXElement* getFX(size_t fx); - FXUnit2* getTube(); - FXUnit2* getChorus(); - FXUnit2* getFlanger(); - FXUnit2* getOrbitone(); - FXUnit2* getPhaser(); - FXUnit2* getDelay(); - FXUnit2* getPlateReverb(); - FXUnit2* getShimmerReverb(); - FXUnit2* getDry(); + 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* getShimmerReverb(); + inline FXUnit2* getDry(); // Processing - void init(); - void reset(); - void processSample(float32_t& outL, float32_t& outR); - void prepare(); + inline void init(); + inline void reset(); + inline void processSample(float32_t& outL, float32_t& outR); void process(float32_t* outL, float32_t* outR); protected: - void updatePan(size_t in); - void setLevel(size_t in, MixerOutput fx, float32_t lvl); - void setSample(size_t in, float32_t sampleL, float32_t sampleR); + 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: const size_t BufferSize; @@ -105,7 +104,7 @@ private: #if defined(DEBUG) public: void dump(std::ostream& out, const std::string& key = "") const; - void inspect(ValueInpector inspector, bool checkInputBuffer = false) const; + size_t inspect(ValueInpector inspector, bool checkInputBuffer = false) const; #endif }; @@ -119,12 +118,10 @@ MixingConsole::MixingConsole(float32_t sampling_rate, size_t buffer_s { 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, this->BufferSize); - memset(this->input_sample_buffer_[StereoChannels::Right][i], 0, 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); } - memset(this->fx_, 0, MixerOutput::kFXCount * sizeof(FXElement*)); - 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); @@ -395,20 +392,9 @@ void MixingConsole::processSample(float32_t& outL, float32_t& outR) outR = fx_inputs_[MixerOutput::MainOutput][StereoChannels::Right]; } -template -void MixingConsole::prepare() -{ - for(size_t i = 0; i < MixerOutput::kFXCount; ++i) - { - this->fx_[i]->prepare(); - } -} - template void MixingConsole::process(float32_t* outL, float32_t* outR) { - this->prepare(); - for(size_t s = 0; s < this->BufferSize; ++s) { for(size_t in = 0; in < nb_inputs; ++in) @@ -608,27 +594,29 @@ void MixingConsole::dump(std::ostream& out, const std::string& key) c #define DUMP2(mixer, out, tag) mixer->dump(cout, tag) template -void MixingConsole::inspect(ValueInpector inspector, bool checkInputBuffer) const +size_t MixingConsole::inspect(ValueInpector inspector, bool checkInputBuffer) const { + size_t nb_errors = 0; + for(size_t i = 0; i < nb_inputs; ++i) { - inspector("Level ", i, this->channel_level_[i]); - inspector("Pan L ", i, this->pan_[StereoChannels::Left][i]); - inspector("Pan R ", i, this->pan_[StereoChannels::Right][i]); - inspector("Pan ", i, this->pan_[StereoChannels::kNumChannels][i]); + nb_errors += inspector("Level ", i, this->channel_level_[i]); + nb_errors += inspector("Pan L ", i, this->pan_[StereoChannels::Left][i]); + nb_errors += inspector("Pan R ", i, this->pan_[StereoChannels::Right][i]); + nb_errors += inspector("Pan ", i, this->pan_[StereoChannels::kNumChannels][i]); } for(size_t i = 0; i < (nb_inputs + MixerOutput::kFXCount - 1); ++i) { - inspector("Input L", i, this->input_samples_[StereoChannels::Left ][i]); - inspector("Input R", i, this->input_samples_[StereoChannels::Right][i]); + nb_errors += inspector("Input L", i, this->input_samples_[StereoChannels::Left ][i]); + nb_errors += inspector("Input R", i, this->input_samples_[StereoChannels::Right][i]); } for(size_t c = 0; c < MixerOutput::kFXCount; ++c) { for(size_t i = 0; i < (nb_inputs + MixerOutput::kFXCount - 1); ++i) { - inspector("Levels ", c * 100 + i, this->levels_[c][i]); + nb_errors += inspector("Levels ", c * 100 + i, this->levels_[c][i]); } } @@ -638,14 +626,16 @@ void MixingConsole::inspect(ValueInpector inspector, bool checkInputB { for(size_t k = 0; k < this->BufferSize; ++k) { - inspector("Buffer ", k * 100 + i, this->input_sample_buffer_[StereoChannels::Left ][i][k]); - inspector("Buffer ", k * 100 + i, this->input_sample_buffer_[StereoChannels::Right][i][k]); + nb_errors += inspector("Buffer ", k * 100 + i, this->input_sample_buffer_[StereoChannels::Left ][i][k]); + nb_errors += inspector("Buffer ", k * 100 + i, this->input_sample_buffer_[StereoChannels::Right][i][k]); } } } + + return nb_errors; } -#define INSPECT(mixer, inspector) mixer->inspect(inspector, true); +#define INSPECT(mixer, inspector) mixer->inspect(inspector, true) #else diff --git a/src/mixing_console_constants.h b/src/mixing_console_constants.h index 0ee414b..bc771fe 100644 --- a/src/mixing_console_constants.h +++ b/src/mixing_console_constants.h @@ -6,13 +6,6 @@ #include #include -enum StereoChannels -{ - Left = 0, - Right, - kNumChannels -}; - enum MixerOutput { OutputStart = 0, diff --git a/src/test/test_fx_helper.h b/src/test/test_fx_helper.h index d92a8a7..9a42bd0 100644 --- a/src/test/test_fx_helper.h +++ b/src/test/test_fx_helper.h @@ -7,7 +7,7 @@ #include "../fx.h" #include "../mixing_console_constants.h" -#define AUDIO_SOURCE_FILE "test.wav" +#define AUDIO_SOURCE_FILE "test2.wav" #define SAMPLING_FREQUENCY 44100.0f diff --git a/src/test/test_fx_rack.cpp b/src/test/test_fx_rack.cpp index fcc6628..15a431a 100644 --- a/src/test/test_fx_rack.cpp +++ b/src/test/test_fx_rack.cpp @@ -12,67 +12,62 @@ using namespace std; #define MAX_SVF_SAMPLES 10000000 #define MAX_NB_ERRORS 100 -void setupRack(FXRack* rack) +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->getChorus()->setEnable(Active(scenario, FXSwitch::FX__Chorus)); rack->getChorus()->setWetLevel(0.5f); rack->getChorus()->setRate(0.4f); rack->getChorus()->setDepth(0.5f); - rack->getPhaser()->setWetLevel(1.0f); - rack->getPhaser()->setRate(0.1f); - rack->getPhaser()->setDepth(1.0f); - rack->getPhaser()->setFeedback(0.5f); - rack->getPhaser()->setNbStages(12); + rack->getFlanger()->setEnable(Active(scenario, FXSwitch::FX__Flanger)); + rack->getFlanger()->setWetLevel(0.5f); + rack->getFlanger()->setRate(0.03f); + rack->getFlanger()->setDepth(0.75f); + rack->getFlanger()->setFeedback(0.5f); + rack->getOrbitone()->setEnable(Active(scenario, FXSwitch::FX__Orbitone)); rack->getOrbitone()->setWetLevel(0.8f); rack->getOrbitone()->setRate(0.4f); rack->getOrbitone()->setDepth(0.5f); - rack->getFlanger()->setWetLevel(0.5f); - rack->getFlanger()->setRate(0.03f); - rack->getFlanger()->setDepth(0.75f); - rack->getFlanger()->setFeedback(0.5f); + rack->getPhaser()->setEnable(Active(scenario, FXSwitch::FX__Phaser)); + rack->getPhaser()->setWetLevel(1.0f); + rack->getPhaser()->setRate(0.1f); + rack->getPhaser()->setDepth(1.0f); + rack->getPhaser()->setFeedback(0.5f); + rack->getPhaser()->setNbStages(12); + rack->getDelay()->setEnable(Active(scenario, FXSwitch::FX__Delay)); rack->getDelay()->setWetLevel(0.6f); rack->getDelay()->setLeftDelayTime(0.15f); rack->getDelay()->setLeftDelayTime(0.2f); rack->getDelay()->setFeedback(0.35f); - rack->getDelay()->setFlutterRate(0.15f); - rack->getDelay()->setFlutterAmount(0.75f); + rack->getDelay()->setFlutterRate(0.0f); + rack->getDelay()->setFlutterAmount(0.0f); - rack->getShimmerReverb()->setWetLevel(0.6f); - rack->getShimmerReverb()->setInputGain(0.55f); + rack->getShimmerReverb()->setEnable(Active(scenario, FXSwitch::FX__ShimmerReverb)); + rack->getShimmerReverb()->setWetLevel(0.5f); + rack->getShimmerReverb()->setInputGain(0.35f); rack->getShimmerReverb()->setTime(0.89f); rack->getShimmerReverb()->setDiffusion(0.75f); rack->getShimmerReverb()->setLP(0.8f); } -void activateRackFXUnitScenario(FXRack* rack, int scenario) -{ - rack->getTube()->setEnable(Active(scenario, FXSwitch::FX__Tube)); - rack->getChorus()->setEnable(Active(scenario, FXSwitch::FX__Chorus)); - rack->getPhaser()->setEnable(Active(scenario, FXSwitch::FX__Phaser)); - rack->getOrbitone()->setEnable(Active(scenario, FXSwitch::FX__Orbitone)); - rack->getFlanger()->setEnable(Active(scenario, FXSwitch::FX__Flanger)); - rack->getDelay()->setEnable(Active(scenario, FXSwitch::FX__Delay)); - rack->getShimmerReverb()->setEnable(Active(scenario, FXSwitch::FX__ShimmerReverb)); -} - TEST_P(FXScenarioTest, FXRackResetAllScenarios) { FXRack *rack = new FXRack(SAMPLING_FREQUENCY); - rack->setEnable(true); - setupRack(rack); - - int fxSwitch = GetParam(); - activateRackFXUnitScenario(rack, fxSwitch); + int fxSwitch = this->GetParam(); + rack->setEnable(true); + setupRack(rack, fxSwitch); rack->reset(); + delete rack; } @@ -87,14 +82,11 @@ TEST_P(FXScenarioTest, ScenarioProcessing) memset(sampleOutR, 0, size * nbRepeats * sizeof(float32_t)); FXRack *rack = new FXRack(SAMPLING_FREQUENCY); - rack->setEnable(true); - setupRack(rack); - - rack->reset(); int fxSwitch = this->GetParam(); - - activateRackFXUnitScenario(rack, fxSwitch); + rack->setEnable(true); + setupRack(rack, fxSwitch); + rack->reset(); string name = getScenarioName(fxSwitch); diff --git a/src/test/test_mixing_console.cpp b/src/test/test_mixing_console.cpp index 2ba22bb..0befe27 100644 --- a/src/test/test_mixing_console.cpp +++ b/src/test/test_mixing_console.cpp @@ -6,16 +6,27 @@ #include "../mixing_console.hpp" -void normalizedValueInspector(const std::string& el, size_t idx, const float32_t value) +size_t nanValueInspector(const std::string& el, size_t idx, const float32_t value) { if(std::isnan(value)) { - std::cout << "NAN - " << el << " " << idx << " = " << value << std::endl; + return 1u; } - else if(value != constrain(value, -1.0f, 1.0f)) + + return 0u; +} + +size_t normalizedValueInspector(const std::string& el, size_t idx, const float32_t value) +{ + if(!std::isnan(value)) { - std::cout << "OoB - " << el << " " << idx << " = " << value << std::endl; + if(value != constrain(value, -1.0f, 1.0f)) + { + return 1u; + } } + + return 0u; } class MixingConsoleScenarioTest : public testing::TestWithParam {}; @@ -34,29 +45,36 @@ typedef MixingConsole<8> Mixer; void setupMixingConsoleFX(Mixer* mixer) { + mixer->getTube()->setMute(false); mixer->getTube()->setOverdrive(0.25f); + mixer->getChorus()->setMute(false); mixer->getChorus()->setRate(0.4f); mixer->getChorus()->setDepth(0.5f); - mixer->getPhaser()->setRate(0.1f); - mixer->getPhaser()->setDepth(1.0f); - mixer->getPhaser()->setFeedback(0.5f); - mixer->getPhaser()->setNbStages(12); + mixer->getFlanger()->setMute(false); + mixer->getFlanger()->setRate(0.03f); + mixer->getFlanger()->setDepth(0.75f); + mixer->getFlanger()->setFeedback(0.5f); + mixer->getOrbitone()->setMute(false); mixer->getOrbitone()->setRate(0.4f); mixer->getOrbitone()->setDepth(0.5f); - mixer->getFlanger()->setRate(0.03f); - mixer->getFlanger()->setDepth(0.75f); - mixer->getFlanger()->setFeedback(0.5f); + mixer->getPhaser()->setMute(false); + mixer->getPhaser()->setRate(0.1f); + mixer->getPhaser()->setDepth(1.0f); + mixer->getPhaser()->setFeedback(0.5f); + mixer->getPhaser()->setNbStages(12); + mixer->getDelay()->setMute(false); mixer->getDelay()->setLeftDelayTime(0.5f); mixer->getDelay()->setLeftDelayTime(0.7f); mixer->getDelay()->setFeedback(0.7f); mixer->getDelay()->setFlutterRate(0.7f); mixer->getDelay()->setFlutterAmount(0.7f); + mixer->getPlateReverb()->setMute(false); mixer->getPlateReverb()->set_bypass(false); mixer->getPlateReverb()->size(0.7f); mixer->getPlateReverb()->hidamp(0.5f); @@ -65,6 +83,7 @@ void setupMixingConsoleFX(Mixer* mixer) mixer->getPlateReverb()->diffusion(0.65f); mixer->getPlateReverb()->level(1.0f); + mixer->getShimmerReverb()->setMute(false); mixer->getShimmerReverb()->setInputGain(0.65f); mixer->getShimmerReverb()->setTime(0.89f); mixer->getShimmerReverb()->setDiffusion(0.75f); @@ -96,20 +115,23 @@ TEST(MixingConsole, DryProcessing) mixer->setChannelLevel(0, 1.0f); mixer->setPan(0, 0.5f); mixer->setSendLevel(0, MixerOutput::MainOutput, 1.0f); - DUMP2(mixer, std::cout, "Post setup"); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); 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); - DUMP2(mixer, std::cout, "Post input injection"); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); mixer->process( out[StereoChannels::Left ], out[StereoChannels::Right] ); - DUMP2(mixer, std::cout, "Post processing"); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); EXPECT_EQ(out[StereoChannels::Left ][0], out[StereoChannels::Right][0]); EXPECT_EQ(out[StereoChannels::Left ][1], out[StereoChannels::Right][1]); @@ -132,27 +154,40 @@ TEST(MixingConsole, ShimmerProcessing) mixer->setReturnLevel(MixerOutput::FX_ShimmerReverb, MixerOutput::MainOutput, 1.0f); mixer->setChannelLevel(0, 1.0f); mixer->setPan(0, 0.5f); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); + 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); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); mixer->process( out1[StereoChannels::Left ], out1[StereoChannels::Right] ); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); mixer->reset(); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); float32_t out2[StereoChannels::kNumChannels][length]; mixer->setInputSampleBuffer(0, in); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); mixer->process( out2[StereoChannels::Left ], out2[StereoChannels::Right] ); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); EXPECT_EQ(out1[StereoChannels::Left ][0], out2[StereoChannels::Left ][0]); EXPECT_EQ(out1[StereoChannels::Right][0], out2[StereoChannels::Right][0]); @@ -174,7 +209,8 @@ TEST(MixingConsole, ShimmerNoiseProcessing) mixer->setReturnLevel(MixerOutput::FX_ShimmerReverb, MixerOutput::MainOutput, 1.0f); mixer->setChannelLevel(0, 1.0f); mixer->setPan(0, 0.5f); - INSPECT(mixer, normalizedValueInspector); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); float32_t in[length]; for(size_t i = 0; i < length; ++i) in[i] = getRandomValue(); @@ -183,20 +219,22 @@ TEST(MixingConsole, ShimmerNoiseProcessing) for(size_t i = 0; i < StereoChannels::kNumChannels; ++i) memset(out[i], 0, length * sizeof(float32_t)); mixer->setInputSampleBuffer(0, in); - INSPECT(mixer, normalizedValueInspector); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); mixer->process( out[StereoChannels::Left ], out[StereoChannels::Right] ); - INSPECT(mixer, normalizedValueInspector); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); delete mixer; } TEST(MixingConsole, SimpleProcessing) { - const unsigned nbRepeats = 4; + const unsigned nbRepeats = 2; unsigned size; float32_t** samples = readWaveFile(AUDIO_SOURCE_FILE, size); float32_t* sampleOutL = new float32_t[size * nbRepeats]; @@ -228,6 +266,8 @@ TEST(MixingConsole, SimpleProcessing) { mixer->setInputSampleBuffer(0, samples[0], samples[1]); mixer->process(sampleOutL + j * size, sampleOutR + j * size); + EXPECT_EQ(0, INSPECT(mixer, nanValueInspector)); + EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector)); } saveWaveFile(getResultFile("result-mixing-console.wav"), sampleOutL, sampleOutR, nbRepeats * size, static_cast(SAMPLING_FREQUENCY), 16);