diff --git a/src/fx_components.h b/src/fx_components.h index 03e8a8a..81837c5 100644 --- a/src/fx_components.h +++ b/src/fx_components.h @@ -150,7 +150,7 @@ public: private: static bool ClassInitializer(); - static const size_t DataPointSize = 352800; + static const size_t DataPointSize = 176400; static const float32_t DeltaTime; static float32_t DataPoints[]; @@ -311,7 +311,7 @@ private: }; -typedef ComplexLFO LFO; +typedef InterpolatedSineOscillator LFO; class JitterGenerator : public FXBase diff --git a/src/fx_engine.hpp b/src/fx_engine.hpp index a3f2f91..1c2d9ee 100644 --- a/src/fx_engine.hpp +++ b/src/fx_engine.hpp @@ -274,6 +274,7 @@ public: inline void read(D& d, int32_t offset, float32_t scale) { assert((D::base + D::length) <= size); + T r; if(offset == -1) { @@ -314,8 +315,9 @@ public: int32_t offset_integral = static_cast(offset); float32_t offset_fractional = offset - static_cast(offset_integral); - float32_t a = DataType::decompress(this->buffer_[(this->write_ptr_ + offset_integral + D::base) & MASK]); - float32_t b = DataType::decompress(this->buffer_[(this->write_ptr_ + offset_integral + D::base + 1) & MASK]); + int32_t index = this->write_ptr_ + offset_integral + D::base; + float32_t a = DataType::decompress(this->buffer_[index & MASK]); + float32_t b = DataType::decompress(this->buffer_[(index + 1) & MASK]); float32_t x = a + (b - a) * offset_fractional; this->previous_read_ = x; diff --git a/src/fx_rack.cpp b/src/fx_rack.cpp index b08e964..7d00652 100644 --- a/src/fx_rack.cpp +++ b/src/fx_rack.cpp @@ -50,10 +50,9 @@ inline void FXRack::reset() inline void FXRack::processSample(float32_t inL, float32_t inR, float32_t& outL, float32_t& outR) { - FXChain::iterator end = this->fx_chain_.end(); - for(FXChain::iterator it = this->fx_chain_.begin(); it != end; it++) + for(FXElement* fx : this->fx_chain_) { - (*it)->processSample(inL, inR, outL, outR); + fx->processSample(inL, inR, outL, outR); inL = outL; inR = outR; diff --git a/src/fx_shimmer_reverb.cpp b/src/fx_shimmer_reverb.cpp index 9c0d490..d9267bf 100644 --- a/src/fx_shimmer_reverb.cpp +++ b/src/fx_shimmer_reverb.cpp @@ -97,20 +97,20 @@ void ShimmerReverb::processSample(float32_t inL, float32_t inR, float32_t& outL, c.writeAllPass(dap1a, kap); c.read(dap1b TAIL, kap); c.writeAllPass(dap1b, -kap); - c.write(del1, 2.0f); + c.write(del1, 1.5f); c.write(wet, 0.0f); outL = wet; c.load(apout); - c.interpolate(del1, 4450.0f, Engine::LFOIndex::LFO_1, 50.0f, krt); + // c.interpolate(del1, 4450.0f, Engine::LFOIndex::LFO_1, 50.0f, krt); c.read(del1 TAIL, krt); c.lp(lp_2, klp); c.read(dap2a TAIL, kap); c.writeAllPass(dap2a, -kap); c.read(dap2b TAIL, -kap); c.writeAllPass(dap2b, kap); - c.write(del2, 2.0f); + c.write(del2, 1.5f); c.write(wet, 0.0f); outR = wet; diff --git a/src/test/Makefile b/src/test/Makefile index 0df43b0..88a71b1 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -2,7 +2,7 @@ BINDIR := bin OBJDIR := objects OUTPUT_FOLDER := results -EXE := $(BINDIR)/all_test.bin +EXE := $(BINDIR)/all_tests.bin BETA := $(BINDIR)/beta.bin CXX := g++ @@ -32,9 +32,9 @@ FX__SRCS += ../fx_shimmer_reverb.cpp FX__SRCS += ../fx_dry.cpp FX__SRCS += ../fx_rack.cpp -TST_SRCS := $(filter-out waveplay.cpp, $(filter-out beta.cpp, $(wildcard *.cpp))) +TST_SRCS := $(filter-out waveplay.cpp $(wildcard beta*.cpp), $(wildcard *.cpp)) -BETASRCS := beta.cpp +BETASRCS := $(wildcard beta*.cpp) BETASRCS += arm_functions.cpp BETASRCS += wavein.cpp BETASRCS += waveout.cpp diff --git a/src/test/beta_lowlevel.cpp b/src/test/beta_lowlevel.cpp new file mode 100644 index 0000000..f53c820 --- /dev/null +++ b/src/test/beta_lowlevel.cpp @@ -0,0 +1,441 @@ +#include + +#include +#include + +#include "test_fx_helper.h" +#include "../fx_engine.hpp" + +#define PRINT_EXEC(ctx, x) \ + std::cout.fill(' '); \ + std::cout.width(80); \ + std::cout << std::left; \ + std::cout.precision(6); \ + std::cout << std::fixed; \ + std::cout << #x; \ + x \ + { \ + float32_t v = 0.0f; \ + ctx.write(v); \ + std::cout << " // accumulator_: " << showpos << v; \ + } \ + std::cout << std::endl + +#define TAIL , -1 + +typedef FxEngine<16384, Format::FORMAT_FLOAT32, true> Engine; + +void processDebugShimmerSample( + Engine& engine_, size_t index, + float32_t& lp_decay_1_, float32_t& lp_decay_2_, + float32_t inL, float32_t inR, + float32_t& outL, float32_t& outR) +{ + // This is the Griesinger topology described in the Dattorro paper + // (4 AP diffusers on the input, then a loop of 2x 2AP+1Delay). + // Modulation is applied in the loop of the first diffuser AP for additional + // smearing; and to the two long delays for a slow shimmer/chorus effect. + typedef Engine::Reserve< 113, + Engine::Reserve< 162, + Engine::Reserve< 241, + Engine::Reserve< 399, + Engine::Reserve<1653, + Engine::Reserve<2038, + Engine::Reserve<3411, + Engine::Reserve<1913, + Engine::Reserve<1663, + Engine::Reserve<4782> > > > > > > > > > Memory; + Engine::DelayLine ap1; + Engine::DelayLine ap2; + Engine::DelayLine ap3; + Engine::DelayLine ap4; + Engine::DelayLine dap1a; + Engine::DelayLine dap1b; + Engine::DelayLine del1; + Engine::DelayLine dap2a; + Engine::DelayLine dap2b; + Engine::DelayLine del2; + Engine::Context c; + + const float32_t kap = 0.8f; + const float32_t klp = 0.7f; + const float32_t krt = 0.75f; + const float32_t gain = 0.55f; + + float32_t lp_1 = lp_decay_1_; + float32_t lp_2 = lp_decay_2_; + + float32_t wet = 0.0f; + float32_t apout = 0.0f; + engine_.start(&c); + + // Smear AP1 inside the loop. + PRINT_EXEC(c, c.interpolate(ap1, 10.0f, Engine::LFOIndex::LFO_1, 60.0f, 1.0f);); + PRINT_EXEC(c, c.write(ap1, 100, 0.0f);); + PRINT_EXEC(c, c.read(inL + inR, gain);); + + // Diffuse through 4 allpasses. + PRINT_EXEC(c, c.read(ap1 TAIL, kap);); + PRINT_EXEC(c, c.writeAllPass(ap1, -kap);); + PRINT_EXEC(c, c.read(ap2 TAIL, kap);); + PRINT_EXEC(c, c.writeAllPass(ap2, -kap);); + PRINT_EXEC(c, c.read(ap3 TAIL, kap);); + PRINT_EXEC(c, c.writeAllPass(ap3, -kap);); + PRINT_EXEC(c, c.read(ap4 TAIL, kap);); + PRINT_EXEC(c, c.writeAllPass(ap4, -kap);); + PRINT_EXEC(c, c.write(apout);); + + // Main reverb loop. + PRINT_EXEC(c, c.load(apout);); + PRINT_EXEC(c, c.interpolate(del2, 4680.0f, Engine::LFOIndex::LFO_2, 100.0f, krt);); + PRINT_EXEC(c, c.lp(lp_1, klp);); + PRINT_EXEC(c, c.read(dap1a TAIL, -kap);); + PRINT_EXEC(c, c.writeAllPass(dap1a, kap);); + PRINT_EXEC(c, c.read(dap1b TAIL, kap);); + PRINT_EXEC(c, c.writeAllPass(dap1b, -kap);); + PRINT_EXEC(c, c.write(del1, 1.5f);); + PRINT_EXEC(c, c.write(wet, 0.0f);); + + outL = wet; + + + PRINT_EXEC(c, c.load(apout);); + // PRINT_EXEC(c, c.interpolate(del1, 4450.0f, Engine::LFOIndex::LFO_1, 50.0f, krt);); + PRINT_EXEC(c, c.read(del1 TAIL, krt);); + PRINT_EXEC(c, c.lp(lp_2, klp);); + PRINT_EXEC(c, c.read(dap2a TAIL, kap);); + PRINT_EXEC(c, c.writeAllPass(dap2a, -kap);); + PRINT_EXEC(c, c.read(dap2b TAIL, -kap);); + PRINT_EXEC(c, c.writeAllPass(dap2b, kap);); + PRINT_EXEC(c, c.write(del2, 1.5f);); + PRINT_EXEC(c, c.write(wet, 0.0f);); + + outR = wet; + + + lp_decay_1_ = lp_1; + lp_decay_2_ = lp_2; + + std::cout << "Index # " << index << " - ( " << inL << ", " << inR << " ) ==> ( " << outL << ", " << outR << " )" << std::endl; + std::cout << std::endl << "***********************************************************************************************************" << std::endl << std::endl; +} + +TEST(LowLevel, TestDiracShimmerAlgo) +{ + 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(); + + Engine engine_(SAMPLING_FREQUENCY); + engine_.setLFOFrequency(Engine::LFOIndex::LFO_1, 0.5f); + engine_.setLFOFrequency(Engine::LFOIndex::LFO_2, 0.3f); + engine_.reset(); + + float32_t lp1 = 0.0f; + float32_t lp2 = 0.0f; + + const size_t size = static_cast(SAMPLING_FREQUENCY) * 4; + float32_t* inSamples = new float32_t[size]; + memset(inSamples, 0, size * sizeof(float32_t)); + inSamples[0] = 1.0f; + + float32_t* outSamplesL = new float32_t[size]; + float32_t* outSamplesR = new float32_t[size]; + memset(outSamplesL, 0, size * sizeof(float32_t)); + memset(outSamplesR, 0, size * sizeof(float32_t)); + + for(size_t i = 0; i < size; ++i) + { + processDebugShimmerSample(engine_, i, lp1, lp2, inSamples[i], inSamples[i], outSamplesL[i], outSamplesR[i]); + } + + saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamplesL, outSamplesR, size, SAMPLING_FREQUENCY, 16); + + delete[] outSamplesL; + delete[] outSamplesR; + + delete[] inSamples; +} + +void processShimmerSample( + Engine& engine_L_, Engine& engine_R_, size_t index, + float32_t& lp_decay_1_, float32_t& lp_decay_2_, + float32_t inL, float32_t inR, + float32_t& outL, float32_t& outR) +{ + // This is the Griesinger topology described in the Dattorro paper + // (4 AP diffusers on the input, then a loop of 2x 2AP+1Delay). + // Modulation is applied in the loop of the first diffuser AP for additional + // smearing; and to the two long delays for a slow shimmer/chorus effect. + typedef Engine::Reserve< 113, + Engine::Reserve< 162, + Engine::Reserve< 241, + Engine::Reserve< 399, + Engine::Reserve<1653, + Engine::Reserve<2038, + Engine::Reserve<3411, + Engine::Reserve<1913, + Engine::Reserve<1663, + Engine::Reserve<4782> > > > > > > > > > Memory; + Engine::DelayLine ap1; + Engine::DelayLine ap2; + Engine::DelayLine ap3; + Engine::DelayLine ap4; + Engine::DelayLine dap1a; + Engine::DelayLine dap1b; + Engine::DelayLine del1; + Engine::DelayLine dap2a; + Engine::DelayLine dap2b; + Engine::DelayLine del2; + Engine::Context cL; + Engine::Context cR; + + const float32_t kap = 0.8f; + const float32_t klp = 0.7f; + const float32_t krt = 0.75f; + const float32_t gain = 0.55f; + + float32_t lp_1 = lp_decay_1_; + float32_t lp_2 = lp_decay_2_; + + float32_t wet = 0.0f; + float32_t apout = 0.0f; + engine_L_.start(&cL); + engine_R_.start(&cR); + + // Smear AP1 inside the loop. + cL.interpolate(ap1, 10.0f, Engine::LFOIndex::LFO_1, 60.0f, 1.0f); + cL.write(ap1, 100, 0.0f); + cL.read(inL, gain); + + // Diffuse through 4 allpasses. + cL.read(ap1 TAIL, kap); + cL.writeAllPass(ap1, -kap); + cL.read(ap2 TAIL, kap); + cL.writeAllPass(ap2, -kap); + cL.read(ap3 TAIL, kap); + cL.writeAllPass(ap3, -kap); + cL.read(ap4 TAIL, kap); + cL.writeAllPass(ap4, -kap); + cL.write(apout); + + // Main reverb loop. + cL.load(apout); + cL.interpolate(del2, 4680.0f, Engine::LFOIndex::LFO_2, 100.0f, krt); + cL.lp(lp_1, klp); + cL.read(dap1a TAIL, -kap); + cL.writeAllPass(dap1a, kap); + cL.read(dap1b TAIL, kap); + cL.writeAllPass(dap1b, -kap); + cL.write(del1, 1.5f); + cL.write(wet, 0.0f); + + outL = wet; + + + // Smear AP1 inside the loop. + cR.interpolate(ap1, 10.0f, Engine::LFOIndex::LFO_1, 60.0f, 1.0f); + cR.write(ap1, 100, 0.0f); + cR.read(inL + inR, gain); + + // Diffuse through 4 allpasses. + cR.read(ap1 TAIL, kap); + cR.writeAllPass(ap1, -kap); + cR.read(ap2 TAIL, kap); + cR.writeAllPass(ap2, -kap); + cR.read(ap3 TAIL, kap); + cR.writeAllPass(ap3, -kap); + cR.read(ap4 TAIL, kap); + cR.writeAllPass(ap4, -kap); + cR.write(apout); + + // Main reverb loop. + cR.load(apout); + // cR.interpolate(del1, 4450.0f, Engine::LFOIndex::LFO_1, 50.0f, krt); + cR.read(del1 TAIL, krt); + cR.lp(lp_2, klp); + cR.read(dap2a TAIL, kap); + cR.writeAllPass(dap2a, -kap); + cR.read(dap2b TAIL, -kap); + cR.writeAllPass(dap2b, kap); + cR.write(del2, 1.5f); + cR.write(wet, 0.0f); + + outR = wet; + + + lp_decay_1_ = lp_1; + lp_decay_2_ = lp_2; +} + +TEST(LowLevel, TestStereoShimmerAlgo) +{ + 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(); + + Engine engine_L_(SAMPLING_FREQUENCY); + Engine engine_R_(SAMPLING_FREQUENCY); + engine_L_.setLFOFrequency(Engine::LFOIndex::LFO_1, 0.5f); + engine_L_.setLFOFrequency(Engine::LFOIndex::LFO_2, 0.3f); + engine_L_.reset(); + engine_R_.setLFOFrequency(Engine::LFOIndex::LFO_1, 0.5f); + engine_R_.setLFOFrequency(Engine::LFOIndex::LFO_2, 0.3f); + engine_R_.reset(); + + float32_t lp1 = 0.0f; + float32_t lp2 = 0.0f; + + size_t size = 0; + float32_t** inSamples = readWaveFile(AUDIO_SOURCE_FILE, size); + + float32_t* outSamplesL = new float32_t[size]; + float32_t* outSamplesR = new float32_t[size]; + memset(outSamplesL, 0, size * sizeof(float32_t)); + memset(outSamplesR, 0, size * sizeof(float32_t)); + + for(size_t i = 0; i < size; ++i) + { + processShimmerSample(engine_L_, engine_R_, i, lp1, lp2, inSamples[0][i], inSamples[1][i], outSamplesL[i], outSamplesR[i]); + } + + saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamplesL, outSamplesR, size, SAMPLING_FREQUENCY, 16); + + delete[] outSamplesL; + delete[] outSamplesR; + + delete[] inSamples[0]; + delete[] inSamples[1]; + delete[] inSamples; +} + +void processShimmerSample( + Engine& engine_, size_t index, + float32_t& lp_decay_1_, float32_t& lp_decay_2_, + float32_t inL, float32_t inR, + float32_t& outL, float32_t& outR) +{ + // This is the Griesinger topology described in the Dattorro paper + // (4 AP diffusers on the input, then a loop of 2x 2AP+1Delay). + // Modulation is applied in the loop of the first diffuser AP for additional + // smearing; and to the two long delays for a slow shimmer/chorus effect. + typedef Engine::Reserve< 113, + Engine::Reserve< 162, + Engine::Reserve< 241, + Engine::Reserve< 399, + Engine::Reserve<1653, + Engine::Reserve<2038, + Engine::Reserve<3411, + Engine::Reserve<1913, + Engine::Reserve<1663, + Engine::Reserve<4782> > > > > > > > > > Memory; + Engine::DelayLine ap1; + Engine::DelayLine ap2; + Engine::DelayLine ap3; + Engine::DelayLine ap4; + Engine::DelayLine dap1a; + Engine::DelayLine dap1b; + Engine::DelayLine del1; + Engine::DelayLine dap2a; + Engine::DelayLine dap2b; + Engine::DelayLine del2; + Engine::Context c; + + const float32_t kap = 0.8f; + const float32_t klp = 0.7f; + const float32_t krt = 0.75f; + const float32_t gain = 0.55f; + + float32_t lp_1 = lp_decay_1_; + float32_t lp_2 = lp_decay_2_; + + float32_t wet = 0.0f; + float32_t apout = 0.0f; + engine_.start(&c); + + // Smear AP1 inside the loop. + c.interpolate(ap1, 10.0f, Engine::LFOIndex::LFO_1, 60.0f, 1.0f); + c.write(ap1, 100, 0.0f); + c.read(inL + inR, gain); + + // Diffuse through 4 allpasses. + c.read(ap1 TAIL, kap); + c.writeAllPass(ap1, -kap); + c.read(ap2 TAIL, kap); + c.writeAllPass(ap2, -kap); + c.read(ap3 TAIL, kap); + c.writeAllPass(ap3, -kap); + c.read(ap4 TAIL, kap); + c.writeAllPass(ap4, -kap); + c.write(apout); + + // Main reverb loop. + c.load(apout); + c.interpolate(del2, 4680.0f, Engine::LFOIndex::LFO_2, 100.0f, krt); + c.lp(lp_1, klp); + c.read(dap1a TAIL, -kap); + c.writeAllPass(dap1a, kap); + c.read(dap1b TAIL, kap); + c.writeAllPass(dap1b, -kap); + c.write(del1, 1.5f); + c.write(wet, 0.0f); + + outL = wet; + + + c.load(apout); + c.read(del1 TAIL, krt); + c.lp(lp_2, klp); + c.read(dap2a TAIL, kap); + c.writeAllPass(dap2a, -kap); + c.read(dap2b TAIL, -kap); + c.writeAllPass(dap2b, kap); + c.write(del2, 1.5f); + c.write(wet, 0.0f); + + outR = wet; + + + lp_decay_1_ = lp_1; + lp_decay_2_ = lp_2; +} + +TEST(LowLevel, TestMonoShimmerAlgo) +{ + 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(); + + Engine engine_(SAMPLING_FREQUENCY); + engine_.setLFOFrequency(Engine::LFOIndex::LFO_1, 0.5f); + engine_.setLFOFrequency(Engine::LFOIndex::LFO_2, 0.3f); + engine_.reset(); + + float32_t lp1 = 0.0f; + float32_t lp2 = 0.0f; + + size_t size = 0; + float32_t** inSamples = readWaveFile(AUDIO_SOURCE_FILE, size); + + float32_t* outSamplesL = new float32_t[size]; + float32_t* outSamplesR = new float32_t[size]; + memset(outSamplesL, 0, size * sizeof(float32_t)); + memset(outSamplesR, 0, size * sizeof(float32_t)); + + for(size_t i = 0; i < size; ++i) + { + processShimmerSample(engine_, i, lp1, lp2, inSamples[0][i], inSamples[1][i], outSamplesL[i], outSamplesR[i]); + } + + saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamplesL, outSamplesR, size, SAMPLING_FREQUENCY, 16); + + delete[] outSamplesL; + delete[] outSamplesR; + + delete[] inSamples[0]; + delete[] inSamples[1]; + delete[] inSamples; +} diff --git a/src/test/lowlevel.cpp b/src/test/lowlevel.cpp deleted file mode 100644 index 1ba89ce..0000000 --- a/src/test/lowlevel.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include - -#include - -#include "test_fx_helper.h" -#include "../fx_engine.hpp" - -#define EXEC_PRINT(ctx, x) \ - std::cout.fill(' '); \ - std::cout.width(80); \ - std::cout << std::left; \ - std::cout.precision(6); \ - std::cout << std::fixed; \ - std::cout << #x; \ - x \ - { \ - float32_t v = 0.0f; \ - ctx.write(v); \ - std::cout << " // accumulator_: " << v; \ - } \ - std::cout << std::endl - -#define TAIL , -1 - -typedef FxEngine<16384, Format::FORMAT_FLOAT32, true> Engine; - -void processShimmerSample( - Engine& engine_, size_t index, - float32_t& lp_decay_1_, float32_t& lp_decay_2_, - float32_t inL, float32_t inR, - float32_t& outL, float32_t& outR) -{ - // This is the Griesinger topology described in the Dattorro paper - // (4 AP diffusers on the input, then a loop of 2x 2AP+1Delay). - // Modulation is applied in the loop of the first diffuser AP for additional - // smearing; and to the two long delays for a slow shimmer/chorus effect. - typedef Engine::Reserve< 113, - Engine::Reserve< 162, - Engine::Reserve< 241, - Engine::Reserve< 399, - Engine::Reserve<1653, - Engine::Reserve<2038, - Engine::Reserve<3411, - Engine::Reserve<1913, - Engine::Reserve<1663, - Engine::Reserve<4782> > > > > > > > > > Memory; - Engine::DelayLine ap1; - Engine::DelayLine ap2; - Engine::DelayLine ap3; - Engine::DelayLine ap4; - Engine::DelayLine dap1a; - Engine::DelayLine dap1b; - Engine::DelayLine del1; - Engine::DelayLine dap2a; - Engine::DelayLine dap2b; - Engine::DelayLine del2; - Engine::Context c; - - const float32_t kap = 0.8f; - const float32_t klp = 0.7f; - const float32_t krt = 0.75f; - const float32_t gain = 0.55f; - - float32_t lp_1 = lp_decay_1_; - float32_t lp_2 = lp_decay_2_; - - float32_t wet = 0.0f; - float32_t apout = 0.0f; - engine_.start(&c); - - // Smear AP1 inside the loop. - EXEC_PRINT(c, c.interpolate(ap1, 10.0f, Engine::LFOIndex::LFO_1, 60.0f, 1.0f);); - EXEC_PRINT(c, c.write(ap1, 100, 0.0f);); - EXEC_PRINT(c, c.read(inL, gain);); - - // Diffuse through 4 allpasses. - EXEC_PRINT(c, c.read(ap1 TAIL, kap);); - EXEC_PRINT(c, c.writeAllPass(ap1, -kap);); - EXEC_PRINT(c, c.read(ap2 TAIL, kap);); - EXEC_PRINT(c, c.writeAllPass(ap2, -kap);); - EXEC_PRINT(c, c.read(ap3 TAIL, kap);); - EXEC_PRINT(c, c.writeAllPass(ap3, -kap);); - EXEC_PRINT(c, c.read(ap4 TAIL, kap);); - EXEC_PRINT(c, c.writeAllPass(ap4, -kap);); - EXEC_PRINT(c, c.write(apout);); - - // Main reverb loop. - EXEC_PRINT(c, c.load(apout);); - EXEC_PRINT(c, c.interpolate(del2, 4680.0f, Engine::LFOIndex::LFO_2, 100.0f, krt);); - EXEC_PRINT(c, c.lp(lp_1, klp);); - EXEC_PRINT(c, c.read(dap1a TAIL, -kap);); - EXEC_PRINT(c, c.writeAllPass(dap1a, kap);); - EXEC_PRINT(c, c.read(dap1b TAIL, kap);); - EXEC_PRINT(c, c.writeAllPass(dap1b, -kap);); - EXEC_PRINT(c, c.write(del1, 2.0f);); - EXEC_PRINT(c, c.write(wet, 0.0f);); - - outL = wet; - - - EXEC_PRINT(c, c.load(apout);); - EXEC_PRINT(c, c.interpolate(del1, 4450.0f, Engine::LFOIndex::LFO_1, 50.0f, krt);); - EXEC_PRINT(c, c.read(del1 TAIL, krt);); - EXEC_PRINT(c, c.lp(lp_2, klp);); - EXEC_PRINT(c, c.read(dap2a TAIL, kap);); - EXEC_PRINT(c, c.writeAllPass(dap2a, -kap);); - EXEC_PRINT(c, c.read(dap2b TAIL, -kap);); - EXEC_PRINT(c, c.writeAllPass(dap2b, kap);); - EXEC_PRINT(c, c.write(del2, 2.0f);); - EXEC_PRINT(c, c.write(wet, 0.0f);); - - outR = wet; - - std::cout << "Index # " << index << " - ( " << inL << ", " << inR << " ) ==> ( " << outL << ", " << outR << " )" << std::endl; - std::cout << std::endl << "**********************************************************************************************************" << std::endl << std::endl; - - lp_decay_1_ = lp_1; - lp_decay_2_ = lp_2; -} - -TEST(LowLevel, TestShimmerAlgo) -{ - 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(); - - Engine engine_(SAMPLING_FREQUENCY); - engine_.setLFOFrequency(Engine::LFOIndex::LFO_1, 0.5f); - engine_.setLFOFrequency(Engine::LFOIndex::LFO_2, 0.3f); - engine_.reset(); - - float32_t lp1 = 0.0f; - float32_t lp2 = 0.0f; - - const size_t size = static_cast(SAMPLING_FREQUENCY); - float32_t* inSamples = new float32_t[size]; - memset(inSamples, 0, size * sizeof(float32_t)); - inSamples[0] = 1.0f; - - float32_t* outSamplesL = new float32_t[size]; - float32_t* outSamplesR = new float32_t[size]; - memset(outSamplesL, 0, size * sizeof(float32_t)); - memset(outSamplesR, 0, size * sizeof(float32_t)); - - for(size_t i = 0; i < size; ++i) - { - processShimmerSample(engine_, i, lp1, lp2, inSamples[i], inSamples[i], outSamplesL[i], outSamplesR[i]); - } - - saveWaveFile(getResultFile(full_test_name + ".wav", true), outSamplesL, outSamplesR, size, SAMPLING_FREQUENCY, 16); - - delete[] outSamplesL; - delete[] outSamplesR; - - delete[] inSamples; -} diff --git a/src/test/test_cpp_performance.cpp b/src/test/test_cpp_performance.cpp index d1d3e3e..99ab2ee 100644 --- a/src/test/test_cpp_performance.cpp +++ b/src/test/test_cpp_performance.cpp @@ -29,7 +29,7 @@ TEST(CppPerformance, LFOPerformance_ComplexLFO_InterpolatedSineOscillator) } auto d2 = LAP_TIME("lfo2"); - EXPECT_LE(d1, d2 + 100); + EXPECT_GE(d1, d2); } TEST(CppPerformance, LFOPerformance_ComplexLFO_FastLFO) diff --git a/src/test/test_fx_helper.h b/src/test/test_fx_helper.h index 4f6f2c5..22098a1 100644 --- a/src/test/test_fx_helper.h +++ b/src/test/test_fx_helper.h @@ -7,7 +7,7 @@ #include "wave.h" #include "../fx.h" -#define AUDIO_SOURCE_FILE "test.wav" +#define AUDIO_SOURCE_FILE "test2.wav" #define SAMPLING_FREQUENCY 44100.0f