From 53a515e2fcf92db940d2b17ddcd0942e2bc0a63e Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Wed, 12 Mar 2025 12:23:38 +0200 Subject: [PATCH 01/14] Made basic CMake project to replace .sln --- CMakeLists.txt | 23 +++++++++++++++++++++++ DSP/CMakeLists.txt | 19 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 DSP/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ab61a02 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.10) + +project(CloudSeedCore VERSION 1.0) + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +add_subdirectory(DSP) + +add_executable(CloudSeedDemo + PluginProcessor.cpp +) + +target_compile_definitions(CloudSeedCore PUBLIC + BUFFER_SIZE=1024 + MAX_STR_SIZE=32 +) + +if(WIN32) + target_compile_definitions(CloudSeedCore PRIVATE NOMINMAX WIN32_LEAN_AND_MEAN) +endif() + +target_link_libraries(CloudSeedDemo PRIVATE CloudSeedCore) diff --git a/DSP/CMakeLists.txt b/DSP/CMakeLists.txt new file mode 100644 index 0000000..0b71e1d --- /dev/null +++ b/DSP/CMakeLists.txt @@ -0,0 +1,19 @@ +add_library(CloudSeedCore STATIC + AllpassDiffuser.h + Biquad.cpp + Biquad.h + DelayLine.h + Hp1.h + LcgRandom.h + Lp1.h + ModulatedAllpass.h + ModulatedDelay.h + MultitapDelay.h + RandomBuffer.cpp + RandomBuffer.h + ReverbChannel.h + ReverbController.h + Utils.h + ../Parameters.cpp + ../Parameters.h +) From 8103130990bd1c6c2c7b7c526779a23a7455e552 Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Wed, 12 Mar 2025 12:45:39 +0200 Subject: [PATCH 02/14] tidy: removed VS solution files. --- CloudSeedCore.sln | 31 ------- CloudSeedCore.vcxproj | 155 ---------------------------------- CloudSeedCore.vcxproj.filters | 81 ------------------ 3 files changed, 267 deletions(-) delete mode 100644 CloudSeedCore.sln delete mode 100644 CloudSeedCore.vcxproj delete mode 100644 CloudSeedCore.vcxproj.filters diff --git a/CloudSeedCore.sln b/CloudSeedCore.sln deleted file mode 100644 index ce2fa61..0000000 --- a/CloudSeedCore.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.7.34221.43 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CloudSeedCore", "CloudSeedCore.vcxproj", "{7EC3FD43-1E45-4046-BEDF-33861EF49015}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7EC3FD43-1E45-4046-BEDF-33861EF49015}.Debug|x64.ActiveCfg = Debug|x64 - {7EC3FD43-1E45-4046-BEDF-33861EF49015}.Debug|x64.Build.0 = Debug|x64 - {7EC3FD43-1E45-4046-BEDF-33861EF49015}.Debug|x86.ActiveCfg = Debug|Win32 - {7EC3FD43-1E45-4046-BEDF-33861EF49015}.Debug|x86.Build.0 = Debug|Win32 - {7EC3FD43-1E45-4046-BEDF-33861EF49015}.Release|x64.ActiveCfg = Release|x64 - {7EC3FD43-1E45-4046-BEDF-33861EF49015}.Release|x64.Build.0 = Release|x64 - {7EC3FD43-1E45-4046-BEDF-33861EF49015}.Release|x86.ActiveCfg = Release|Win32 - {7EC3FD43-1E45-4046-BEDF-33861EF49015}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {984BFEEF-D2E4-4A1A-968E-CD3044280064} - EndGlobalSection -EndGlobal diff --git a/CloudSeedCore.vcxproj b/CloudSeedCore.vcxproj deleted file mode 100644 index 94a5f5b..0000000 --- a/CloudSeedCore.vcxproj +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 17.0 - Win32Proj - {7ec3fd43-1e45-4046-bedf-33861ef49015} - CloudSeedCore - 10.0 - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;BUFFER_SIZE=1024;MAX_STR_SIZE=32;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CloudSeedCore.vcxproj.filters b/CloudSeedCore.vcxproj.filters deleted file mode 100644 index 0f6ec53..0000000 --- a/CloudSeedCore.vcxproj.filters +++ /dev/null @@ -1,81 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {d1a62df7-fbd4-4696-b69e-0dfb810054a1} - - - - - Source Files - - - Source Files - - - Source Files\DSP - - - Source Files\DSP - - - - - Source Files - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files\DSP - - - Source Files - - - \ No newline at end of file From 77d26811502019dc4c047f0a0f52c5e67eae3b7b Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Wed, 12 Mar 2025 12:47:22 +0200 Subject: [PATCH 03/14] fix: used maxLen (was unused) instead of MAX_STR_SIZE. --- CMakeLists.txt | 3 +++ Parameters.h | 36 ++++++++++++++++++------------------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab61a02..04322a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,9 @@ add_executable(CloudSeedDemo target_compile_definitions(CloudSeedCore PUBLIC BUFFER_SIZE=1024 +) + +target_compile_definitions(CloudSeedDemo PUBLIC MAX_STR_SIZE=32 ) diff --git a/Parameters.h b/Parameters.h index 1863396..42ccdac 100644 --- a/Parameters.h +++ b/Parameters.h @@ -192,9 +192,9 @@ namespace Cloudseed case Parameter::EqLowpassEnabled: case Parameter::EarlyDiffuseEnabled: if (ScaleParam(val, paramId) == 1) - strcpy_s(buffer, MAX_STR_SIZE, "ENABLED"); + strcpy_s(buffer, maxLen, "ENABLED"); else - strcpy_s(buffer, MAX_STR_SIZE, "DISABLED"); + strcpy_s(buffer, maxLen, "DISABLED"); break; case Parameter::InputMix: @@ -202,14 +202,14 @@ namespace Cloudseed case Parameter::TapDecay: case Parameter::LateDiffuseFeedback: case Parameter::EqCrossSeed: - snprintf(buffer, MAX_STR_SIZE, "%d%%", (int)(s * 100)); + snprintf(buffer, maxLen, "%d%%", (int)(s * 100)); break; case Parameter::SeedTap: case Parameter::SeedDiffusion: case Parameter::SeedDelay: case Parameter::SeedPostDiffusion: - snprintf(buffer, MAX_STR_SIZE, "%03d", (int)s); + snprintf(buffer, maxLen, "%03d", (int)s); break; case Parameter::LowCut: @@ -217,23 +217,23 @@ namespace Cloudseed case Parameter::EqLowFreq: case Parameter::EqHighFreq: case Parameter::EqCutoff: - snprintf(buffer, MAX_STR_SIZE, "%d Hz", (int)s); + snprintf(buffer, maxLen, "%d Hz", (int)s); break; case Parameter::DryOut: case Parameter::EarlyOut: case Parameter::LateOut: if (s <= -30) - strcpy_s(buffer, MAX_STR_SIZE, "MUTED"); + strcpy_s(buffer, maxLen, "MUTED"); else - snprintf(buffer, MAX_STR_SIZE, "%.1f dB", s); + snprintf(buffer, maxLen, "%.1f dB", s); break; case Parameter::TapCount: case Parameter::EarlyDiffuseCount: case Parameter::LateLineCount: case Parameter::LateDiffuseCount: - snprintf(buffer, MAX_STR_SIZE, "%d", (int)s); + snprintf(buffer, maxLen, "%d", (int)s); break; case Parameter::TapPredelay: @@ -241,44 +241,44 @@ namespace Cloudseed case Parameter::EarlyDiffuseDelay: case Parameter::LateLineSize: case Parameter::LateDiffuseDelay: - snprintf(buffer, MAX_STR_SIZE, "%d ms", (int)s); + snprintf(buffer, maxLen, "%d ms", (int)s); break; case Parameter::LateLineDecay: if (s < 1) - snprintf(buffer, MAX_STR_SIZE, "%d ms", (int)(s * 1000)); + snprintf(buffer, maxLen, "%d ms", (int)(s * 1000)); else if (s < 10) - snprintf(buffer, MAX_STR_SIZE, "%.2f sec", s); + snprintf(buffer, maxLen, "%.2f sec", s); else - snprintf(buffer, MAX_STR_SIZE, "%.1f sec", s); + snprintf(buffer, maxLen, "%.1f sec", s); break; case Parameter::LateMode: if (s == 1) - strcpy_s(buffer, MAX_STR_SIZE, "POST"); + strcpy_s(buffer, maxLen, "POST"); else - strcpy_s(buffer, MAX_STR_SIZE, "PRE"); + strcpy_s(buffer, maxLen, "PRE"); break; case Parameter::EarlyDiffuseModAmount: case Parameter::LateLineModAmount: case Parameter::LateDiffuseModAmount: - snprintf(buffer, MAX_STR_SIZE, "%d%%", (int)(s * 100)); + snprintf(buffer, maxLen, "%d%%", (int)(s * 100)); break; case Parameter::EarlyDiffuseModRate: case Parameter::LateLineModRate: case Parameter::LateDiffuseModRate: - snprintf(buffer, MAX_STR_SIZE, "%.2f Hz", s); + snprintf(buffer, maxLen, "%.2f Hz", s); break; case Parameter::EqLowGain: case Parameter::EqHighGain: - snprintf(buffer, MAX_STR_SIZE, "%.1f dB", s); + snprintf(buffer, maxLen, "%.1f dB", s); break; default: - snprintf(buffer, MAX_STR_SIZE, "%.2f", s); + snprintf(buffer, maxLen, "%.2f", s); } } } From 2f32634f4343b76a509b5834496e27f5d6c6697b Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Wed, 12 Mar 2025 13:20:48 +0200 Subject: [PATCH 04/14] Parameters.h - use more common stdncpy instead of Windows exclusive strcpy_s. --- Parameters.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Parameters.h b/Parameters.h index 42ccdac..e365ef2 100644 --- a/Parameters.h +++ b/Parameters.h @@ -179,6 +179,7 @@ namespace Cloudseed inline void FormatParameter(float val, int maxLen, int paramId, char* buffer) { double s = ScaleParam(val, paramId); + const auto maxLenTerminated = maxLen - 1; switch (paramId) { @@ -192,9 +193,9 @@ namespace Cloudseed case Parameter::EqLowpassEnabled: case Parameter::EarlyDiffuseEnabled: if (ScaleParam(val, paramId) == 1) - strcpy_s(buffer, maxLen, "ENABLED"); + strncpy(buffer, "ENABLED", maxLenTerminated); else - strcpy_s(buffer, maxLen, "DISABLED"); + strncpy(buffer, "ENABLED", maxLenTerminated); break; case Parameter::InputMix: @@ -224,7 +225,7 @@ namespace Cloudseed case Parameter::EarlyOut: case Parameter::LateOut: if (s <= -30) - strcpy_s(buffer, maxLen, "MUTED"); + strncpy(buffer, "MUTED", maxLenTerminated); else snprintf(buffer, maxLen, "%.1f dB", s); break; @@ -255,9 +256,9 @@ namespace Cloudseed case Parameter::LateMode: if (s == 1) - strcpy_s(buffer, maxLen, "POST"); + strncpy(buffer, "POST", maxLenTerminated); else - strcpy_s(buffer, maxLen, "PRE"); + strncpy(buffer, "PRE", maxLenTerminated); break; case Parameter::EarlyDiffuseModAmount: From 4226367197bac2adb84539719eb847e1c82f42aa Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Wed, 12 Mar 2025 13:24:38 +0200 Subject: [PATCH 05/14] Removed over definition for some platforms. should be defined in preprocessor. --- DSP/Hp1.h | 1 - DSP/Lp1.h | 1 - 2 files changed, 2 deletions(-) diff --git a/DSP/Hp1.h b/DSP/Hp1.h index 3fe8544..d04d4cf 100644 --- a/DSP/Hp1.h +++ b/DSP/Hp1.h @@ -22,7 +22,6 @@ THE SOFTWARE. #pragma once -#define _USE_MATH_DEFINES #include namespace Cloudseed diff --git a/DSP/Lp1.h b/DSP/Lp1.h index 61b4199..524dd00 100644 --- a/DSP/Lp1.h +++ b/DSP/Lp1.h @@ -22,7 +22,6 @@ THE SOFTWARE. #pragma once -#define _USE_MATH_DEFINES #include namespace Cloudseed From 369c55a4c193584da60c03309cafc2e98d64287a Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Wed, 12 Mar 2025 15:08:10 +0200 Subject: [PATCH 06/14] Add include header (wrapper). --- include/CloudSeedCore.h | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 include/CloudSeedCore.h diff --git a/include/CloudSeedCore.h b/include/CloudSeedCore.h new file mode 100644 index 0000000..4e366d1 --- /dev/null +++ b/include/CloudSeedCore.h @@ -0,0 +1,3 @@ +#pragma once + +#include "../DSP/ReverbController.h" From eb00245f9a577868af619552e7abfc506e5d62cb Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Wed, 12 Mar 2025 15:37:53 +0200 Subject: [PATCH 07/14] CMake - use generated config.h to set MAX_BUFFER_SIZE. --- .gitignore | 3 ++- CMakeLists.txt | 10 ++++++++-- DSP/AllpassDiffuser.h | 3 ++- DSP/DelayLine.h | 4 ++-- DSP/ReverbChannel.h | 8 ++++---- DSP/ReverbController.h | 10 +++++----- include/config.h.in | 3 +++ 7 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 include/config.h.in diff --git a/.gitignore b/.gitignore index f932f6d..4a91166 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,5 @@ Releases/* **/.DS_Store !VC_redist.x64.exe outputLeft.bin -outputRight.bin \ No newline at end of file +outputRight.bin +include/config.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 04322a3..b9d640c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,14 @@ add_executable(CloudSeedDemo PluginProcessor.cpp ) -target_compile_definitions(CloudSeedCore PUBLIC - BUFFER_SIZE=1024 +set(CLOUDSEED_MAX_BUFFER_SIZE 1024 CACHE STRING "Maximum allocated and supported buffer size for CloudSeedCore") + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/include/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/include/config.h +) + +include_directories(PRIVATE CLoudSeedCore + ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_compile_definitions(CloudSeedDemo PUBLIC diff --git a/DSP/AllpassDiffuser.h b/DSP/AllpassDiffuser.h index 7702b3e..2bccd30 100644 --- a/DSP/AllpassDiffuser.h +++ b/DSP/AllpassDiffuser.h @@ -23,6 +23,7 @@ THE SOFTWARE. #pragma once #include +#include "config.h" #include "ModulatedAllpass.h" #include "RandomBuffer.h" @@ -126,7 +127,7 @@ namespace Cloudseed void Process(float* input, float* output, int bufSize) { - float tempBuffer[BUFFER_SIZE]; + float tempBuffer[MAX_BUFFER_SIZE]; filters[0].Process(input, tempBuffer, bufSize); diff --git a/DSP/DelayLine.h b/DSP/DelayLine.h index e6b3ba5..7ad7d08 100644 --- a/DSP/DelayLine.h +++ b/DSP/DelayLine.h @@ -116,7 +116,7 @@ namespace Cloudseed Biquad lowShelf; Biquad highShelf; Lp1 lowPass; - CircularBuffer<2*BUFFER_SIZE> feedbackBuffer; + CircularBuffer<2*MAX_BUFFER_SIZE> feedbackBuffer; float feedback; public: @@ -241,7 +241,7 @@ namespace Cloudseed void Process(float* input, float* output, int bufSize) { - float tempBuffer[BUFFER_SIZE]; + float tempBuffer[MAX_BUFFER_SIZE]; feedbackBuffer.Pop(tempBuffer, bufSize); for (int i = 0; i < bufSize; i++) diff --git a/DSP/ReverbChannel.h b/DSP/ReverbChannel.h index 570d78b..a8aba3f 100644 --- a/DSP/ReverbChannel.h +++ b/DSP/ReverbChannel.h @@ -314,10 +314,10 @@ namespace Cloudseed void Process(float* input, float* output, int bufSize) { - float tempBuffer[BUFFER_SIZE]; - float earlyOutBuffer[BUFFER_SIZE]; - float lineOutBuffer[BUFFER_SIZE]; - float lineSumBuffer[BUFFER_SIZE]; + float tempBuffer[MAX_BUFFER_SIZE]; + float earlyOutBuffer[MAX_BUFFER_SIZE]; + float lineOutBuffer[MAX_BUFFER_SIZE]; + float lineSumBuffer[MAX_BUFFER_SIZE]; Utils::Copy(tempBuffer, input, bufSize); diff --git a/DSP/ReverbController.h b/DSP/ReverbController.h index 3601e09..ac4a9a6 100644 --- a/DSP/ReverbController.h +++ b/DSP/ReverbController.h @@ -86,12 +86,12 @@ namespace Cloudseed void Process(float* inL, float* inR, float* outL, float* outR, int bufSize) { - float outLTemp[BUFFER_SIZE]; - float outRTemp[BUFFER_SIZE]; + float outLTemp[MAX_BUFFER_SIZE]; + float outRTemp[MAX_BUFFER_SIZE]; while (bufSize > 0) { - int subBufSize = bufSize > BUFFER_SIZE ? BUFFER_SIZE : bufSize; + int subBufSize = bufSize > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : bufSize; ProcessChunk(inL, inR, outLTemp, outRTemp, subBufSize); Utils::Copy(outL, outLTemp, subBufSize); Utils::Copy(outR, outRTemp, subBufSize); @@ -106,8 +106,8 @@ namespace Cloudseed private: void ProcessChunk(float* inL, float* inR, float* outL, float* outR, int bufSize) { - float leftChannelIn[BUFFER_SIZE]; - float rightChannelIn[BUFFER_SIZE]; + float leftChannelIn[MAX_BUFFER_SIZE]; + float rightChannelIn[MAX_BUFFER_SIZE]; float inputMix = ScaleParam(parameters[Parameter::InputMix], Parameter::InputMix); float cm = inputMix * 0.5; diff --git a/include/config.h.in b/include/config.h.in new file mode 100644 index 0000000..3ee594b --- /dev/null +++ b/include/config.h.in @@ -0,0 +1,3 @@ +#pragma once + +#define MAX_BUFFER_SIZE ${CLOUDSEED_MAX_BUFFER_SIZE} From b1375aa61ffdc7c73371b28f9c9f9ae610eb15bd Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Wed, 12 Mar 2025 16:33:25 +0200 Subject: [PATCH 08/14] Updated Readme.md --- Readme.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index c6b9b0f..13c4761 100644 --- a/Readme.md +++ b/Readme.md @@ -34,7 +34,14 @@ The output is written to a raw binary file, which you can open using Audacity: * Channels: 1 Channel (mono) * Sample Rate: 48000 Hz -## Preprocessor Definitions +Using CMake: +``` + cmake -B ./build +``` + +## Demo Preprocessor Definitions - BUFFER_SIZE=1024 (or whatever you want the maximum supported buffer size to be) MAX_STR_SIZE=32 (maximum length of strings being formatted and returned) + +## Configurable Compile Time Definitions + CLOUDSEED_MAX_BUFFER_SIZE=1024 (Compile-time maximum supported buffer size) From 01fb8cf112a7110974575cdeb9c8ef8aea286fa2 Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Mon, 17 Mar 2025 10:45:32 +0200 Subject: [PATCH 09/14] fix compiler warnings seen with clang/xcode. --- DSP/AllpassDiffuser.h | 4 ++-- DSP/DelayLine.h | 6 +++--- DSP/Hp1.h | 2 +- DSP/Lp1.h | 2 +- DSP/ModulatedAllpass.h | 6 +++--- DSP/ModulatedDelay.h | 6 +++--- DSP/MultitapDelay.h | 4 ++-- DSP/ReverbChannel.h | 20 ++++++++++++-------- DSP/ReverbController.h | 12 ++++++++---- DSP/Utils.h | 26 +++++++++++++------------- Parameters.h | 14 +++++++------- 11 files changed, 55 insertions(+), 47 deletions(-) diff --git a/DSP/AllpassDiffuser.h b/DSP/AllpassDiffuser.h index 2bccd30..343b5c2 100644 --- a/DSP/AllpassDiffuser.h +++ b/DSP/AllpassDiffuser.h @@ -114,7 +114,7 @@ namespace Cloudseed void SetModAmount(float amount) { for (int i = 0; i < MaxStageCount; i++) - filters[i].ModAmount = amount * (0.85 + 0.3 * seedValues[MaxStageCount + i]); + filters[i].ModAmount = static_cast(amount * (0.85 + 0.3 * seedValues[MaxStageCount + i])); } void SetModRate(float rate) @@ -122,7 +122,7 @@ namespace Cloudseed modRate = rate; for (int i = 0; i < MaxStageCount; i++) - filters[i].ModRate = rate * (0.85 + 0.3 * seedValues[MaxStageCount * 2 + i]) / samplerate; + filters[i].ModRate = static_cast(rate * (0.85 + 0.3 * seedValues[MaxStageCount * 2 + i]) / samplerate); } void Process(float* input, float* output, int bufSize) diff --git a/DSP/DelayLine.h b/DSP/DelayLine.h index 7ad7d08..dd8da4f 100644 --- a/DSP/DelayLine.h +++ b/DSP/DelayLine.h @@ -44,7 +44,7 @@ namespace Cloudseed void Reset() { - for (int i = 0; i < N; i++) + for (unsigned int i = 0; i < N; i++) buffer[i] = 0.0f; idxRead = 0; idxWrite = 0; @@ -56,7 +56,7 @@ namespace Cloudseed return count; } - int PushZeros(float* data, int bufSize) + int PushZeros(float* /*data*/, int bufSize) { int countBefore = count; for (int i = 0; i < bufSize; i++) @@ -79,7 +79,7 @@ namespace Cloudseed buffer[idxWrite] = data[i]; idxWrite = (idxWrite + 1) % N; count++; - if (count >= N) + if (count >= (int)N) break; // overflow } diff --git a/DSP/Hp1.h b/DSP/Hp1.h index d04d4cf..027168e 100644 --- a/DSP/Hp1.h +++ b/DSP/Hp1.h @@ -79,7 +79,7 @@ namespace Cloudseed if (cutoffHz >= fs * 0.5f) cutoffHz = fs * 0.499f; - auto x = 2.0f * M_PI * cutoffHz / fs; + auto x = static_cast(2.0f * M_PI * cutoffHz / fs); auto nn = (2.0f - cosf(x)); auto alpha = nn - sqrtf(nn * nn - 1); diff --git a/DSP/Lp1.h b/DSP/Lp1.h index 524dd00..27c40c5 100644 --- a/DSP/Lp1.h +++ b/DSP/Lp1.h @@ -76,7 +76,7 @@ namespace Cloudseed if (cutoffHz >= fs * 0.5f) cutoffHz = fs * 0.499f; - auto x = 2.0f * M_PI * cutoffHz / fs; + auto x = static_cast(2.0f * M_PI * cutoffHz / fs); auto nn = (2.0f - cosf(x)); auto alpha = nn - sqrtf(nn * nn - 1); diff --git a/DSP/ModulatedAllpass.h b/DSP/ModulatedAllpass.h index a661fa7..83bc554 100644 --- a/DSP/ModulatedAllpass.h +++ b/DSP/ModulatedAllpass.h @@ -60,7 +60,7 @@ namespace Cloudseed index = DelayBufferSize - 1; samplesProcessed = 0; - modPhase = 0.01 + 0.98 * std::rand() / (float)RAND_MAX; + modPhase = static_cast(0.01 + 0.98 * std::rand() / (float)RAND_MAX); delayA = 0; delayB = 0; gainA = 0; @@ -162,9 +162,9 @@ namespace Cloudseed { modPhase += ModRate * ModulationUpdateRate; if (modPhase > 1) - modPhase = std::fmod(modPhase, 1.0); + modPhase = std::fmod(modPhase, 1.0f); - auto mod = std::sinf(modPhase * 2 * M_PI); + auto mod = std::sinf(static_cast(modPhase * 2 * M_PI)); if (ModAmount >= SampleDelay) // don't modulate to negative value ModAmount = SampleDelay - 1; diff --git a/DSP/ModulatedDelay.h b/DSP/ModulatedDelay.h index 9e26984..67a7f3f 100644 --- a/DSP/ModulatedDelay.h +++ b/DSP/ModulatedDelay.h @@ -58,7 +58,7 @@ namespace Cloudseed readIndexB = 0; samplesProcessed = 0; - modPhase = 0.01 + 0.98 * (std::rand() / (float)RAND_MAX); + modPhase = static_cast(0.01 + 0.98 * (std::rand() / (float)RAND_MAX)); gainA = 0; gainB = 0; @@ -103,9 +103,9 @@ namespace Cloudseed { modPhase += ModRate * ModulationUpdateRate; if (modPhase > 1) - modPhase = std::fmod(modPhase, 1.0); + modPhase = std::fmod(modPhase, 1.0f); - auto mod = std::sinf(modPhase * 2 * M_PI); + auto mod = std::sinf(static_cast(modPhase * 2 * M_PI)); auto totalDelay = SampleDelay + ModAmount * mod; auto delayA = (int)totalDelay; diff --git a/DSP/MultitapDelay.h b/DSP/MultitapDelay.h index 982bc6b..84abf22 100644 --- a/DSP/MultitapDelay.h +++ b/DSP/MultitapDelay.h @@ -99,7 +99,7 @@ namespace Cloudseed void Process(float* input, float* output, int bufSize) { float lengthScaler = lengthSamples / (float)count; - float totalGain = 3.0 / std::sqrtf(1 + count); + float totalGain = 3.0f / std::sqrtf(1 + count); totalGain *= (1 + decay * 2); for (int i = 0; i < bufSize; i++) @@ -110,7 +110,7 @@ namespace Cloudseed for (int j = 0; j < count; j++) { float offset = tapPosition[j] * lengthScaler; - float decayEffective = std::expf(-offset / lengthSamples * 3.3) * decay + (1-decay); + float decayEffective = std::expf(-offset / lengthSamples * 3.3f) * decay + (1-decay); int readIdx = writeIdx - (int)offset; if (readIdx < 0) readIdx += DelayBufferSize; diff --git a/DSP/ReverbChannel.h b/DSP/ReverbChannel.h index a8aba3f..3fe4ef0 100644 --- a/DSP/ReverbChannel.h +++ b/DSP/ReverbChannel.h @@ -22,6 +22,9 @@ THE SOFTWARE. #pragma once +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wshadow" + #include #include #include "../Parameters.h" @@ -49,14 +52,13 @@ namespace Cloudseed private: static const int TotalLineCount = 12; - double paramsScaled[Parameter::COUNT] = { 0.0 }; + float paramsScaled[Parameter::COUNT] = { 0.0 }; int samplerate; ModulatedDelay preDelay; MultitapDelay multitap; AllpassDiffuser diffuser; DelayLine lines[TotalLineCount]; - RandomBuffer rand; Hp1 highPass; Lp1 lowPass; @@ -116,7 +118,7 @@ namespace Cloudseed SetParameter(i, paramsScaled[i]); } - void SetParameter(int para, double scaledValue) + void SetParameter(int para, float scaledValue) { paramsScaled[para] = scaledValue; @@ -287,7 +289,7 @@ namespace Cloudseed case Parameter::EqCrossSeed: - crossSeed = channelLr == ChannelLR::Right ? 0.5 * scaledValue : 1 - 0.5 * scaledValue; + crossSeed = channelLr == ChannelLR::Right ? 0.5f * scaledValue : 1 - 0.5f * scaledValue; multitap.SetCrossSeed(crossSeed); diffuser.SetCrossSeed(crossSeed); UpdateLines(); @@ -375,7 +377,7 @@ namespace Cloudseed private: float GetPerLineGain() { - return 1.0 / std::sqrt(lineCount); + return 1.0f / std::sqrtf(lineCount); } void UpdateLines() @@ -394,10 +396,10 @@ namespace Cloudseed for (int i = 0; i < TotalLineCount; i++) { - auto modAmount = lineModAmount * (0.7 + 0.3 * delayLineSeeds[i]); - auto modRate = lineModRate * (0.7 + 0.3 * delayLineSeeds[TotalLineCount + i]) / samplerate; + auto modAmount = lineModAmount * (0.7f + 0.3f * delayLineSeeds[i]); + auto modRate = lineModRate * (0.7f + 0.3f * delayLineSeeds[TotalLineCount + i]) / samplerate; - auto delaySamples = (0.5 + 1.0 * delayLineSeeds[TotalLineCount * 2 + i]) * lineDelaySamples; + auto delaySamples = (0.5f + 1.0f * delayLineSeeds[TotalLineCount * 2 + i]) * lineDelaySamples; if (delaySamples < modAmount + 2) // when the delay is set really short, and the modulation is very high delaySamples = modAmount + 2; // the mod could actually take the delay time negative, prevent that! -- provide 2 extra sample as margin of safety @@ -426,3 +428,5 @@ namespace Cloudseed }; } + +#pragma clang diagnostic pop diff --git a/DSP/ReverbController.h b/DSP/ReverbController.h index ac4a9a6..24b71d7 100644 --- a/DSP/ReverbController.h +++ b/DSP/ReverbController.h @@ -38,7 +38,7 @@ namespace Cloudseed ReverbChannel channelL; ReverbChannel channelR; - double parameters[(int)Parameter::COUNT] = {0}; + float parameters[(int)Parameter::COUNT] = {0}; public: ReverbController(int samplerate) : @@ -53,24 +53,28 @@ namespace Cloudseed return samplerate; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wshadow" + void SetSamplerate(int samplerate) { this->samplerate = samplerate; channelL.SetSamplerate(samplerate); channelR.SetSamplerate(samplerate); } +#pragma clang diagnostic pop int GetParameterCount() { return Parameter::COUNT; } - double* GetAllParameters() + float* GetAllParameters() { return parameters; } - void SetParameter(int paramId, double value) + void SetParameter(int paramId, float value) { parameters[paramId] = value; auto scaled = ScaleParam(value, paramId); @@ -110,7 +114,7 @@ namespace Cloudseed float rightChannelIn[MAX_BUFFER_SIZE]; float inputMix = ScaleParam(parameters[Parameter::InputMix], Parameter::InputMix); - float cm = inputMix * 0.5; + float cm = inputMix * 0.5f; float cmi = (1 - cm); for (int i = 0; i < bufSize; i++) diff --git a/DSP/Utils.h b/DSP/Utils.h index 97ad74e..33bcc15 100644 --- a/DSP/Utils.h +++ b/DSP/Utils.h @@ -80,19 +80,19 @@ namespace Cloudseed return 20.0f * log10f(input); } - const float dec1Mult = (10 / 9.0) * 0.1; - const float dec2Mult = (100 / 99.0) * 0.01; - const float dec3Mult = (1000 / 999.0) * 0.001; - const float dec4Mult = (10000 / 9999.0) * 0.0001; - - const float oct1Mult = (2 / 1.0) * 0.5; - const float oct2Mult = (4 / 3.0) * 0.25; - const float oct3Mult = (8 / 7.0) * 0.125; - const float oct4Mult = (16 / 15.0) * 0.0625; - const float oct5Mult = (32 / 31.0) * 0.03125; - const float oct6Mult = (64 / 63.0) * 0.015625; - const float oct7Mult = (128 / 127.0) * 0.0078125; - const float oct8Mult = (256 / 255.0) * 0.00390625; + const float dec1Mult = (10 / 9.0f) * 0.1f; + const float dec2Mult = (100 / 99.0f) * 0.01f; + const float dec3Mult = (1000 / 999.0f) * 0.001f; + const float dec4Mult = (10000 / 9999.0f) * 0.0001f; + + const float oct1Mult = (2 / 1.0f) * 0.5f; + const float oct2Mult = (4 / 3.0f) * 0.25f; + const float oct3Mult = (8 / 7.0f) * 0.125f; + const float oct4Mult = (16 / 15.0f) * 0.0625f; + const float oct5Mult = (32 / 31.0f) * 0.03125f; + const float oct6Mult = (64 / 63.0f) * 0.015625f; + const float oct7Mult = (128 / 127.0f) * 0.0078125f; + const float oct8Mult = (256 / 255.0f) * 0.00390625f; inline float Resp1dec(float x) { return (powf(10, x) - 1) * dec1Mult; } inline float Resp2dec(float x) { return (powf(10, 2 * x) - 1) * dec2Mult; } diff --git a/Parameters.h b/Parameters.h index e365ef2..c031aac 100644 --- a/Parameters.h +++ b/Parameters.h @@ -83,11 +83,11 @@ namespace Cloudseed const int SeedPostDiffusion = 44; const int COUNT = 45; - }; + } extern const char* ParameterLabel[Parameter::COUNT]; - inline double ScaleParam(double val, int index) + inline float ScaleParam(float val, int index) { switch (index) { @@ -100,7 +100,7 @@ namespace Cloudseed case Parameter::EqHighShelfEnabled: case Parameter::EqLowpassEnabled: case Parameter::EarlyDiffuseEnabled: - return val < 0.5 ? 0.0 : 1.0; + return val < 0.5f ? 0.0f : 1.0f; case Parameter::InputMix: case Parameter::EarlyDiffuseFeedback: @@ -137,7 +137,7 @@ namespace Cloudseed case Parameter::EarlyDiffuseDelay: return 10 + val * 90; case Parameter::EarlyDiffuseModAmount: - return val * 2.5; + return val * 2.5f; case Parameter::EarlyDiffuseModRate: return Utils::Resp2dec(val) * 5; @@ -150,13 +150,13 @@ namespace Cloudseed case Parameter::LateLineSize: return 20 + Utils::Resp2dec(val) * 980; case Parameter::LateLineModAmount: - return val * 2.5; + return val * 2.5f; case Parameter::LateDiffuseDelay: return 10 + val * 90; case Parameter::LateDiffuseModAmount: - return val * 2.5; + return val * 2.5f; case Parameter::LateLineDecay: - return 0.05 + Utils::Resp3dec(val) * 59.95; + return 0.05f + Utils::Resp3dec(val) * 59.95f; case Parameter::LateLineModRate: return Utils::Resp2dec(val) * 5; case Parameter::LateDiffuseModRate: From 304d51e330e158fb660c392216a1cf9ceab92eb8 Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Mon, 17 Mar 2025 12:01:17 +0200 Subject: [PATCH 10/14] fix regression in previous commit when compiling under gcc. --- DSP/ModulatedAllpass.h | 2 +- DSP/ModulatedDelay.h | 2 +- DSP/MultitapDelay.h | 4 ++-- DSP/ReverbChannel.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/DSP/ModulatedAllpass.h b/DSP/ModulatedAllpass.h index 83bc554..9a78388 100644 --- a/DSP/ModulatedAllpass.h +++ b/DSP/ModulatedAllpass.h @@ -164,7 +164,7 @@ namespace Cloudseed if (modPhase > 1) modPhase = std::fmod(modPhase, 1.0f); - auto mod = std::sinf(static_cast(modPhase * 2 * M_PI)); + auto mod = sinf(static_cast(modPhase * 2 * M_PI)); if (ModAmount >= SampleDelay) // don't modulate to negative value ModAmount = SampleDelay - 1; diff --git a/DSP/ModulatedDelay.h b/DSP/ModulatedDelay.h index 67a7f3f..2ab2799 100644 --- a/DSP/ModulatedDelay.h +++ b/DSP/ModulatedDelay.h @@ -105,7 +105,7 @@ namespace Cloudseed if (modPhase > 1) modPhase = std::fmod(modPhase, 1.0f); - auto mod = std::sinf(static_cast(modPhase * 2 * M_PI)); + auto mod = sinf(static_cast(modPhase * 2 * M_PI)); auto totalDelay = SampleDelay + ModAmount * mod; auto delayA = (int)totalDelay; diff --git a/DSP/MultitapDelay.h b/DSP/MultitapDelay.h index 84abf22..8e4a7fc 100644 --- a/DSP/MultitapDelay.h +++ b/DSP/MultitapDelay.h @@ -99,7 +99,7 @@ namespace Cloudseed void Process(float* input, float* output, int bufSize) { float lengthScaler = lengthSamples / (float)count; - float totalGain = 3.0f / std::sqrtf(1 + count); + float totalGain = 3.0f / sqrtf(1 + count); totalGain *= (1 + decay * 2); for (int i = 0; i < bufSize; i++) @@ -110,7 +110,7 @@ namespace Cloudseed for (int j = 0; j < count; j++) { float offset = tapPosition[j] * lengthScaler; - float decayEffective = std::expf(-offset / lengthSamples * 3.3f) * decay + (1-decay); + float decayEffective = expf(-offset / lengthSamples * 3.3f) * decay + (1-decay); int readIdx = writeIdx - (int)offset; if (readIdx < 0) readIdx += DelayBufferSize; diff --git a/DSP/ReverbChannel.h b/DSP/ReverbChannel.h index 3fe4ef0..bd944ee 100644 --- a/DSP/ReverbChannel.h +++ b/DSP/ReverbChannel.h @@ -377,7 +377,7 @@ namespace Cloudseed private: float GetPerLineGain() { - return 1.0f / std::sqrtf(lineCount); + return 1.0f / sqrtf(lineCount); } void UpdateLines() From b46bd7e0b9467c31d6b95444bfc290169932eaa1 Mon Sep 17 00:00:00 2001 From: Tal Aviram Date: Sat, 30 Aug 2025 18:20:09 +0200 Subject: [PATCH 11/14] add missing include --- include/CloudSeedCore.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/CloudSeedCore.h b/include/CloudSeedCore.h index 4e366d1..39112d7 100644 --- a/include/CloudSeedCore.h +++ b/include/CloudSeedCore.h @@ -1,3 +1,4 @@ #pragma once +#include #include "../DSP/ReverbController.h" From b1042b7e5b0fde6fcd79fc697c256f6e535ba996 Mon Sep 17 00:00:00 2001 From: Luke Palmer Date: Wed, 11 Mar 2026 14:03:06 -0500 Subject: [PATCH 12/14] Optimize ZeroBuffer function using memset Replaced manual zeroing of buffer with memset for efficiency. Fixes SoundRadix/Radical1#1740 --- DSP/Utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DSP/Utils.h b/DSP/Utils.h index 33bcc15..5efab7e 100644 --- a/DSP/Utils.h +++ b/DSP/Utils.h @@ -25,6 +25,7 @@ THE SOFTWARE. #define _USE_MATH_DEFINES 1 #include #include +#include namespace Cloudseed { @@ -33,8 +34,7 @@ namespace Cloudseed template inline void ZeroBuffer(T* buffer, int len) { - for (int i = 0; i < len; i++) - buffer[i] = 0; + memset(buffer, 0, len * sizeof(T)); } template From d9b9a16df4237f8b09d4ed6dbd49f5e8740fe29a Mon Sep 17 00:00:00 2001 From: Luke Palmer Date: Thu, 20 Aug 2026 15:22:01 -0500 Subject: [PATCH 13/14] Reserve RandomBuffer::Generate's output up front Generate fills its vectors with push_back from empty, so the number of reallocations is decided by the standard library's growth factor rather than by the work: 1.5x on the MSVC STL against 2x on libc++ and libstdc++, which is roughly 1.7x more allocations for an identical result. That shows up on the audio thread. SetParameter -> UpdateLines calls Generate on every decay, size or modulation change, and each call builds three of these vectors, so a host automating a reverb parameter pays 33 allocations per call on Windows against 21 elsewhere. The count is known before the loop starts, so reserve it. One allocation per vector on every platform, and the platform difference goes away. Co-Authored-By: Claude Opus 5 (1M context) --- DSP/RandomBuffer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DSP/RandomBuffer.cpp b/DSP/RandomBuffer.cpp index d43bdef..a663182 100644 --- a/DSP/RandomBuffer.cpp +++ b/DSP/RandomBuffer.cpp @@ -30,6 +30,7 @@ namespace Cloudseed { LcgRandom rand(seed); std::vector output; + output.reserve((size_t)count); for (int i = 0; i < count; i++) { @@ -49,6 +50,7 @@ namespace Cloudseed auto seriesB = Generate(seedB, count); std::vector output; + output.reserve((size_t)count); for (int i = 0; i < count; i++) output.push_back(seriesA[i] * (1 - crossSeed) + seriesB[i] * crossSeed); From 5fe75970e8401fe48d576c7ec0e63d50c1327662 Mon Sep 17 00:00:00 2001 From: Luke Palmer Date: Tue, 25 Aug 2026 16:32:31 -0500 Subject: [PATCH 14/14] Qualify size_t in RandomBuffer::Generate The unqualified name is not declared in this translation unit. MSVC's headers happen to drag ::size_t in transitively so it built there, but libstdc++ does not, and GCC 13 rejects it: RandomBuffer.cpp:33:33: error: 'size_t' was not declared in this scope; did you mean 'std::size_t'? Say std::size_t and include for it, rather than relying on whatever pulls in. Co-Authored-By: Claude Opus 5 (1M context) --- DSP/RandomBuffer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/DSP/RandomBuffer.cpp b/DSP/RandomBuffer.cpp index a663182..113fcf3 100644 --- a/DSP/RandomBuffer.cpp +++ b/DSP/RandomBuffer.cpp @@ -21,6 +21,7 @@ THE SOFTWARE. */ #include +#include #include "RandomBuffer.h" #include "LcgRandom.h" @@ -30,7 +31,7 @@ namespace Cloudseed { LcgRandom rand(seed); std::vector output; - output.reserve((size_t)count); + output.reserve(static_cast(count)); for (int i = 0; i < count; i++) { @@ -50,7 +51,7 @@ namespace Cloudseed auto seriesB = Generate(seedB, count); std::vector output; - output.reserve((size_t)count); + output.reserve(static_cast(count)); for (int i = 0; i < count; i++) output.push_back(seriesA[i] * (1 - crossSeed) + seriesB[i] * crossSeed);