|
|
|
@ -2,6 +2,7 @@ |
|
|
|
|
#include <iomanip> |
|
|
|
|
#include <iostream> |
|
|
|
|
#include <fstream> |
|
|
|
|
#include <string> |
|
|
|
|
|
|
|
|
|
#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<size_t>(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); |
|
|
|
|
} |
|
|
|
|