diff --git a/src/fx_chorus.cpp b/src/fx_chorus.cpp index 751fbff..a9f66ea 100644 --- a/src/fx_chorus.cpp +++ b/src/fx_chorus.cpp @@ -6,7 +6,7 @@ #define LFO2_MAX_FREQ 0.35f Chorus::Chorus(float32_t sampling_rate) : - FXElement(sampling_rate, 1.1049f), + FXElement(sampling_rate, 1.1035f), engine_(sampling_rate, 0.0f), rate_(0.0f), depth_(0.0f), diff --git a/src/fx_components.cpp b/src/fx_components.cpp index cc17a8b..3610a8c 100644 --- a/src/fx_components.cpp +++ b/src/fx_components.cpp @@ -34,7 +34,8 @@ FastLFO::FastLFO(float32_t sampling_rate, float32_t min_frequency, float32_t max y0_(0.0f), y1_(0.0f), iir_coefficient_(0.0f), - initial_amplitude_(0.0f) + initial_amplitude_(0.0f), + current_(0.0f) { assert(this->min_frequency_ <= this->max_frequency_); assert(this->max_frequency_ < sampling_rate / 2.0f); @@ -56,8 +57,8 @@ void FastLFO::setNormalizedFrequency(float32_t normalized_frequency) this->frequency_ = frequency; this->unitary_frequency_ = this->frequency_ / this->getSamplingRate(); - this->nb_sub_increment_ = (frequency >= 3.0f ? 1 : 300); - this->unitary_frequency_ *= this->nb_sub_increment_; + this->nb_sub_increment_ = (frequency >= 3.0f ? 10 : 100); + this->unitary_frequency_ *= static_cast(this->nb_sub_increment_); this->updateCoefficient(); } @@ -78,8 +79,8 @@ void FastLFO::setFrequency(float32_t frequency) this->frequency_ = frequency; this->unitary_frequency_ = this->frequency_ / this->getSamplingRate(); - this->nb_sub_increment_ = (frequency >= 3.0f ? 1 : 300); - this->unitary_frequency_ *= this->nb_sub_increment_; + this->nb_sub_increment_ = (frequency >= 3.0f ? 10 : (frequency < 0.1f ? 1000 : 100)); + this->unitary_frequency_ *= static_cast(this->nb_sub_increment_); this->updateCoefficient(); } @@ -92,27 +93,7 @@ float32_t FastLFO::getFrequency() const void FastLFO::updateCoefficient() { - float32_t frequency = this->unitary_frequency_ * 268.0f / 240.0f; - - float32_t sign = 16.0f; - frequency -= 0.25f; - if(frequency < 0.0f) - { - frequency = -frequency; - } - else - { - if(frequency > 0.5f) - { - frequency -= 0.5f; - } - else - { - sign = -16.0f; - } - } - - this->iir_coefficient_ = sign * frequency * (1.0f - 2.0f * frequency); + this->iir_coefficient_ = 2.0f * cos(Constants::M2PI * this->unitary_frequency_); this->initial_amplitude_ = this->iir_coefficient_ * 0.25f; this->reset(); @@ -120,6 +101,8 @@ void FastLFO::updateCoefficient() void FastLFO::reset() { + static const float32_t epsilon = 1e-3; + this->sub_increment_ = 0.0f; // computing cos(0) = sin(-PI/2) @@ -133,15 +116,23 @@ void FastLFO::reset() float32_t p_i = Constants::M2PI * this->unitary_frequency_ / static_cast(this->nb_sub_increment_); float32_t p = Constants::MPI_2; + float32_t oldP = 1000.0f; float32_t t_p = this->InitialPhase; + const float32_t target = sin(this->InitialPhase); if(t_p < p) { p -= Constants::M2PI; } - while(p < t_p) + float32_t tuning = -3.0f; + while(p < t_p || abs(tuning - target) > epsilon) { - this->process(); + oldP = p; + tuning = this->process(); p += p_i; + if(oldP == p) + { + return; + } } } @@ -173,6 +164,106 @@ float32_t FastLFO::current() const } +///////////////////////////// +// FastLFO2 implemlentation // +///////////////////////////// +FastLFO2::FastLFO2(float32_t sampling_rate, float32_t min_frequency, float32_t max_frequency, float32_t initial_phase, bool centered) : + FXBase(sampling_rate), + InitialPhase(initial_phase), + min_frequency_(min_frequency), + max_frequency_(max_frequency), + centered_(centered), + frequency_(0.0f), + phase_(initial_phase), + phase_increment_(0.0f), + current_(0.0f) +{ + assert(this->min_frequency_ <= this->max_frequency_); + assert(this->max_frequency_ < sampling_rate / 2.0f); + + this->setFrequency(this->min_frequency_); +} + +FastLFO2::~FastLFO2() +{ +} + +void FastLFO2::setNormalizedFrequency(float32_t normalized_frequency) +{ + normalized_frequency = constrain(normalized_frequency, 0.0f, 1.0f); + if(this->normalized_frequency_ != normalized_frequency) + { + float32_t frequency = mapfloat(normalized_frequency, 0.0f, 1.0f, this->min_frequency_, this->max_frequency_); + this->normalized_frequency_ = normalized_frequency; + this->frequency_ = frequency; + + this->phase_increment_ = Constants::M2PI * frequency / this->getSamplingRate(); + } +} + +float32_t FastLFO2::getNormalizedFrequency() const +{ + return this->normalized_frequency_; +} + +void FastLFO2::setFrequency(float32_t frequency) +{ + frequency = constrain(frequency, this->min_frequency_, this->max_frequency_); + if(this->frequency_ != frequency) + { + float32_t normalized_frequency = mapfloat(frequency, this->min_frequency_, this->max_frequency_, 0.0f, 1.0f); + this->normalized_frequency_ = normalized_frequency; + this->frequency_ = frequency; + + this->phase_increment_ = Constants::M2PI * frequency / this->getSamplingRate(); + } +} + +float32_t FastLFO2::getFrequency() const +{ + return this->frequency_; +} + +void FastLFO2::reset() +{ + this->phase_ = this->InitialPhase; +} + +float32_t FastLFO2::process() +{ + static const float32_t K = 5.0f * Constants::M_PI_POW_2; + + float32_t x = this->phase_; + float32_t f = 4.0f; + if(x > PI) + { + x -= PI; + f = -4.0f; + } + + float32_t tmp = 4.0f * x * (PI - x); + this->current_ = f * tmp / (K - tmp); + + if(!this->centered_) + { + this->current_ = this->current_ * 0.5f + 0.5f; + } + + this->phase_ += this->phase_increment_; + if(this->phase_ > Constants::M2PI) + { + this->phase_ -= Constants::M2PI; + } + + return this->current_; +} + +float32_t FastLFO2::current() const +{ + return this->current_; +} + + //////////////////////////////////////////////// // InterpolatedSineOscillator implemlentation // //////////////////////////////////////////////// diff --git a/src/fx_components.h b/src/fx_components.h index d2b7891..2a404fb 100644 --- a/src/fx_components.h +++ b/src/fx_components.h @@ -143,6 +143,89 @@ private: }; +class FastLFO2 : public FXBase +{ + DISALLOW_COPY_AND_ASSIGN(FastLFO2); + +public: + FastLFO2(float32_t sampling_rate, float32_t min_frequency = LFO_MIN_FREQUENCY, float32_t max_frequency = LFO_MAX_FREQUENCY, float32_t initial_phase = 0.0f, bool centered = true); + virtual ~FastLFO2(); + + void setNormalizedFrequency(float32_t normalized_frequency); + float32_t getNormalizedFrequency() const; + + void setFrequency(float32_t frequency); + float32_t getFrequency() const; + + virtual void reset() override; + float32_t process(); + float32_t current() const; + +private: + const float32_t InitialPhase; + const float32_t min_frequency_; + const float32_t max_frequency_; + const bool centered_; + float32_t frequency_; + float32_t normalized_frequency_; + float32_t phase_; + float32_t phase_increment_; + 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, '|', "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, '+'); + 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->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 + ".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 + ".phase_", this->phase_, 0.0f, Constants::M2PI, deepInspection); + nb_errors += inspector(tag + ".phase_", this->phase_increment_, 0.0f, Constants::M2PI, deepInspection); + nb_errors += inspector(tag + ".current_", this->current_, -1.0f, 1.0f, deepInspection); + + return nb_errors; + ) +}; + + class InterpolatedSineOscillator : public FXBase { DISALLOW_COPY_AND_ASSIGN(InterpolatedSineOscillator); @@ -327,7 +410,7 @@ private: }; -typedef InterpolatedSineOscillator LFO; +typedef FastLFO2 LFO; class JitterGenerator : public FXBase diff --git a/src/fx_flanger.cpp b/src/fx_flanger.cpp index 5f163ba..0908138 100644 --- a/src/fx_flanger.cpp +++ b/src/fx_flanger.cpp @@ -1,7 +1,7 @@ #include "fx_flanger.h" Flanger::Flanger(float32_t sampling_rate, float32_t rate, float32_t depth, float32_t feedback) : - FXElement(sampling_rate, 0.9288f), + FXElement(sampling_rate, 0.928f), MaxDelayLineSize(static_cast(MAX_FLANGER_DELAY * sampling_rate)), write_index_(0) { diff --git a/src/fx_orbitone.cpp b/src/fx_orbitone.cpp index 9fd42cd..0632715 100644 --- a/src/fx_orbitone.cpp +++ b/src/fx_orbitone.cpp @@ -4,7 +4,7 @@ #define LFO_FAST_MAX_FREQUENCY 8.8f Orbitone::Orbitone(float32_t sampling_rate, float32_t rate, float32_t depth) : - FXElement(sampling_rate, 1.4442f), + FXElement(sampling_rate, 1.4426f), engine_(sampling_rate, 0.0f), depth_(0.0f), fullscale_depth_(0.0f) diff --git a/src/test/Makefile b/src/test/Makefile index 130d60d..c001e86 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -83,8 +83,8 @@ $(OBJDIR)/%.o: ../%.cpp $(OBJDIR) $(EXE): $(BINDIR) $(TST_OBJS) $(FX__OBJS) $(LD) $(CXXFLAGS) $(call wildcard,$(TST_OBJS)) $(call wildcard,$(FX__OBJS)) -o $@ $(LIBS) -$(BETA): $(BINDIR) $(BETAOBJS) $(FX__OBJS) - $(LD) $(CXXFLAGS) $(BETAOBJS) $(call wildcard,$(FX__OBJS)) -o $@ $(LIBS) +$(BETA): $(BINDIR) $(BETAOBJS) + $(LD) $(CXXFLAGS) $(BETAOBJS) -o $@ $(LIBS) clean: rm -rf $(OBJDIR) $(BINDIR) $(OUTPUT_FOLDER) diff --git a/src/test/test_cpp_performance.cpp b/src/test/test_cpp_performance.cpp index 7022bc2..3c16317 100644 --- a/src/test/test_cpp_performance.cpp +++ b/src/test/test_cpp_performance.cpp @@ -59,6 +59,62 @@ TEST(CppPerformance, LFOPerformance_ComplexLFO_FastLFO) EXPECT_GE(d1, d2); } +TEST(CppPerformance, LFOPerformance_InterpolatedSineOscillator_FastLFO) +{ + const size_t NB = 10000000; + float32_t freq = 0.1f; + + InterpolatedSineOscillator lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f, Constants::MPI_2); + FastLFO lfo2(SAMPLING_FREQUENCY, 0.0f, 10.0f); + + lfo1.setFrequency(freq); + LAP_TIME("lfo1"); + for(size_t i = 0; i < NB; ++i) + { + lfo1.process(); + } + auto d1 = LAP_TIME("lfo1"); + + lfo2.setFrequency(freq); + LAP_TIME("lfo2"); + for(size_t i = 0; i < NB; ++i) + { + lfo2.process(); + } + auto d2 = LAP_TIME("lfo2"); + + EXPECT_GE(d1, d2); +} + +TEST(CppPerformance, LFOPerformance_FastLFO_FastLFO2) +{ + const size_t NB = 10000000; + float32_t freq = 0.1f; + + FastLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f, Constants::MPI_2); + FastLFO2 lfo2(SAMPLING_FREQUENCY, 0.0f, 10.0f); + + lfo1.setFrequency(freq); + lfo1.reset(); + LAP_TIME("lfo1"); + for(size_t i = 0; i < NB; ++i) + { + lfo1.process(); + } + auto d1 = LAP_TIME("lfo1"); + + lfo2.setFrequency(freq); + lfo2.reset(); + LAP_TIME("lfo2"); + for(size_t i = 0; i < NB; ++i) + { + lfo2.process(); + } + auto d2 = LAP_TIME("lfo2"); + + EXPECT_GE(d1, d2); +} + TEST(CppPerformance, FastLFOTuning) { const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); @@ -91,3 +147,109 @@ TEST(CppPerformance, FastLFOTuning) } out.close(); } + + +TEST(CppPerformance, FastLFO2Tuning) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + size_t NB = static_cast(1.0f * SAMPLING_FREQUENCY); + float32_t freq = 1.5f; + + FastLFO2 lfo1(SAMPLING_FREQUENCY, freq, 440.0f); + lfo1.setFrequency(freq); + + InterpolatedSineOscillator lfo2(SAMPLING_FREQUENCY, freq, 440.0f); + lfo2.setFrequency(freq); + + ComplexLFO lfo3(SAMPLING_FREQUENCY, freq, 440.0f); + lfo3.setFrequency(freq); + + std::ofstream out(getResultFile(full_test_name + ".data.csv", true)); + setupOuputStreamForCSV(out); + out << "index;FastLFO;InterpolatedSineOscillator;ComplexLFO" << std::endl; + for(size_t i = 0; i < NB; ++i) + { + out + << i << ";" + << lfo1.process() << ";" + << lfo2.process() << ";" + << lfo3.process() << std::endl; + } + out.close(); +} + +TEST(CppPerformance, FastLFOsTuningOctave) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + size_t NB = static_cast(1.0f * SAMPLING_FREQUENCY); + float32_t freq = 1.5f; + + FastLFO lfo1(SAMPLING_FREQUENCY, freq, 440.0f); + lfo1.setFrequency(freq); + + FastLFO2 lfo2(SAMPLING_FREQUENCY, freq, 440.0f); + lfo2.setFrequency(freq); + + InterpolatedSineOscillator lfo3(SAMPLING_FREQUENCY, freq, 440.0f); + lfo3.setFrequency(freq); + + ComplexLFO lfo4(SAMPLING_FREQUENCY, freq, 440.0f); + lfo4.setFrequency(freq); + + std::stringstream ssLFO1; + std::stringstream ssLFO2; + std::stringstream ssLFO3; + std::stringstream ssLFO4; + + for(size_t i = 0; i < NB; ++i) + { + ssLFO1 << lfo1.process() << (i == (NB - 1) ? "" : ", "); + ssLFO2 << lfo2.process() << (i == (NB - 1) ? "" : ", "); + ssLFO3 << lfo3.process() << (i == (NB - 1) ? "" : ", "); + ssLFO4 << lfo4.process() << (i == (NB - 1) ? "" : ", "); + } + + std::ofstream _lfo1(getResultFile(std::string("data/") + full_test_name + ".fast.data", true)); + _lfo1 << ssLFO1.str(); + _lfo1.close(); + + std::ofstream _lfo2(getResultFile(std::string("data/") + full_test_name + ".fst2.data", true)); + _lfo2 << ssLFO2.str(); + _lfo2.close(); + + std::ofstream _lfo3(getResultFile(std::string("data/") + full_test_name + ".intr.data", true)); + _lfo3 << ssLFO3.str(); + _lfo3.close(); + + std::ofstream _lfo4(getResultFile(std::string("data/") + full_test_name + ".cplx.data", true)); + _lfo4 << ssLFO4.str(); + _lfo4.close(); + + std::ofstream out(getResultFile(full_test_name + ".data.m", true)); + out << "# m file to tune FastLFO component" << std::endl << std::endl; + out << "# Parameters:" << std::endl + << "# + frequency: " << freq << "Hz" << std::endl + << "# + # samples: " << NB << std::endl << std::endl; + + out << "time = 0 : " << (NB - 1) << ";" << std::endl; + out << "fast_lfo = load(\"-ascii\", \"data/" << full_test_name << ".fast.data\");" << std::endl; + out << "fst2_lfo = load(\"-ascii\", \"data/" << full_test_name << ".fst2.data\");" << std::endl; + out << "intr_lfo = load(\"-ascii\", \"data/" << full_test_name << ".intr.data\");" << std::endl; + out << "cplx_lfo = load(\"-ascii\", \"data/" << full_test_name << ".cplx.data\");" << std::endl; + + out << std::endl << std::endl; + + out << "plot(time, fast_lfo, '-r', 'LineWidth', 6, time, fst2_lfo, '-o', 'LineWidth', 6, time, intr_lfo, '-b', 'LineWidth', 4, cplx_lfo, '-g', 'LineWidth', 4);" << std::endl; + out << "title('LFO tuning');" << std::endl; + out << "legend('FastLFO2', 'InterpolatedSineOscillator', 'ComplexLFO');" << std::endl; + + out.close(); +} diff --git a/src/test/test_fx_components.cpp b/src/test/test_fx_components.cpp index 505cfb5..912d8e1 100644 --- a/src/test/test_fx_components.cpp +++ b/src/test/test_fx_components.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "test_fx_helper.h" @@ -126,24 +127,233 @@ TEST(CppOptimization, InterpolatedSineOscillatorPrecisionTest) EXPECT_GT(epsilon, max_delta); } -TEST(CppOptimization, FastLFOPrecisionTest) +void testFastLFOPrecision(std::string file, float32_t freq, float32_t init_phase) { - const float32_t freq = 0.15f; const size_t NB = static_cast(2.0f * SAMPLING_FREQUENCY); + const float32_t init_phase_deg = init_phase * 180.0f / PI; - const float32_t epsilon = 1e-3; + const float32_t epsilon = 40e-3; - ComplexLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f); - FastLFO lfo2(SAMPLING_FREQUENCY, 0.0f, 10.0f); + ComplexLFO lfo0(SAMPLING_FREQUENCY, 0.0f, 220.0f, init_phase, true); + FastLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 220.0f, init_phase, true); + FastLFO2 lfo2(SAMPLING_FREQUENCY, 0.0f, 220.0f, init_phase, true); + lfo0.setFrequency(freq); lfo1.setFrequency(freq); lfo2.setFrequency(freq); - float32_t max_delta = 0.0f; + + std::string file0 = string("data/") + file + ".ComplexLFO." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data"; + std::string file1 = string("data/") + file + ".FastLFO." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data"; + std::string file2 = string("data/") + file + ".FastLFO2." + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data"; + std::string file3 = string(file + ".") + std::to_string(freq) + "Hz-" + std::to_string(init_phase_deg) + ".data.m"; + + std::ofstream _lfo0(getResultFile(file0, true)); + std::ofstream _lfo1(getResultFile(file1, true)); + std::ofstream _lfo2(getResultFile(file2, true)); + std::ofstream _m(getResultFile(file3, true)); + + float32_t max_delta1 = 0.0f; + float32_t max_delta2 = 0.0f; for(size_t i = 0; i < NB; ++i) { + float32_t v0 = lfo0.process(); float32_t v1 = lfo1.process(); float32_t v2 = lfo2.process(); - max_delta = std::max(max_delta, std::abs(v1 - v2)); + _lfo0 << std::setprecision(6) << std::fixed << v0 << ((i == (NB - 1)) ? "" : ", "); + _lfo1 << std::setprecision(6) << std::fixed << v1 << ((i == (NB - 1)) ? "" : ", "); + _lfo2 << std::setprecision(6) << std::fixed << v2 << ((i == (NB - 1)) ? "" : ", "); + + max_delta1 = std::max(max_delta1, std::abs(v1 - v0)); + max_delta2 = std::max(max_delta2, std::abs(v2 - v0)); } - EXPECT_GT(epsilon, max_delta); + + _lfo0.close(); + _lfo1.close(); + _lfo2.close(); + + _m << "# Tests of FastLFO precision:" << std::endl; + _m << std::setprecision(2) << std::fixed << "# + frequency: " << freq << " Hz" << std::endl; + _m << std::setprecision(2) << std::fixed << "# + initial phase: " << init_phase << std::endl; + _m << std::endl; + _m << "time = 0 : " << (NB - 1) << ";" << std::endl; + _m << "cplx_lfo = load(\"-ascii\", \"" << file0 << "\");" << std::endl; + _m << "fast_lfo = load(\"-ascii\", \"" << file1 << "\");" << std::endl; + _m << "fast_lfo2 = load(\"-ascii\", \"" << file2 << "\");" << std::endl; + _m << "plot(time, cplx_lfo, '-b', 'LineWidth', 6, time, fast_lfo, '-r', 'LineWidth', 4, time, fast_lfo2, '-o', 'LineWidth', 4);" << std::endl; + _m << "title('LFO tuning @ " << freq << "Hz / " << init_phase_deg << "°');" << std::endl; + _m << "legend('ComplexLFO', 'FastLFO');" << std::endl; + _m.close(); + + EXPECT_GT(epsilon, max_delta1) << "FastLFO is not precise enough for " << freq << " Hz starting with phase: " << (init_phase * 180.0f / PI); + EXPECT_GT(epsilon, max_delta2) << "FastLFO2 is not precise enough for " << freq << " Hz starting with phase: " << (init_phase * 180.0f / PI); +} + +TEST(CppOptimization, FastLFOPrecisionTest0_01Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 0.01f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest0_15Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 0.15f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest0_2Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 0.2f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest0_3Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 0.3f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest0_5Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 0.5f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest1Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 1.0f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest2_15Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 2.15f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest5Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 5.0f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest10_5Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 10.5f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); +} + +TEST(CppOptimization, FastLFOPrecisionTest120_5Hz) +{ + const testing::TestInfo* test_info = testing::UnitTest::GetInstance()->current_test_info(); + std::string full_test_name = test_info->test_case_name(); + full_test_name += "."; + full_test_name += test_info->name(); + + const float32_t freq = 120.5f; + testFastLFOPrecision(full_test_name, freq, 0.0f); + testFastLFOPrecision(full_test_name, freq, PI / 6.0f); + // testFastLFOPrecision(full_test_name, freq, PI / 3.0f); + testFastLFOPrecision(full_test_name, freq, PI / 2.0f); + testFastLFOPrecision(full_test_name, freq, 2.0f * PI / 3.0f); + // testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 4.0f); + testFastLFOPrecision(full_test_name, freq, 3.0f * PI / 2.0f); }