Object inspection framework extension to debug fx

pull/495/head
abscisys 2 years ago
parent 0011ad932e
commit 0cec94f491
  1. 103
      src/debug.hpp
  2. 3
      src/effect_platervbstereo.h
  3. 3
      src/fx.h
  4. 4
      src/fx_chorus.cpp
  5. 65
      src/fx_chorus.h
  6. 9
      src/fx_components.cpp
  7. 249
      src/fx_components.h
  8. 136
      src/fx_delay.h
  9. 9
      src/fx_dry.h
  10. 78
      src/fx_engine.hpp
  11. 94
      src/fx_flanger.h
  12. 4
      src/fx_orbitone.cpp
  13. 57
      src/fx_orbitone.h
  14. 1
      src/fx_phaser.cpp
  15. 98
      src/fx_phaser.h
  16. 57
      src/fx_rack.h
  17. 3
      src/fx_shimmer_reverb.h
  18. 5
      src/fx_svf.cpp
  19. 63
      src/fx_svf.h
  20. 2
      src/fx_tube.cpp
  21. 39
      src/fx_tube.h
  22. 436
      src/mixing_console.hpp
  23. 2
      src/mixing_console_constants.h
  24. 7
      src/test/Makefile
  25. 8
      src/test/test_cpp_performance.cpp
  26. 22
      src/test/test_framework.cpp
  27. 12
      src/test/test_fx_components.cpp
  28. 2
      src/test/test_fx_helper.h
  29. 72
      src/test/test_mixing_console.cpp

@ -0,0 +1,103 @@
#pragma once
#if defined(DEBUG)
#include <cmath>
#include <string>
#include <iostream>
#include <sstream>
typedef size_t (*ValueInpector)(const std::string& tag, const float32_t valueToTest, const float32_t _min, float32_t _max, bool outDebugInfo);
inline size_t nanValueInspector(const std::string& tag, const float32_t valueToTest, const float32_t _min, float32_t _max, bool outDebugInfo)
{
if(std::isnan(valueToTest))
{
if(outDebugInfo)
{
std::cerr << tag << ": nan" << std::endl;
}
return 1u;
}
return 0u;
}
inline size_t normalizedValueInspector(const std::string& tag, const float32_t valueToTest, const float32_t _min, float32_t _max, bool outDebugInfo)
{
if(valueToTest > _max || valueToTest < _min)
{
if(outDebugInfo)
{
std::cerr << tag << ": out of bounds - value: " << valueToTest << " - boundaries: [" << _min << ", " << _max << "]" << std::endl;
}
return 1u;
}
return 0u;
}
inline size_t fullInspector(const std::string& tag, const float32_t valueToTest, const float32_t _min = -1.0f, float32_t _max = 1.0f, bool outDebugInfo = true)
{
if(std::isnan(valueToTest))
{
if(outDebugInfo)
{
std::cerr << tag << ": nan" << std::endl;
}
return 1u;
}
else if(valueToTest > _max || valueToTest < _min)
{
if(outDebugInfo)
{
std::cerr << tag << ": out of bounds - value: " << valueToTest << " - boundaries: [" << _min << ", " << _max << "]" << std::endl;
}
return 1u;
}
return 0u;
}
#define SS_RESET(ss, prec, align) ss.str(""); ss.precision(prec); ss << align; ss << std::fixed
#define SS_SPACE(ss, spc, nb, align, sep) ss.fill(spc); ss.width(nb); ss << "" << sep
#define SS__TEXT(ss, spc, nb, align, sep, txt) ss << align; ss.fill(spc); ss.width(nb); ss << txt << sep
class ValueInpectorDebugger
{
public:
ValueInpectorDebugger() {}
virtual ~ValueInpectorDebugger() {}
virtual void dump(std::ostream& out, bool deepInspection = true, const std::string& tag = "") const = 0;
virtual size_t inspect(ValueInpector inspector, bool deepInspection = true, const std::string& tag = "") const = 0;
};
#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\
{\
code\
}
#define IMPLEMENT_INSPECT(code) \
public:\
virtual size_t inspect(ValueInpector inspector, bool deepInspection = true, const std::string& tag = "") const override\
{\
code\
}
#define INSPECT(obj, inspector) obj->inspect(inspector, true)
#define INSPECT2(obj, inspector, deepInspection) obj->inpect(inspector, deepInspection)
#else
#define INSPECTABLE(clazz) clazz
#define IMPLEMENT_DUMP(code)
#define IMPLEMENT_INSPECT(code)
#define INSPECT(obj, inspector)
#define INSPECT2(obj, inspector, deepInspection)
#endif

@ -196,6 +196,9 @@ private:
uint32_t lfo2_phase_acc; // LFO 2
uint32_t lfo2_adder;
IMPLEMENT_DUMP()
IMPLEMENT_INSPECT(return 0u;)
};
#endif // _EFFECT_PLATEREV_H

@ -22,9 +22,10 @@
#include <arm_math.h>
#include "common.h"
#include "debug.hpp"
#include "fx_base.h"
class FXBase
class INSPECTABLE(FXBase)
{
DISALLOW_COPY_AND_ASSIGN(FXBase);

@ -5,8 +5,6 @@
#define LFO1_MAX_FREQ 0.25f
#define LFO2_MAX_FREQ 0.35f
#define FULLSCALE_DEPTH_RATIO 1536.0f
Chorus::Chorus(float32_t sampling_rate) :
FXElement(sampling_rate),
engine_(sampling_rate, 0.0f),
@ -93,7 +91,7 @@ void Chorus::setDepth(float32_t depth)
if(this->depth_ != depth)
{
this->depth_ = depth;
this->fullscale_depth_ = this->depth_ * FULLSCALE_DEPTH_RATIO;
this->fullscale_depth_ = this->depth_ * CHORUS_FULLSCALE_DEPTH_RATIO;
}
}

@ -22,6 +22,8 @@
#include "fx_components.h"
#include "fx_engine.hpp"
#define CHORUS_FULLSCALE_DEPTH_RATIO 1536.0f
class Chorus : public FXElement
{
DISALLOW_COPY_AND_ASSIGN(Chorus);
@ -58,4 +60,67 @@ private:
float32_t feedback_; // Feedback level of the chorus (0.0 - 1.0)
LFO* lfo_[LFOIndex::kLFOCount];
IMPLEMENT_DUMP(
const size_t space = 16;
const size_t precision = 5;
std::stringstream ss;
out << "START " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
if(deepInspection)
{
this->engine_.dump(out, deepInspection, tag + ".engine_");
}
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space, std::left, '|', "rate_");
SS__TEXT(ss, ' ', space, std::left, '|', "depth_");
SS__TEXT(ss, ' ', space, std::left, '|', "fullscale_depth_");
SS__TEXT(ss, ' ', space, std::left, '|', "feedback_");
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, '+');
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->rate_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->depth_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->fullscale_depth_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->feedback_);
out << "\t" << ss.str() << std::endl;
if(deepInspection)
{
for(size_t i = 0; i < LFOIndex::kLFOCount; ++i)
{
this->lfo_[i]->dump(out, deepInspection, tag + ".lfo_[ " + std::to_string(i) + " ]");
}
}
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_");
for(size_t i = 0; i < LFOIndex::kLFOCount; ++i)
{
nb_errors += this->lfo_[i]->inspect(inspector, deepInspection, tag + ".lfo_[ " + std::to_string(i) + " ]");
}
}
nb_errors += inspector(tag + ".rate_", this->rate_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".depth_", this->depth_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".fullscale_depth_", this->fullscale_depth_, 0.0f, CHORUS_FULLSCALE_DEPTH_RATIO, deepInspection);
return nb_errors;
)
};

@ -410,6 +410,9 @@ JitterGenerator::~JitterGenerator()
void JitterGenerator::setSpeed(float32_t speed)
{
static const float32_t max_frequency = 0.45f * this->getSamplingRate();
speed = constrain(speed, 0.0f, max_frequency);
if(this->speed_ != speed)
{
this->speed_ = speed;
@ -424,7 +427,7 @@ float32_t JitterGenerator::getSpeed() const
void JitterGenerator::setMagnitude(float32_t magnitude)
{
this->magnitude_ = magnitude;
this->magnitude_ = constrain(magnitude, 0.0f, 1.0f);
}
float32_t JitterGenerator::getMagnitude() const
@ -588,8 +591,8 @@ float32_t softSaturator1(float32_t in, float32_t threshold)
float32_t softSaturator2(float32_t input, float32_t saturation)
{
constexpr static float kTubeCurve = 4.0f;
constexpr static float kTubeBias = 0.5f;
const static float kTubeCurve = 4.0f;
const static float kTubeBias = 0.5f;
float absInput = std::abs(input);
float output = 0.0f;

@ -67,6 +67,66 @@ private:
float32_t iir_coefficient_;
float32_t initial_amplitude_;
float32_t current_;
IMPLEMENT_DUMP(
const size_t space = 21;
const size_t precision = 5;
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, '|', "InitialPhase");
SS__TEXT(ss, ' ', space, std::left, '|', "frequency_");
SS__TEXT(ss, ' ', space, std::left, '|', "normalized_frequency_");
SS__TEXT(ss, ' ', space, std::left, '|', "unitary_frequency_");
SS__TEXT(ss, ' ', space, std::left, '|', "y0_");
SS__TEXT(ss, ' ', space, std::left, '|', "y1_");
SS__TEXT(ss, ' ', space, std::left, '|', "iir_coefficient_");
SS__TEXT(ss, ' ', space, std::left, '|', "initial_amplitude_");
SS__TEXT(ss, ' ', space, std::left, '|', "current_");
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, '+');
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->InitialPhase);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->frequency_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->normalized_frequency_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->unitary_frequency_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->y0_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->y1_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->iir_coefficient_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->initial_amplitude_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->current_);
out << "\t" << ss.str() << std::endl;
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".InitialPhase", this->InitialPhase, 0.0f, Constants::M2PI, deepInspection);
nb_errors += inspector(tag + ".frequency_", this->frequency_, this->min_frequency_, this->max_frequency_, deepInspection);
nb_errors += inspector(tag + ".normalized_frequency_", this->normalized_frequency_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".unitary_frequency_", this->unitary_frequency_, this->min_frequency_ / this->getSamplingRate(), this->max_frequency_ / this->getSamplingRate(), deepInspection);
nb_errors += inspector(tag + ".current_", this->current_, -1.0f, 1.0f, deepInspection);
return nb_errors;
)
};
@ -90,7 +150,7 @@ public:
private:
static bool ClassInitializer();
static const size_t DataPointSize = 192000;
static const size_t DataPointSize = 352800;
static const float32_t DeltaTime;
static float32_t DataPoints[];
@ -102,6 +162,56 @@ private:
float32_t phase_index_;
float32_t phase_index_increment_;
float32_t current_sample_;
IMPLEMENT_DUMP(
const size_t space = 22;
const size_t precision = 5;
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, '|', "InitialPhase");
SS__TEXT(ss, ' ', space, std::left, '|', "normalized_frequency_");
SS__TEXT(ss, ' ', space, std::left, '|', "frequency_");
SS__TEXT(ss, ' ', space, std::left, '|', "phase_index_");
SS__TEXT(ss, ' ', space, std::left, '|', "phase_index_increment_");
SS__TEXT(ss, ' ', space, std::left, '|', "current_sample_");
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->InitialPhase);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->normalized_frequency_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->frequency_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_index_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_index_increment_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->current_sample_);
out << "\t" << ss.str() << std::endl;
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".InitialPhase", this->InitialPhase, 0.0f, Constants::M2PI, deepInspection);
nb_errors += inspector(tag + ".normalized_frequency_", this->normalized_frequency_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".frequency_", this->frequency_, this->min_frequency_, this->max_frequency_, deepInspection);
nb_errors += inspector(tag + ".phase_index_", this->phase_index_, 0.0f, static_cast<float32_t>(InterpolatedSineOscillator::DataPointSize), deepInspection);
nb_errors += inspector(tag + ".current_sample_", this->current_sample_, -1.0f, 1.0f, deepInspection);
return nb_errors;
)
};
class ComplexLFO : public FXBase
@ -147,6 +257,57 @@ private:
std::random_device rnd_device_;
std::mt19937 rnd_generator_;
std::uniform_real_distribution<float32_t> rnd_distribution_;
IMPLEMENT_DUMP(
const size_t space = 21;
const size_t precision = 5;
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, '|', "InitialPhase");
SS__TEXT(ss, ' ', space, std::left, '|', "normalized_frequency_");
SS__TEXT(ss, ' ', space, std::left, '|', "frequency_");
SS__TEXT(ss, ' ', space, std::left, '|', "phase_");
SS__TEXT(ss, ' ', space, std::left, '|', "phase_increment_");
SS__TEXT(ss, ' ', space, std::left, '|', "current_sample_");
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->InitialPhase);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->normalized_frequency_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->frequency_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_increment_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->current_sample_);
out << "\t" << ss.str() << std::endl;
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".InitialPhase", this->InitialPhase, 0.0f, Constants::M2PI, deepInspection);
nb_errors += inspector(tag + ".normalized_frequency_", this->normalized_frequency_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".frequency_", this->frequency_, this->min_frequency_, this->max_frequency_, deepInspection);
nb_errors += inspector(tag + ".phase_", this->phase_, 0.0f, Constants::M2PI, deepInspection);
nb_errors += inspector(tag + ".phase_increment_", this->phase_increment_, 0.0f, Constants::M2PI, deepInspection);
nb_errors += inspector(tag + ".current_sample_", this->current_sample_, -1.0f, 1.0f, deepInspection);
return nb_errors;
)
};
@ -178,6 +339,49 @@ private:
float32_t magnitude_;
float32_t phase_;
float32_t phase_increment_;
IMPLEMENT_DUMP(
const size_t space = 16;
const size_t precision = 5;
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, '|', "speed_");
SS__TEXT(ss, ' ', space, std::left, '|', "magnitude_");
SS__TEXT(ss, ' ', space, std::left, '|', "phase_");
SS__TEXT(ss, ' ', space, std::left, '|', "phase_increment_");
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, '+');
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->speed_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->magnitude_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_increment_);
out << "\t" << ss.str() << std::endl;
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".speed_", this->speed_, 0.0f, 0.45f * this->getSamplingRate(), deepInspection);
nb_errors += inspector(tag + ".magnitude_", this->magnitude_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".phase_", this->phase_, 0.0f, Constants::M2PI, deepInspection);
nb_errors += inspector(tag + ".phase_increment_", this->phase_increment_, 0.0f, 0.45f * Constants::M2PI, deepInspection);
return nb_errors;
)
};
@ -208,6 +412,49 @@ private:
float32_t current_;
static const float32_t Gradients[];
IMPLEMENT_DUMP(
const size_t space = 16;
const size_t precision = 5;
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, '|', "rate_");
SS__TEXT(ss, ' ', space, std::left, '|', "phase_");
SS__TEXT(ss, ' ', space, std::left, '|', "phase_increment_");
SS__TEXT(ss, ' ', space, std::left, '|', "current_");
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, '+');
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->rate_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->phase_increment_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->current_);
out << "\t" << ss.str() << std::endl;
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".rate_", this->rate_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".phase_", this->phase_, 0.0f, Constants::M2PI, deepInspection);
nb_errors += inspector(tag + ".phase_increment_", this->phase_increment_, 0.0f, Constants::M2PI / this->getSamplingRate(), deepInspection);
nb_errors += inspector(tag + ".current_", this->current_, -1.0f, 1.0f, deepInspection);
return nb_errors;
)
};
float32_t softSaturator1(float32_t in, float32_t threshold);

@ -45,8 +45,50 @@ class Delay : public FXElement
StateVariableFilter lpf_;
StateVariableFilter hpf_;
float32_t ratio_;
};
IMPLEMENT_DUMP(
const size_t space = 10;
const size_t precision = 5;
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, '|', "ratio_");
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, 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->ratio_);
out << "\t" << ss.str() << std::endl;
if(deepInspection)
{
out << "\t" << std::endl;
this->lpf_.dump(out, deepInspection, tag + ".lpf_");
this->hpf_.dump(out, deepInspection, tag + ".hpf_");
}
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
if(deepInspection)
{
nb_errors += this->lpf_.inspect(inspector, deepInspection, tag + ".lpf_");
nb_errors += this->hpf_.inspect(inspector, deepInspection, tag + ".hpf_");
}
nb_errors += inspector(tag + ".ratio_", this->ratio_, -1.0f, 1.0f, deepInspection);
return nb_errors;
)
};
public:
Delay(const float32_t sampling_rate, float32_t default_delay_time = 0.25f, float32_t default_flutter_level = 1.0f, float32_t default_wet_level = 0.5f);
@ -83,4 +125,96 @@ private:
LowHighPassFilter filter_;
PerlinNoiseGenerator jitter_generator_;
IMPLEMENT_DUMP(
const size_t space = 18;
const size_t precision = 5;
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, '|', "read_pos_L_");
SS__TEXT(ss, ' ', space, std::left, '|', "read_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);
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->read_pos_L_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->read_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)
{
out << "Flanger internal delay lines:" << std::endl;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space, std::left, '|', "index");
SS__TEXT(ss, ' ', space, std::left, '|', "buffer_L_");
SS__TEXT(ss, ' ', space, std::left, '|', "buffer_R_");
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, '+');
out << "\t" << ss.str() << std::endl;
for(size_t i = 0; i < this->MaxSampleDelayTime; ++i)
{
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", i);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->buffer_L_[i]);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->buffer_R_[i]);
out << "\t" << ss.str() << std::endl;
}
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;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0;
nb_errors += inspector(tag + ".read_pos_L_", static_cast<float32_t>(this->read_pos_L_), 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection);
nb_errors += inspector(tag + ".read_pos_R_", static_cast<float32_t>(this->read_pos_R_), 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection);
nb_errors += inspector(tag + ".delay_time_L_", this->delay_time_L_, 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), deepInspection);
nb_errors += inspector(tag + ".delay_time_R_", this->delay_time_R_, 0.0f, static_cast<float32_t>(this->MaxSampleDelayTime), 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)
{
for(size_t i = 0; i < this->MaxSampleDelayTime; ++i)
{
nb_errors += inspector(tag + ".buffer_L_[ " + std::to_string(i) + " ]", this->buffer_L_[i], -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".buffer_R_[ " + std::to_string(i) + " ]", this->buffer_R_[i], -1.0f, 1.0f, deepInspection);
}
nb_errors += this->filter_.inspect(inspector, deepInspection, tag + ".filter_");
nb_errors += this->jitter_generator_.inspect(inspector, deepInspection, tag + ".jitter_generator_");
}
return nb_errors;
)
};

@ -30,4 +30,13 @@ public:
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;
)
};

@ -384,4 +384,82 @@ private:
int32_t write_ptr_;
LFO* lfo_[LFOIndex::kLFOCount];
IMPLEMENT_DUMP(
const size_t space = 10;
const size_t precision = 5;
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, '|', "write_ptr_");
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, 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->write_ptr_);
out << "\t" << ss.str() << std::endl;
if(deepInspection)
{
out << "FXEngine internal buffer:" << std::endl;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space, std::left, '|', "index");
SS__TEXT(ss, ' ', space, std::left, '|', "buffer_");
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, 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 < size; ++i)
{
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", i);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->buffer_[i]);
out << "\t" << ss.str() << std::endl;
}
if(enable_lfo)
{
for(size_t i = 0; i < LFOIndex::kLFOCount; ++i)
{
this->lfo_[i]->dump(out, deepInspection, tag + ".lfo_[ " + std::to_string(i) + " ]");
}
}
}
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".write_ptr_", static_cast<float32_t>(this->write_ptr_), 0.0f, static_cast<float32_t>(size), deepInspection);
if(deepInspection)
{
for(size_t i = 0; i < size; ++i)
{
nb_errors += inspector(tag + ".buffer[ " + std::to_string(i) + " ]", this->buffer_[i], -1.0f, 1.0f, deepInspection);
}
if(enable_lfo)
{
for(size_t i = 0; i < size; ++i)
{
this->lfo_[i]->inspect(inspector, deepInspection, tag + ".lfo_[ " + std::to_string(i) + " ]");
}
}
}
return nb_errors;
)
};

@ -59,4 +59,96 @@ private:
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
};
IMPLEMENT_DUMP(
const size_t space = 22;
const size_t precision = 5;
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, '|', "write_index_");
SS__TEXT(ss, ' ', space, std::left, '|', "feedback_samples_[ L ]");
SS__TEXT(ss, ' ', space, std::left, '|', "feedback_samples_[ R ]");
SS__TEXT(ss, ' ', space, std::left, '|', "depth_");
SS__TEXT(ss, ' ', space, std::left, '|', "feedback_");
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;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->write_index_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->feedback_samples_[StereoChannels::Left ]);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->feedback_samples_[StereoChannels::Right]);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->depth_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->feedback_);
out << "\t" << ss.str() << std::endl;
if(deepInspection)
{
out << "Flanger internal delay lines:" << std::endl;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space, std::left, '|', "index");
SS__TEXT(ss, ' ', space, std::left, '|', "delay_lineL_");
SS__TEXT(ss, ' ', space, std::left, '|', "delay_lineR_");
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, '+');
out << "\t" << ss.str() << std::endl;
for(size_t i = 0; i < this->MaxDelayLineSize; ++i)
{
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", i);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->delay_lineL_[i]);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->delay_lineR_[i]);
out << "\t" << ss.str() << std::endl;
}
for(size_t i = 0; i < LFOIndex::kLFOCount; ++i)
{
this->lfo_[i]->dump(out, deepInspection, tag + ".lfo_[ " + std::to_string(i) + " ]");
}
}
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".write_index_", static_cast<float32_t>(this->write_index_), 0.0, static_cast<float32_t>(this->MaxDelayLineSize), deepInspection);
nb_errors += inspector(tag + ".feedback_samples_[ L ]", this->feedback_samples_[StereoChannels::Left ], -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".feedback_samples_[ R ]", this->feedback_samples_[StereoChannels::Right], -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".depth_", this->depth_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".feedback_", this->feedback_, 0.0f, 0.97f, deepInspection);
if(deepInspection)
{
for(size_t i = 0; i < this->MaxDelayLineSize; ++i)
{
nb_errors += inspector(tag + ".delay_lineL_[ " + std::to_string(i) + " ]", this->delay_lineL_[i], -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".delay_lineR_[ " + std::to_string(i) + " ]", this->delay_lineR_[i], -1.0f, 1.0f, deepInspection);
}
for(size_t i = 0; i < LFOIndex::kLFOCount; ++i)
{
nb_errors += this->lfo_[i]->inspect(inspector, deepInspection, tag + ".lfo_[ " + std::to_string(i) + " ]");
}
}
return nb_errors;
)
};

@ -5,8 +5,6 @@
#define LFO_SLOW_MAX_FREQUENCY 1.0f
#define LFO_FAST_MAX_FREQUENCY 8.8f
#define FULLSCALE_DEPTH_RATIO 256.0f
Orbitone::Orbitone(float32_t sampling_rate, float32_t rate, float32_t depth) :
FXElement(sampling_rate),
engine_(sampling_rate, 0.0f),
@ -114,7 +112,7 @@ void Orbitone::setDepth(float32_t depth)
if(this->depth_ != depth)
{
this->depth_ = depth;
this->fullscale_depth_ = this->depth_ * FULLSCALE_DEPTH_RATIO;
this->fullscale_depth_ = this->depth_ * ORBITONE_FULLSCALE_DEPTH_RATIO;
}
}

@ -22,6 +22,8 @@
#include "fx_components.h"
#include "fx_engine.hpp"
#define ORBITONE_FULLSCALE_DEPTH_RATIO 256.0f
class Orbitone : public FXElement
{
DISALLOW_COPY_AND_ASSIGN(Orbitone);
@ -58,4 +60,59 @@ private:
float32_t fullscale_depth_;
LFO* lfo_[LFOIndex::kLFOCount];
IMPLEMENT_DUMP(
const size_t space = 16;
const size_t precision = 5;
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, '|', "depth_");
SS__TEXT(ss, ' ', space, std::left, '|', "fullscale_depth_");
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, 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->depth_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->fullscale_depth_);
out << "\t" << ss.str() << std::endl;
if(deepInspection)
{
this->engine_.dump(out, deepInspection, tag + ".engine_");
for(size_t i = 0; i < LFOIndex::kLFOCount; ++i)
{
this->lfo_[i]->dump(out, deepInspection, tag + ".lfo_[ " + std::to_string(i) + " ]");
}
}
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".depth_", this->depth_, -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".fullscale_depth_", this->fullscale_depth_, 0.0f, ORBITONE_FULLSCALE_DEPTH_RATIO, deepInspection);
if(deepInspection)
{
this->engine_.inspect(inspector, deepInspection, tag + ".engine_");
for(size_t i = 0; i < LFOIndex::kLFOCount; ++i)
{
this->lfo_[i]->inspect(inspector, deepInspection, tag + ".lfo_[ " + std::to_string(i) + " ]");
}
}
return nb_errors;
)
};

@ -4,6 +4,7 @@
#include <cmath>
Phaser::AllpassDelay::AllpassDelay() :
FXElement(0.0f),
a1_(0.0f)
{
this->reset();

@ -27,7 +27,7 @@ class Phaser : public FXElement
DISALLOW_COPY_AND_ASSIGN(Phaser);
public:
class AllpassDelay
class AllpassDelay : public FXElement
{
DISALLOW_COPY_AND_ASSIGN(AllpassDelay);
@ -43,6 +43,39 @@ public:
private:
float32_t a1_;
float32_t z_[StereoChannels::kNumChannels];
IMPLEMENT_DUMP(
const size_t space = 10;
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, '|', "a1_");
SS__TEXT(ss, ' ', space, std::left, '|', "z_[ L ]");
SS__TEXT(ss, ' ', space, std::left, '|', "z_[ R ]");
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, '+');
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->a1_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->z_[StereoChannels::Left ]);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->z_[StereoChannels::Right]);
out << "\t" << ss.str() << std::endl;
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
return 0u;
)
};
Phaser(float32_t sampling_rate, float32_t rate = 0.5f, float32_t depth = 1.0f, float32_t feedback = 0.7f, unsigned nb_stages = 12);
@ -74,4 +107,67 @@ private:
unsigned nb_stages_;
AllpassDelay stages_[MAX_NB_PHASES];
float32_t z_[StereoChannels::kNumChannels];
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, '|', "depth_");
SS__TEXT(ss, ' ', space, std::left, '|', "feedback_");
SS__TEXT(ss, ' ', space, std::left, '|', "dmin_");
SS__TEXT(ss, ' ', space, std::left, '|', "dmax_");
SS__TEXT(ss, ' ', space, std::left, '|', "nb_stages_");
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;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->depth_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->feedback_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->dmin_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->dmax_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->nb_stages_);
out << "\t" << ss.str() << std::endl;
if(deepInspection)
{
this->lfo_.dump(out, deepInspection, tag + ".lfo_");
for(unsigned i = 0; i < MAX_NB_PHASES; ++i)
{
this->stages_[i].dump(out, deepInspection, tag + ".stages_[ " + std::to_string(i) + " ]");
}
}
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + ".depth_", this->depth_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".feedback_", this->feedback_, 0.0f, 0.97f, deepInspection);
nb_errors += inspector(tag + ".nb_stages_", static_cast<float32_t>(this->nb_stages_), 0.0f, static_cast<float32_t>(MAX_NB_PHASES), deepInspection);
if(deepInspection)
{
nb_errors += this->lfo_.inspect(inspector, deepInspection, tag + ".lfo_");
for(unsigned i = 0; i < MAX_NB_PHASES; ++i)
{
nb_errors += this->stages_[i].inspect(inspector, deepInspection, tag + ".stages_[ " + std::to_string(i) + " ]");
}
}
return nb_errors;
)
};

@ -72,4 +72,61 @@ private:
FXUnit<Phaser>* fxPhaser_;
FXUnit<Delay>* fxDelay_;
FXUnit<ShimmerReverb>* fxShimmerReverb_;
IMPLEMENT_DUMP(
const size_t space = 10;
const size_t precision = 5;
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, '|', "enable_");
SS__TEXT(ss, ' ', space, std::left, '|', "wet_level_");
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, 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->enable_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->wet_level_);
out << "\t" << ss.str() << std::endl;
if(deepInspection)
{
this->fxTube_->dump(out, deepInspection, tag + ".fxTube_");
this->fxChorus_->dump(out, deepInspection, tag + ".fxChorus_");
this->fxFlanger_->dump(out, deepInspection, tag + ".fxFlanger_");
this->fxOrbitone_->dump(out, deepInspection, tag + ".fxOrbitone_");
this->fxPhaser_->dump(out, deepInspection, tag + ".fxPhaser_");
this->fxDelay_->dump(out, deepInspection, tag + ".fxDelay_");
this->fxShimmerReverb_->dump(out, deepInspection, tag + ".fxShimmerReverb_");
}
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0;
nb_errors += inspector(tag + ".enable_", this->enable_, -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".wet_level_", this->wet_level_, -1.0f, 1.0f, deepInspection);
if(deepInspection)
{
nb_errors += this->fxTube_->inspect(inspector, deepInspection, tag + ".fxTube_");
nb_errors += this->fxChorus_->inspect(inspector, deepInspection, tag + ".fxChorus_");
nb_errors += this->fxFlanger_->inspect(inspector, deepInspection, tag + ".fxFlanger_");
nb_errors += this->fxOrbitone_->inspect(inspector, deepInspection, tag + ".fxOrbitone_");
nb_errors += this->fxPhaser_->inspect(inspector, deepInspection, tag + ".fxPhaser_");
nb_errors += this->fxDelay_->inspect(inspector, deepInspection, tag + ".fxDelay_");
nb_errors += this->fxShimmerReverb_->inspect(inspector, deepInspection, tag + ".fxShimmerReverb_");
}
return nb_errors;
)
};

@ -59,4 +59,7 @@ private:
float32_t lp_decay_1_;
float32_t lp_decay_2_;
IMPLEMENT_DUMP()
IMPLEMENT_INSPECT(return 0u;)
};

@ -31,7 +31,9 @@ void StateVariableFilter::setFilterType(Type type)
void StateVariableFilter::setCutoff(float32_t cutoff)
{
cutoff = constrain(cutoff, 1.0f, this->getSamplingRate() / 2.0f);
static const float32_t max_frequency = 0.45f * this->getSamplingRate();
cutoff = constrain(cutoff, 1.0f, max_frequency);
if(this->cutoff_ != cutoff)
{
this->cutoff_ = cutoff;
@ -72,7 +74,6 @@ void StateVariableFilter::updateCoefficients()
switch(this->type_)
{
case Type::LPF:
this->d1_ = 0.0f;
this->d0_ = 0.25f * this->c1_ * this->c2_;

@ -60,4 +60,67 @@ private:
float32_t d1_;
float32_t z1_[StereoChannels::kNumChannels];
float32_t z2_[StereoChannels::kNumChannels];
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, '|', "gain_");
SS__TEXT(ss, ' ', space, std::left, '|', "cutoff_");
SS__TEXT(ss, ' ', space, std::left, '|', "resonance_");
SS__TEXT(ss, ' ', space, std::left, '|', "g_");
SS__TEXT(ss, ' ', space, std::left, '|', "w_");
SS__TEXT(ss, ' ', space, std::left, '|', "a_");
SS__TEXT(ss, ' ', space, std::left, '|', "b_");
SS__TEXT(ss, ' ', space, std::left, '|', "c1_");
SS__TEXT(ss, ' ', space, std::left, '|', "c2_");
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, '+');
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->gain_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->cutoff_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->resonance_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->g_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->w_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->a_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->b_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->c1_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->c2_);
out << "\t" << ss.str() << std::endl;
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0u;
nb_errors += inspector(tag + "gain_", this->gain_, -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + "cutoff_", this->cutoff_, 1.0f, this->getSamplingRate() / 2.0f, deepInspection);
nb_errors += inspector(tag + "resonance_", this->resonance_, 0.005f, 1.0f, deepInspection);
nb_errors += inspector(tag + "g_", this->g_, 0.0f, 16.0f, deepInspection);
nb_errors += inspector(tag + "w_", this->w_, 0.0f, 13.0f, deepInspection);
nb_errors += inspector(tag + "a_", this->a_, 0.0f, 2526.0f, deepInspection);
nb_errors += inspector(tag + "b_", this->b_, 0.0f, 160.0f, deepInspection);
nb_errors += inspector(tag + "c1_", this->c1_, 0.0f, 2.06f, deepInspection);
nb_errors += inspector(tag + "c2_", this->c2_, 0.0f, 0.06f, deepInspection);
return nb_errors;
)
};

@ -37,7 +37,7 @@ void Tube::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_
void Tube::setOverdrive(float32_t overdrive)
{
static constexpr float32_t N = 200.0f;
static const float32_t N = 200.0f;
overdrive = constrain(overdrive, 0.0f, 1.0f);
if(this->overdrive_ != overdrive)

@ -38,4 +38,43 @@ private:
float32_t overdrive_;
float32_t saturator_factor_;
float32_t gain_factor_;
IMPLEMENT_DUMP(
const size_t space = 17;
const size_t precision = 5;
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, '|', "overdrive_");
SS__TEXT(ss, ' ', space, std::left, '|', "saturator_factor_");
SS__TEXT(ss, ' ', space, std::left, '|', "gain_factor_");
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, '+');
out << "\t" << ss.str() << std::endl;
SS_RESET(ss, precision, std::left);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->overdrive_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->saturator_factor_);
SS__TEXT(ss, ' ', space - 1, std::right, " |", this->gain_factor_);
out << "\t" << ss.str() << std::endl;
out << "END " << tag << "(" << typeid(*this).name() << ") dump" << std::endl << std::endl;
)
IMPLEMENT_INSPECT(
size_t nb_errors = 0;
nb_errors += inspector(tag + ".overdrive_", this->overdrive_, 0.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".saturator_factor_", this->saturator_factor_, 1.0f, 201.0f, deepInspection);
nb_errors += inspector(tag + ".gain_factor_", this->gain_factor_, 0.0f, 4.0f, deepInspection);
return nb_errors;
)
};

@ -33,10 +33,6 @@
#include "fx_dry.h"
#include "fx_unit2.hpp"
#if defined(DEBUG)
typedef size_t (*ValueInpector)(const std::string&, size_t, const float32_t);
#endif
template<size_t nb_inputs>
class MixingConsole : public FXBase
{
@ -101,11 +97,218 @@ private:
FXUnit2<ShimmerReverb>* shimmer_reverb_;
FXUnit2<Dry>* dry_;
#if defined(DEBUG)
public:
void dump(std::ostream& out, const std::string& key = "") const;
size_t inspect(ValueInpector inspector, bool checkInputBuffer = false) const;
#endif
IMPLEMENT_DUMP(
const size_t space = 10;
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<MixerOutput>(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<MixerOutput>(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<MixerOutput>(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->shimmer_reverb_->dump(out, deepInspection, tag + ".shimmer_reverb_");
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<MixerOutput>(i - nb_inputs)) + " ]", this->input_samples_[StereoChannels::Left ][i], -1.0f, 1.0f, deepInspection);
nb_errors += inspector(tag + ".input[ R ][ input " + toString(static_cast<MixerOutput>(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->BufferSize; ++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->shimmer_reverb_->inspect(inspector, deepInspection, tag + ".shimmer_reverb_");
nb_errors += this->dry_->inspect(inspector, deepInspection, tag + ".dry_");
}
return nb_errors;
)
};
@ -340,8 +543,8 @@ void MixingConsole<nb_inputs>::reset()
{
for(size_t i = 0; i < nb_inputs; ++i)
{
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, 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)
@ -358,7 +561,7 @@ void MixingConsole<nb_inputs>::reset()
template<size_t nb_inputs>
void MixingConsole<nb_inputs>::processSample(float32_t& outL, float32_t& outR)
{
constexpr size_t bufferSize = nb_inputs + MixerOutput::kFXCount - 1;
const size_t bufferSize = nb_inputs + MixerOutput::kFXCount - 1;
float32_t fx_inputs_[MixerOutput::kFXCount][StereoChannels::kNumChannels];
float32_t fx_outputs_[MixerOutput::kFXCount][StereoChannels::kNumChannels];
@ -436,212 +639,3 @@ void MixingConsole<nb_inputs>::setSample(size_t in, float32_t sampleL, float32_t
this->input_samples_[StereoChannels::Left ][in] = sampleL;
this->input_samples_[StereoChannels::Right][in] = sampleR;
}
#if defined(DEBUG)
#define SS_RESET(ss, prec, align) ss.str(""); ss.precision(prec); ss << align; ss << std::fixed
#define SS_SPACE(ss, spc, nb, align, sep) ss.fill(spc); ss.width(nb); ss << "" << sep
#define SS__TEXT(ss, spc, nb, align, sep, txt) ss << align; ss.fill(spc); ss.width(nb); ss << txt << sep
template<size_t nb_inputs>
void MixingConsole<nb_inputs>::dump(std::ostream& out, const std::string& key) const
{
constexpr size_t space = 10;
constexpr size_t precision = 5;
std::stringstream ss;
out << "MixingConsole dump - START - " << key.c_str() << 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<MixerOutput>(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<MixerOutput>(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<MixerOutput>(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;
out << "MixingConsole dump - END - " << key.c_str() << std::endl;
}
#define DUMP1(mixer, out) mixer->dump(cout)
#define DUMP2(mixer, out, tag) mixer->dump(cout, tag)
template<size_t nb_inputs>
size_t MixingConsole<nb_inputs>::inspect(ValueInpector inspector, bool checkInputBuffer) const
{
size_t nb_errors = 0;
for(size_t i = 0; i < nb_inputs; ++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)
{
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)
{
nb_errors += inspector("Levels ", c * 100 + i, this->levels_[c][i]);
}
}
if(checkInputBuffer)
{
for(size_t i = 0; i < nb_inputs; ++i)
{
for(size_t k = 0; k < this->BufferSize; ++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)
#else
#define DUMP1(mixer, out)
#define DUMP2(mixer, out, tag)
#define INSPECT(mixer, inspector)
#endif

@ -23,7 +23,7 @@ enum MixerOutput
inline std::string toString(MixerOutput enum_val)
{
static constexpr std::array<const char*, MixerOutput::kFXCount> names
static const std::array<const char*, MixerOutput::kFXCount> names
{
"Tube",
"Chorus",

@ -4,13 +4,14 @@ EXE := all_test.bin
BETA := beta.bin
CXX := g++
CXXFLAGS = -g -std=c++20
CXXFLAGS = -g -std=c++20 -MMD -MP
DEFINES = -DCPU=x86 -DDEBUG -DOUTPUT_FOLDER="\"$(OUTPUT_FOLDER)\""
INCLUDES = -I../../CMSIS_5/CMSIS/DSP/Include/ \
-I../../CMSIS_5/CMSIS/Core/Include/ \
-I../../Synth_Dexed/src/
# -I../../circle-stdlib/libs/circle/include \
# -I../../circle-stdlib/libs/circle/addon \
-include $(TST_OBJS:.o=.d)
-include $(FX__OBJS:.o=.d)
LD := g++
LIBS := -lm -lstdc++ -lgtest -lpthread

@ -7,10 +7,10 @@
TEST(CppPerformance, LFOPerformance_ComplexLFO_InterpolatedSineOscillator)
{
constexpr size_t NB = 10000000;
const size_t NB = 10000000;
float32_t freq = 0.1f;
LFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f);
ComplexLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f);
InterpolatedSineOscillator lfo2(SAMPLING_FREQUENCY, 0.0f, 10.0f);
lfo1.setFrequency(freq);
@ -29,12 +29,12 @@ TEST(CppPerformance, LFOPerformance_ComplexLFO_InterpolatedSineOscillator)
}
auto d2 = LAP_TIME("lfo2");
EXPECT_GE(d1, d2);
EXPECT_LE(d1, d2 + 100);
}
TEST(CppPerformance, LFOPerformance_ComplexLFO_FastLFO)
{
constexpr size_t NB = 10000000;
const size_t NB = 10000000;
float32_t freq = 0.1f;
ComplexLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f, Constants::MPI_2);

@ -0,0 +1,22 @@
#include <gtest/gtest.h>
#include "test_fx_helper.h"
#include "wave.h"
#include "../debug.hpp"
#include "../fx_base.h"
TEST(Framework, TestWaveIn)
{
unsigned size;
float32_t** samples = readWaveFile(AUDIO_SOURCE_FILE, size);
size_t nb_errors = 0;
for(size_t i = 0; i < size; ++i)
{
nb_errors += fullInspector("L", samples[StereoChannels::Left ][i], -1.0f, 1.0f, true);
nb_errors += fullInspector("R", samples[StereoChannels::Right][i], -1.0f, 1.0f, true);
}
EXPECT_EQ(nb_errors, 0);
}

@ -109,10 +109,10 @@ TEST(FXComponent, SVF)
TEST(CppOptimization, InterpolatedSineOscillatorPrecisionTest)
{
constexpr float32_t freq = 0.15f;
constexpr size_t NB = static_cast<size_t>(2.0f * SAMPLING_FREQUENCY);
const float32_t freq = 0.15f;
const size_t NB = static_cast<size_t>(2.0f * SAMPLING_FREQUENCY);
constexpr float32_t epsilon = 1e-3;
const float32_t epsilon = 1e-3;
ComplexLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f);
InterpolatedSineOscillator lfo2(SAMPLING_FREQUENCY, 0.0f, 10.0f);
@ -131,10 +131,10 @@ TEST(CppOptimization, InterpolatedSineOscillatorPrecisionTest)
TEST(CppOptimization, FastLFOPrecisionTest)
{
constexpr float32_t freq = 0.15f;
constexpr size_t NB = static_cast<size_t>(2.0f * SAMPLING_FREQUENCY);
const float32_t freq = 0.15f;
const size_t NB = static_cast<size_t>(2.0f * SAMPLING_FREQUENCY);
constexpr float32_t epsilon = 1e-3;
const float32_t epsilon = 1e-3;
ComplexLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f);
FastLFO lfo2(SAMPLING_FREQUENCY, 0.0f, 10.0f);

@ -11,8 +11,6 @@
#define SAMPLING_FREQUENCY 44100.0f
#define stringify( x ) # x
#define Active(scenarioKey, FxID) ((scenarioKey & (1 << FxID)) == (1 << FxID))
std::string getScenarioName(int scenario);

@ -6,29 +6,6 @@
#include "../mixing_console.hpp"
size_t nanValueInspector(const std::string& el, size_t idx, const float32_t value)
{
if(std::isnan(value))
{
return 1u;
}
return 0u;
}
size_t normalizedValueInspector(const std::string& el, size_t idx, const float32_t value)
{
if(!std::isnan(value))
{
if(value != constrain(value, -1.0f, 1.0f))
{
return 1u;
}
}
return 0u;
}
class MixingConsoleScenarioTest : public testing::TestWithParam<MixerOutput> {};
TEST_P(MixingConsoleScenarioTest, MixerOutputTest)
@ -92,8 +69,8 @@ void setupMixingConsoleFX(Mixer* mixer)
TEST(MixingConsole, DryProcessing)
{
constexpr float32_t epsilon = 1e-7;
constexpr size_t length = 2;
const float32_t epsilon = 1e-7;
const size_t length = 2;
Mixer* mixer = new Mixer(SAMPLING_FREQUENCY, length);
mixer->reset();
@ -115,23 +92,20 @@ TEST(MixingConsole, DryProcessing)
mixer->setChannelLevel(0, 1.0f);
mixer->setPan(0, 0.5f);
mixer->setSendLevel(0, MixerOutput::MainOutput, 1.0f);
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_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);
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
mixer->process(
out[StereoChannels::Left ],
out[StereoChannels::Right]
);
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
EXPECT_EQ(out[StereoChannels::Left ][0], out[StereoChannels::Right][0]);
EXPECT_EQ(out[StereoChannels::Left ][1], out[StereoChannels::Right][1]);
@ -143,8 +117,8 @@ TEST(MixingConsole, DryProcessing)
TEST(MixingConsole, ShimmerProcessing)
{
constexpr float32_t epsilon = 1e-7;
constexpr size_t length = 2;
const float32_t epsilon = 1e-7;
const size_t length = 2;
Mixer* mixer = new Mixer(SAMPLING_FREQUENCY, length);
mixer->reset();
@ -154,8 +128,7 @@ 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));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
float32_t in[length] = {0.1, 0.2};
@ -163,31 +136,26 @@ TEST(MixingConsole, ShimmerProcessing)
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));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
mixer->process(
out1[StereoChannels::Left ],
out1[StereoChannels::Right]
);
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
mixer->reset();
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
float32_t out2[StereoChannels::kNumChannels][length];
mixer->setInputSampleBuffer(0, in);
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
mixer->process(
out2[StereoChannels::Left ],
out2[StereoChannels::Right]
);
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
EXPECT_EQ(out1[StereoChannels::Left ][0], out2[StereoChannels::Left ][0]);
EXPECT_EQ(out1[StereoChannels::Right][0], out2[StereoChannels::Right][0]);
@ -199,7 +167,7 @@ TEST(MixingConsole, ShimmerProcessing)
TEST(MixingConsole, ShimmerNoiseProcessing)
{
constexpr size_t length = 1024;
const size_t length = 1024;
Mixer* mixer = new Mixer(SAMPLING_FREQUENCY, length);
mixer->reset();
@ -209,8 +177,7 @@ TEST(MixingConsole, ShimmerNoiseProcessing)
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));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
float32_t in[length];
for(size_t i = 0; i < length; ++i) in[i] = getRandomValue();
@ -219,15 +186,13 @@ TEST(MixingConsole, ShimmerNoiseProcessing)
for(size_t i = 0; i < StereoChannels::kNumChannels; ++i) memset(out[i], 0, length * sizeof(float32_t));
mixer->setInputSampleBuffer(0, in);
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
mixer->process(
out[StereoChannels::Left ],
out[StereoChannels::Right]
);
EXPECT_EQ(0, INSPECT(mixer, nanValueInspector));
EXPECT_EQ(0, INSPECT(mixer, normalizedValueInspector));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
delete mixer;
}
@ -266,8 +231,7 @@ 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));
EXPECT_EQ(0, INSPECT(mixer, fullInspector));
}
saveWaveFile(getResultFile("result-mixing-console.wav"), sampleOutL, sampleOutR, nbRepeats * size, static_cast<unsigned>(SAMPLING_FREQUENCY), 16);

Loading…
Cancel
Save