Fixing the Shimmer Reverb unstability

pull/495/head
abscisys 2 years ago
parent 11114ee657
commit 2a272801d3
  1. 4
      src/fx_components.h
  2. 6
      src/fx_engine.hpp
  3. 5
      src/fx_rack.cpp
  4. 6
      src/fx_shimmer_reverb.cpp
  5. 6
      src/test/Makefile
  6. 441
      src/test/beta_lowlevel.cpp
  7. 157
      src/test/lowlevel.cpp
  8. 2
      src/test/test_cpp_performance.cpp
  9. 2
      src/test/test_fx_helper.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

@ -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<int32_t>(offset);
float32_t offset_fractional = offset - static_cast<float32_t>(offset_integral);
float32_t a = DataType<format>::decompress(this->buffer_[(this->write_ptr_ + offset_integral + D::base) & MASK]);
float32_t b = DataType<format>::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<format>::decompress(this->buffer_[index & MASK]);
float32_t b = DataType<format>::decompress(this->buffer_[(index + 1) & MASK]);
float32_t x = a + (b - a) * offset_fractional;
this->previous_read_ = x;

@ -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;

@ -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;

@ -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

@ -0,0 +1,441 @@
#include <gtest/gtest.h>
#include <iostream>
#include <iomanip>
#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<Memory, 0> ap1;
Engine::DelayLine<Memory, 1> ap2;
Engine::DelayLine<Memory, 2> ap3;
Engine::DelayLine<Memory, 3> ap4;
Engine::DelayLine<Memory, 4> dap1a;
Engine::DelayLine<Memory, 5> dap1b;
Engine::DelayLine<Memory, 6> del1;
Engine::DelayLine<Memory, 7> dap2a;
Engine::DelayLine<Memory, 8> dap2b;
Engine::DelayLine<Memory, 9> 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<float32_t>(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<Memory, 0> ap1;
Engine::DelayLine<Memory, 1> ap2;
Engine::DelayLine<Memory, 2> ap3;
Engine::DelayLine<Memory, 3> ap4;
Engine::DelayLine<Memory, 4> dap1a;
Engine::DelayLine<Memory, 5> dap1b;
Engine::DelayLine<Memory, 6> del1;
Engine::DelayLine<Memory, 7> dap2a;
Engine::DelayLine<Memory, 8> dap2b;
Engine::DelayLine<Memory, 9> 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<Memory, 0> ap1;
Engine::DelayLine<Memory, 1> ap2;
Engine::DelayLine<Memory, 2> ap3;
Engine::DelayLine<Memory, 3> ap4;
Engine::DelayLine<Memory, 4> dap1a;
Engine::DelayLine<Memory, 5> dap1b;
Engine::DelayLine<Memory, 6> del1;
Engine::DelayLine<Memory, 7> dap2a;
Engine::DelayLine<Memory, 8> dap2b;
Engine::DelayLine<Memory, 9> 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;
}

@ -1,157 +0,0 @@
#include <gtest/gtest.h>
#include <iostream>
#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<Memory, 0> ap1;
Engine::DelayLine<Memory, 1> ap2;
Engine::DelayLine<Memory, 2> ap3;
Engine::DelayLine<Memory, 3> ap4;
Engine::DelayLine<Memory, 4> dap1a;
Engine::DelayLine<Memory, 5> dap1b;
Engine::DelayLine<Memory, 6> del1;
Engine::DelayLine<Memory, 7> dap2a;
Engine::DelayLine<Memory, 8> dap2b;
Engine::DelayLine<Memory, 9> 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<float32_t>(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;
}

@ -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)

@ -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

Loading…
Cancel
Save