mirror of https://github.com/probonopd/MiniDexed
parent
f14ac0a967
commit
926ba5339e
@ -0,0 +1,117 @@ |
||||
#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 DUMP(clazz, out) clazz->dump(out, true, "") |
||||
#define DUMP2(clazz, out, tag) clazz->dump(out, true, tag) |
||||
#define FAST_DUMP(clazz, out, tag) clazz->dump(out, false, "") |
||||
#define FAST_DUMP2(clazz, out, tag) clazz->dump(out, false, tag) |
||||
|
||||
#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->inspect(inspector, deepInspection) |
||||
#define FULL_INSPECT(obj, deepInspection) obj->inspect(fullInspector, deepInspection) |
||||
#define FULL_INSPECT2(obj, deepInspection, tag) obj->inspect(fullInspector, deepInspection, tag) |
||||
|
||||
#else |
||||
|
||||
#define INSPECTABLE(clazz) clazz |
||||
#define IMPLEMENT_DUMP(code) |
||||
#define IMPLEMENT_INSPECT(code) |
||||
|
||||
#define DUMP(clazz, out) |
||||
#define DUMP2(clazz, out, tag) |
||||
#define FAST_DUMP(clazz, out, tag) |
||||
#define FAST_DUMP2(clazz, out, tag) |
||||
|
||||
#define INSPECT(obj, inspector) |
||||
#define INSPECT2(obj, inspector, deepInspection) |
||||
#define FULL_INSPECT(obj, deepInspection) |
||||
#define FULL_INSPECT2(obj, deepInspection, tag) |
||||
|
||||
#endif |
@ -0,0 +1,10 @@ |
||||
#pragma once |
||||
|
||||
#include "extra_features.h" |
||||
|
||||
enum StereoChannels |
||||
{ |
||||
Left = 0, |
||||
Right, |
||||
kNumChannels |
||||
}; |
@ -1,92 +1,63 @@ |
||||
CXX := gcc
|
||||
# CXXFLAGS := -O2
|
||||
CXXFLAGS := -g
|
||||
DEFINES := -DCPU=x86
|
||||
INCLUDES := -I../../CMSIS_5/CMSIS/DSP/Include/ -I../../CMSIS_5/CMSIS/Core/Include/
|
||||
GCC := $(CXX) $(INCLUDES) $(CXXFLAGS)
|
||||
OBJDIR := objects
|
||||
OUTPUT_FOLDER = results
|
||||
EXE := all_test.bin
|
||||
BETA := beta.bin
|
||||
|
||||
LD := gcc
|
||||
LIBS := -lm -lstdc++
|
||||
CXX := g++
|
||||
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/
|
||||
|
||||
OBJS := \
|
||||
wavein.o \
|
||||
waveout.o \
|
||||
fx.o \
|
||||
fx_components.o \
|
||||
fx_svf.o \
|
||||
fx_tube.o \
|
||||
fx_chorus.o \
|
||||
fx_phaser.o \
|
||||
fx_orbitone.o \
|
||||
fx_flanger.o \
|
||||
fx_delay.o \
|
||||
fx_shimmer_reverb.o \
|
||||
fx_rack.o \
|
||||
fxrack_test.o
|
||||
-include $(TST_OBJS:.o=.d) |
||||
-include $(FX__OBJS:.o=.d) |
||||
|
||||
test: fxrack_test |
||||
./fxrack_test
|
||||
LD := g++
|
||||
LIBS := -lm -lstdc++ -lgtest -lpthread
|
||||
|
||||
# %.o: ../%.cpp
|
||||
# $(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
FX__SRCS := ../fx.cpp
|
||||
FX__SRCS += ../fx_components.cpp
|
||||
FX__SRCS += ../fx_svf.cpp
|
||||
FX__SRCS += ../fx_tube.cpp
|
||||
FX__SRCS += ../fx_chorus.cpp
|
||||
FX__SRCS += ../fx_phaser.cpp
|
||||
FX__SRCS += ../fx_orbitone.cpp
|
||||
FX__SRCS += ../fx_flanger.cpp
|
||||
FX__SRCS += ../fx_delay.cpp
|
||||
FX__SRCS += ../effect_platervbstereo.cpp
|
||||
FX__SRCS += ../fx_shimmer_reverb.cpp
|
||||
FX__SRCS += ../fx_rack.cpp
|
||||
|
||||
wavein.o: wavein.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
TST_SRCS := $(filter-out waveplay.cpp, $(wildcard *.cpp))
|
||||
|
||||
waveout.o: waveout.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
FX__OBJS = $(patsubst ../%, $(OBJDIR)/%, $(FX__SRCS:.cpp=.o))
|
||||
TST_OBJS = $(TST_SRCS:%.cpp=$(OBJDIR)/%.o)
|
||||
|
||||
# waveplay.o: waveplay.cpp
|
||||
# $(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
all: $(EXE) test |
||||
|
||||
fx.o: ../fx.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
test: $(EXE) $(OUTPUT_FOLDER) |
||||
rm -rf $(OUTPUT_FOLDER)/*
|
||||
./$(EXE)
|
||||
|
||||
fx_components.o: ../fx_components.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
test-debug: $(EXE) $(OUTPUT_FOLDER) |
||||
rm -rf $(OUTPUT_FOLDER)/*
|
||||
valgrind --leak-check=full --leak-resolution=high --show-leak-kinds=all --xtree-leak=yes --show-mismatched-frees=yes --error-limit=no --log-file=$(OUTPUT_FOLDER)/valgrind-analysis-results.txt ./$(EXE)
|
||||
|
||||
fx_svf.o: ../fx_svf.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
$(OBJDIR): |
||||
mkdir -p $@
|
||||
|
||||
fx_tube.o: ../fx_tube.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
$(OUTPUT_FOLDER): |
||||
mkdir -p $@
|
||||
|
||||
../fx_chorus.cpp: ../fx_engine.hpp |
||||
touch ../fx_chorus.cpp
|
||||
$(OBJDIR)/%.o: %.cpp $(OBJDIR) |
||||
$(CXX) $(CXXFLAGS) $(DEFINES) $(INCLUDES) -c $< -o $@
|
||||
|
||||
fx_chorus.o: ../fx_chorus.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
$(OBJDIR)/%.o: ../%.cpp $(OBJDIR) |
||||
$(CXX) $(CXXFLAGS) $(DEFINES) $(INCLUDES) -c $< -o $@
|
||||
|
||||
fx_phaser.o: ../fx_phaser.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
|
||||
../fx_orbitone.cpp: ../fx_engine.hpp |
||||
touch ../fx_orbitone.cpp
|
||||
|
||||
fx_orbitone.o: ../fx_orbitone.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
|
||||
fx_flanger.o: ../fx_flanger.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
|
||||
fx_delay.o: ../fx_delay.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
|
||||
../fx_shimmer_reverb.cpp: ../fx_engine.hpp |
||||
touch ../fx_shimmer_reverb.cpp
|
||||
|
||||
fx_shimmer_reverb.o: ../fx_shimmer_reverb.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
|
||||
fx_rack.o: ../fx_rack.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
|
||||
fxrack_test.o: fxrack_test.cpp |
||||
$(CXX) $(DEFINES) $(INCLUDES) $(CXXFLAGS) -c $^ -o $@
|
||||
|
||||
|
||||
fxrack_test: $(OBJS) |
||||
$(LD) $(OBJS) -o fxrack_test $(LIBS)
|
||||
$(EXE): $(TST_OBJS) $(FX__OBJS) |
||||
$(LD) $(CXXFLAGS) $(call wildcard,$(TST_OBJS)) $(call wildcard,$(FX__OBJS)) -o $@ $(LIBS)
|
||||
|
||||
clean: |
||||
rm -f *.o fxrack_test
|
||||
rm -rf *.o $(OBJDIR) $(EXE) $(OUTPUT_FOLDER)
|
||||
|
@ -0,0 +1,7 @@ |
||||
#include <gtest/gtest.h> |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
@ -0,0 +1,46 @@ |
||||
#include <arm_math.h> |
||||
|
||||
float32_t arm_sin_f32(float32_t phase) |
||||
{ |
||||
return sin(phase); |
||||
} |
||||
|
||||
float32_t arm_cos_f32(float32_t phase) |
||||
{ |
||||
return cos(phase); |
||||
} |
||||
|
||||
void arm_scale_f32(const float32_t *pSrc, float32_t scale, float32_t *pDst, uint32_t blockSize) |
||||
{ |
||||
for(unsigned i = 0; i < blockSize; ++i) |
||||
{ |
||||
pDst[i] = scale * pSrc[i]; |
||||
} |
||||
} |
||||
|
||||
void arm_copy_f32(const float32_t *pSrc, float32_t *pDst, uint32_t blockSize) |
||||
{ |
||||
memcpy(pDst, pSrc, blockSize * sizeof(float32_t)); |
||||
} |
||||
|
||||
void arm_add_f32(const float32_t *pSrcA, const float32_t *pSrcB, float32_t *pDst, uint32_t blockSize) |
||||
{ |
||||
for(size_t i = 0; i < blockSize; ++i) pDst[i] = pSrcA[i] + pSrcB[i]; |
||||
} |
||||
|
||||
void arm_fill_f32(float32_t value, float32_t *pDst, uint32_t blockSize) |
||||
{ |
||||
for(size_t i = 0; i < blockSize; ++i) pDst[i] = value; |
||||
} |
||||
|
||||
float32_t arm_weighted_sum_f32(const float32_t *in, const float32_t *weights, uint32_t blockSize) |
||||
{ |
||||
float32_t m = 0.0f; |
||||
for(size_t i = 0; i < blockSize; ++i) m += in[i] * weights[i]; |
||||
return m; |
||||
} |
||||
|
||||
void arm_clip_f32(const float32_t *pSrc, float32_t *pDst, float32_t low, float32_t high, uint32_t numSamples) |
||||
{ |
||||
for(size_t i = 0; i < numSamples; ++i) pDst[i] = (pSrc[i] < low) ? low : (pSrc[i] > high) ? high : pSrc[i]; |
||||
} |
@ -1,235 +0,0 @@ |
||||
#include "../fx_rack.h" |
||||
|
||||
#include <iomanip> |
||||
#include <iostream> |
||||
#include <fstream> |
||||
#include <locale> |
||||
#include <ctime> |
||||
#include <random> |
||||
#include "wave.h" |
||||
|
||||
using namespace std; |
||||
|
||||
#define FS 44100.0f |
||||
#define MAX_SVF_SAMPLES 10000000 |
||||
#define MAX_NB_ERRORS 100 |
||||
|
||||
std::random_device rd; |
||||
std::mt19937 gen(rd()); |
||||
std::uniform_real_distribution<float32_t> dist(-1.0f, 1.0f); |
||||
|
||||
void testLFO(unsigned& step) |
||||
{ |
||||
cout << "Step #" << (++step) << ": Testing LFO" << endl; |
||||
|
||||
const float32_t freq = 10.0f; |
||||
|
||||
LFO lfo(FS, LFO::Waveform::Sine, 0.0f, freq); |
||||
unsigned size = static_cast<unsigned>(8.0f * FS / freq); |
||||
float32_t rate = 0.0f; |
||||
float32_t rate_increment = freq / 2.0f / FS; |
||||
|
||||
// float32_t* output = new float32_t[size];
|
||||
ofstream out("result.csv"); |
||||
|
||||
struct comma_separator : std::numpunct<char> |
||||
{ |
||||
virtual char do_decimal_point() const override { return ','; } |
||||
}; |
||||
|
||||
out.imbue(std::locale(out.getloc(), new comma_separator)); |
||||
out << fixed << showpoint; |
||||
|
||||
out << "index;LFO" << endl; |
||||
for(unsigned i = 0; i < size; ++i) |
||||
{ |
||||
lfo.setNormalizedFrequency(rate); |
||||
out << i << ";" << lfo.process() << endl; |
||||
rate += rate_increment; |
||||
|
||||
if(rate >= 1.0f || rate <= 0.0f) |
||||
{ |
||||
rate_increment *= -1.0f; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void testFlutter(unsigned& step) |
||||
{ |
||||
cout << "Step #" << (++step) << ": Testing JitterGenerator" << endl; |
||||
|
||||
JitterGenerator jg(FS); |
||||
jg.setSpeed(1.0f); |
||||
jg.setMagnitude(0.1f); |
||||
|
||||
for (unsigned i = 0; i < 1000; ++i) |
||||
{ |
||||
cout << jg.process() << endl; |
||||
} |
||||
} |
||||
|
||||
void testSVF(unsigned& step) |
||||
{ |
||||
float32_t inL, inR; |
||||
float32_t outL, outR; |
||||
StateVariableFilter svf(FS, StateVariableFilter::Type::LPF, 12000.0f); |
||||
|
||||
cout << "Step #" << (++step) << ": Testing SVF in LPF mode" << endl; |
||||
{ |
||||
svf.setFilterType(StateVariableFilter::Type::LPF); |
||||
svf.setCutoff(12000.0f); |
||||
svf.setResonance(0.0f); |
||||
unsigned nbSamples = 0; |
||||
unsigned nbErrors = 0; |
||||
while (nbErrors < MAX_NB_ERRORS && nbSamples < MAX_SVF_SAMPLES) |
||||
{ |
||||
nbSamples++; |
||||
inL = dist(gen); |
||||
inR = dist(gen); |
||||
svf.processSample(inL, inR, outL, outR); |
||||
|
||||
if (std::abs(outL) > 1.0f) |
||||
nbErrors++; |
||||
if (std::abs(outR) > 1.0f) |
||||
nbErrors++; |
||||
} |
||||
cout << "nbSamples: " << nbSamples << " -- nbErrors: " << nbErrors << endl; |
||||
} |
||||
|
||||
cout << "Step #" << (++step) << ": Testing SVF in HPF mode" << endl; |
||||
{ |
||||
svf.setFilterType(StateVariableFilter::Type::LPF); |
||||
svf.setCutoff(60.0f); |
||||
svf.setResonance(0.0f); |
||||
unsigned nbSamples = 0; |
||||
unsigned nbErrors = 0; |
||||
while (nbErrors < MAX_NB_ERRORS && nbSamples < MAX_SVF_SAMPLES) |
||||
{ |
||||
nbSamples++; |
||||
inL = dist(gen); |
||||
inR = dist(gen); |
||||
svf.processSample(inL, inR, outL, outR); |
||||
|
||||
if (std::abs(outL) > 1.0f) |
||||
nbErrors++; |
||||
if (std::abs(outR) > 1.0f) |
||||
nbErrors++; |
||||
} |
||||
cout << "nbSamples: " << nbSamples << " -- nbErrors: " << nbErrors << endl; |
||||
} |
||||
} |
||||
|
||||
enum FXSitch |
||||
{ |
||||
Tube = 1 << 0, |
||||
Chorus = 1 << 1, |
||||
Phaser = 1 << 2, |
||||
Orbitone = 1 << 3, |
||||
Flanger = 1 << 4, |
||||
Delay = 1 << 5, |
||||
Shimmer = 1 << 6 |
||||
}; |
||||
|
||||
#define Active(fxSwitch, FxID) (fxSwitch & FxID) == FxID |
||||
|
||||
void testFXRack(unsigned& step, unsigned fxSwitch) |
||||
{ |
||||
cout << "Step #" << (++step) << ": Intanciation FXRack" << endl; |
||||
FXRack *rack = new FXRack(44100.0f); |
||||
|
||||
cout << "Step #" << (++step) << ": Test preparation" << endl; |
||||
rack->setEnable(true); |
||||
rack->setWetLevel(1.0f); |
||||
|
||||
rack->getTube()->setEnable(Active(fxSwitch, FXSitch::Tube)); |
||||
rack->getTube()->setWetLevel(0.25f); |
||||
rack->getTube()->setOverdrive(0.25f); |
||||
|
||||
rack->getChorus()->setEnable(Active(fxSwitch, FXSitch::Chorus)); |
||||
rack->getChorus()->setWetLevel(0.5f); |
||||
rack->getChorus()->setRate(0.4f); |
||||
rack->getChorus()->setDepth(0.5f); |
||||
|
||||
rack->getPhaser()->setEnable(Active(fxSwitch, FXSitch::Phaser)); |
||||
rack->getPhaser()->setWetLevel(1.0f); |
||||
rack->getPhaser()->setRate(0.1f); |
||||
rack->getPhaser()->setDepth(1.0f); |
||||
rack->getPhaser()->setFeedback(0.5f); |
||||
rack->getPhaser()->setNbStages(12); |
||||
|
||||
rack->getOrbitone()->setEnable(Active(fxSwitch, FXSitch::Orbitone)); |
||||
rack->getOrbitone()->setWetLevel(0.8f); |
||||
rack->getOrbitone()->setRate(0.4f); |
||||
rack->getOrbitone()->setDepth(0.5f); |
||||
|
||||
rack->getFlanger()->setEnable(Active(fxSwitch, FXSitch::Flanger)); |
||||
rack->getFlanger()->setWetLevel(0.5f); |
||||
rack->getFlanger()->setRate(0.03f); |
||||
rack->getFlanger()->setDepth(0.75f); |
||||
rack->getFlanger()->setFeedback(0.5f); |
||||
|
||||
rack->getDelay()->setEnable(Active(fxSwitch, FXSitch::Delay)); |
||||
rack->getDelay()->setWetLevel(0.6f); |
||||
rack->getDelay()->setLeftDelayTime(0.075f); |
||||
rack->getDelay()->setLeftDelayTime(0.05f); |
||||
rack->getDelay()->setFeedbak(0.5f); |
||||
|
||||
rack->getShimmerReverb()->setEnable(Active(fxSwitch, FXSitch::Shimmer)); |
||||
rack->getShimmerReverb()->setWetLevel(0.5f); |
||||
rack->getShimmerReverb()->setInputGain(0.35f); |
||||
rack->getShimmerReverb()->setTime(0.89f); |
||||
rack->getShimmerReverb()->setDiffusion(0.75f); |
||||
rack->getShimmerReverb()->setLP(0.8f); |
||||
|
||||
unsigned nbRepeats = 4; |
||||
|
||||
unsigned size; |
||||
float32_t** samples = readWaveFile("test.wav", size); |
||||
float32_t* sampleOutL = new float32_t[size * nbRepeats]; |
||||
float32_t* sampleOutR = new float32_t[size * nbRepeats]; |
||||
memset(sampleOutL, 0, size * nbRepeats * sizeof(float32_t)); |
||||
memset(sampleOutR, 0, size * nbRepeats * sizeof(float32_t)); |
||||
|
||||
for (unsigned i = 0; i < nbRepeats; ++i) |
||||
{ |
||||
rack->process(samples[0], samples[1], sampleOutL + i * size, sampleOutR + i * size, size); |
||||
} |
||||
|
||||
saveWaveFile("result.wav", sampleOutL, sampleOutR, nbRepeats * size, static_cast<unsigned>(FS), 16); |
||||
|
||||
delete[] sampleOutL; |
||||
delete[] sampleOutR; |
||||
delete[] samples[0]; |
||||
delete[] samples[1]; |
||||
delete[] samples; |
||||
|
||||
cout << "Step #" << (++step) << ": Test cleanup" << endl; |
||||
delete rack; |
||||
} |
||||
|
||||
int main() |
||||
{ |
||||
unsigned step = 0; |
||||
|
||||
// testLFO(step);
|
||||
// testFlutter(step);
|
||||
// testSVF(step);
|
||||
// testFXRack(step, FXSitch::Tube);
|
||||
// testFXRack(step, FXSitch::Flanger);
|
||||
// testFXRack(step, FXSitch::Phaser);
|
||||
// testFXRack(step, FXSitch::Chorus);
|
||||
// testFXRack(step, FXSitch::Orbitone);
|
||||
// testFXRack(step, FXSitch::Delay);
|
||||
// testFXRack(step, FXSitch::Shimmer);
|
||||
testFXRack( |
||||
step, |
||||
FXSitch::Tube |
|
||||
FXSitch::Chorus |
|
||||
FXSitch::Flanger |
|
||||
FXSitch::Orbitone |
|
||||
FXSitch::Phaser |
|
||||
FXSitch::Delay |
|
||||
FXSitch::Shimmer); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,69 @@ |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "../fx_components.h" |
||||
#include <chrono> |
||||
#include <fstream> |
||||
|
||||
int nb = 0; |
||||
|
||||
int NbIteration() { |
||||
nb++; |
||||
return 3; |
||||
} |
||||
|
||||
TEST(Cpp, NbCallsInUpperBoudariesInForLoop) |
||||
{ |
||||
for(int i = 0; i < NbIteration(); ++i) |
||||
{ |
||||
// Does something
|
||||
} |
||||
EXPECT_EQ(nb, 4); |
||||
} |
||||
|
||||
#define CLASS_INIT(clazz) clazz::StaticInit() |
||||
class StaticCtorTest |
||||
{ |
||||
private: |
||||
static int n_; |
||||
|
||||
public: |
||||
int i_; |
||||
|
||||
static int StaticInit() |
||||
{ |
||||
static int i = 0; |
||||
i++; |
||||
|
||||
StaticCtorTest::n_ = 2; |
||||
|
||||
return i; |
||||
} |
||||
|
||||
StaticCtorTest() : i_(0) |
||||
{ |
||||
static int init = CLASS_INIT(StaticCtorTest); |
||||
static int NB = 0; |
||||
EXPECT_EQ(init, 1); |
||||
|
||||
this->i_ = ++NB; |
||||
|
||||
EXPECT_EQ(StaticCtorTest::n_, 2); |
||||
} |
||||
|
||||
~StaticCtorTest() |
||||
{ |
||||
} |
||||
}; |
||||
|
||||
int StaticCtorTest::n_ = 0; |
||||
|
||||
TEST(Cpp, StaticCtorTest) |
||||
{ |
||||
StaticCtorTest obj1; |
||||
StaticCtorTest obj2; |
||||
StaticCtorTest obj3; |
||||
|
||||
EXPECT_EQ(obj1.i_, 1); |
||||
EXPECT_EQ(obj2.i_, 2); |
||||
EXPECT_EQ(obj3.i_, 3); |
||||
} |
@ -0,0 +1,89 @@ |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include <fstream> |
||||
|
||||
#include "test_fx_helper.h" |
||||
#include "../fx_components.h" |
||||
|
||||
TEST(CppPerformance, LFOPerformance_ComplexLFO_InterpolatedSineOscillator) |
||||
{ |
||||
const size_t NB = 10000000; |
||||
float32_t freq = 0.1f; |
||||
|
||||
ComplexLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f); |
||||
InterpolatedSineOscillator 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_LE(d1, d2 + 100); |
||||
} |
||||
|
||||
TEST(CppPerformance, LFOPerformance_ComplexLFO_FastLFO) |
||||
{ |
||||
const size_t NB = 10000000; |
||||
float32_t freq = 0.1f; |
||||
|
||||
ComplexLFO 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, FastLFOTuning) |
||||
{ |
||||
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<size_t>(1.0f * SAMPLING_FREQUENCY); |
||||
float32_t freq = 5.0f; |
||||
|
||||
FastLFO lfo1(SAMPLING_FREQUENCY, freq, 440.0f); |
||||
lfo1.setFrequency(freq); |
||||
|
||||
ComplexLFO lfo2(SAMPLING_FREQUENCY, freq, 440.0f); |
||||
lfo2.setFrequency(freq); |
||||
|
||||
std::ofstream out(getResultFile(full_test_name + ".FastLFOTuning-data.csv", true)); |
||||
setupOuputStreamForCSV(out); |
||||
out << "index;FastLFO;ComplexLFO" << std::endl; |
||||
for(size_t i = 0; i < NB; ++i) |
||||
{ |
||||
out
|
||||
<< i << ";"
|
||||
<< lfo1.process() << ";"
|
||||
<< lfo2.process() << std::endl; |
||||
} |
||||
out.close(); |
||||
} |
@ -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) |
||||
{ |
||||
size_t 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); |
||||
} |
@ -0,0 +1,71 @@ |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "test_fx_helper.h" |
||||
#include "wave.h" |
||||
|
||||
#include "../effect_platervbstereo.h" |
||||
|
||||
TEST(FXElement, PlateReverbMigration) |
||||
{ |
||||
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 unsigned nbRepeats = 4; |
||||
|
||||
AudioEffectPlateReverb* reverb = new AudioEffectPlateReverb(SAMPLING_FREQUENCY); |
||||
reverb->set_bypass(false); |
||||
reverb->size(0.7f); |
||||
reverb->hidamp(0.5f); |
||||
reverb->lodamp(0.5f); |
||||
reverb->lowpass(0.3f); |
||||
reverb->diffusion(0.65f); |
||||
reverb->level(1.0f); |
||||
|
||||
size_t size; |
||||
float32_t** samples = readWaveFile(AUDIO_SOURCE_FILE, size); |
||||
float32_t* sampleOutL = new float32_t[size * nbRepeats]; |
||||
float32_t* sampleOutR = new float32_t[size * nbRepeats]; |
||||
memset(sampleOutL, 0, size * nbRepeats * sizeof(float32_t)); |
||||
memset(sampleOutR, 0, size * nbRepeats * sizeof(float32_t)); |
||||
|
||||
unsigned index = 0; |
||||
for(unsigned i = 0; i < nbRepeats; ++i) |
||||
{ |
||||
for(unsigned j = 0; j < size; ++j) |
||||
{ |
||||
reverb->processSample(samples[0][j], samples[1][j], sampleOutL[index], sampleOutR[index]); |
||||
++index; |
||||
} |
||||
} |
||||
saveWaveFile(getResultFile(full_test_name + ".PlateReverb-new.wav", true), sampleOutL, sampleOutR, nbRepeats * size, static_cast<unsigned>(SAMPLING_FREQUENCY), 16); |
||||
|
||||
unsigned indexOut = 0; |
||||
for (unsigned i = 0; i < nbRepeats; ++i) |
||||
{ |
||||
unsigned len = size; |
||||
unsigned indexIn = 0; |
||||
|
||||
while(len > 0) |
||||
{ |
||||
unsigned grainSize = (len < 1024 ? len : 1024); |
||||
|
||||
reverb->doReverb(samples[0] + indexIn, samples[1] + indexIn, sampleOutL + indexOut, sampleOutR + indexOut, grainSize); |
||||
|
||||
indexIn += grainSize; |
||||
indexOut += grainSize; |
||||
len -= grainSize; |
||||
} |
||||
|
||||
} |
||||
saveWaveFile(getResultFile(full_test_name + ".PlateReverb-legacy.wav", true), sampleOutL, sampleOutR, nbRepeats * size, static_cast<unsigned>(SAMPLING_FREQUENCY), 16); |
||||
|
||||
delete[] sampleOutL; |
||||
delete[] sampleOutR; |
||||
delete[] samples[0]; |
||||
delete[] samples[1]; |
||||
delete[] samples; |
||||
|
||||
delete reverb; |
||||
} |
@ -0,0 +1,156 @@ |
||||
#include <gtest/gtest.h> |
||||
#include <iomanip> |
||||
#include <iostream> |
||||
#include <fstream> |
||||
#include <sstream> |
||||
#include <string> |
||||
#include <locale> |
||||
#include <ctime> |
||||
#include <cmath> |
||||
#include <random> |
||||
#include "wave.h" |
||||
|
||||
#include "test_fx_helper.h" |
||||
|
||||
#include "../fx_rack.h" |
||||
#include "../effect_platervbstereo.h" |
||||
|
||||
#define MAX_SVF_SAMPLES 10000000 |
||||
#define MAX_NB_ERRORS 100 |
||||
|
||||
TEST(FXComponent, LFO) |
||||
{ |
||||
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.0f; |
||||
|
||||
LFO lfo(SAMPLING_FREQUENCY, 0.0f, freq); |
||||
unsigned size = static_cast<unsigned>(8.0f * SAMPLING_FREQUENCY / freq); |
||||
float32_t rate = 0.0f; |
||||
float32_t rate_increment = freq / 2.0f / SAMPLING_FREQUENCY; |
||||
|
||||
std::ofstream out(getResultFile(full_test_name + ".FXComponent.LFO.csv", true)); |
||||
setupOuputStreamForCSV(out); |
||||
out << std::fixed << std::showpoint; |
||||
|
||||
out << "index;LFO" << std::endl; |
||||
for(unsigned i = 0; i < size; ++i) |
||||
{ |
||||
lfo.setNormalizedFrequency(rate); |
||||
out << i << ";" << lfo.process() << std::endl; |
||||
rate += rate_increment; |
||||
|
||||
if(rate >= 1.0f || rate <= 0.0f) |
||||
{ |
||||
rate_increment *= -1.0f; |
||||
} |
||||
} |
||||
} |
||||
|
||||
TEST(FXComponent, Flutter) |
||||
{ |
||||
JitterGenerator jg(SAMPLING_FREQUENCY); |
||||
jg.setSpeed(1.0f); |
||||
jg.setMagnitude(0.1f); |
||||
|
||||
for (unsigned i = 0; i < 1000; ++i) |
||||
{ |
||||
jg.process(); |
||||
} |
||||
} |
||||
|
||||
TEST(FXComponent, SVF) |
||||
{ |
||||
float32_t inL, inR; |
||||
float32_t outL, outR; |
||||
StateVariableFilter svf(SAMPLING_FREQUENCY, StateVariableFilter::Type::LPF, 12000.0f); |
||||
|
||||
{ |
||||
svf.setFilterType(StateVariableFilter::Type::LPF); |
||||
svf.setCutoff(12000.0f); |
||||
svf.setResonance(0.0f); |
||||
unsigned nbSamples = 0; |
||||
unsigned nbErrors = 0; |
||||
while(nbErrors < MAX_NB_ERRORS && nbSamples < MAX_SVF_SAMPLES) |
||||
{ |
||||
nbSamples++; |
||||
inL = getRandomValue(); |
||||
inR = getRandomValue(); |
||||
svf.processSample(inL, inR, outL, outR); |
||||
|
||||
if(std::abs(outL) > 1.0f) |
||||
nbErrors++; |
||||
if(std::abs(outR) > 1.0f) |
||||
nbErrors++; |
||||
} |
||||
EXPECT_LT(nbErrors, MAX_NB_ERRORS); |
||||
} |
||||
|
||||
{ |
||||
svf.setFilterType(StateVariableFilter::Type::LPF); |
||||
svf.setCutoff(60.0f); |
||||
svf.setResonance(0.0f); |
||||
unsigned nbSamples = 0; |
||||
unsigned nbErrors = 0; |
||||
while(nbErrors < MAX_NB_ERRORS && nbSamples < MAX_SVF_SAMPLES) |
||||
{ |
||||
nbSamples++; |
||||
inL = getRandomValue(); |
||||
inR = getRandomValue(); |
||||
svf.processSample(inL, inR, outL, outR); |
||||
|
||||
if(std::abs(outL) > 1.0f) |
||||
nbErrors++; |
||||
if(std::abs(outR) > 1.0f) |
||||
nbErrors++; |
||||
} |
||||
EXPECT_LT(nbErrors, MAX_NB_ERRORS); |
||||
} |
||||
} |
||||
|
||||
TEST(CppOptimization, InterpolatedSineOscillatorPrecisionTest) |
||||
{ |
||||
const float32_t freq = 0.15f; |
||||
const size_t NB = static_cast<size_t>(2.0f * SAMPLING_FREQUENCY); |
||||
|
||||
const float32_t epsilon = 1e-3; |
||||
|
||||
ComplexLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f); |
||||
InterpolatedSineOscillator lfo2(SAMPLING_FREQUENCY, 0.0f, 10.0f); |
||||
lfo1.setFrequency(freq); |
||||
lfo2.setFrequency(freq); |
||||
float32_t max_delta = 0.0f; |
||||
for(size_t i = 0; i < NB; ++i) |
||||
{ |
||||
float32_t v1 = lfo1.process(); |
||||
float32_t v2 = lfo2.process(); |
||||
|
||||
max_delta = std::max(max_delta, std::abs(v1 - v2)); |
||||
} |
||||
EXPECT_GT(epsilon, max_delta); |
||||
} |
||||
|
||||
TEST(CppOptimization, FastLFOPrecisionTest) |
||||
{ |
||||
const float32_t freq = 0.15f; |
||||
const size_t NB = static_cast<size_t>(2.0f * SAMPLING_FREQUENCY); |
||||
|
||||
const float32_t epsilon = 1e-3; |
||||
|
||||
ComplexLFO lfo1(SAMPLING_FREQUENCY, 0.0f, 10.0f); |
||||
FastLFO lfo2(SAMPLING_FREQUENCY, 0.0f, 10.0f); |
||||
lfo1.setFrequency(freq); |
||||
lfo2.setFrequency(freq); |
||||
float32_t max_delta = 0.0f; |
||||
for(size_t i = 0; i < NB; ++i) |
||||
{ |
||||
float32_t v1 = lfo1.process(); |
||||
float32_t v2 = lfo2.process(); |
||||
|
||||
max_delta = std::max(max_delta, std::abs(v1 - v2)); |
||||
} |
||||
// EXPECT_GT(epsilon, max_delta);
|
||||
} |
@ -0,0 +1,132 @@ |
||||
#include "test_fx_helper.h" |
||||
|
||||
#include <iostream> |
||||
#include <filesystem> |
||||
|
||||
std::string getScenarioName(int scenario) |
||||
{ |
||||
std::stringstream ss; |
||||
|
||||
bool fxTube = Active(scenario, FXSwitch::FX__Tube); |
||||
bool fxChorus = Active(scenario, FXSwitch::FX__Chorus); |
||||
bool fxPhaser = Active(scenario, FXSwitch::FX__Phaser); |
||||
bool fxOrbitone = Active(scenario, FXSwitch::FX__Orbitone); |
||||
bool fxFlanger = Active(scenario, FXSwitch::FX__Flanger); |
||||
bool fxDelay = Active(scenario, FXSwitch::FX__Delay); |
||||
bool fxShimmer = Active(scenario, FXSwitch::FX__ShimmerReverb); |
||||
bool fxReverb = Active(scenario, FXSwitch::FX__PlateReverb); |
||||
bool first = true; |
||||
|
||||
ss << "[ "; |
||||
|
||||
if(fxTube)
|
||||
{ |
||||
if(!first) ss << ", "; |
||||
ss << "Tube"; |
||||
first = false; |
||||
} |
||||
|
||||
if(fxChorus)
|
||||
{ |
||||
if(!first) ss << ", "; |
||||
ss << "Chrs"; |
||||
first = false; |
||||
} |
||||
|
||||
if(fxPhaser)
|
||||
{ |
||||
if(!first) ss << ", "; |
||||
ss << "Phsr"; |
||||
first = false; |
||||
} |
||||
|
||||
if(fxOrbitone)
|
||||
{ |
||||
if(!first) ss << ", "; |
||||
ss << "Orbt"; |
||||
first = false; |
||||
} |
||||
|
||||
if(fxFlanger)
|
||||
{ |
||||
if(!first) ss << ", "; |
||||
ss << "Flgr"; |
||||
first = false; |
||||
} |
||||
|
||||
if(fxDelay)
|
||||
{ |
||||
if(!first) ss << ", "; |
||||
ss << "Dely"; |
||||
first = false; |
||||
} |
||||
|
||||
if(fxReverb)
|
||||
{ |
||||
if(!first) ss << ", "; |
||||
ss << "Revb"; |
||||
first = false; |
||||
} |
||||
|
||||
if(fxShimmer)
|
||||
{ |
||||
if(!first) ss << ", "; |
||||
ss << "Shim"; |
||||
first = false; |
||||
} |
||||
|
||||
ss << " ]"; |
||||
|
||||
return ss.str(); |
||||
} |
||||
|
||||
|
||||
void setupOuputStreamForCSV(std::ostream& out) |
||||
{ |
||||
struct comma_separator : std::numpunct<char> |
||||
{ |
||||
virtual char do_decimal_point() const override { return ','; } |
||||
}; |
||||
|
||||
out.imbue(std::locale(out.getloc(), new comma_separator)); |
||||
out << std::fixed << std::showpoint; |
||||
} |
||||
|
||||
bool createFolderStructure(std::string& path) |
||||
{ |
||||
try |
||||
{ |
||||
std::filesystem::path file_path(path); |
||||
if(!std::filesystem::exists(file_path.parent_path())) |
||||
{ |
||||
std::filesystem::create_directories(file_path.parent_path()); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
catch(const std::exception& e) |
||||
{ |
||||
std::cerr << e.what() << '\n'; |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
std::string getResultFile(const std::string& filename, bool createPath) |
||||
{ |
||||
std::string f = std::string(OUTPUT_FOLDER) + "/" + filename; |
||||
if(createPath) |
||||
{ |
||||
createFolderStructure(f); |
||||
} |
||||
|
||||
return f; |
||||
} |
||||
|
||||
float32_t getRandomValue() |
||||
{ |
||||
static std::random_device rd; |
||||
static std::mt19937 gen(rd()); |
||||
static std::uniform_real_distribution<float32_t> dist(-1.0f, 1.0f); |
||||
|
||||
return dist(gen); |
||||
} |
@ -0,0 +1,38 @@ |
||||
#pragma once |
||||
|
||||
#include <random> |
||||
#include <string> |
||||
#include <gtest/gtest.h> |
||||
|
||||
#include "../fx.h" |
||||
|
||||
#define AUDIO_SOURCE_FILE "test.wav" |
||||
|
||||
#define SAMPLING_FREQUENCY 44100.0f |
||||
|
||||
#define Active(scenarioKey, FxID) ((scenarioKey & (1 << FxID)) == (1 << FxID)) |
||||
|
||||
std::string getScenarioName(int scenario); |
||||
|
||||
enum FXSwitch |
||||
{ |
||||
FX__Tube = 0, |
||||
FX__Chorus, |
||||
FX__Flanger, |
||||
FX__Orbitone, |
||||
FX__Phaser, |
||||
FX__Delay, |
||||
FX__ShimmerReverb, |
||||
FX__PlateReverb, |
||||
__kFXCount |
||||
}; |
||||
|
||||
void setupOuputStreamForCSV(std::ostream& out); |
||||
|
||||
bool createFolderStructure(std::string& path); |
||||
|
||||
std::string getResultFile(const std::string& filename, bool createPath); |
||||
|
||||
float32_t getRandomValue(); |
||||
|
||||
class FXScenarioTest : public testing::TestWithParam<int> {}; |
@ -0,0 +1,117 @@ |
||||
#include <gtest/gtest.h> |
||||
#include <cmath> |
||||
|
||||
#include "test_fx_helper.h" |
||||
#include "wave.h" |
||||
|
||||
#include "../fx_rack.h" |
||||
#include "../effect_platervbstereo.h" |
||||
|
||||
using namespace std; |
||||
|
||||
#define MAX_SVF_SAMPLES 10000000 |
||||
#define MAX_NB_ERRORS 100 |
||||
|
||||
void setupRack(FXRack* rack, int scenario) |
||||
{ |
||||
rack->setWetLevel(1.0f); |
||||
|
||||
rack->getTube()->setEnable(Active(scenario, FXSwitch::FX__Tube)); |
||||
rack->getTube()->setWetLevel(0.25f); |
||||
rack->getTube()->setOverdrive(0.25f); |
||||
|
||||
rack->getChorus()->setEnable(Active(scenario, FXSwitch::FX__Chorus)); |
||||
rack->getChorus()->setWetLevel(0.5f); |
||||
rack->getChorus()->setRate(0.4f); |
||||
rack->getChorus()->setDepth(0.5f); |
||||
|
||||
rack->getFlanger()->setEnable(Active(scenario, FXSwitch::FX__Flanger)); |
||||
rack->getFlanger()->setWetLevel(0.5f); |
||||
rack->getFlanger()->setRate(0.03f); |
||||
rack->getFlanger()->setDepth(0.75f); |
||||
rack->getFlanger()->setFeedback(0.5f); |
||||
|
||||
rack->getOrbitone()->setEnable(Active(scenario, FXSwitch::FX__Orbitone)); |
||||
rack->getOrbitone()->setWetLevel(0.8f); |
||||
rack->getOrbitone()->setRate(0.4f); |
||||
rack->getOrbitone()->setDepth(0.5f); |
||||
|
||||
rack->getPhaser()->setEnable(Active(scenario, FXSwitch::FX__Phaser)); |
||||
rack->getPhaser()->setWetLevel(1.0f); |
||||
rack->getPhaser()->setRate(0.1f); |
||||
rack->getPhaser()->setDepth(1.0f); |
||||
rack->getPhaser()->setFeedback(0.5f); |
||||
rack->getPhaser()->setNbStages(12); |
||||
|
||||
rack->getDelay()->setEnable(Active(scenario, FXSwitch::FX__Delay)); |
||||
rack->getDelay()->setWetLevel(0.6f); |
||||
rack->getDelay()->setLeftDelayTime(0.15f); |
||||
rack->getDelay()->setLeftDelayTime(0.2f); |
||||
rack->getDelay()->setFeedback(0.35f); |
||||
rack->getDelay()->setFlutterRate(0.0f); |
||||
rack->getDelay()->setFlutterAmount(0.0f); |
||||
|
||||
rack->getShimmerReverb()->setEnable(Active(scenario, FXSwitch::FX__ShimmerReverb)); |
||||
rack->getShimmerReverb()->setWetLevel(0.5f); |
||||
rack->getShimmerReverb()->setInputGain(0.35f); |
||||
rack->getShimmerReverb()->setTime(0.89f); |
||||
rack->getShimmerReverb()->setDiffusion(0.75f); |
||||
rack->getShimmerReverb()->setLP(0.8f); |
||||
} |
||||
|
||||
TEST_P(FXScenarioTest, FXRackResetAllScenarios) |
||||
{ |
||||
FXRack *rack = new FXRack(SAMPLING_FREQUENCY); |
||||
|
||||
int fxSwitch = this->GetParam(); |
||||
rack->setEnable(true); |
||||
setupRack(rack, fxSwitch); |
||||
rack->reset(); |
||||
|
||||
delete rack; |
||||
} |
||||
|
||||
TEST_P(FXScenarioTest, ScenarioProcessing) |
||||
{ |
||||
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 unsigned nbRepeats = 1; |
||||
size_t size; |
||||
float32_t** samples = readWaveFile(AUDIO_SOURCE_FILE, size); |
||||
float32_t* sampleOutL = new float32_t[size * nbRepeats]; |
||||
float32_t* sampleOutR = new float32_t[size * nbRepeats]; |
||||
memset(sampleOutL, 0, size * nbRepeats * sizeof(float32_t)); |
||||
memset(sampleOutR, 0, size * nbRepeats * sizeof(float32_t)); |
||||
|
||||
FXRack *rack = new FXRack(SAMPLING_FREQUENCY); |
||||
|
||||
int fxSwitch = this->GetParam(); |
||||
rack->setEnable(true); |
||||
setupRack(rack, fxSwitch); |
||||
rack->reset(); |
||||
|
||||
string name = getScenarioName(fxSwitch); |
||||
|
||||
for(unsigned i = 0; i < nbRepeats; ++i) |
||||
{ |
||||
rack->process(samples[0], samples[1], sampleOutL + i * size, sampleOutR + i * size, size); |
||||
} |
||||
|
||||
stringstream ss; |
||||
ss << full_test_name << "-fx-rack" << name << ".wav"; |
||||
saveWaveFile(getResultFile(ss.str(), true), sampleOutL, sampleOutR, nbRepeats * size, static_cast<unsigned>(SAMPLING_FREQUENCY), 16); |
||||
|
||||
delete[] samples[0]; |
||||
delete[] samples[1]; |
||||
delete[] samples; |
||||
|
||||
delete[] sampleOutL; |
||||
delete[] sampleOutR; |
||||
|
||||
delete rack; |
||||
} |
||||
|
||||
INSTANTIATE_TEST_SUITE_P(FXRack, FXScenarioTest, testing::Range(0, 1 << (FXSwitch::FX__ShimmerReverb + 1))); |
Loading…
Reference in new issue