From 67ea23cfa86469dd1debc4fcbb8602960c9748fb Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Sat, 20 Nov 2021 20:57:07 +0100 Subject: [PATCH 1/8] fix broken firmware launch config --- .vscode/launch.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 606ba37..48f740f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,15 +11,15 @@ "cwd": "${workspaceRoot}", "environment": [], "externalConsole": false, - "debugServerArgs": "-f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f target/stm32h7x.cfg -c init -c \"reset init\"", + "debugServerArgs": "-f interface/stlink.cfg -f target/stm32h7x.cfg -c init -c \"reset init\"", "serverLaunchTimeout": 20000, "filterStderr": true, "filterStdout": false, "serverStarted": "target halted due to debug-request, current mode: Thread", - "preLaunchTask": "build-TapeLooper-debug", + "preLaunchTask": "build firmware", "setupCommands": [ { "text": "-target-select remote localhost:3333", "description": "connect to target", "ignoreFailures": false }, - { "text": "-file-exec-and-symbols ${workspaceRoot}/build/TapeLooper.elf", "description": "load file", "ignoreFailures": false}, + { "text": "-file-exec-and-symbols ${workspaceRoot}/firmware/build/TapeLooper.elf", "description": "load file", "ignoreFailures": false}, { "text": "-interpreter-exec console \"monitor endian little\"", "ignoreFailures": false }, { "text": "-interpreter-exec console \"monitor reset\"", "ignoreFailures": false }, { "text": "-interpreter-exec console \"monitor halt\"", "ignoreFailures": false }, @@ -40,7 +40,7 @@ }, "osx": { "MIMode": "gdb", - "MIDebuggerPath": "/Users/johannes/dev/gcc-arm-none-eabi-9-2020-q2-update/bin/arm-none-eabi-gdb", + "MIDebuggerPath": "/Users/johanneselliesen/dev/gcc-arm-none-eabi-9-2020-q2-update/bin/arm-none-eabi-gdb", "debugServerPath": "openocd" }, "windows": { From f778b1db1dde8067cb18e831e1dc03150f6638c7 Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Sat, 20 Nov 2021 20:57:26 +0100 Subject: [PATCH 2/8] generate debug symbols in release builds --- .vscode/tasks.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9b462c9..7b54697 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -20,6 +20,8 @@ "TOOLCHAIN_PREFIX=\"${env:HOME}/dev/gcc-arm-none-eabi-9-2020-q2-update\"", "-D", "CMAKE_TOOLCHAIN_FILE=\"${workspaceRoot}/lib/libDaisy/cmake/toolchains/stm32h750xx.cmake\"", + "-D", + "CMAKE_BUILD_TYPE=RelWithDebInfo", "-S", "firmware", "-B", @@ -39,6 +41,8 @@ "TOOLCHAIN_PREFIX=\\\"C:/Program Files (x86)/GNU Arm Embedded Toolchain/9 2020-q2-update\\\"", "-D", "CMAKE_TOOLCHAIN_FILE=\\\"${workspaceRoot}/lib/libDaisy/cmake/toolchains/stm32h750xx.cmake\\\"", + "-D", + "CMAKE_BUILD_TYPE=RelWithDebInfo", "-S", "firmware", "-B", From 41f9b0970d48ff22f70872aecf5dff7b5016785a Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Sat, 20 Nov 2021 20:59:02 +0100 Subject: [PATCH 3/8] add loopers to firmware for load testing --- dsp/src/dsp/AudioBuffer.h | 2 +- dsp/src/dsp/TapeLooper.h | 2 +- dsp/src/util/Memory.h | 1 + firmware/src/constants.h | 6 ++ firmware/src/main.cpp | 72 +++++++++++++++++++---- firmware/src/util/LateInitializedObject.h | 29 +++++++++ 6 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 firmware/src/util/LateInitializedObject.h diff --git a/dsp/src/dsp/AudioBuffer.h b/dsp/src/dsp/AudioBuffer.h index 26eb9c6..6a74452 100644 --- a/dsp/src/dsp/AudioBuffer.h +++ b/dsp/src/dsp/AudioBuffer.h @@ -39,7 +39,7 @@ class AudioBufferPtr AudioBufferPtr subBlock(size_t startSample, size_t length = size_t(-1)) const { - const auto resultMaxLength = std::max(size_ - startSample, 0ul); + const auto resultMaxLength = std::max(size_ - startSample, size_t(0)); const auto resultLength = std::min(resultMaxLength, length); AudioBufferPtr result(resultLength); for (size_t ch = 0; ch < numChannels; ch++) diff --git a/dsp/src/dsp/TapeLooper.h b/dsp/src/dsp/TapeLooper.h index c8bef04..b526a75 100644 --- a/dsp/src/dsp/TapeLooper.h +++ b/dsp/src/dsp/TapeLooper.h @@ -30,7 +30,7 @@ class LooperStorage : public LooperStoragePtr for (size_t ch = 0; ch < numChannels; ch++) { storage_[ch].fill(0.0f); - this->data[ch] = storage_[ch]; + this->data[ch] = storage_[ch].data(); } this->numSamples = size; } diff --git a/dsp/src/util/Memory.h b/dsp/src/util/Memory.h index 2a6f3e5..1c9e73f 100644 --- a/dsp/src/util/Memory.h +++ b/dsp/src/util/Memory.h @@ -1,6 +1,7 @@ #pragma once #include +#include /** * Represents a fixed size chunk of memory to which data can be written. diff --git a/firmware/src/constants.h b/firmware/src/constants.h index dd1f268..5160428 100644 --- a/firmware/src/constants.h +++ b/firmware/src/constants.h @@ -7,3 +7,9 @@ constexpr daisy::SaiHandle::Config::SampleRate sampleRate = daisy::SaiHandle::Co constexpr uint8_t blockSize = 48; constexpr uint16_t sampleRateHz = 48000; +constexpr uint8_t numChannelsPerLooper = 2; +constexpr uint8_t numLoopers = 4; + +constexpr size_t sdramSize = 64 * 1024 * 1024; +constexpr size_t totalLooperMemorySize = sdramSize - 256; +constexpr size_t looperSamplesPerChannel = totalLooperMemorySize / numChannelsPerLooper / numLoopers / sizeof(float); diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index 37bb8de..2148439 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -8,6 +8,8 @@ #include "hardware/Leds.h" #include "hardware/Pots.h" #include "ui/UiBasePage.h" +#include "dsp/TapeLooper.h" +#include "util/LateInitializedObject.h" #define EXTERNAL_SDRAM_SECTION __attribute__((section(".sdram_bss"))) @@ -37,7 +39,12 @@ PeakMeter peakMeterOutL; PeakMeter peakMeterOutR; // dsp static objects -// TODO +#define EXTERNAL_SDRAM_SECTION __attribute__((section(".sdram_bss"))) +using LooperType = TapeLooper; +using LooperStorageType = LooperStorage; + +std::array, numLoopers> EXTERNAL_SDRAM_SECTION looperStorages = {}; +std::array, numLoopers> loopers; // misc daisy::CpuLoadMeter cpuLoadMeter; @@ -89,6 +96,28 @@ void initUiPages() ui.OpenPage(basePage); } +// =================================================================== +// DSP Init +// =================================================================== + +void initDsp() +{ + for (size_t l = 0; l < numLoopers; l++) + { + looperStorages[l].create(); + loopers[l].create(*looperStorages[l]); + } + + // init peak meters + peakMeterInL.init(0.5f); + peakMeterInR.init(0.5f); + peakMeterOutL.init(0.5f); + peakMeterOutR.init(0.5f); + + // init CPU load meter + cpuLoadMeter.Init(seed.AudioSampleRate(), seed.AudioBlockSize()); +} + // =================================================================== // =================================================================== @@ -98,9 +127,9 @@ void configureHardware() // These are separate to allow reconfiguration of any of the internal // components before initialization. seed.Configure(); + seed.Init(true /* enable 480MHz boost */); seed.SetAudioBlockSize(blockSize); seed.SetAudioSampleRate(sampleRate); - seed.Init(true /* enable 480MHz boost */); potReader.init(); buttonReader.init(); @@ -133,7 +162,24 @@ void audioCallback(const float* const* in, float** out, size_t size) peakMeterInL.readPeaks(in[0]); peakMeterInR.readPeaks(in[1]); - // TODO: add processing here + AudioBufferPtr inputs(in, size); + AudioBufferPtr outputs(out, size); + outputs.fill(0.0f); + for (size_t l = 0; l < numLoopers; l++) + { + loopers[l]->process( + 4.0f, // speed + 1.0f, // wow & flutter amt + Direction::forwards, + { + 0.5f, // drive amt + 0.5f // grain amt + }, + 1.0f, // pre gain + 1.0f, // post gain + inputs, + outputs); + } // peak meters peakMeterOutL.readPeaks(out[0]); @@ -143,6 +189,9 @@ void audioCallback(const float* const* in, float** out, size_t size) // TODO cpuLoadMeter.OnBlockEnd(); + // Set breakpoint here to check load + const auto load = cpuLoadMeter.GetAvgCpuLoad(); + (void) load; } int main(void) @@ -159,22 +208,21 @@ int main(void) buttonDoubleClickTimeoutMs, retriggerTimeoutMs, retriggerPeriodMs); - // init UI + initUi(); initUiPages(); - // init peak meters - peakMeterInL.init(0.5f); - peakMeterInR.init(0.5f); - peakMeterOutL.init(0.5f); - peakMeterOutR.init(0.5f); - - // init CPU load meter - cpuLoadMeter.Init(seed.AudioSampleRate(), seed.AudioBlockSize()); + initDsp(); // start audio seed.StartAudio(&audioCallback); + for (size_t l = 0; l < numLoopers; l++) + loopers[l]->switchState(LooperState::recording); + seed.system.Delay(200); + for (size_t l = 0; l < numLoopers; l++) + loopers[l]->switchState(LooperState::playing); + // UI loop for (;;) { diff --git a/firmware/src/util/LateInitializedObject.h b/firmware/src/util/LateInitializedObject.h new file mode 100644 index 0000000..f1d05f6 --- /dev/null +++ b/firmware/src/util/LateInitializedObject.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include +#include + +template +class LateInitializedObject +{ +public: + LateInitializedObject() : + object_(nullptr) + { + } + + template + void create(Args&&... args) + { + object_ = new (::std::addressof(storage_)) T(std::forward(args)...); + } + + operator T*() { return object_; } + operator const T*() const { return object_; } + T* operator->() { return object_; } + const T* operator->() const { return object_; } + +private: + typename std::aligned_storage::type storage_; + T* object_; +}; \ No newline at end of file From 8eebd92a0fcd91030fc6e1b7babbcaa96d470339 Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Sat, 20 Nov 2021 21:06:36 +0100 Subject: [PATCH 4/8] remove pre gain (can be added to processor if required) --- dsp/src/dsp/Player.h | 9 +- dsp/src/dsp/TapeLooper.h | 2 - dsp/tests/Player_gtest.cpp | 568 ++++++++++++------------------- firmware/src/main.cpp | 1 - plugin/src/TapeLooperProcessor.h | 1 - 5 files changed, 225 insertions(+), 356 deletions(-) diff --git a/dsp/src/dsp/Player.h b/dsp/src/dsp/Player.h index 2f90716..607acc6 100644 --- a/dsp/src/dsp/Player.h +++ b/dsp/src/dsp/Player.h @@ -33,7 +33,6 @@ class Player { processor_.reset(); speedModulator_.reset(); - preGainSmoother_.reset(0); postGainSmoother_.reset(0); speedSmoother_.reset(0); playbackLength_ = 0; @@ -69,18 +68,14 @@ class Player void process(float paramSpeed, float speedModulationAmt, Direction direction, - float paramPreProcessorGain, float paramPostProcessorGain, const typename ProcessorType::Parameters& processorParameters, AudioBufferPtr outputToAddTo, - ExponentialSmoother::TimeConstant preGainSmootherTimeConstant = - ExponentialSmoother::TimeConstant(0.05f, sampleRateHz, 1), ExponentialSmoother::TimeConstant postGainSmootherTimeConstant = ExponentialSmoother::TimeConstant(0.05f, sampleRateHz, 1), ExponentialSmoother::TimeConstant speedSmootherTimeConstant = ExponentialSmoother::TimeConstant(0.5f, sampleRateHz, 1)) { - const auto preGainTarget = paramPreProcessorGain; const auto postGainTarget = (isPlaying_) ? paramPostProcessorGain : 0.0f; const auto speedTarget = limit(paramSpeed, minSpeed_, maxSpeed_); @@ -89,7 +84,6 @@ class Player for (size_t i = 0; i < outputToAddTo.size_; i++) { - const auto preGain = preGainSmoother_.smooth(preGainTarget, preGainSmootherTimeConstant); const auto postGain = postGainSmoother_.smooth(postGainTarget, postGainSmootherTimeConstant); const auto speedModulation = speedModulator_.getAndAdvance() * speedModulationAmt; const auto speed = speedModulation + speedSmoother_.smooth(speedTarget, speedSmootherTimeConstant); @@ -114,7 +108,7 @@ class Player for (size_t ch = 0; ch < numChannels; ch++) { interpolationBuffer_[1][ch] = interpolationBuffer_[0][ch]; - interpolationBuffer_[0][ch] = sampleBuffer_[ch][indexToRead] * preGain; + interpolationBuffer_[0][ch] = sampleBuffer_[ch][indexToRead]; } processor_.process(interpolationBuffer_[0].data(), processorParameters); } @@ -156,7 +150,6 @@ class Player return value; } - ExponentialSmoother preGainSmoother_; ExponentialSmoother postGainSmoother_; ExponentialSmoother speedSmoother_; diff --git a/dsp/src/dsp/TapeLooper.h b/dsp/src/dsp/TapeLooper.h index b526a75..16411c6 100644 --- a/dsp/src/dsp/TapeLooper.h +++ b/dsp/src/dsp/TapeLooper.h @@ -100,7 +100,6 @@ class TapeLooper float wowAndFlutterAmt, Direction direction, const typename ProcessorType::Parameters& processorParameters, - float paramPreGain, float paramPostGain, AudioBufferPtr input, AudioBufferPtr outputToAddTo) @@ -109,7 +108,6 @@ class TapeLooper player_.process(paramSpeed, mappedWowAndFlutterAmt * maxWowAndFlutterAmt_, direction, - paramPreGain, paramPostGain, processorParameters, outputToAddTo); diff --git a/dsp/tests/Player_gtest.cpp b/dsp/tests/Player_gtest.cpp index c174651..c744561 100644 --- a/dsp/tests/Player_gtest.cpp +++ b/dsp/tests/Player_gtest.cpp @@ -110,7 +110,6 @@ TEST_F(DSP_Player, b_reset) TEST_F(DSP_Player, c_playForwardsNormalSpeed) { - const auto expectedPreGain = 0.6734258f; const auto expectedPostGain = 0.89563f; const auto numSamplesToPlay = 2 * numSamples_; @@ -142,21 +141,17 @@ TEST_F(DSP_Player, c_playForwardsNormalSpeed) player_.process(1.0f, // speed 0.0f, // speed modulation amount Direction::forwards, - expectedPreGain, expectedPostGain, { 0.0f }, // processor parameters outputBuffer.subBlock(0, numSamplesToPlay / 2 + 1), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant player_.process(1.0f, // speed 0.0f, // speed modulation amount Direction::forwards, - expectedPreGain, expectedPostGain, { 1.0f }, // processor parameters (changed this time) outputBuffer.subBlock(numSamplesToPlay / 2 + 1), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant @@ -164,32 +159,32 @@ TEST_F(DSP_Player, c_playForwardsNormalSpeed) std::array, numChannels_> expectedProcessorCallArgs_input = { // left channel std::vector( - { 1.0f * expectedPreGain, - 2.0f * expectedPreGain, - 3.0f * expectedPreGain, - 4.0f * expectedPreGain, - 5.0f * expectedPreGain, - 1.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 2.0f * expectedPreGain, - 3.0f * expectedPreGain, - 4.0f * expectedPreGain, - 5.0f * expectedPreGain, // last sample of second buffer + { 1.0f, + 2.0f, + 3.0f, + 4.0f, + 5.0f, + 1.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 2.0f, + 3.0f, + 4.0f, + 5.0f, // last sample of second buffer // this is the additonal sample from the linear interpolation - 1.0f * expectedPreGain }), + 1.0f }), // right channel std::vector( - { 101.0f * expectedPreGain, - 102.0f * expectedPreGain, - 103.0f * expectedPreGain, - 104.0f * expectedPreGain, - 105.0f * expectedPreGain, - 101.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 102.0f * expectedPreGain, - 103.0f * expectedPreGain, - 104.0f * expectedPreGain, - 105.0f * expectedPreGain, // last sample of second buffer + { 101.0f, + 102.0f, + 103.0f, + 104.0f, + 105.0f, + 101.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 102.0f, + 103.0f, + 104.0f, + 105.0f, // last sample of second buffer // this is the additonal sample from the linear interpolation - 101.0f * expectedPreGain }) + 101.0f }) }; EXPECT_EQ(processCallArgs_input, expectedProcessorCallArgs_input); // expect correct parameters to be passed to the processor @@ -213,35 +208,34 @@ TEST_F(DSP_Player, c_playForwardsNormalSpeed) std::array, 2> expectedOutputSamples = { // left channel std::vector( - { (100 + 1 * expectedPreGain) * expectedPostGain, - (100 + 2 * expectedPreGain) * expectedPostGain, - (100 + 3 * expectedPreGain) * expectedPostGain, - (100 + 4 * expectedPreGain) * expectedPostGain, - (100 + 5 * expectedPreGain) * expectedPostGain, - (100 + 1 * expectedPreGain) * expectedPostGain, // this is where the buffer wrapped around - (100 + 2 * expectedPreGain) * expectedPostGain, - (100 + 3 * expectedPreGain) * expectedPostGain, - (100 + 4 * expectedPreGain) * expectedPostGain, - (100 + 5 * expectedPreGain) * expectedPostGain }), + { (100 + 1) * expectedPostGain, + (100 + 2) * expectedPostGain, + (100 + 3) * expectedPostGain, + (100 + 4) * expectedPostGain, + (100 + 5) * expectedPostGain, + (100 + 1) * expectedPostGain, // this is where the buffer wrapped around + (100 + 2) * expectedPostGain, + (100 + 3) * expectedPostGain, + (100 + 4) * expectedPostGain, + (100 + 5) * expectedPostGain }), // right channel std::vector( - { (100 + 101 * expectedPreGain) * expectedPostGain, - (100 + 102 * expectedPreGain) * expectedPostGain, - (100 + 103 * expectedPreGain) * expectedPostGain, - (100 + 104 * expectedPreGain) * expectedPostGain, - (100 + 105 * expectedPreGain) * expectedPostGain, - (100 + 101 * expectedPreGain) * expectedPostGain, // this is where the buffer wrapped around - (100 + 102 * expectedPreGain) * expectedPostGain, - (100 + 103 * expectedPreGain) * expectedPostGain, - (100 + 104 * expectedPreGain) * expectedPostGain, - (100 + 105 * expectedPreGain) * expectedPostGain }) + { (100 + 101) * expectedPostGain, + (100 + 102) * expectedPostGain, + (100 + 103) * expectedPostGain, + (100 + 104) * expectedPostGain, + (100 + 105) * expectedPostGain, + (100 + 101) * expectedPostGain, // this is where the buffer wrapped around + (100 + 102) * expectedPostGain, + (100 + 103) * expectedPostGain, + (100 + 104) * expectedPostGain, + (100 + 105) * expectedPostGain }) }; EXPECT_EQ(toArrOfVecs(outputBuffer), expectedOutputSamples); } TEST_F(DSP_Player, d_playForwardsHalfSpeed) { - const auto expectedPreGain = 0.6734258f; const auto expectedPostGain = 0.89563f; const auto numSamplesToPlay = 2 * numSamples_; @@ -273,21 +267,17 @@ TEST_F(DSP_Player, d_playForwardsHalfSpeed) player_.process(0.5f, // speed 0.0f, // speed modulation amount Direction::forwards, - expectedPreGain, expectedPostGain, { 0.0f }, // processor params outputBuffer.subBlock(0, numSamplesToPlay / 2 + 1), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant player_.process(0.5f, // speed 0.0f, // speed modulation amount Direction::forwards, - expectedPreGain, expectedPostGain, { 1.0f }, // processor params (changed this time) outputBuffer.subBlock(numSamplesToPlay / 2 + 1), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant @@ -296,22 +286,22 @@ TEST_F(DSP_Player, d_playForwardsHalfSpeed) std::array, numChannels_> expectedProcessorCallArgs_input = { // left channel std::vector( - { 1.0f * expectedPreGain, - 2.0f * expectedPreGain, - 3.0f * expectedPreGain, - 4.0f * expectedPreGain, - 5.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + { 1.0f, + 2.0f, + 3.0f, + 4.0f, + 5.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) // this is the additonal sample from the linear interpolation - 1.0f * expectedPreGain }), + 1.0f }), // right channel std::vector( - { 101.0f * expectedPreGain, - 102.0f * expectedPreGain, - 103.0f * expectedPreGain, - 104.0f * expectedPreGain, - 105.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + { 101.0f, + 102.0f, + 103.0f, + 104.0f, + 105.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) // this is the additonal sample from the linear interpolation - 101.0f * expectedPreGain }) + 101.0f }) }; EXPECT_EQ(processCallArgs_input, expectedProcessorCallArgs_input); // expect correct parameters to be passed to the processor @@ -330,30 +320,30 @@ TEST_F(DSP_Player, d_playForwardsHalfSpeed) // left channel std::vector( { - (100 + 1.0f * expectedPreGain) * expectedPostGain, - (100 + 1.5f * expectedPreGain) * expectedPostGain, // interpolated between 1.0f and 2.0f due to half speed - (100 + 2.0f * expectedPreGain) * expectedPostGain, - (100 + 2.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 3.0f * expectedPreGain) * expectedPostGain, - (100 + 3.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 4.0f * expectedPreGain) * expectedPostGain, - (100 + 4.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 5.0f * expectedPreGain) * expectedPostGain, - (100 + 3.0f * expectedPreGain) * expectedPostGain // interpolated between 5.0f and 1.0f + (100 + 1.0f) * expectedPostGain, + (100 + 1.5f) * expectedPostGain, // interpolated between 1.0f and 2.0f due to half speed + (100 + 2.0f) * expectedPostGain, + (100 + 2.5f) * expectedPostGain, // interpolated + (100 + 3.0f) * expectedPostGain, + (100 + 3.5f) * expectedPostGain, // interpolated + (100 + 4.0f) * expectedPostGain, + (100 + 4.5f) * expectedPostGain, // interpolated + (100 + 5.0f) * expectedPostGain, + (100 + 3.0f) * expectedPostGain // interpolated between 5.0f and 1.0f }), // right channel std::vector( { - (100 + 101.0f * expectedPreGain) * expectedPostGain, - (100 + 101.5f * expectedPreGain) * expectedPostGain, // interpolated between 101.0f and 102.0f due to half speed - (100 + 102.0f * expectedPreGain) * expectedPostGain, - (100 + 102.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 103.0f * expectedPreGain) * expectedPostGain, - (100 + 103.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 104.0f * expectedPreGain) * expectedPostGain, - (100 + 104.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 105.0f * expectedPreGain) * expectedPostGain, - (100 + 103.0f * expectedPreGain) * expectedPostGain // interpolated between 105.0f and 101.0f + (100 + 101.0f) * expectedPostGain, + (100 + 101.5f) * expectedPostGain, // interpolated between 101.0f and 102.0f due to half speed + (100 + 102.0f) * expectedPostGain, + (100 + 102.5f) * expectedPostGain, // interpolated + (100 + 103.0f) * expectedPostGain, + (100 + 103.5f) * expectedPostGain, // interpolated + (100 + 104.0f) * expectedPostGain, + (100 + 104.5f) * expectedPostGain, // interpolated + (100 + 105.0f) * expectedPostGain, + (100 + 103.0f) * expectedPostGain // interpolated between 105.0f and 101.0f }) }; EXPECT_EQ(toArrOfVecs(outputBuffer), expectedOutputSamples); @@ -361,7 +351,6 @@ TEST_F(DSP_Player, d_playForwardsHalfSpeed) TEST_F(DSP_Player, e_playForwardsDoubleSpeed) { - const auto expectedPreGain = 0.6734258f; const auto expectedPostGain = 0.89563f; const auto numSamplesToPlay = 6; @@ -393,21 +382,17 @@ TEST_F(DSP_Player, e_playForwardsDoubleSpeed) player_.process(2.0f, // speed 0.0f, // speed modulation amount Direction::forwards, - expectedPreGain, expectedPostGain, { 0.0f }, // processor params outputBuffer.subBlock(0, numSamplesToPlay / 2 + 1), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant player_.process(2.0f, // speed 0.0f, // speed modulation amount Direction::forwards, - expectedPreGain, expectedPostGain, { 1.0f }, // processor params (changed this time) outputBuffer.subBlock(numSamplesToPlay / 2 + 1), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant @@ -416,34 +401,34 @@ TEST_F(DSP_Player, e_playForwardsDoubleSpeed) std::array, numChannels_> expectedProcessorCallArgs_input = { // left channel std::vector( - { 1.0f * expectedPreGain, - 2.0f * expectedPreGain, - 3.0f * expectedPreGain, - 4.0f * expectedPreGain, - 5.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 1.0f * expectedPreGain, - 2.0f * expectedPreGain, - 3.0f * expectedPreGain, - 4.0f * expectedPreGain, - 5.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 1.0f * expectedPreGain, + { 1.0f, + 2.0f, + 3.0f, + 4.0f, + 5.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 1.0f, + 2.0f, + 3.0f, + 4.0f, + 5.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 1.0f, // this is the additonal sample from the linear interpolation - 2.0f * expectedPreGain }), + 2.0f }), // right channel std::vector( - { 101.0f * expectedPreGain, - 102.0f * expectedPreGain, - 103.0f * expectedPreGain, - 104.0f * expectedPreGain, - 105.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 101.0f * expectedPreGain, - 102.0f * expectedPreGain, - 103.0f * expectedPreGain, - 104.0f * expectedPreGain, - 105.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 101.0f * expectedPreGain, + { 101.0f, + 102.0f, + 103.0f, + 104.0f, + 105.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 101.0f, + 102.0f, + 103.0f, + 104.0f, + 105.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 101.0f, // this is the additonal sample from the linear interpolation - 102.0f * expectedPreGain }) + 102.0f }) }; EXPECT_EQ(processCallArgs_input, expectedProcessorCallArgs_input); // expect correct parameters to be passed to the processor @@ -467,27 +452,26 @@ TEST_F(DSP_Player, e_playForwardsDoubleSpeed) std::array, numChannels_> expectedOutputSamples = { // left channel std::vector( - { (100 + 1.0f * expectedPreGain) * expectedPostGain, - (100 + 3.0f * expectedPreGain) * expectedPostGain, - (100 + 5.0f * expectedPreGain) * expectedPostGain, - (100 + 2.0f * expectedPreGain) * expectedPostGain, - (100 + 4.0f * expectedPreGain) * expectedPostGain, - (100 + 1.0f * expectedPreGain) * expectedPostGain }), + { (100 + 1.0f) * expectedPostGain, + (100 + 3.0f) * expectedPostGain, + (100 + 5.0f) * expectedPostGain, + (100 + 2.0f) * expectedPostGain, + (100 + 4.0f) * expectedPostGain, + (100 + 1.0f) * expectedPostGain }), // right channel std::vector( - { (100 + 101.0f * expectedPreGain) * expectedPostGain, - (100 + 103.0f * expectedPreGain) * expectedPostGain, - (100 + 105.0f * expectedPreGain) * expectedPostGain, - (100 + 102.0f * expectedPreGain) * expectedPostGain, - (100 + 104.0f * expectedPreGain) * expectedPostGain, - (100 + 101.0f * expectedPreGain) * expectedPostGain }), + { (100 + 101.0f) * expectedPostGain, + (100 + 103.0f) * expectedPostGain, + (100 + 105.0f) * expectedPostGain, + (100 + 102.0f) * expectedPostGain, + (100 + 104.0f) * expectedPostGain, + (100 + 101.0f) * expectedPostGain }), }; EXPECT_EQ(toArrOfVecs(outputBuffer), expectedOutputSamples); } TEST_F(DSP_Player, f_playBackwardsNormalSpeed) { - const auto expectedPreGain = 0.6734258f; const auto expectedPostGain = 0.89563f; const auto numSamplesToPlay = 2 * numSamples_; @@ -519,21 +503,17 @@ TEST_F(DSP_Player, f_playBackwardsNormalSpeed) player_.process(1.0f, // speed 0.0f, // speed modulation amount Direction::backwards, - expectedPreGain, expectedPostGain, { 0.0f }, // processor params outputBuffer.subBlock(0, numSamplesToPlay / 2 + 1), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant player_.process(1.0f, // speed 0.0f, // speed modulation amount Direction::backwards, - expectedPreGain, expectedPostGain, { 1.0f }, // processor params (changed this time) outputBuffer.subBlock(numSamplesToPlay / 2 + 1), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant @@ -541,32 +521,32 @@ TEST_F(DSP_Player, f_playBackwardsNormalSpeed) std::array, numChannels_> expectedProcessorCallArgs_input = { // left channel std::vector( - { 5.0f * expectedPreGain, - 4.0f * expectedPreGain, - 3.0f * expectedPreGain, - 2.0f * expectedPreGain, - 1.0f * expectedPreGain, - 5.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 4.0f * expectedPreGain, - 3.0f * expectedPreGain, - 2.0f * expectedPreGain, - 1.0f * expectedPreGain, // last sample of second buffer + { 5.0f, + 4.0f, + 3.0f, + 2.0f, + 1.0f, + 5.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 4.0f, + 3.0f, + 2.0f, + 1.0f, // last sample of second buffer // this is the additonal sample from the linear interpolation - 5.0f * expectedPreGain }), + 5.0f }), // right channel std::vector( - { 105.0f * expectedPreGain, - 104.0f * expectedPreGain, - 103.0f * expectedPreGain, - 102.0f * expectedPreGain, - 101.0f * expectedPreGain, - 105.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 104.0f * expectedPreGain, - 103.0f * expectedPreGain, - 102.0f * expectedPreGain, - 101.0f * expectedPreGain, // last sample of second buffer + { 105.0f, + 104.0f, + 103.0f, + 102.0f, + 101.0f, + 105.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 104.0f, + 103.0f, + 102.0f, + 101.0f, // last sample of second buffer // this is the additonal sample from the linear interpolation - 105.0f * expectedPreGain }), + 105.0f }), }; EXPECT_EQ(processCallArgs_input, expectedProcessorCallArgs_input); // expect correct parameters to be passed to the processor @@ -590,35 +570,34 @@ TEST_F(DSP_Player, f_playBackwardsNormalSpeed) std::array, numChannels_> expectedOutputSamples = { // left channel std::vector( - { (100 + 5 * expectedPreGain) * expectedPostGain, - (100 + 4 * expectedPreGain) * expectedPostGain, - (100 + 3 * expectedPreGain) * expectedPostGain, - (100 + 2 * expectedPreGain) * expectedPostGain, - (100 + 1 * expectedPreGain) * expectedPostGain, - (100 + 5 * expectedPreGain) * expectedPostGain, // this is where the buffer wrapped around - (100 + 4 * expectedPreGain) * expectedPostGain, - (100 + 3 * expectedPreGain) * expectedPostGain, - (100 + 2 * expectedPreGain) * expectedPostGain, - (100 + 1 * expectedPreGain) * expectedPostGain }), + { (100 + 5) * expectedPostGain, + (100 + 4) * expectedPostGain, + (100 + 3) * expectedPostGain, + (100 + 2) * expectedPostGain, + (100 + 1) * expectedPostGain, + (100 + 5) * expectedPostGain, // this is where the buffer wrapped around + (100 + 4) * expectedPostGain, + (100 + 3) * expectedPostGain, + (100 + 2) * expectedPostGain, + (100 + 1) * expectedPostGain }), // right channel std::vector( - { (100 + 105 * expectedPreGain) * expectedPostGain, - (100 + 104 * expectedPreGain) * expectedPostGain, - (100 + 103 * expectedPreGain) * expectedPostGain, - (100 + 102 * expectedPreGain) * expectedPostGain, - (100 + 101 * expectedPreGain) * expectedPostGain, - (100 + 105 * expectedPreGain) * expectedPostGain, // this is where the buffer wrapped around - (100 + 104 * expectedPreGain) * expectedPostGain, - (100 + 103 * expectedPreGain) * expectedPostGain, - (100 + 102 * expectedPreGain) * expectedPostGain, - (100 + 101 * expectedPreGain) * expectedPostGain }) + { (100 + 105) * expectedPostGain, + (100 + 104) * expectedPostGain, + (100 + 103) * expectedPostGain, + (100 + 102) * expectedPostGain, + (100 + 101) * expectedPostGain, + (100 + 105) * expectedPostGain, // this is where the buffer wrapped around + (100 + 104) * expectedPostGain, + (100 + 103) * expectedPostGain, + (100 + 102) * expectedPostGain, + (100 + 101) * expectedPostGain }) }; EXPECT_EQ(toArrOfVecs(outputBuffer), expectedOutputSamples); } TEST_F(DSP_Player, g_playBackwardsHalfSpeed) { - const auto expectedPreGain = 0.6734258f; const auto expectedPostGain = 0.89563f; const auto numSamplesToPlay = 2 * numSamples_; @@ -650,21 +629,17 @@ TEST_F(DSP_Player, g_playBackwardsHalfSpeed) player_.process(0.5f, // speed 0.0f, // speed modulation amount Direction::backwards, - expectedPreGain, expectedPostGain, { 0.0f }, // processor params outputBuffer.subBlock(0, numSamplesToPlay / 2 + 1), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant player_.process(0.5f, // speed 0.0f, // speed modulation amount Direction::backwards, - expectedPreGain, expectedPostGain, { 1.0f }, // processor params (changed this time) outputBuffer.subBlock(numSamplesToPlay / 2 + 1), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant @@ -673,20 +648,20 @@ TEST_F(DSP_Player, g_playBackwardsHalfSpeed) std::array, numChannels_> expectedProcessorCallArgs_input = { // left channel std::vector( - { 5.0f * expectedPreGain, - 4.0f * expectedPreGain, - 3.0f * expectedPreGain, - 2.0f * expectedPreGain, - 1.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 5.0f * expectedPreGain }), // this is the additonal sample from the linear interpolation + { 5.0f, + 4.0f, + 3.0f, + 2.0f, + 1.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 5.0f }), // this is the additonal sample from the linear interpolation // right channel std::vector( - { 105.0f * expectedPreGain, - 104.0f * expectedPreGain, - 103.0f * expectedPreGain, - 102.0f * expectedPreGain, - 101.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 105.0f * expectedPreGain }) // this is the additonal sample from the linear interpolation + { 105.0f, + 104.0f, + 103.0f, + 102.0f, + 101.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 105.0f }) // this is the additonal sample from the linear interpolation }; EXPECT_EQ(processCallArgs_input, expectedProcessorCallArgs_input); // expect correct parameters to be passed to the processor @@ -705,30 +680,30 @@ TEST_F(DSP_Player, g_playBackwardsHalfSpeed) // left channel std::vector( { - (100 + 5.0f * expectedPreGain) * expectedPostGain, - (100 + 4.5f * expectedPreGain) * expectedPostGain, // interpolated between 4.0f and 5.0f due to half speed - (100 + 4.0f * expectedPreGain) * expectedPostGain, - (100 + 3.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 3.0f * expectedPreGain) * expectedPostGain, - (100 + 2.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 2.0f * expectedPreGain) * expectedPostGain, - (100 + 1.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 1.0f * expectedPreGain) * expectedPostGain, - (100 + 3.0f * expectedPreGain) * expectedPostGain // interpolated between 1.0f and 5.0f + (100 + 5.0f) * expectedPostGain, + (100 + 4.5f) * expectedPostGain, // interpolated between 4.0f and 5.0f due to half speed + (100 + 4.0f) * expectedPostGain, + (100 + 3.5f) * expectedPostGain, // interpolated + (100 + 3.0f) * expectedPostGain, + (100 + 2.5f) * expectedPostGain, // interpolated + (100 + 2.0f) * expectedPostGain, + (100 + 1.5f) * expectedPostGain, // interpolated + (100 + 1.0f) * expectedPostGain, + (100 + 3.0f) * expectedPostGain // interpolated between 1.0f and 5.0f }), // right channel std::vector( { - (100 + 105.0f * expectedPreGain) * expectedPostGain, - (100 + 104.5f * expectedPreGain) * expectedPostGain, // interpolated between 4.0f and 5.0f due to half speed - (100 + 104.0f * expectedPreGain) * expectedPostGain, - (100 + 103.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 103.0f * expectedPreGain) * expectedPostGain, - (100 + 102.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 102.0f * expectedPreGain) * expectedPostGain, - (100 + 101.5f * expectedPreGain) * expectedPostGain, // interpolated - (100 + 101.0f * expectedPreGain) * expectedPostGain, - (100 + 103.0f * expectedPreGain) * expectedPostGain // interpolated between 1.0f and 5.0f + (100 + 105.0f) * expectedPostGain, + (100 + 104.5f) * expectedPostGain, // interpolated between 4.0f and 5.0f due to half speed + (100 + 104.0f) * expectedPostGain, + (100 + 103.5f) * expectedPostGain, // interpolated + (100 + 103.0f) * expectedPostGain, + (100 + 102.5f) * expectedPostGain, // interpolated + (100 + 102.0f) * expectedPostGain, + (100 + 101.5f) * expectedPostGain, // interpolated + (100 + 101.0f) * expectedPostGain, + (100 + 103.0f) * expectedPostGain // interpolated between 1.0f and 5.0f }), }; EXPECT_EQ(toArrOfVecs(outputBuffer), expectedOutputSamples); @@ -736,7 +711,6 @@ TEST_F(DSP_Player, g_playBackwardsHalfSpeed) TEST_F(DSP_Player, h_playBackwardsDoubleSpeed) { - const auto expectedPreGain = 0.6734258f; const auto expectedPostGain = 0.89563f; const auto numSamplesToPlay = 6; @@ -768,21 +742,17 @@ TEST_F(DSP_Player, h_playBackwardsDoubleSpeed) player_.process(2.0f, // speed 0.0f, // speed modulation amount Direction::backwards, - expectedPreGain, expectedPostGain, { 0.0f }, // processor params outputBuffer.subBlock(0, numSamplesToPlay / 2 + 1), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant player_.process(2.0f, // speed 0.0f, // speed modulation amount Direction::backwards, - expectedPreGain, expectedPostGain, { 1.0f }, // processor params (changed this time) outputBuffer.subBlock(numSamplesToPlay / 2 + 1), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant @@ -791,32 +761,32 @@ TEST_F(DSP_Player, h_playBackwardsDoubleSpeed) std::array, numChannels_> expectedProcessorCallArgs_input = { // left channel std::vector( - { 5.0f * expectedPreGain, - 4.0f * expectedPreGain, - 3.0f * expectedPreGain, - 2.0f * expectedPreGain, - 1.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 5.0f * expectedPreGain, - 4.0f * expectedPreGain, - 3.0f * expectedPreGain, - 2.0f * expectedPreGain, - 1.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 5.0f * expectedPreGain, - 4.0f * expectedPreGain }), // this is the additonal sample from the linear interpolation + { 5.0f, + 4.0f, + 3.0f, + 2.0f, + 1.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 5.0f, + 4.0f, + 3.0f, + 2.0f, + 1.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 5.0f, + 4.0f }), // this is the additonal sample from the linear interpolation // right channel std::vector( - { 105.0f * expectedPreGain, - 104.0f * expectedPreGain, - 103.0f * expectedPreGain, - 102.0f * expectedPreGain, - 101.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 105.0f * expectedPreGain, - 104.0f * expectedPreGain, - 103.0f * expectedPreGain, - 102.0f * expectedPreGain, - 101.0f * expectedPreGain, // here the playback buffer must wrap around to the beginning (just 5 samples long!) - 105.0f * expectedPreGain, - 104.0f * expectedPreGain }), // this is the additonal sample from the linear interpolation + { 105.0f, + 104.0f, + 103.0f, + 102.0f, + 101.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 105.0f, + 104.0f, + 103.0f, + 102.0f, + 101.0f, // here the playback buffer must wrap around to the beginning (just 5 samples long!) + 105.0f, + 104.0f }), // this is the additonal sample from the linear interpolation }; EXPECT_EQ(processCallArgs_input, expectedProcessorCallArgs_input); // expect correct parameters to be passed to the processor @@ -840,99 +810,25 @@ TEST_F(DSP_Player, h_playBackwardsDoubleSpeed) std::array, numChannels_> expectedOutputSamples = { // left channel std::vector( - { (100 + 5.0f * expectedPreGain) * expectedPostGain, - (100 + 3.0f * expectedPreGain) * expectedPostGain, - (100 + 1.0f * expectedPreGain) * expectedPostGain, - (100 + 4.0f * expectedPreGain) * expectedPostGain, - (100 + 2.0f * expectedPreGain) * expectedPostGain, - (100 + 5.0f * expectedPreGain) * expectedPostGain }), + { (100 + 5.0f) * expectedPostGain, + (100 + 3.0f) * expectedPostGain, + (100 + 1.0f) * expectedPostGain, + (100 + 4.0f) * expectedPostGain, + (100 + 2.0f) * expectedPostGain, + (100 + 5.0f) * expectedPostGain }), // right channel std::vector( - { (100 + 105.0f * expectedPreGain) * expectedPostGain, - (100 + 103.0f * expectedPreGain) * expectedPostGain, - (100 + 101.0f * expectedPreGain) * expectedPostGain, - (100 + 104.0f * expectedPreGain) * expectedPostGain, - (100 + 102.0f * expectedPreGain) * expectedPostGain, - (100 + 105.0f * expectedPreGain) * expectedPostGain }) + { (100 + 105.0f) * expectedPostGain, + (100 + 103.0f) * expectedPostGain, + (100 + 101.0f) * expectedPostGain, + (100 + 104.0f) * expectedPostGain, + (100 + 102.0f) * expectedPostGain, + (100 + 105.0f) * expectedPostGain }) }; EXPECT_EQ(toArrOfVecs(outputBuffer), expectedOutputSamples); } -TEST_F(DSP_Player, i_applySmoothingToPreGain) -{ - const auto numSamplesToPlay = 10; - - // the processor mock stores its argument values - std::array, numChannels_> processCallArgs_input; - ON_CALL(player_.getProcessor(), process(_, _)) - .WillByDefault([&](float inputsAndOutputs[numChannels_], const MockProcessor::Parameters&) { - for (size_t ch = 0; ch < numChannels_; ch++) - processCallArgs_input[ch].push_back(inputsAndOutputs[ch]); - }); - - // fill input buffer with 1.0f - buffer_.fill(1.0f); - // add this expectation to silence gmock warning. - EXPECT_CALL(player_.getProcessor(), process(_, _)).Times(::testing::AnyNumber()); - - // play the full buffer - player_.startPlaying(numSamples_); - - // the smoothing we'll use - const auto timeConstant = ExponentialSmoother::TimeConstant::fromRawValue(0.5f); - const auto targetGain = 1.0f; - - AudioBuffer outputBuffer; - outputBuffer.fill(0.0f); - // process block (ramping the gain up) - player_.process(1.0f, // speed - 0.0f, // speed modulation amount - Direction::forwards, - targetGain, // target pre gain - 1.0f, // post gain - { 0.0f }, // processor params - outputBuffer.subBlock(0, numSamplesToPlay / 2), // first half of the buffer - timeConstant, // pre gain time constant - ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant - ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant - // process block (ramping the gain back down) - player_.process(1.0f, // speed - 0.0f, // speed modulation amount - Direction::forwards, - 0.0f, // target pre gain - 1.0f, // post gain - { 0.0f }, // processor params - outputBuffer.subBlock(numSamplesToPlay / 2), // second half of the buffer - timeConstant, // pre gain time constant - ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant - ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant - - // we expect the gain to ramp up/down exponentially with the supplied smoothing constant - std::vector expectedProcessorInputSamples = { - targetGain * 0.5f, // first sample processed - // due to the linear interpolation, the second input sample is also processed - // while calculating the first output sample. Thus, it gets the same gain - // as the first sample, since we expect the gain to be smoothed in sync with - // the output samples. - targetGain * 0.5f, - targetGain * 0.75f, - targetGain * 0.875f, - targetGain * 0.9375f, - targetGain * 0.96875f, - // ramping down again - targetGain * 0.484375f, - targetGain * 0.2421875f, - targetGain * 0.12109375f, - targetGain * 0.060546875f, - targetGain * 0.0302734375f, - }; - // left and right channel had the same input samples (all 1.0f) - // so we also expect the same output samples - EXPECT_EQ(processCallArgs_input[0], expectedProcessorInputSamples); - EXPECT_EQ(processCallArgs_input[1], expectedProcessorInputSamples); -} - -TEST_F(DSP_Player, j_applySmoothingToPostGain) +TEST_F(DSP_Player, i_applySmoothingToPostGain) { const auto numSamplesToPlay = 10; @@ -958,22 +854,18 @@ TEST_F(DSP_Player, j_applySmoothingToPostGain) player_.process(1.0f, // speed 0.0f, // speed modulation amount Direction::forwards, - 1.0f, // pre gain targetGain, // post gain { 0.0f }, // processor params outputBuffer.subBlock(0, numSamplesToPlay / 2), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant timeConstant, // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant // process block (ramping the gain back down) player_.process(1.0f, // speed 0.0f, // speed modulation amount Direction::forwards, - 1.0f, // pre gain 0.0f, // target post gain { 0.0f }, // processor params outputBuffer.subBlock(numSamplesToPlay / 2), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant timeConstant, // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant @@ -1013,7 +905,7 @@ TEST_F(DSP_Player, j_applySmoothingToPostGain) EXPECT_EQ(toArrOfVecs(outputBuffer), expectedOutputSamples); } -TEST_F(DSP_Player, k_applySmoothingToSpeed) +TEST_F(DSP_Player, j_applySmoothingToSpeed) { const auto numSamplesToPlay = 6; @@ -1038,22 +930,18 @@ TEST_F(DSP_Player, k_applySmoothingToSpeed) player_.process(targetSpeed1, 0.0f, // speed modulation amount Direction::forwards, - 1.0f, // pre gain 1.0f, // post gain { 0.0f }, // processor params outputBuffer.subBlock(0, numSamplesToPlay / 2), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant timeConstant); // speed time constant // process block (ramping the speed back up) player_.process(targetSpeed2, 0.0f, // speed modulation amount Direction::forwards, - 1.0f, // pre gain 1.0f, // post gain { 0.0f }, // processor params outputBuffer.subBlock(numSamplesToPlay / 2), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant timeConstant); // speed time constant @@ -1076,7 +964,7 @@ TEST_F(DSP_Player, k_applySmoothingToSpeed) EXPECT_EQ(toArrOfVecs(outputBuffer), toArrOfVecs(expectedOutputSamples)); } -TEST_F(DSP_Player, l_applyNoSmoothingToProcessorParameters) +TEST_F(DSP_Player, k_applyNoSmoothingToProcessorParameters) { const auto numSamplesToPlay = 10; @@ -1103,22 +991,18 @@ TEST_F(DSP_Player, l_applyNoSmoothingToProcessorParameters) player_.process(1.0f, // speed 0.0f, // speed modulation amount Direction::forwards, - 0.0f, // pre gain 0.0f, // post gain { targetParamValue1 }, outputBuffer.subBlock(0, numSamplesToPlay / 2), // first half of the buffer - timeConstant, // pre gain time constant timeConstant, // post gain time constant timeConstant); // speed time constant // process block with another parameter value player_.process(1.0f, // speed 0.0f, // speed modulation amount Direction::forwards, - 0.0f, // pre gain 0.0f, // post gain { targetParamValue2 }, outputBuffer.subBlock(numSamplesToPlay / 2), // second half of the buffer - timeConstant, // pre gain time constant timeConstant, // post gain time constant timeConstant); // speed time constant @@ -1138,7 +1022,7 @@ TEST_F(DSP_Player, l_applyNoSmoothingToProcessorParameters) EXPECT_EQ(processCallArgs_param, expectedParameterValues); } -TEST_F(DSP_Player, m_useSpeedModulator) +TEST_F(DSP_Player, l_useSpeedModulator) { const auto numSamplesToPlay = 6; @@ -1161,11 +1045,9 @@ TEST_F(DSP_Player, m_useSpeedModulator) player_.process(1.0f, // speed 1.0f, // speed modulation amount Direction::forwards, - 1.0f, // pre gain 1.0f, // post gain { 0.0f }, // processor params outputBuffer.subBlock(0, numSamplesToPlay / 2), // first half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant ExponentialSmoother::TimeConstant::instantaneous()); // speed time constant // process block with speed modulator returning 0.5, but mod amount set to 2.0 @@ -1175,11 +1057,9 @@ TEST_F(DSP_Player, m_useSpeedModulator) player_.process(1.0f, 2.0f, // speed modulation amount Direction::forwards, - 1.0f, // pre gain 1.0f, // post gain { 0.0f }, // processor params outputBuffer.subBlock(numSamplesToPlay / 2), // second half of the buffer - ExponentialSmoother::TimeConstant::instantaneous(), // pre gain time constant ExponentialSmoother::TimeConstant::instantaneous(), // post gain time constant // this time, we have a smoothing time constant to make sure that the modulator is not smoothed ExponentialSmoother::TimeConstant::fromRawValue(0.5f)); // speed time constant diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index 2148439..d1a612a 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -175,7 +175,6 @@ void audioCallback(const float* const* in, float** out, size_t size) 0.5f, // drive amt 0.5f // grain amt }, - 1.0f, // pre gain 1.0f, // post gain inputs, outputs); diff --git a/plugin/src/TapeLooperProcessor.h b/plugin/src/TapeLooperProcessor.h index 8af395e..09d6485 100644 --- a/plugin/src/TapeLooperProcessor.h +++ b/plugin/src/TapeLooperProcessor.h @@ -139,7 +139,6 @@ class TapeLooperProcessor : public ITapeLooperProcessor wowAndFlutterAmt, direction, params, - 1.0f, // pre gain postGain, AudioBufferPtr<2, const float>( inChPtrs, input.getNumSamples()), From d29f8852b692b9c8a01edac6fb2fc8294059e981 Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Sat, 20 Nov 2021 21:45:06 +0100 Subject: [PATCH 5/8] remove high shelf emphasis EQ to save processing cycles --- dsp/src/dsp/EmphasisEq.h | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/dsp/src/dsp/EmphasisEq.h b/dsp/src/dsp/EmphasisEq.h index f2ea328..666c3c4 100644 --- a/dsp/src/dsp/EmphasisEq.h +++ b/dsp/src/dsp/EmphasisEq.h @@ -125,9 +125,9 @@ class FixedOnePoleShelvingEq /** * An pre-emphasis / de-emphasis EQ consisting of - * a first order high shelf and low shelf EQ. - * The pre-emphasis section boosts bass and treble, - * while the de-emphasis section cuts them by the same amount. + * two first order low shelf EQs. + * The pre-emphasis section boosts bass, + * while the de-emphasis section cuts it by the same amount. */ template class EmphasisEq @@ -140,32 +140,27 @@ class EmphasisEq void reset() { lowShelfPreEmphasis_.reset(); - highShelfPreEmphasis_.reset(); lowShelfDeEmphasis_.reset(); - highShelfDeEmphasis_.reset(); } - /** Boosts bass and treble by 12dB */ + /** Boosts bass by 12dB */ MANUAL_INLINE FloatType processPreEmphasis(const FloatType inputSample) { FloatType sample = inputSample; sample = lowShelfPreEmphasis_.processSample(sample); - sample = highShelfPreEmphasis_.processSample(sample); return sample; } - /** Cuts bass and treble by 12dB */ + /** Cuts bass by 12dB */ MANUAL_INLINE FloatType processDeEmphasis(const FloatType inputSample) { FloatType sample = inputSample; sample = lowShelfDeEmphasis_.processSample(sample); - sample = highShelfDeEmphasis_.processSample(sample); return sample; } private: static constexpr int lowFrequencyInHz_ = 500; - static constexpr int highFrequencyInHz_ = 2000; static constexpr int gainInDecibels_ = 12; FixedOnePoleShelvingEq> lowShelfPreEmphasis_; - FixedOnePoleShelvingEq> - highShelfPreEmphasis_; FixedOnePoleShelvingEq> lowShelfDeEmphasis_; - FixedOnePoleShelvingEq> - highShelfDeEmphasis_; }; From e6eff2ac089d4e00c58cb0d7196de25a9acd686e Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Sat, 20 Nov 2021 21:45:22 +0100 Subject: [PATCH 6/8] add missing MANUAL_INLINE --- dsp/src/dsp/TapeGrain.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/src/dsp/TapeGrain.h b/dsp/src/dsp/TapeGrain.h index d3ae438..5a0dbe6 100644 --- a/dsp/src/dsp/TapeGrain.h +++ b/dsp/src/dsp/TapeGrain.h @@ -63,7 +63,7 @@ class ClockedNoiseGenerator FloatType getCurrentOutputValue() const { return currentOutputValue_; } private: - void updatePhaseIncrement(FloatType frequency) + MANUAL_INLINE void updatePhaseIncrement(FloatType frequency) { phaseIncrement_ = frequency / FloatType(sampleRate); } From 733fd989cabb9f0eb169e868a48e6851f3ff28ac Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Sat, 20 Nov 2021 21:45:32 +0100 Subject: [PATCH 7/8] increase Wow&Flutter amount --- dsp/src/dsp/TapeLooper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/src/dsp/TapeLooper.h b/dsp/src/dsp/TapeLooper.h index 16411c6..e1e2626 100644 --- a/dsp/src/dsp/TapeLooper.h +++ b/dsp/src/dsp/TapeLooper.h @@ -175,7 +175,7 @@ class TapeLooper const LooperStoragePtr getSampleStoragePtr() const { return storage_; } private: - static constexpr float maxWowAndFlutterAmt_ = 0.0125f; + static constexpr float maxWowAndFlutterAmt_ = 0.025f; const LooperStoragePtr storage_; LooperState state_; PlayerType player_; From aedaf88d56a1af9c33dadf073cdc157ba4223b29 Mon Sep 17 00:00:00 2001 From: TheSlowGrowth <9356320+TheSlowGrowth@users.noreply.github.com> Date: Sun, 21 Nov 2021 23:42:17 +0100 Subject: [PATCH 8/8] update .gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index abcb214..d0b88b0 100644 --- a/.gitignore +++ b/.gitignore @@ -34,9 +34,13 @@ *.sch-bak *.kicad_pcb-bak +# build directories and binaries firmware/build firmware/tests/build firmware/tests/TapeLooper_gtest dsp/tests/build dsp/tests/TapeLooperDSP_gtest plugin/build + +# macOS crap +.DS_Store