diff --git a/.travis.yml b/.travis.yml index 286eeb5..8da774d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,9 +17,9 @@ matrix: - _MINGW=mingw32 - _HOST=i686-w64-mingw32 before_install: - - docker pull jpcima/arch-mingw + - docker pull archlinux install: - - container=$(docker run -d -i -t -v /home:/home jpcima/arch-mingw /bin/bash) + - container=$(docker run -d -i -t -v /home:/home archlinux /bin/bash) - | cross() { docker exec -w "$(pwd)" -e "_BUILD=$_BUILD" -e "_MINGW=$_MINGW" -e "_HOST=$_HOST" -i -t "$container" "$@" @@ -37,9 +37,9 @@ matrix: - _MINGW=mingw64 - _HOST=x86_64-w64-mingw32 before_install: - - docker pull jpcima/arch-mingw + - docker pull archlinux install: - - container=$(docker run -d -i -t -v /home:/home jpcima/arch-mingw /bin/bash) + - container=$(docker run -d -i -t -v /home:/home archlinux /bin/bash) - | cross() { docker exec -w "$(pwd)" -e "_BUILD=$_BUILD" -e "_MINGW=$_MINGW" -e "_HOST=$_HOST" -i -t "$container" "$@" @@ -61,14 +61,14 @@ matrix: - install -d release - zip -9 -r release/string-machine-"$_BUILD".zip string-machine-"$_BUILD" - os: linux - dist: trusty + dist: xenial env: - _BITS=64 - _BUILD=linux64 before_install: - sudo apt-get update -qq install: - - sudo apt-get install checkinstall libcairo2-dev + - sudo apt-get install checkinstall libcairo2-dev mesa-common-dev script: - bash .travis/script-linux.sh - cp -drfv bin string-machine-"$_BUILD" @@ -91,6 +91,10 @@ before_deploy: export TRAVIS_TAG=automatic git tag -f "$TRAVIS_TAG" fi + - | + if test "$_BUILD" = "macos"; then + gem uninstall openssl --all --force + fi deploy: provider: releases diff --git a/.travis/script-macos.sh b/.travis/script-macos.sh index d326c6c..06b9643 100755 --- a/.travis/script-macos.sh +++ b/.travis/script-macos.sh @@ -43,11 +43,12 @@ export LDFLAGS="-L/opt/local/lib -arch i386 -arch x86_64" # dependencies build_auto_dep() { + echo "** Building autotools dependency $1" cd "$1" shift - ./configure --enable-silent-rules --enable-static --disable-shared --prefix=/opt/local "$@" - make $MAKE_ARGS - sudo make install + ./configure --enable-silent-rules --enable-static --disable-shared --prefix=/opt/local "$@" &> /dev/null + make $MAKE_ARGS &> /dev/null + sudo make install &> /dev/null cd .. } diff --git a/.travis/script-mingw.sh b/.travis/script-mingw.sh index 9a4bce7..975f8fb 100755 --- a/.travis/script-mingw.sh +++ b/.travis/script-mingw.sh @@ -35,14 +35,28 @@ export CFLAGS="-I/opt/$_MINGW/include" export CXXFLAGS="-I/opt/$_MINGW/include" export LDFLAGS="-L/opt/$_MINGW/lib" +# --------------------------------------------------------------------------------------------------------------------- + +cat >>/etc/pacman.conf <(iConst18, std::max(0, iTemp3))) & 16383)] * (0.0f - (fTemp1 + (-1.0f - fTemp4)))) + ((fTemp1 - fTemp4) * fVec0[((IOTA - std::min(iConst18, std::max(0, (iTemp3 + 1)))) & 16383)]))); - output0[i] = FAUSTFLOAT(fTemp5); - float fTemp6 = (fConst0 * ((0.00100000005f * float(input4[i])) + 0.00499999989f)); - float fTemp7 = (fTemp6 + 4.99999987e-06f); - int iTemp8 = int(fTemp7); - float fTemp9 = std::floor(fTemp7); - float fTemp10 = (fConst5 * ((fVec0[((IOTA - std::min(iConst18, std::max(0, iTemp8))) & 16383)] * (0.0f - (fTemp6 + (-1.0f - fTemp9)))) + ((fTemp6 - fTemp9) * fVec0[((IOTA - std::min(iConst18, std::max(0, (iTemp8 + 1)))) & 16383)]))); - output1[i] = FAUSTFLOAT(fTemp10); - float fTemp11 = (fConst0 * ((0.00100000005f * float(input0[i])) + 0.00499999989f)); - float fTemp12 = (fTemp11 + 4.99999987e-06f); - int iTemp13 = int(fTemp12); - float fTemp14 = std::floor(fTemp12); - output2[i] = FAUSTFLOAT((fConst5 * ((fVec0[((IOTA - std::min(iConst18, std::max(0, iTemp13))) & 16383)] * (0.0f - (fTemp11 + (-1.0f - fTemp14)))) + ((fTemp11 - fTemp14) * fVec0[((IOTA - std::min(iConst18, std::max(0, (iTemp13 + 1)))) & 16383)])))); - output3[i] = FAUSTFLOAT(fTemp5); - output4[i] = FAUSTFLOAT(fTemp10); - float fTemp15 = (fConst0 * ((0.00100000005f * float(input1[i])) + 0.00499999989f)); - float fTemp16 = (fTemp15 + 4.99999987e-06f); - int iTemp17 = int(fTemp16); - float fTemp18 = std::floor(fTemp16); - output5[i] = FAUSTFLOAT((fConst5 * ((fVec0[((IOTA - std::min(iConst18, std::max(0, iTemp17))) & 16383)] * (0.0f - (fTemp15 + (-1.0f - fTemp18)))) + ((fTemp15 - fTemp18) * fVec0[((IOTA - std::min(iConst18, std::max(0, (iTemp17 + 1)))) & 16383)])))); + int iTemp4 = std::min(iConst18, std::max(0, iTemp3)); + float fTemp5 = std::floor(fTemp2); + float fTemp6 = (0.0f - (fTemp1 + (-1.0f - fTemp5))); + float fTemp7 = (fTemp1 - fTemp5); + int iTemp8 = std::min(iConst18, std::max(0, (iTemp3 + 1))); + output0[i] = FAUSTFLOAT((fConst5 * ((fVec0[((IOTA - iTemp4) & 16383)] * fTemp6) + (fTemp7 * fVec0[((IOTA - iTemp8) & 16383)])))); + float fTemp9 = (fConst0 * ((0.00100000005f * float(input3[i])) + 0.00499999989f)); + float fTemp10 = (fTemp9 + 4.99999987e-06f); + int iTemp11 = int(fTemp10); + int iTemp12 = std::min(iConst18, std::max(0, iTemp11)); + float fTemp13 = std::floor(fTemp10); + float fTemp14 = (0.0f - (fTemp9 + (-1.0f - fTemp13))); + float fTemp15 = (fTemp9 - fTemp13); + int iTemp16 = std::min(iConst18, std::max(0, (iTemp11 + 1))); + output1[i] = FAUSTFLOAT((fConst5 * ((fVec0[((IOTA - iTemp12) & 16383)] * fTemp14) + (fTemp15 * fVec0[((IOTA - iTemp16) & 16383)])))); + float fTemp17 = (fConst0 * ((0.00100000005f * float(input4[i])) + 0.00499999989f)); + float fTemp18 = (fTemp17 + 4.99999987e-06f); + int iTemp19 = int(fTemp18); + int iTemp20 = std::min(iConst18, std::max(0, iTemp19)); + float fTemp21 = std::floor(fTemp18); + float fTemp22 = (0.0f - (fTemp17 + (-1.0f - fTemp21))); + float fTemp23 = (fTemp17 - fTemp21); + int iTemp24 = std::min(iConst18, std::max(0, (iTemp19 + 1))); + output2[i] = FAUSTFLOAT((fConst5 * ((fVec0[((IOTA - iTemp20) & 16383)] * fTemp22) + (fTemp23 * fVec0[((IOTA - iTemp24) & 16383)])))); + fRec5[0] = (float(input1[i]) - (fConst12 * ((fConst13 * fRec5[1]) + (fConst14 * fRec5[2])))); + fRec4[0] = (0.0f - (fConst12 * (((fConst13 * fRec4[1]) + (fConst14 * fRec4[2])) - (fConst8 * ((fRec5[1] + (0.5f * fRec5[0])) + (0.5f * fRec5[2])))))); + fRec3[0] = ((fConst11 * ((fRec4[1] + (0.5f * fRec4[0])) + (0.5f * fRec4[2]))) - (fConst15 * ((fConst16 * fRec3[1]) + (fConst17 * fRec3[2])))); + float fTemp25 = ((fRec3[1] + (0.5f * fRec3[0])) + (0.5f * fRec3[2])); + fVec1[(IOTA & 16383)] = fTemp25; + output3[i] = FAUSTFLOAT((fConst5 * ((fTemp6 * fVec1[((IOTA - iTemp4) & 16383)]) + (fTemp7 * fVec1[((IOTA - iTemp8) & 16383)])))); + output4[i] = FAUSTFLOAT((fConst5 * ((fTemp14 * fVec1[((IOTA - iTemp12) & 16383)]) + (fTemp15 * fVec1[((IOTA - iTemp16) & 16383)])))); + output5[i] = FAUSTFLOAT((fConst5 * ((fTemp22 * fVec1[((IOTA - iTemp20) & 16383)]) + (fTemp23 * fVec1[((IOTA - iTemp24) & 16383)])))); fRec2[2] = fRec2[1]; fRec2[1] = fRec2[0]; fRec1[2] = fRec1[1]; @@ -353,6 +380,12 @@ class Delay3PhaseDigitalStereoDsp : public dsp { fRec0[2] = fRec0[1]; fRec0[1] = fRec0[0]; IOTA = (IOTA + 1); + fRec5[2] = fRec5[1]; + fRec5[1] = fRec5[0]; + fRec4[2] = fRec4[1]; + fRec4[1] = fRec4[0]; + fRec3[2] = fRec3[1]; + fRec3[1] = fRec3[0]; } } diff --git a/plugins/string-machine-chorus/ChorusPlugin.cpp b/plugins/string-machine-chorus/ChorusPlugin.cpp index 691d4da..d419632 100644 --- a/plugins/string-machine-chorus/ChorusPlugin.cpp +++ b/plugins/string-machine-chorus/ChorusPlugin.cpp @@ -61,24 +61,22 @@ void ChorusPlugin::initParameter(uint32_t index, Parameter ¶meter) float ChorusPlugin::getParameterValue(uint32_t index) const { - const SolinaChorus &chorus = fChorus[0]; - switch (index) { case pIdBypass: return fBypass; case pIdChoDepth: - return chorus.getLfo().get_globaldepth(); + return fChorus.getLfo().get_globaldepth(); case pIdChoRate1: - return chorus.getLfo().get_rate1(); + return fChorus.getLfo().get_rate1(); case pIdChoDepth1: - return chorus.getLfo().get_depth1(); + return fChorus.getLfo().get_depth1(); case pIdChoRate2: - return chorus.getLfo().get_rate2(); + return fChorus.getLfo().get_rate2(); case pIdChoDepth2: - return chorus.getLfo().get_depth2(); + return fChorus.getLfo().get_depth2(); case pIdChoModel: - return chorus.getAnalogMode(); + return fChorus.getAnalogMode(); case pIdWetGain: return fWetGain; @@ -99,28 +97,22 @@ void ChorusPlugin::setParameterValue(uint32_t index, float value) break; case pIdChoDepth: - for (SolinaChorus &chorus : fChorus) - chorus.getLfo().set_globaldepth(value); + fChorus.getLfo().set_globaldepth(value); break; case pIdChoRate1: - for (SolinaChorus &chorus : fChorus) - chorus.getLfo().set_rate1(value); + fChorus.getLfo().set_rate1(value); break; case pIdChoDepth1: - for (SolinaChorus &chorus : fChorus) - chorus.getLfo().set_depth1(value); + fChorus.getLfo().set_depth1(value); break; case pIdChoRate2: - for (SolinaChorus &chorus : fChorus) - chorus.getLfo().set_rate2(value); + fChorus.getLfo().set_rate2(value); break; case pIdChoDepth2: - for (SolinaChorus &chorus : fChorus) - chorus.getLfo().set_depth2(value); + fChorus.getLfo().set_depth2(value); break; case pIdChoModel: - for (SolinaChorus &chorus : fChorus) - chorus.setAnalogMode((int)value); + fChorus.setAnalogMode((int)value); break; case pIdWetGain: @@ -140,10 +132,8 @@ void ChorusPlugin::activate() { double sampleRate = getSampleRate(); - for (SolinaChorus &chorus : fChorus) { - chorus.init(sampleRate); - chorus.setEnabled(true); - } + fChorus.init(sampleRate); + fChorus.setEnabled(true); fWasBypassed = false; } @@ -161,26 +151,30 @@ void ChorusPlugin::run(const float **inputs, float **outputs, uint32_t totalFram if (bypass) { auto checked_memcpy = [](void *dst, const void *src, size_t count) { if (dst != src) memcpy(dst, src, count); }; - if (DISTRHO_PLUGIN_NUM_INPUTS == 1) { - checked_memcpy(outputs[0], inputs[0], totalFrames * sizeof(float)); - checked_memcpy(outputs[1], inputs[0], totalFrames * sizeof(float)); - } - else if (DISTRHO_PLUGIN_NUM_INPUTS == 2) { - checked_memcpy(outputs[0], inputs[0], totalFrames * sizeof(float)); - checked_memcpy(outputs[1], inputs[1], totalFrames * sizeof(float)); - } +#if DISTRHO_PLUGIN_NUM_INPUTS == 1 + checked_memcpy(outputs[0], inputs[0], totalFrames * sizeof(float)); + checked_memcpy(outputs[1], inputs[0], totalFrames * sizeof(float)); +#elif DISTRHO_PLUGIN_NUM_INPUTS == 2 + checked_memcpy(outputs[0], inputs[0], totalFrames * sizeof(float)); + checked_memcpy(outputs[1], inputs[1], totalFrames * sizeof(float)); +#endif return; } - if (wasBypassed) { - for (SolinaChorus &chorus : fChorus) - chorus.clear(); - } + if (wasBypassed) + fChorus.clear(); WebCore::DenormalDisabler denormalsDisabled; constexpr unsigned bufferLimit = StringSynthDefs::BufferLimit; +#if DISTRHO_PLUGIN_NUM_INPUTS == 1 + const float *in = inputs[0]; +#elif DISTRHO_PLUGIN_NUM_INPUTS == 2 + const float *inL = inputs[0]; + const float *inR = inputs[1]; +#endif + float *outL = outputs[0]; float *outR = outputs[1]; @@ -196,33 +190,30 @@ void ChorusPlugin::run(const float **inputs, float **outputs, uint32_t totalFram float mixL[bufferLimit]; float mixR[bufferLimit]; - if (DISTRHO_PLUGIN_NUM_INPUTS == 1) { - const float *input = inputs[0]; - for (uint32_t i = 0; i < frames; ++i) - mixL[i] = dryGain * input[frameIndex + i]; - memcpy(mixR, mixL, frames * sizeof(float)); - } - else if (DISTRHO_PLUGIN_NUM_INPUTS == 2) { - const float *inputL = inputs[0]; - const float *inputR = inputs[1]; - for (uint32_t i = 0; i < frames; ++i) { - mixL[i] = dryGain * inputL[frameIndex + i]; - mixR[i] = dryGain * inputR[frameIndex + i]; - } +#if DISTRHO_PLUGIN_NUM_INPUTS == 1 + for (uint32_t i = 0; i < frames; ++i) + mixL[i] = dryGain * in[frameIndex + i]; + memcpy(mixR, mixL, frames * sizeof(float)); +#elif DISTRHO_PLUGIN_NUM_INPUTS == 2 + for (uint32_t i = 0; i < frames; ++i) { + mixL[i] = dryGain * inL[frameIndex + i]; + mixR[i] = dryGain * inR[frameIndex + i]; } - - for (unsigned channel = 0; channel < DISTRHO_PLUGIN_NUM_INPUTS; ++channel) { - float tempL[bufferLimit]; - float tempR[bufferLimit]; - float tempDiscard[bufferLimit]; - - float *outputsTemp[3] = { tempL, tempR, tempDiscard }; - fChorus[channel].process(inputs[channel] + frameIndex, outputsTemp, frames); - - for (uint32_t i = 0; i < frames; ++i) { - mixL[i] += wetGain * tempL[i]; - mixR[i] += wetGain * tempR[i]; - } +#endif + + float tempL[bufferLimit]; + float tempR[bufferLimit]; + float *outputsTemp[2] = { tempL, tempR }; +#if DISTRHO_PLUGIN_NUM_INPUTS == 1 + fChorus.process(in + frameIndex, outputsTemp, frames); +#elif DISTRHO_PLUGIN_NUM_INPUTS == 2 + const float *inputsTemp[2] = { inL + frameIndex, inR + frameIndex }; + fChorus.process(inputsTemp, outputsTemp, frames); +#endif + + for (uint32_t i = 0; i < frames; ++i) { + mixL[i] += wetGain * tempL[i]; + mixR[i] += wetGain * tempR[i]; } memcpy(outL + frameIndex, mixL, frames * sizeof(float)); diff --git a/plugins/string-machine-chorus/ChorusPlugin.hpp b/plugins/string-machine-chorus/ChorusPlugin.hpp index e7d927b..b9c33ea 100644 --- a/plugins/string-machine-chorus/ChorusPlugin.hpp +++ b/plugins/string-machine-chorus/ChorusPlugin.hpp @@ -1,6 +1,7 @@ #pragma once #include "ChorusShared.hpp" #include "SolinaChorus.h" +#include "SolinaChorusStereo.h" class ChorusPlugin : public Plugin { public: @@ -30,5 +31,9 @@ class ChorusPlugin : public Plugin { float fWetGain = 0.0; float fDryGain = 0.0; - SolinaChorus fChorus[DISTRHO_PLUGIN_NUM_INPUTS]; +#if DISTRHO_PLUGIN_NUM_INPUTS == 1 + SolinaChorus fChorus; +#elif DISTRHO_PLUGIN_NUM_INPUTS == 2 + SolinaChorusStereo fChorus; +#endif }; diff --git a/plugins/string-machine-chorus/ChorusShared.cpp b/plugins/string-machine-chorus/ChorusShared.cpp index 8bd1206..23f5120 100644 --- a/plugins/string-machine-chorus/ChorusShared.cpp +++ b/plugins/string-machine-chorus/ChorusShared.cpp @@ -12,33 +12,33 @@ void InitParameter(uint32_t index, Parameter ¶meter) case pIdChoDepth: parameter.symbol = "cho_depth"; parameter.name = "Chorus global depth"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "%"; parameter.ranges = ParameterRanges(100.0, 0.0, 100.0); break; case pIdChoRate1: parameter.symbol = "cho_rate1"; parameter.name = "Chorus rate 1"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(5.8346, 3.0, 9.0); break; case pIdChoDepth1: parameter.symbol = "cho_depth1"; parameter.name = "Chorus depth 1"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "%"; parameter.ranges = ParameterRanges(30.71, 0.0, 100.0); break; case pIdChoRate2: parameter.symbol = "cho_rate2"; parameter.name = "Chorus rate 2"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(0.5835, 0.3, 0.9); break; case pIdChoDepth2: parameter.symbol = "cho_depth2"; parameter.name = "Chorus depth 2"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "%"; parameter.ranges = ParameterRanges(90.55, 0.0, 100.0); break; @@ -56,14 +56,14 @@ void InitParameter(uint32_t index, Parameter ¶meter) case pIdWetGain: parameter.symbol = "wet_gain"; parameter.name = "Wet gain"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "dB"; parameter.ranges = ParameterRanges(-6.0, -60.0, +20.0); break; case pIdDryGain: parameter.symbol = "dry_gain"; parameter.name = "Dry gain"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "dB"; parameter.ranges = ParameterRanges(-60.0, -60.0, +20.0); break; diff --git a/plugins/string-machine/Makefile b/plugins/string-machine/Makefile index 7326822..b476e3c 100644 --- a/plugins/string-machine/Makefile +++ b/plugins/string-machine/Makefile @@ -19,6 +19,7 @@ NAME = string-machine FILES_SHARED = \ StringMachineShared.cpp \ + StringMachinePresets.cpp \ sources/StringOsc.cpp \ sources/StringSynth.cpp \ sources/StringFilters.cpp \ @@ -81,6 +82,8 @@ artwork: $(RES2C) Artwork artwork .PHONY: artwork +# -------------------------------------------------------------- + layouts: StringMachineUILayouts.Main.inc .PHONY: layouts @@ -92,3 +95,16 @@ StringMachineUILayouts.%.inc: layouts/%.fl $(LAYOUT_TOOL) $(LAYOUT_TOOL) $< > $@ # -------------------------------------------------------------- + +presets: StringMachinePresets.inc +.PHONY: presets + +PRESETS_TOOL := ../../tools/presets/bin/presets$(APP_EXT) +$(PRESETS_TOOL): + $(MAKE) -C ../../tools/presets + +StringMachinePresets.inc: $(PRESETS_TOOL) + $(PRESETS_TOOL) ../../presets/string-machine/*.json > $@ +.PHONY: StringMachinePresets.inc + +# -------------------------------------------------------------- diff --git a/plugins/string-machine/StringMachinePlugin.cpp b/plugins/string-machine/StringMachinePlugin.cpp index 9ef0158..6e107a9 100644 --- a/plugins/string-machine/StringMachinePlugin.cpp +++ b/plugins/string-machine/StringMachinePlugin.cpp @@ -4,7 +4,7 @@ #include "DenormalDisabler.h" StringMachinePlugin::StringMachinePlugin() - : Plugin(Parameter_Count, NumPrograms, State_Count) + : Plugin(Parameter_Count, NumPresets, State_Count) { double sampleRate = getSampleRate(); fSynth.init(sampleRate); @@ -13,6 +13,7 @@ StringMachinePlugin::StringMachinePlugin() Parameter param; InitParameter(p, param); setParameterValue(p, param.ranges.def); + fParameterDefaults[p] = param.ranges.def; } } @@ -75,8 +76,10 @@ float StringMachinePlugin::getParameterValue(uint32_t index) const return synth.getOscSettings().pwmDepth; case pIdOscPwmFrequency: return synth.getOscSettings().pwmFrequency; - case pIdOscEnhance: - return synth.getOscSettings().enhance; + case pIdOscEnhanceUpper: + return synth.getOscSettings().enhanceUpper; + case pIdOscEnhanceLower: + return synth.getOscSettings().enhanceLower; case pIdFltLpCutoffUpper: return synth.getFltSettings().lowpassUpperCutoff; @@ -169,8 +172,11 @@ void StringMachinePlugin::setParameterValue(uint32_t index, float value) case pIdOscPwmFrequency: synth.getOscSettings().pwmFrequency = value; break; - case pIdOscEnhance: - synth.getOscSettings().enhance = value; + case pIdOscEnhanceUpper: + synth.getOscSettings().enhanceUpper = value; + break; + case pIdOscEnhanceLower: + synth.getOscSettings().enhanceLower = value; break; case pIdFltLpCutoffUpper: @@ -261,17 +267,21 @@ void StringMachinePlugin::setParameterValue(uint32_t index, float value) void StringMachinePlugin::initProgramName(uint32_t index, String &programName) { - DISTRHO_SAFE_ASSERT_RETURN(index < NumPrograms, ); + DISTRHO_SAFE_ASSERT_RETURN(index < NumPresets, ); - programName = Programs[index].name; + programName = Presets[index].name; } void StringMachinePlugin::loadProgram(uint32_t index) { - DISTRHO_SAFE_ASSERT_RETURN(index < NumPrograms, ); + DISTRHO_SAFE_ASSERT_RETURN(index < NumPresets, ); + + std::array values = fParameterDefaults; + for (const Preset::Parameter *pp = Presets[index].parameters; pp->id != -1; ++pp) + values[pp->id] = pp->value; for (unsigned p = 0; p < Parameter_Count; ++p) - setParameterValue(p, Programs[index].values[p]); + setParameterValue(p, values[p]); } void StringMachinePlugin::activate() diff --git a/plugins/string-machine/StringMachinePlugin.hpp b/plugins/string-machine/StringMachinePlugin.hpp index 7f73e53..db55995 100644 --- a/plugins/string-machine/StringMachinePlugin.hpp +++ b/plugins/string-machine/StringMachinePlugin.hpp @@ -2,6 +2,7 @@ #include "StringMachineShared.hpp" #include "StringSynth.h" #include "dsp/AmpFollower.h" +#include class StringMachinePlugin : public Plugin { public: @@ -32,4 +33,5 @@ class StringMachinePlugin : public Plugin { private: StringSynth fSynth; AmpFollower fOutputLevelFollower[2]; + std::array fParameterDefaults; }; diff --git a/plugins/string-machine/StringMachinePresets.cpp b/plugins/string-machine/StringMachinePresets.cpp new file mode 100644 index 0000000..d76d22e --- /dev/null +++ b/plugins/string-machine/StringMachinePresets.cpp @@ -0,0 +1,2 @@ +#include "StringMachinePresets.hpp" +#include "StringMachinePresets.inc" diff --git a/plugins/string-machine/StringMachinePresets.hpp b/plugins/string-machine/StringMachinePresets.hpp index 18e714a..b43ffac 100644 --- a/plugins/string-machine/StringMachinePresets.hpp +++ b/plugins/string-machine/StringMachinePresets.hpp @@ -1,718 +1,13 @@ #pragma once #include "DistrhoPluginInfo.h" -#if !defined(DECL_IGNORABLE) -#if defined(__GNUC__) -#define DECL_IGNORABLE __attribute__((unused)) -#else -#define DECL_IGNORABLE -#endif -#endif - -struct Program { +struct Preset { const char *name; - const char *group; - float values[Parameter_Count]; -}; - -DECL_IGNORABLE static const Program Programs[] = { - -/* - Melodic contributed by sm7x7, from the Zynthian forums - https://discourse.zynthian.org/t/any-lv2-arp-solina-roland-rs-type-string-machines/3627/20 - */ - -{"001-String Short 1 BB", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ 7.71654, -/* Oscillator HP Cutoff 8' */ 7.71654, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.25, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 5.2, -/* Filters HP Cutoff 4' */ 12.2, -/* Filters LP Cutoff 8' */ 16.4, -/* Filters HP Cutoff 8' */ -0.4, -/* Filters HS Cutoff 4' */ 24.8, -/* Filters HS Boost 4' */ 6, -/* Mix Gain 4' */ 0, -/* Mix Gain 8' */ 0, -/* Envelope attack */ 0.1939, -/* Envelope hold */ 0.01, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 1, -/* Chorus global depth */ 99.2126, -/* Chorus rate 1 */ 5.7874, -/* Chorus depth 1 */ 30.7087, -/* Chorus rate 2 */ 0.583465, -/* Chorus depth 2 */ 89.7638, -/* Chorus model */ 1, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"002-String Short 2 Br", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ 7.71654, -/* Oscillator HP Cutoff 8' */ 7.71654, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.25, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 5.2, -/* Filters HP Cutoff 4' */ 12.2, -/* Filters LP Cutoff 8' */ 16.4, -/* Filters HP Cutoff 8' */ -0.4, -/* Filters HS Cutoff 4' */ 24.8, -/* Filters HS Boost 4' */ 6, -/* Mix Gain 4' */ 0, -/* Mix Gain 8' */ 0, -/* Envelope attack */ 0.1939, -/* Envelope hold */ 0.01, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 1, -/* Chorus global depth */ 99.2126, -/* Chorus rate 1 */ 5.7874, -/* Chorus depth 1 */ 30.7087, -/* Chorus rate 2 */ 0.583465, -/* Chorus depth 2 */ 89.7638, -/* Chorus model */ 0, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"003-Default [All in left]", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ -20, -/* Oscillator HP Cutoff 8' */ -20, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ -20, -/* Filters HP Cutoff 4' */ -20, -/* Filters LP Cutoff 8' */ -20, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ -20, -/* Filters HS Boost 4' */ -20, -/* Mix Gain 4' */ -20, -/* Mix Gain 8' */ -20, -/* Envelope attack */ 0.01, -/* Envelope hold */ 0.01, -/* Envelope decay */ 0.01, -/* Envelope sustain */ -60, -/* Envelope release */ 0.01, -/* Chorus enabled */ 0, -/* Chorus global depth */ 0, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 0, -/* Chorus model */ 0, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"004-Plain 8' 1", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ -20, -/* Oscillator HP Cutoff 8' */ 20.315, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ -20, -/* Filters HP Cutoff 4' */ 50.5512, -/* Filters LP Cutoff 8' */ 50.5512, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ 50.5512, -/* Filters HS Boost 4' */ -20, -/* Mix Gain 4' */ -20, -/* Mix Gain 8' */ -10.8661, -/* Envelope attack */ 0.01, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 1, -/* Chorus global depth */ 99.2126, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 99.2126, -/* Chorus model */ 1, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"005-Plain 4' 1", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ -20, -/* Oscillator HP Cutoff 8' */ 20.315, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ -20, -/* Filters HP Cutoff 4' */ 50.5512, -/* Filters LP Cutoff 8' */ 50.5512, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ 50.5512, -/* Filters HS Boost 4' */ -20, -/* Mix Gain 4' */ -20, -/* Mix Gain 8' */ -10.8661, -/* Envelope attack */ 0.01, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 0, -/* Chorus global depth */ 0, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 0, -/* Chorus model */ 0, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"006-Moskito 4'", "By S.M.", { -/* Oscillator detune */ 1, -/* Oscillator HP Cutoff 4' */ 20.315, -/* Oscillator HP Cutoff 8' */ -20, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 50.5512, -/* Filters HP Cutoff 4' */ -20, -/* Filters LP Cutoff 8' */ -20, -/* Filters HP Cutoff 8' */ 50.5512, -/* Filters HS Cutoff 4' */ -20, -/* Filters HS Boost 4' */ -0.15748, -/* Mix Gain 4' */ -10.2362, -/* Mix Gain 8' */ -20, -/* Envelope attack */ 0.01, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 0, -/* Chorus global depth */ 0, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 0, -/* Chorus model */ 0, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"007-Moskito 8'", "By S.M.", { -/* Oscillator detune */ 1, -/* Oscillator HP Cutoff 4' */ -20, -/* Oscillator HP Cutoff 8' */ 20.315, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ -20, -/* Filters HP Cutoff 4' */ 50.5512, -/* Filters LP Cutoff 8' */ 50.5512, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ 50.5512, -/* Filters HS Boost 4' */ -20, -/* Mix Gain 4' */ -20, -/* Mix Gain 8' */ -10.8661, -/* Envelope attack */ 0.01, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 0, -/* Chorus global depth */ 0, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 0, -/* Chorus model */ 0, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"008-Plain 4' 2", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ 20.315, -/* Oscillator HP Cutoff 8' */ -20, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 50.5512, -/* Filters HP Cutoff 4' */ -20, -/* Filters LP Cutoff 8' */ -20, -/* Filters HP Cutoff 8' */ 50.5512, -/* Filters HS Cutoff 4' */ -20, -/* Filters HS Boost 4' */ -0.15748, -/* Mix Gain 4' */ -10.2362, -/* Mix Gain 8' */ -20, -/* Envelope attack */ 0.01, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 0, -/* Chorus global depth */ 0, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 0, -/* Chorus model */ 0, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"009-Plain 8' 2", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ -20, -/* Oscillator HP Cutoff 8' */ 20.315, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ -20, -/* Filters HP Cutoff 4' */ 50.5512, -/* Filters LP Cutoff 8' */ 50.5512, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ 50.5512, -/* Filters HS Boost 4' */ -20, -/* Mix Gain 4' */ -20, -/* Mix Gain 8' */ -10.8661, -/* Envelope attack */ 0.01, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 0, -/* Chorus global depth */ 0, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 0, -/* Chorus model */ 0, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"010-Slow 8' 1", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ -20, -/* Oscillator HP Cutoff 8' */ 20.315, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ -20, -/* Filters HP Cutoff 4' */ 50.5512, -/* Filters LP Cutoff 8' */ 50.5512, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ 50.5512, -/* Filters HS Boost 4' */ -20, -/* Mix Gain 4' */ -20, -/* Mix Gain 8' */ -10.8661, -/* Envelope attack */ 0.01, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 1, -/* Chorus global depth */ 99.2126, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 99.2126, -/* Chorus model */ 1, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"011-Slow 4' 1", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ 20.315, -/* Oscillator HP Cutoff 8' */ -20, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 50.5512, -/* Filters HP Cutoff 4' */ -20, -/* Filters LP Cutoff 8' */ -20, -/* Filters HP Cutoff 8' */ 50.5512, -/* Filters HS Cutoff 4' */ -20, -/* Filters HS Boost 4' */ -0.15748, -/* Mix Gain 4' */ -10.2362, -/* Mix Gain 8' */ -20, -/* Envelope attack */ 0.01, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.01, -/* Chorus enabled */ 1, -/* Chorus global depth */ 100, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 100, -/* Chorus model */ 0, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"012-Soft 4' Mid", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ 10.8661, -/* Oscillator HP Cutoff 8' */ -20, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 0.944882, -/* Filters HP Cutoff 4' */ -0.15748, -/* Filters LP Cutoff 8' */ -20, -/* Filters HP Cutoff 8' */ 50.5512, -/* Filters HS Cutoff 4' */ 100.157, -/* Filters HS Boost 4' */ 20, -/* Mix Gain 4' */ 0, -/* Mix Gain 8' */ -20, -/* Envelope attack */ 0.0886614, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.481969, -/* Chorus enabled */ 1, -/* Chorus global depth */ 50.3937, -/* Chorus rate 1 */ 4.98425, -/* Chorus depth 1 */ 51.1811, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 50.3937, -/* Chorus model */ 1, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"013-Soft 8' Mid", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ -20, -/* Oscillator HP Cutoff 8' */ -20, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ -0.15748, -/* Filters HP Cutoff 4' */ 0.944882, -/* Filters LP Cutoff 8' */ 20.7874, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ -0.15748, -/* Filters HS Boost 4' */ 0.15748, -/* Mix Gain 4' */ -20, -/* Mix Gain 8' */ 0, -/* Envelope attack */ 0.0886614, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.481969, -/* Chorus enabled */ 1, -/* Chorus global depth */ 50.3937, -/* Chorus rate 1 */ 4.98425, -/* Chorus depth 1 */ 51.1811, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 50.3937, -/* Chorus model */ 1, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"014-Mix No Mids", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ 33.5433, -/* Oscillator HP Cutoff 8' */ -7.40157, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 60.4724, -/* Filters HP Cutoff 4' */ -0.15748, -/* Filters LP Cutoff 8' */ -0.15748, -/* Filters HP Cutoff 8' */ 10.8661, -/* Filters HS Cutoff 4' */ -0.15748, -/* Filters HS Boost 4' */ 0.787402, -/* Mix Gain 4' */ -10.5512, -/* Mix Gain 8' */ -0.787402, -/* Envelope attack */ 0.0886614, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.481969, -/* Chorus enabled */ 1, -/* Chorus global depth */ 50.3937, -/* Chorus rate 1 */ 6.02362, -/* Chorus depth 1 */ 30.7087, -/* Chorus rate 2 */ 0.602362, -/* Chorus depth 2 */ 60.6299, -/* Chorus model */ 1, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"015-Full 4'+8' 1", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ 33.5433, -/* Oscillator HP Cutoff 8' */ -7.40157, -/* Oscillator PWM Depth */ 0, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 22.9921, -/* Filters HP Cutoff 4' */ 38.4252, -/* Filters LP Cutoff 8' */ 27.4016, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ 54.9606, -/* Filters HS Boost 4' */ -0.787402, -/* Mix Gain 4' */ -3.30709, -/* Mix Gain 8' */ -1.5748, -/* Envelope attack */ 0.0886614, -/* Envelope hold */ 10, -/* Envelope decay */ 10, -/* Envelope sustain */ 0, -/* Envelope release */ 0.481969, -/* Chorus enabled */ 1, -/* Chorus global depth */ 50.3937, -/* Chorus rate 1 */ 6.02362, -/* Chorus depth 1 */ 30.7087, -/* Chorus rate 2 */ 0.602362, -/* Chorus depth 2 */ 60.6299, -/* Chorus model */ 1, -/* Master Gain */ -0.15748, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, - -/* - Percussions contributed by sm7x7, from the Zynthian forums - https://discourse.zynthian.org/t/any-lv2-arp-solina-roland-rs-type-string-machines/3627/20 - */ - -{"016-Kick (-2 oct)", "By S.M.", { -/* Oscillator detune */ 0, -/* Oscillator HP Cutoff 4' */ -20, -/* Oscillator HP Cutoff 8' */ 7.71654, -/* Oscillator PWM Depth */ 100, -/* Oscillator PWM Frequency */ 5, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ -20, -/* Filters HP Cutoff 4' */ -20, -/* Filters LP Cutoff 8' */ 14.1732, -/* Filters HP Cutoff 8' */ -20, -/* Filters HS Cutoff 4' */ -20, -/* Filters HS Boost 4' */ -20, -/* Mix Gain 4' */ -20, -/* Mix Gain 8' */ 0, -/* Envelope attack */ 0.01, -/* Envelope hold */ 0.01, -/* Envelope decay */ 0.01, -/* Envelope sustain */ -60, -/* Envelope release */ 0.01, -/* Chorus enabled */ 0, -/* Chorus global depth */ 0, -/* Chorus rate 1 */ 3, -/* Chorus depth 1 */ 0, -/* Chorus rate 2 */ 0.3, -/* Chorus depth 2 */ 0, -/* Chorus model */ 0, -/* Master Gain */ 10.5512, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"017-Hat-ish Hit", "By S.M.", { -/* Oscillator detune */ 0.692913, -/* Oscillator HP Cutoff 4' */ 50.5512, -/* Oscillator HP Cutoff 8' */ 37.3228, -/* Oscillator PWM Depth */ 99.2126, -/* Oscillator PWM Frequency */ 5, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 102.362, -/* Filters HP Cutoff 4' */ 107.874, -/* Filters LP Cutoff 8' */ 120, -/* Filters HP Cutoff 8' */ 120, -/* Filters HS Cutoff 4' */ 114.488, -/* Filters HS Boost 4' */ 19.3701, -/* Mix Gain 4' */ 0, -/* Mix Gain 8' */ -7.55906, -/* Envelope attack */ 0.01, -/* Envelope hold */ 0.01, -/* Envelope decay */ 0.01, -/* Envelope sustain */ -60, -/* Envelope release */ 0.01, -/* Chorus enabled */ 1, -/* Chorus global depth */ 100, -/* Chorus rate 1 */ 9, -/* Chorus depth 1 */ 100, -/* Chorus rate 2 */ 0.9, -/* Chorus depth 2 */ 99.2126, -/* Chorus model */ 0, -/* Master Gain */ 10.5512, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"018-Shaker (Mid C)", "By S.M.", { -/* Oscillator detune */ 1, -/* Oscillator HP Cutoff 4' */ 42.3622, -/* Oscillator HP Cutoff 8' */ 36.6929, -/* Oscillator PWM Depth */ 99.2126, -/* Oscillator PWM Frequency */ 0.1, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 58.2677, -/* Filters HP Cutoff 4' */ 62.6772, -/* Filters LP Cutoff 8' */ 63.7795, -/* Filters HP Cutoff 8' */ 88.0315, -/* Filters HS Cutoff 4' */ 40.6299, -/* Filters HS Boost 4' */ 17.4803, -/* Mix Gain 4' */ -12.9134, -/* Mix Gain 8' */ -17.4803, -/* Envelope attack */ 0.167323, -/* Envelope hold */ 0.01, -/* Envelope decay */ 0.324646, -/* Envelope sustain */ -38.7402, -/* Envelope release */ 0.245984, -/* Chorus enabled */ 1, -/* Chorus global depth */ 99.2126, -/* Chorus rate 1 */ 9, -/* Chorus depth 1 */ 99.2126, -/* Chorus rate 2 */ 0.9, -/* Chorus depth 2 */ 99.2126, -/* Chorus model */ 1, -/* Master Gain */ 0.472441, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, -{"019-Snare-ish (3-4 keys-at-once)", "By S.M.", { -/* Oscillator detune */ 1, -/* Oscillator HP Cutoff 4' */ 60, -/* Oscillator HP Cutoff 8' */ 38.5827, -/* Oscillator PWM Depth */ 100, -/* Oscillator PWM Frequency */ 5, -/* Oscillator enhance */ 0, -/* Filters LP Cutoff 4' */ 49.4488, -/* Filters HP Cutoff 4' */ 41.7323, -/* Filters LP Cutoff 8' */ 50.5512, -/* Filters HP Cutoff 8' */ 47.2441, -/* Filters HS Cutoff 4' */ 30.7087, -/* Filters HS Boost 4' */ 2.67717, -/* Mix Gain 4' */ -10.0787, -/* Mix Gain 8' */ -12.7559, -/* Envelope attack */ 0.01, -/* Envelope hold */ 0.01, -/* Envelope decay */ 0.245984, -/* Envelope sustain */ -60, -/* Envelope release */ 0.167323, -/* Chorus enabled */ 1, -/* Chorus global depth */ 100, -/* Chorus rate 1 */ 9, -/* Chorus depth 1 */ 100, -/* Chorus rate 2 */ 0.9, -/* Chorus depth 2 */ 100, -/* Chorus model */ 1, -/* Master Gain */ 15.5906, -/* Polyphony */ 16, -/* Oscillator detune 4' */ 0, -/* Oscillator detune 8' */ 0, -/* Chorus phase 1 */ 0, -/* Chorus phase 2 */ 0, -/* Master level 1 */ 0, -/* Master level 2 */ 0, -}}, - + struct Group { const char *name; }; + struct Parameter { int id; float value; }; + const Group *group; + const Parameter *parameters; }; -DECL_IGNORABLE static constexpr unsigned NumPrograms = sizeof(Programs) / sizeof(Programs[0]); +extern const Preset Presets[]; +extern const unsigned NumPresets; diff --git a/plugins/string-machine/StringMachinePresets.inc b/plugins/string-machine/StringMachinePresets.inc new file mode 100644 index 0000000..79fef4c --- /dev/null +++ b/plugins/string-machine/StringMachinePresets.inc @@ -0,0 +1,632 @@ +static const Preset::Group pg0 = {"Melodic by S.M."}; +static const Preset::Group pg1 = {"Drums by S.M."}; +static const Preset::Parameter pp0_0[] = { + {pIdChoDepth, 99.2126}, + {pIdChoDepth1, 30.7087}, + {pIdChoDepth2, 89.7638}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 5.7874}, + {pIdChoRate2, 0.583465}, + {pIdEnvAttack, 0.1939}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 0.01}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -0.4}, + {pIdFltHpCutoffUpper, 12.2}, + {pIdFltHsBoostEq, 6}, + {pIdFltHsCutoffEq, 24.8}, + {pIdFltLpCutoffLower, 16.4}, + {pIdFltLpCutoffUpper, 5.2}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, 0}, + {pIdMixGainUpper, 0}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 7.71654}, + {pIdOscHpCutoffUpper, 7.71654}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.25}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_1[] = { + {pIdChoDepth, 99.2126}, + {pIdChoDepth1, 30.7087}, + {pIdChoDepth2, 89.7638}, + {pIdChoEnabled, 1}, + {pIdChoModel, 0}, + {pIdChoRate1, 5.7874}, + {pIdChoRate2, 0.583465}, + {pIdEnvAttack, 0.1939}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 0.01}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -0.4}, + {pIdFltHpCutoffUpper, 12.2}, + {pIdFltHsBoostEq, 6}, + {pIdFltHsCutoffEq, 24.8}, + {pIdFltLpCutoffLower, 16.4}, + {pIdFltLpCutoffUpper, 5.2}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, 0}, + {pIdMixGainUpper, 0}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 7.71654}, + {pIdOscHpCutoffUpper, 7.71654}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.25}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_2[] = { + {pIdChoDepth, 0}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 0}, + {pIdChoEnabled, 0}, + {pIdChoModel, 0}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 0.01}, + {pIdEnvHold, 0.01}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, -60}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, -20}, + {pIdFltHsBoostEq, -20}, + {pIdFltHsCutoffEq, -20}, + {pIdFltLpCutoffLower, -20}, + {pIdFltLpCutoffUpper, -20}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -20}, + {pIdMixGainUpper, -20}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, -20}, + {pIdOscHpCutoffUpper, -20}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_3[] = { + {pIdChoDepth, 99.2126}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 99.2126}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, 50.5512}, + {pIdFltHsBoostEq, -20}, + {pIdFltHsCutoffEq, 50.5512}, + {pIdFltLpCutoffLower, 50.5512}, + {pIdFltLpCutoffUpper, -20}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -10.8661}, + {pIdMixGainUpper, -20}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 20.315}, + {pIdOscHpCutoffUpper, -20}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_4[] = { + {pIdChoDepth, 0}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 0}, + {pIdChoEnabled, 0}, + {pIdChoModel, 0}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, 50.5512}, + {pIdFltHsBoostEq, -20}, + {pIdFltHsCutoffEq, 50.5512}, + {pIdFltLpCutoffLower, 50.5512}, + {pIdFltLpCutoffUpper, -20}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -10.8661}, + {pIdMixGainUpper, -20}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 20.315}, + {pIdOscHpCutoffUpper, -20}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_5[] = { + {pIdChoDepth, 0}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 0}, + {pIdChoEnabled, 0}, + {pIdChoModel, 0}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, 50.5512}, + {pIdFltHpCutoffUpper, -20}, + {pIdFltHsBoostEq, -0.15748}, + {pIdFltHsCutoffEq, -20}, + {pIdFltLpCutoffLower, -20}, + {pIdFltLpCutoffUpper, 50.5512}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -20}, + {pIdMixGainUpper, -10.2362}, + {pIdOscDetune, 1}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, -20}, + {pIdOscHpCutoffUpper, 20.315}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_6[] = { + {pIdChoDepth, 0}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 0}, + {pIdChoEnabled, 0}, + {pIdChoModel, 0}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, 50.5512}, + {pIdFltHsBoostEq, -20}, + {pIdFltHsCutoffEq, 50.5512}, + {pIdFltLpCutoffLower, 50.5512}, + {pIdFltLpCutoffUpper, -20}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -10.8661}, + {pIdMixGainUpper, -20}, + {pIdOscDetune, 1}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 20.315}, + {pIdOscHpCutoffUpper, -20}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_7[] = { + {pIdChoDepth, 0}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 0}, + {pIdChoEnabled, 0}, + {pIdChoModel, 0}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, 50.5512}, + {pIdFltHpCutoffUpper, -20}, + {pIdFltHsBoostEq, -0.15748}, + {pIdFltHsCutoffEq, -20}, + {pIdFltLpCutoffLower, -20}, + {pIdFltLpCutoffUpper, 50.5512}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -20}, + {pIdMixGainUpper, -10.2362}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, -20}, + {pIdOscHpCutoffUpper, 20.315}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_8[] = { + {pIdChoDepth, 0}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 0}, + {pIdChoEnabled, 0}, + {pIdChoModel, 0}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, 50.5512}, + {pIdFltHsBoostEq, -20}, + {pIdFltHsCutoffEq, 50.5512}, + {pIdFltLpCutoffLower, 50.5512}, + {pIdFltLpCutoffUpper, -20}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -10.8661}, + {pIdMixGainUpper, -20}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 20.315}, + {pIdOscHpCutoffUpper, -20}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_9[] = { + {pIdChoDepth, 99.2126}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 99.2126}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, 50.5512}, + {pIdFltHsBoostEq, -20}, + {pIdFltHsCutoffEq, 50.5512}, + {pIdFltLpCutoffLower, 50.5512}, + {pIdFltLpCutoffUpper, -20}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -10.8661}, + {pIdMixGainUpper, -20}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 20.315}, + {pIdOscHpCutoffUpper, -20}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_10[] = { + {pIdChoDepth, 100}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 100}, + {pIdChoEnabled, 1}, + {pIdChoModel, 0}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, 50.5512}, + {pIdFltHpCutoffUpper, -20}, + {pIdFltHsBoostEq, -0.15748}, + {pIdFltHsCutoffEq, -20}, + {pIdFltLpCutoffLower, -20}, + {pIdFltLpCutoffUpper, 50.5512}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -20}, + {pIdMixGainUpper, -10.2362}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, -20}, + {pIdOscHpCutoffUpper, 20.315}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_11[] = { + {pIdChoDepth, 50.3937}, + {pIdChoDepth1, 51.1811}, + {pIdChoDepth2, 50.3937}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 4.98425}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.0886614}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.481969}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, 50.5512}, + {pIdFltHpCutoffUpper, -0.15748}, + {pIdFltHsBoostEq, 20}, + {pIdFltHsCutoffEq, 100.157}, + {pIdFltLpCutoffLower, -20}, + {pIdFltLpCutoffUpper, 0.944882}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -20}, + {pIdMixGainUpper, 0}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, -20}, + {pIdOscHpCutoffUpper, 10.8661}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_12[] = { + {pIdChoDepth, 50.3937}, + {pIdChoDepth1, 51.1811}, + {pIdChoDepth2, 50.3937}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 4.98425}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.0886614}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.481969}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, 0.944882}, + {pIdFltHsBoostEq, 0.15748}, + {pIdFltHsCutoffEq, -0.15748}, + {pIdFltLpCutoffLower, 20.7874}, + {pIdFltLpCutoffUpper, -0.15748}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, 0}, + {pIdMixGainUpper, -20}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, -20}, + {pIdOscHpCutoffUpper, -20}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_13[] = { + {pIdChoDepth, 50.3937}, + {pIdChoDepth1, 30.7087}, + {pIdChoDepth2, 60.6299}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 6.02362}, + {pIdChoRate2, 0.602362}, + {pIdEnvAttack, 0.0886614}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.481969}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, 10.8661}, + {pIdFltHpCutoffUpper, -0.15748}, + {pIdFltHsBoostEq, 0.787402}, + {pIdFltHsCutoffEq, -0.15748}, + {pIdFltLpCutoffLower, -0.15748}, + {pIdFltLpCutoffUpper, 60.4724}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -0.787402}, + {pIdMixGainUpper, -10.5512}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, -7.40157}, + {pIdOscHpCutoffUpper, 33.5433}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp0_14[] = { + {pIdChoDepth, 50.3937}, + {pIdChoDepth1, 30.7087}, + {pIdChoDepth2, 60.6299}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 6.02362}, + {pIdChoRate2, 0.602362}, + {pIdEnvAttack, 0.0886614}, + {pIdEnvDecay, 10}, + {pIdEnvHold, 10}, + {pIdEnvRelease, 0.481969}, + {pIdEnvSustain, 0}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, 38.4252}, + {pIdFltHsBoostEq, -0.787402}, + {pIdFltHsCutoffEq, 54.9606}, + {pIdFltLpCutoffLower, 27.4016}, + {pIdFltLpCutoffUpper, 22.9921}, + {pIdMasterGain, -0.15748}, + {pIdMixGainLower, -1.5748}, + {pIdMixGainUpper, -3.30709}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, -7.40157}, + {pIdOscHpCutoffUpper, 33.5433}, + {pIdOscPwmDepth, 0}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp1_0[] = { + {pIdChoDepth, 0}, + {pIdChoDepth1, 0}, + {pIdChoDepth2, 0}, + {pIdChoEnabled, 0}, + {pIdChoModel, 0}, + {pIdChoRate1, 3}, + {pIdChoRate2, 0.3}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 0.01}, + {pIdEnvHold, 0.01}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, -60}, + {pIdFltHpCutoffLower, -20}, + {pIdFltHpCutoffUpper, -20}, + {pIdFltHsBoostEq, -20}, + {pIdFltHsCutoffEq, -20}, + {pIdFltLpCutoffLower, 14.1732}, + {pIdFltLpCutoffUpper, -20}, + {pIdMasterGain, 10.5512}, + {pIdMixGainLower, 0}, + {pIdMixGainUpper, -20}, + {pIdOscDetune, 0}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 7.71654}, + {pIdOscHpCutoffUpper, -20}, + {pIdOscPwmDepth, 100}, + {pIdOscPwmFrequency, 5}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp1_1[] = { + {pIdChoDepth, 100}, + {pIdChoDepth1, 100}, + {pIdChoDepth2, 99.2126}, + {pIdChoEnabled, 1}, + {pIdChoModel, 0}, + {pIdChoRate1, 9}, + {pIdChoRate2, 0.9}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 0.01}, + {pIdEnvHold, 0.01}, + {pIdEnvRelease, 0.01}, + {pIdEnvSustain, -60}, + {pIdFltHpCutoffLower, 120}, + {pIdFltHpCutoffUpper, 107.874}, + {pIdFltHsBoostEq, 19.3701}, + {pIdFltHsCutoffEq, 114.488}, + {pIdFltLpCutoffLower, 120}, + {pIdFltLpCutoffUpper, 102.362}, + {pIdMasterGain, 10.5512}, + {pIdMixGainLower, -7.55906}, + {pIdMixGainUpper, 0}, + {pIdOscDetune, 0.692913}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 37.3228}, + {pIdOscHpCutoffUpper, 50.5512}, + {pIdOscPwmDepth, 99.2126}, + {pIdOscPwmFrequency, 5}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp1_2[] = { + {pIdChoDepth, 99.2126}, + {pIdChoDepth1, 99.2126}, + {pIdChoDepth2, 99.2126}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 9}, + {pIdChoRate2, 0.9}, + {pIdEnvAttack, 0.167323}, + {pIdEnvDecay, 0.324646}, + {pIdEnvHold, 0.01}, + {pIdEnvRelease, 0.245984}, + {pIdEnvSustain, -38.7402}, + {pIdFltHpCutoffLower, 88.0315}, + {pIdFltHpCutoffUpper, 62.6772}, + {pIdFltHsBoostEq, 17.4803}, + {pIdFltHsCutoffEq, 40.6299}, + {pIdFltLpCutoffLower, 63.7795}, + {pIdFltLpCutoffUpper, 58.2677}, + {pIdMasterGain, 0.472441}, + {pIdMixGainLower, -17.4803}, + {pIdMixGainUpper, -12.9134}, + {pIdOscDetune, 1}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 36.6929}, + {pIdOscHpCutoffUpper, 42.3622}, + {pIdOscPwmDepth, 99.2126}, + {pIdOscPwmFrequency, 0.1}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +static const Preset::Parameter pp1_3[] = { + {pIdChoDepth, 100}, + {pIdChoDepth1, 100}, + {pIdChoDepth2, 100}, + {pIdChoEnabled, 1}, + {pIdChoModel, 1}, + {pIdChoRate1, 9}, + {pIdChoRate2, 0.9}, + {pIdEnvAttack, 0.01}, + {pIdEnvDecay, 0.245984}, + {pIdEnvHold, 0.01}, + {pIdEnvRelease, 0.167323}, + {pIdEnvSustain, -60}, + {pIdFltHpCutoffLower, 47.2441}, + {pIdFltHpCutoffUpper, 41.7323}, + {pIdFltHsBoostEq, 2.67717}, + {pIdFltHsCutoffEq, 30.7087}, + {pIdFltLpCutoffLower, 50.5512}, + {pIdFltLpCutoffUpper, 49.4488}, + {pIdMasterGain, 15.5906}, + {pIdMixGainLower, -12.7559}, + {pIdMixGainUpper, -10.0787}, + {pIdOscDetune, 1}, + {pIdOscEnhanceLower, 0}, + {pIdOscEnhanceUpper, 0}, + {pIdOscHpCutoffLower, 38.5827}, + {pIdOscHpCutoffUpper, 60}, + {pIdOscPwmDepth, 100}, + {pIdOscPwmFrequency, 5}, + {pIdPolyphony, 16}, + {-1, 0}, +}; +const Preset Presets[] = { + {"001-String Short 1 BB", &pg0, pp0_0}, + {"002-String Short 2 Br", &pg0, pp0_1}, + {"003-Default [All in left]", &pg0, pp0_2}, + {"004-Plain 8' 1", &pg0, pp0_3}, + {"005-Plain 4' 1", &pg0, pp0_4}, + {"006-Moskito 4'", &pg0, pp0_5}, + {"007-Moskito 8'", &pg0, pp0_6}, + {"008-Plain 4' 2", &pg0, pp0_7}, + {"009-Plain 8' 2", &pg0, pp0_8}, + {"010-Slow 8' 1", &pg0, pp0_9}, + {"011-Slow 4' 1", &pg0, pp0_10}, + {"012-Soft 4' Mid", &pg0, pp0_11}, + {"013-Soft 8' Mid", &pg0, pp0_12}, + {"014-Mix No Mids", &pg0, pp0_13}, + {"015-Full 4'+8' 1", &pg0, pp0_14}, + {"016-Kick (-2 oct)", &pg1, pp1_0}, + {"017-Hat-ish Hit", &pg1, pp1_1}, + {"018-Shaker (Mid C)", &pg1, pp1_2}, + {"019-Snare-ish (3-4 keys-at-once)", &pg1, pp1_3}, +}; +const unsigned NumPresets = 19; diff --git a/plugins/string-machine/StringMachineShared.cpp b/plugins/string-machine/StringMachineShared.cpp index 269cec4..f3bc75e 100644 --- a/plugins/string-machine/StringMachineShared.cpp +++ b/plugins/string-machine/StringMachineShared.cpp @@ -10,76 +10,82 @@ void InitParameter(uint32_t index, Parameter ¶meter) case pIdOscDetune: parameter.symbol = "osc_detune"; parameter.name = "Oscillator detune"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(0.0016, 0.0, 1.0); break; case pIdOscHpCutoffUpper: parameter.symbol = "osc_hp_cutoff_upper"; parameter.name = "Oscillator HP Cutoff 4'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(8.0, -20.0, 60.0); break; case pIdOscHpCutoffLower: parameter.symbol = "osc_hp_cutoff_lower"; parameter.name = "Oscillator HP Cutoff 8'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(8.0, -20.0, 60.0); break; case pIdOscPwmDepth: parameter.symbol = "osc_pwm_depth"; parameter.name = "Oscillator PWM Depth"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "%"; parameter.ranges = ParameterRanges(0.0, 0.0, 100.0); break; case pIdOscPwmFrequency: parameter.symbol = "osc_pwm_frequency"; parameter.name = "Oscillator PWM Frequency"; - parameter.hints = kParameterIsAutomable|kParameterIsLogarithmic; + parameter.hints = kParameterIsAutomatable|kParameterIsLogarithmic; parameter.unit = "Hz"; parameter.ranges = ParameterRanges(0.25, 0.1, 5.0); break; - case pIdOscEnhance: - parameter.symbol = "osc_enhance"; - parameter.name = "Oscillator enhance"; - parameter.hints = kParameterIsAutomable; + case pIdOscEnhanceUpper: + parameter.symbol = "osc_enhance_upper"; + parameter.name = "Oscillator enhance 4'"; + parameter.hints = kParameterIsAutomatable; + parameter.ranges = ParameterRanges(0.0, 0.0, 0.5); + break; + case pIdOscEnhanceLower: + parameter.symbol = "osc_enhance_lower"; + parameter.name = "Oscillator enhance 8'"; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(0.0, 0.0, 0.5); break; case pIdFltLpCutoffUpper: parameter.symbol = "flt_lp_cutoff_upper"; parameter.name = "Filters LP Cutoff 4'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(5.2, -20.0, 120.0); break; case pIdFltHpCutoffUpper: parameter.symbol = "flt_hp_cutoff_upper"; parameter.name = "Filters HP Cutoff 4'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(12.2, -20.0, 120.0); break; case pIdFltLpCutoffLower: parameter.symbol = "flt_lp_cutoff_lower"; parameter.name = "Filters LP Cutoff 8'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(16.4, -20.0, 120.0); break; case pIdFltHpCutoffLower: parameter.symbol = "flt_hp_cutoff_lower"; parameter.name = "Filters HP Cutoff 8'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(-0.4, -20.0, 120.0); break; case pIdFltHsCutoffEq: parameter.symbol = "flt_hs_cutoff_eq"; parameter.name = "Filters HS Cutoff 4'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(24.8, -20.0, 120.0); break; case pIdFltHsBoostEq: parameter.symbol = "flt_hs_boost_eq"; parameter.name = "Filters HS Boost 4'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "dB"; parameter.ranges = ParameterRanges(6.0, -20.0, 20.0); break; @@ -87,14 +93,14 @@ void InitParameter(uint32_t index, Parameter ¶meter) case pIdMixGainUpper: parameter.symbol = "mix_gain_upper"; parameter.name = "Mix Gain 4'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "dB"; parameter.ranges = ParameterRanges(0.0, -20.0, 0.0); break; case pIdMixGainLower: parameter.symbol = "mix_gain_lower"; parameter.name = "Mix Gain 8'"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "dB"; parameter.ranges = ParameterRanges(0.0, -20.0, 0.0); break; @@ -102,35 +108,35 @@ void InitParameter(uint32_t index, Parameter ¶meter) case pIdEnvAttack: parameter.symbol = "env_attack"; parameter.name = "Envelope attack"; - parameter.hints = kParameterIsAutomable|kParameterIsLogarithmic; + parameter.hints = kParameterIsAutomatable|kParameterIsLogarithmic; parameter.unit = "s"; parameter.ranges = ParameterRanges(0.1939, 0.01, 10.0); break; case pIdEnvHold: parameter.symbol = "env_hold"; parameter.name = "Envelope hold"; - parameter.hints = kParameterIsAutomable|kParameterIsLogarithmic; + parameter.hints = kParameterIsAutomatable|kParameterIsLogarithmic; parameter.unit = "s"; parameter.ranges = ParameterRanges(0.01, 0.01, 10.0); break; case pIdEnvDecay: parameter.symbol = "env_decay"; parameter.name = "Envelope decay"; - parameter.hints = kParameterIsAutomable|kParameterIsLogarithmic; + parameter.hints = kParameterIsAutomatable|kParameterIsLogarithmic; parameter.unit = "s"; parameter.ranges = ParameterRanges(10.0, 0.01, 10.0); break; case pIdEnvSustain: parameter.symbol = "env_sustain"; parameter.name = "Envelope sustain"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "dB"; parameter.ranges = ParameterRanges(0.0, -60.0, 0.0); break; case pIdEnvRelease: parameter.symbol = "env_release"; parameter.name = "Envelope release"; - parameter.hints = kParameterIsAutomable|kParameterIsLogarithmic; + parameter.hints = kParameterIsAutomatable|kParameterIsLogarithmic; parameter.unit = "s"; parameter.ranges = ParameterRanges(3.0, 0.01, 10.0); break; @@ -144,33 +150,33 @@ void InitParameter(uint32_t index, Parameter ¶meter) case pIdChoDepth: parameter.symbol = "cho_depth"; parameter.name = "Chorus global depth"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "%"; parameter.ranges = ParameterRanges(100.0, 0.0, 100.0); break; case pIdChoRate1: parameter.symbol = "cho_rate1"; parameter.name = "Chorus rate 1"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(5.8346, 1.0, 9.0); break; case pIdChoDepth1: parameter.symbol = "cho_depth1"; parameter.name = "Chorus depth 1"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "%"; parameter.ranges = ParameterRanges(30.71, 0.0, 100.0); break; case pIdChoRate2: parameter.symbol = "cho_rate2"; parameter.name = "Chorus rate 2"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.ranges = ParameterRanges(0.5835, 0.1, 0.9); break; case pIdChoDepth2: parameter.symbol = "cho_depth2"; parameter.name = "Chorus depth 2"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "%"; parameter.ranges = ParameterRanges(90.55, 0.0, 100.0); break; @@ -188,7 +194,7 @@ void InitParameter(uint32_t index, Parameter ¶meter) case pIdMasterGain: parameter.symbol = "master_gain"; parameter.name = "Master Gain"; - parameter.hints = kParameterIsAutomable; + parameter.hints = kParameterIsAutomatable; parameter.unit = "dB"; parameter.ranges = ParameterRanges(3.0, -60.0, +20.0); break; @@ -196,47 +202,47 @@ void InitParameter(uint32_t index, Parameter ¶meter) case pIdPolyphony: parameter.symbol = "polyphony"; parameter.name = "Polyphony"; - parameter.hints = kParameterIsAutomable|kParameterIsInteger; + parameter.hints = kParameterIsAutomatable|kParameterIsInteger; parameter.ranges = ParameterRanges(16.0, 1.0, StringSynthDefs::PolyphonyLimit); break; case pIdOutDetuneUpper: parameter.symbol = "osc_current_detune_upper"; parameter.name = "Oscillator detune 4'"; - parameter.hints = kParameterIsAutomable|kParameterIsOutput; + parameter.hints = kParameterIsAutomatable|kParameterIsOutput; parameter.ranges = ParameterRanges(0.0, -1.0, +1.0); break; case pIdOutDetuneLower: parameter.symbol = "osc_current_detune_lower"; parameter.name = "Oscillator detune 8'"; - parameter.hints = kParameterIsAutomable|kParameterIsOutput; + parameter.hints = kParameterIsAutomatable|kParameterIsOutput; parameter.ranges = ParameterRanges(0.0, -1.0, +1.0); break; case pIdOutChorusPhase1: parameter.symbol = "cho_current_phase1"; parameter.name = "Chorus phase 1"; - parameter.hints = kParameterIsAutomable|kParameterIsOutput; + parameter.hints = kParameterIsAutomatable|kParameterIsOutput; parameter.unit = "rad"; parameter.ranges = ParameterRanges(0.0, 0.0, 2 * M_PI); break; case pIdOutChorusPhase2: parameter.symbol = "cho_current_phase2"; parameter.name = "Chorus phase 2"; - parameter.hints = kParameterIsAutomable|kParameterIsOutput; + parameter.hints = kParameterIsAutomatable|kParameterIsOutput; parameter.unit = "rad"; parameter.ranges = ParameterRanges(0.0, 0.0, 2 * M_PI); break; case pIdOutMasterLevel1: parameter.symbol = "master_current_level1"; parameter.name = "Master level 1"; - parameter.hints = kParameterIsAutomable|kParameterIsOutput; + parameter.hints = kParameterIsAutomatable|kParameterIsOutput; parameter.unit = "dB"; parameter.ranges = ParameterRanges(0.0, -100.0, +100.0); break; case pIdOutMasterLevel2: parameter.symbol = "master_current_level2"; parameter.name = "Master level 2"; - parameter.hints = kParameterIsAutomable|kParameterIsOutput; + parameter.hints = kParameterIsAutomatable|kParameterIsOutput; parameter.unit = "dB"; parameter.ranges = ParameterRanges(0.0, -100.0, +100.0); break; diff --git a/plugins/string-machine/StringMachineUI.cpp b/plugins/string-machine/StringMachineUI.cpp index e4ed7e2..930a35b 100644 --- a/plugins/string-machine/StringMachineUI.cpp +++ b/plugins/string-machine/StringMachineUI.cpp @@ -2,7 +2,6 @@ #include "StringMachineUILayouts.hpp" #include "StringMachinePresets.hpp" #include "Artwork.hpp" -#include "Window.hpp" #include "ui/components/SkinSlider.hpp" #include "ui/components/SkinToggleButton.hpp" #include "ui/components/SkinTriggerButton.hpp" @@ -55,7 +54,8 @@ StringMachineUI::StringMachineUI() KNOB(OscHpCutoffLower); KNOB(OscPwmDepth); KNOB(OscPwmFrequency); - KNOB(OscEnhance); + KNOB(OscEnhanceUpper); + KNOB(OscEnhanceLower); KNOB(FltLpCutoffUpper); KNOB(FltHpCutoffUpper); KNOB(FltLpCutoffLower); @@ -82,7 +82,8 @@ StringMachineUI::StringMachineUI() VALUE_DISPLAY(OscHpCutoffLower); VALUE_DISPLAY(OscPwmDepth); VALUE_DISPLAY(OscPwmFrequency); - VALUE_DISPLAY(OscEnhance); + VALUE_DISPLAY(OscEnhanceUpper); + VALUE_DISPLAY(OscEnhanceLower); VALUE_DISPLAY(FltLpCutoffUpper); VALUE_DISPLAY(FltLpCutoffLower); VALUE_DISPLAY(FltHpCutoffUpper); @@ -157,7 +158,7 @@ void StringMachineUI::onDisplay() { FontEngine &fe = *fFontEngine; - cairo_t *cr = getParentWindow().getGraphicsContext().cairo; + cairo_t *cr = static_cast(getGraphicsContext()).handle; cairo_set_source_rgba8(cr, bgColor); cairo_paint(cr); @@ -187,7 +188,8 @@ void StringMachineUI::onDisplay() &MainLayout::knob_OscHpCutoffLower_label, &MainLayout::knob_OscPwmDepth_label, &MainLayout::knob_OscPwmFrequency_label, - &MainLayout::knob_OscEnhance_label, + &MainLayout::knob_OscEnhanceUpper_label, + &MainLayout::knob_OscEnhanceLower_label, &MainLayout::knob_FltLpCutoffUpper_label, &MainLayout::knob_FltLpCutoffLower_label, &MainLayout::knob_FltHpCutoffUpper_label, @@ -318,10 +320,14 @@ void StringMachineUI::parameterChanged(uint32_t index, float value) void StringMachineUI::programLoaded(uint32_t index) { - DISTRHO_SAFE_ASSERT_RETURN(index < NumPrograms, ); + DISTRHO_SAFE_ASSERT_RETURN(index < NumPresets, ); + + std::array values = getParameterDefaults(); + for (const Preset::Parameter *pp = Presets[index].parameters; pp->id != -1; ++pp) + values[pp->id] = pp->value; for (unsigned p = 0; p < Parameter_Count; ++p) - parameterChanged(p, Programs[index].values[p]); + parameterChanged(p, values[p]); } void StringMachineUI::uiIdle() @@ -331,7 +337,7 @@ void StringMachineUI::uiIdle() bool StringMachineUI::onKeyboard(const KeyboardEvent &event) { if (event.press && event.mod == 0) { - fKeyHistory[fKeyHistoryIndex++] = KeyPress{event.key, false}; + fKeyHistory[fKeyHistoryIndex++] = event.key; fKeyHistoryIndex %= KeyHistorySize; checkForDeveloperCode(); } @@ -339,17 +345,6 @@ bool StringMachineUI::onKeyboard(const KeyboardEvent &event) return UI::onKeyboard(event); } -bool StringMachineUI::onSpecial(const SpecialEvent &event) -{ - if (event.press && event.mod == 0) { - fKeyHistory[fKeyHistoryIndex++] = KeyPress{event.key, true}; - fKeyHistoryIndex %= KeyHistorySize; - checkForDeveloperCode(); - } - - return UI::onSpecial(event); -} - void StringMachineUI::updateParameterValue(uint32_t index, float value) { DISTRHO_SAFE_ASSERT_RETURN(index < Parameter_Count,); @@ -404,6 +399,14 @@ void StringMachineUI::updateParameterValue(uint32_t index, float value) } } +std::array StringMachineUI::getParameterDefaults() const +{ + std::array values; + for (unsigned p = 0; p < Parameter_Count; ++p) + values[p] = fParameters[p].ranges.def; + return values; +} + SkinSlider *StringMachineUI::createKnobForParameter(unsigned index, const Rect &bounds, const KnobSkin &skin) { DISTRHO_SAFE_ASSERT_RETURN(index < Parameter_Count, nullptr); @@ -509,7 +512,7 @@ void StringMachineUI::computeAdsrPlot(float *data, unsigned size) data[i] *= 0.9f; } -bool StringMachineUI::checkForKeySequence(const KeyPress *sequence, unsigned sequenceSize) +bool StringMachineUI::checkForKeySequence(const uint32_t *sequence, unsigned sequenceSize) { if (KeyHistorySize < sequenceSize) return false; @@ -526,20 +529,20 @@ bool StringMachineUI::checkForKeySequence(const KeyPress *sequence, unsigned seq void StringMachineUI::checkForDeveloperCode() { - const std::array sequence1{{ - {kKeyUp, true}, {kKeyUp, true}, - {kKeyDown, true}, {kKeyDown, true}, - {kKeyLeft, true}, {kKeyRight, true}, - {kKeyLeft, true}, {kKeyRight, true}, - {'\r', false}, + const std::array sequence1{{ + kKeyUp, kKeyUp, + kKeyDown, kKeyDown, + kKeyLeft, kKeyRight, + kKeyLeft, kKeyRight, + '\r', }}; - const std::array sequence2{{ - {kKeyUp, true}, {kKeyUp, true}, - {kKeyDown, true}, {kKeyDown, true}, - {kKeyLeft, true}, {kKeyRight, true}, - {kKeyLeft, true}, {kKeyRight, true}, - {'b', false}, {'a', false}, + const std::array sequence2{{ + kKeyUp, kKeyUp, + kKeyDown, kKeyDown, + kKeyLeft, kKeyRight, + kKeyLeft, kKeyRight, + 'b', 'a', }}; bool entered = checkForKeySequence(sequence1.data(), sequence1.size()) || @@ -614,12 +617,16 @@ void StringMachineUI::randomizeParameters() } } -bool StringMachineUI::isRandomizableParameter(unsigned index) +bool StringMachineUI::isRandomizableParameter(unsigned index) const { switch (index) { case pIdMasterGain: return false; default: + if (index >= Parameter_Count) + return false; + if (fParameters[index].hints & kParameterIsOutput) + return false; return true; } } diff --git a/plugins/string-machine/StringMachineUI.hpp b/plugins/string-machine/StringMachineUI.hpp index dec5877..092eff8 100644 --- a/plugins/string-machine/StringMachineUI.hpp +++ b/plugins/string-machine/StringMachineUI.hpp @@ -5,6 +5,7 @@ #include "ui/Geometry.h" #include "dsp/AHDSREnvelope.h" #include +#include #include #include @@ -28,10 +29,10 @@ class StringMachineUI : public UI { void uiIdle() override; bool onKeyboard(const KeyboardEvent &event) override; - bool onSpecial(const SpecialEvent &event) override; private: void updateParameterValue(uint32_t index, float value); + std::array getParameterDefaults() const; SkinSlider *createKnobForParameter(unsigned index, const Rect &bounds, const KnobSkin &skin); SkinToggleButton *createToggleButtonForParameter(unsigned index, const Rect &bounds, const KnobSkin &skin); @@ -40,7 +41,7 @@ class StringMachineUI : public UI { void computeAdsrPlot(float *data, unsigned size); struct KeyPress; - bool checkForKeySequence(const KeyPress *sequence, unsigned sequenceSize); + bool checkForKeySequence(const uint32_t *sequence, unsigned sequenceSize); void checkForDeveloperCode(); void enableDeveloperMode(); @@ -49,7 +50,7 @@ class StringMachineUI : public UI { double convertNormalizedFromParameter(unsigned index, double value); void randomizeParameters(); - static bool isRandomizableParameter(unsigned index); + bool isRandomizableParameter(unsigned index) const; static std::string formatDisplayValue(double value); @@ -76,18 +77,8 @@ class StringMachineUI : public UI { Parameter fParameters[Parameter_Count]; - struct KeyPress { - uint32_t key; - bool special; - - bool operator==(const KeyPress &other) const - { return key == other.key && special == other.special; } - bool operator!=(const KeyPress &other) const - { return !operator==(other); } - }; - enum { KeyHistorySize = 16 }; - KeyPress fKeyHistory[KeyHistorySize] = {}; + uint32_t fKeyHistory[KeyHistorySize] = {}; unsigned fKeyHistoryIndex = 0; bool fDeveloperMode = false; diff --git a/plugins/string-machine/StringMachineUILayouts.Main.inc b/plugins/string-machine/StringMachineUILayouts.Main.inc index 334ab1e..7a7b96c 100644 --- a/plugins/string-machine/StringMachineUILayouts.Main.inc +++ b/plugins/string-machine/StringMachineUILayouts.Main.inc @@ -11,8 +11,10 @@ DECL_IGNORABLE static Rect knob_OscHpCutoffLower = {120, 120, 30, 30}; DECL_IGNORABLE static Rect val_OscHpCutoffUpper = {115, 88, 40, 12}; DECL_IGNORABLE static Rect val_OscHpCutoffLower = {115, 153, 40, 12}; DECL_IGNORABLE static Rect subgroup_StringOscEnhance = {175, 25, 80, 145}; -DECL_IGNORABLE static Rect knob_OscEnhance = {200, 55, 30, 30}; -DECL_IGNORABLE static Rect val_OscEnhance = {195, 88, 40, 12}; +DECL_IGNORABLE static Rect knob_OscEnhanceUpper = {200, 55, 30, 30}; +DECL_IGNORABLE static Rect val_OscEnhanceUpper = {195, 88, 40, 12}; +DECL_IGNORABLE static Rect knob_OscEnhanceLower = {200, 120, 30, 30}; +DECL_IGNORABLE static Rect val_OscEnhanceLower = {195, 153, 40, 12}; DECL_IGNORABLE static Rect group_StringFilters = {260, 40, 210, 155}; DECL_IGNORABLE static Rect knob_FltLpCutoffUpper = {275, 75, 30, 30}; DECL_IGNORABLE static Rect val_FltLpCutoffUpper = {270, 108, 40, 12}; @@ -76,7 +78,8 @@ DECL_IGNORABLE static Label subgroup_StringOsc_label = {"Shape", 17, {95, 25, 80 DECL_IGNORABLE static Label knob_OscHpCutoffUpper_label = {"4' HP", 1, {120, 55, 30, 30}}; DECL_IGNORABLE static Label knob_OscHpCutoffLower_label = {"8' HP", 1, {120, 120, 30, 30}}; DECL_IGNORABLE static Label subgroup_StringOscEnhance_label = {"Enhance", 17, {175, 25, 80, 145}}; -DECL_IGNORABLE static Label knob_OscEnhance_label = {"Clip Bias", 1, {200, 55, 30, 30}}; +DECL_IGNORABLE static Label knob_OscEnhanceUpper_label = {"4' Clip Bias", 1, {200, 55, 30, 30}}; +DECL_IGNORABLE static Label knob_OscEnhanceLower_label = {"8' Clip Bias", 1, {200, 120, 30, 30}}; DECL_IGNORABLE static Label group_StringFilters_label = {"String Filters", 17, {260, 40, 210, 155}}; DECL_IGNORABLE static Label knob_FltLpCutoffUpper_label = {"4' LP", 1, {275, 75, 30, 30}}; DECL_IGNORABLE static Label knob_FltLpCutoffLower_label = {"8' LP", 1, {275, 140, 30, 30}}; diff --git a/plugins/string-machine/layouts/Main.fl b/plugins/string-machine/layouts/Main.fl index b4e5e41..2072884 100644 --- a/plugins/string-machine/layouts/Main.fl +++ b/plugins/string-machine/layouts/Main.fl @@ -54,13 +54,20 @@ Function {make_window()} {open label Enhance open xywh {175 25 80 145} box UP_BOX labelfont 1 labelsize 10 align 17 } { - Fl_Dial knob_OscEnhance { - label {Clip Bias} + Fl_Dial knob_OscEnhanceUpper { + label {4' Clip Bias} xywh {200 55 30 30} labelsize 10 align 1 } - Fl_Box val_OscEnhance { + Fl_Box val_OscEnhanceUpper { xywh {195 88 40 12} box THIN_UP_BOX labelsize 10 } + Fl_Dial knob_OscEnhanceLower { + label {8' Clip Bias} + xywh {200 120 30 30} labelsize 10 align 1 + } + Fl_Box val_OscEnhanceLower { + xywh {195 153 40 12} box THIN_UP_BOX labelsize 10 + } } } Fl_Group group_StringFilters { diff --git a/plugins/string-machine/meta/DistrhoPluginInfo.h b/plugins/string-machine/meta/DistrhoPluginInfo.h index 4f35924..7ac5384 100644 --- a/plugins/string-machine/meta/DistrhoPluginInfo.h +++ b/plugins/string-machine/meta/DistrhoPluginInfo.h @@ -2,9 +2,9 @@ #define DISTRHO_PLUGIN_BRAND "Jean Pierre Cimalando" #define DISTRHO_PLUGIN_NAME "String machine" -#define DISTRHO_PLUGIN_URI "http://jpcima.sdf1.org/lv2/string-machine" -#define DISTRHO_PLUGIN_HOMEPAGE "https://github.com/jpcima/string-machine-mk2" -#define DISTRHO_PLUGIN_UNIQUE_ID 'S','t','r','M' +#define DISTRHO_PLUGIN_URI "http://jpcima.sdf1.org/lv2/string-machine-mk2" +#define DISTRHO_PLUGIN_HOMEPAGE "https://github.com/jpcima/string-machine" +#define DISTRHO_PLUGIN_UNIQUE_ID 'S','t','M','2' #define DISTRHO_PLUGIN_VERSION 0,0,0 #define DISTRHO_PLUGIN_LABEL "String machine" #define DISTRHO_PLUGIN_LICENSE "http://spdx.org/licenses/GPL-2.0-or-later" @@ -27,7 +27,8 @@ enum { pIdOscHpCutoffLower, pIdOscPwmDepth, pIdOscPwmFrequency, - pIdOscEnhance, + pIdOscEnhanceUpper, + pIdOscEnhanceLower, pIdFltLpCutoffUpper, pIdFltHpCutoffUpper, diff --git a/presets/string-machine/001-MelodicBySM.json b/presets/string-machine/001-MelodicBySM.json new file mode 100644 index 0000000..8738afc --- /dev/null +++ b/presets/string-machine/001-MelodicBySM.json @@ -0,0 +1,519 @@ +{ + "group": "Melodic by S.M.", + "comment": [ + "Melodic contributed by sm7x7, from the Zynthian forums", + "https://discourse.zynthian.org/t/any-lv2-arp-solina-roland-rs-type-string-machines/3627/20" + ], + "presets": [ + { + "name": "001-String Short 1 BB", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": 7.71654, + "osc_hp_cutoff_lower": 7.71654, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.25, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 5.2, + "flt_hp_cutoff_upper": 12.2, + "flt_lp_cutoff_lower": 16.4, + "flt_hp_cutoff_lower": -0.4, + "flt_hs_cutoff_eq": 24.8, + "flt_hs_boost_eq": 6, + "mix_gain_upper": 0, + "mix_gain_lower": 0, + "env_attack": 0.1939, + "env_hold": 0.01, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 1, + "cho_depth": 99.2126, + "cho_rate1": 5.7874, + "cho_depth1": 30.7087, + "cho_rate2": 0.583465, + "cho_depth2": 89.7638, + "cho_model": 1, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "002-String Short 2 Br", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": 7.71654, + "osc_hp_cutoff_lower": 7.71654, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.25, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 5.2, + "flt_hp_cutoff_upper": 12.2, + "flt_lp_cutoff_lower": 16.4, + "flt_hp_cutoff_lower": -0.4, + "flt_hs_cutoff_eq": 24.8, + "flt_hs_boost_eq": 6, + "mix_gain_upper": 0, + "mix_gain_lower": 0, + "env_attack": 0.1939, + "env_hold": 0.01, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 1, + "cho_depth": 99.2126, + "cho_rate1": 5.7874, + "cho_depth1": 30.7087, + "cho_rate2": 0.583465, + "cho_depth2": 89.7638, + "cho_model": 0, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "003-Default [All in left]", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": -20, + "osc_hp_cutoff_lower": -20, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": -20, + "flt_hp_cutoff_upper": -20, + "flt_lp_cutoff_lower": -20, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": -20, + "flt_hs_boost_eq": -20, + "mix_gain_upper": -20, + "mix_gain_lower": -20, + "env_attack": 0.01, + "env_hold": 0.01, + "env_decay": 0.01, + "env_sustain": -60, + "env_release": 0.01, + "cho_enabled": 0, + "cho_depth": 0, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 0, + "cho_model": 0, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "004-Plain 8' 1", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": -20, + "osc_hp_cutoff_lower": 20.315, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": -20, + "flt_hp_cutoff_upper": 50.5512, + "flt_lp_cutoff_lower": 50.5512, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": 50.5512, + "flt_hs_boost_eq": -20, + "mix_gain_upper": -20, + "mix_gain_lower": -10.8661, + "env_attack": 0.01, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 1, + "cho_depth": 99.2126, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 99.2126, + "cho_model": 1, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "005-Plain 4' 1", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": -20, + "osc_hp_cutoff_lower": 20.315, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": -20, + "flt_hp_cutoff_upper": 50.5512, + "flt_lp_cutoff_lower": 50.5512, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": 50.5512, + "flt_hs_boost_eq": -20, + "mix_gain_upper": -20, + "mix_gain_lower": -10.8661, + "env_attack": 0.01, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 0, + "cho_depth": 0, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 0, + "cho_model": 0, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "006-Moskito 4'", + "parameters": { + "osc_detune": 1, + "osc_hp_cutoff_upper": 20.315, + "osc_hp_cutoff_lower": -20, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 50.5512, + "flt_hp_cutoff_upper": -20, + "flt_lp_cutoff_lower": -20, + "flt_hp_cutoff_lower": 50.5512, + "flt_hs_cutoff_eq": -20, + "flt_hs_boost_eq": -0.15748, + "mix_gain_upper": -10.2362, + "mix_gain_lower": -20, + "env_attack": 0.01, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 0, + "cho_depth": 0, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 0, + "cho_model": 0, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "007-Moskito 8'", + "parameters": { + "osc_detune": 1, + "osc_hp_cutoff_upper": -20, + "osc_hp_cutoff_lower": 20.315, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": -20, + "flt_hp_cutoff_upper": 50.5512, + "flt_lp_cutoff_lower": 50.5512, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": 50.5512, + "flt_hs_boost_eq": -20, + "mix_gain_upper": -20, + "mix_gain_lower": -10.8661, + "env_attack": 0.01, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 0, + "cho_depth": 0, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 0, + "cho_model": 0, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "008-Plain 4' 2", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": 20.315, + "osc_hp_cutoff_lower": -20, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 50.5512, + "flt_hp_cutoff_upper": -20, + "flt_lp_cutoff_lower": -20, + "flt_hp_cutoff_lower": 50.5512, + "flt_hs_cutoff_eq": -20, + "flt_hs_boost_eq": -0.15748, + "mix_gain_upper": -10.2362, + "mix_gain_lower": -20, + "env_attack": 0.01, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 0, + "cho_depth": 0, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 0, + "cho_model": 0, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "009-Plain 8' 2", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": -20, + "osc_hp_cutoff_lower": 20.315, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": -20, + "flt_hp_cutoff_upper": 50.5512, + "flt_lp_cutoff_lower": 50.5512, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": 50.5512, + "flt_hs_boost_eq": -20, + "mix_gain_upper": -20, + "mix_gain_lower": -10.8661, + "env_attack": 0.01, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 0, + "cho_depth": 0, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 0, + "cho_model": 0, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "010-Slow 8' 1", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": -20, + "osc_hp_cutoff_lower": 20.315, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": -20, + "flt_hp_cutoff_upper": 50.5512, + "flt_lp_cutoff_lower": 50.5512, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": 50.5512, + "flt_hs_boost_eq": -20, + "mix_gain_upper": -20, + "mix_gain_lower": -10.8661, + "env_attack": 0.01, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 1, + "cho_depth": 99.2126, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 99.2126, + "cho_model": 1, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "011-Slow 4' 1", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": 20.315, + "osc_hp_cutoff_lower": -20, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 50.5512, + "flt_hp_cutoff_upper": -20, + "flt_lp_cutoff_lower": -20, + "flt_hp_cutoff_lower": 50.5512, + "flt_hs_cutoff_eq": -20, + "flt_hs_boost_eq": -0.15748, + "mix_gain_upper": -10.2362, + "mix_gain_lower": -20, + "env_attack": 0.01, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.01, + "cho_enabled": 1, + "cho_depth": 100, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 100, + "cho_model": 0, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "012-Soft 4' Mid", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": 10.8661, + "osc_hp_cutoff_lower": -20, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 0.944882, + "flt_hp_cutoff_upper": -0.15748, + "flt_lp_cutoff_lower": -20, + "flt_hp_cutoff_lower": 50.5512, + "flt_hs_cutoff_eq": 100.157, + "flt_hs_boost_eq": 20, + "mix_gain_upper": 0, + "mix_gain_lower": -20, + "env_attack": 0.0886614, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.481969, + "cho_enabled": 1, + "cho_depth": 50.3937, + "cho_rate1": 4.98425, + "cho_depth1": 51.1811, + "cho_rate2": 0.3, + "cho_depth2": 50.3937, + "cho_model": 1, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "013-Soft 8' Mid", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": -20, + "osc_hp_cutoff_lower": -20, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": -0.15748, + "flt_hp_cutoff_upper": 0.944882, + "flt_lp_cutoff_lower": 20.7874, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": -0.15748, + "flt_hs_boost_eq": 0.15748, + "mix_gain_upper": -20, + "mix_gain_lower": 0, + "env_attack": 0.0886614, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.481969, + "cho_enabled": 1, + "cho_depth": 50.3937, + "cho_rate1": 4.98425, + "cho_depth1": 51.1811, + "cho_rate2": 0.3, + "cho_depth2": 50.3937, + "cho_model": 1, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "014-Mix No Mids", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": 33.5433, + "osc_hp_cutoff_lower": -7.40157, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 60.4724, + "flt_hp_cutoff_upper": -0.15748, + "flt_lp_cutoff_lower": -0.15748, + "flt_hp_cutoff_lower": 10.8661, + "flt_hs_cutoff_eq": -0.15748, + "flt_hs_boost_eq": 0.787402, + "mix_gain_upper": -10.5512, + "mix_gain_lower": -0.787402, + "env_attack": 0.0886614, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.481969, + "cho_enabled": 1, + "cho_depth": 50.3937, + "cho_rate1": 6.02362, + "cho_depth1": 30.7087, + "cho_rate2": 0.602362, + "cho_depth2": 60.6299, + "cho_model": 1, + "master_gain": -0.15748, + "polyphony": 16 + } + }, + { + "name": "015-Full 4'+8' 1", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": 33.5433, + "osc_hp_cutoff_lower": -7.40157, + "osc_pwm_depth": 0, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 22.9921, + "flt_hp_cutoff_upper": 38.4252, + "flt_lp_cutoff_lower": 27.4016, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": 54.9606, + "flt_hs_boost_eq": -0.787402, + "mix_gain_upper": -3.30709, + "mix_gain_lower": -1.5748, + "env_attack": 0.0886614, + "env_hold": 10, + "env_decay": 10, + "env_sustain": 0, + "env_release": 0.481969, + "cho_enabled": 1, + "cho_depth": 50.3937, + "cho_rate1": 6.02362, + "cho_depth1": 30.7087, + "cho_rate2": 0.602362, + "cho_depth2": 60.6299, + "cho_model": 1, + "master_gain": -0.15748, + "polyphony": 16 + } + } + ] +} diff --git a/presets/string-machine/002-DrumsBySM.json b/presets/string-machine/002-DrumsBySM.json new file mode 100644 index 0000000..edca481 --- /dev/null +++ b/presets/string-machine/002-DrumsBySM.json @@ -0,0 +1,145 @@ +{ + "group": "Drums by S.M.", + "comment": [ + "Drums contributed by sm7x7, from the Zynthian forums", + "https://discourse.zynthian.org/t/any-lv2-arp-solina-roland-rs-type-string-machines/3627/20" + ], + "presets": [ + { + "name": "016-Kick (-2 oct)", + "parameters": { + "osc_detune": 0, + "osc_hp_cutoff_upper": -20, + "osc_hp_cutoff_lower": 7.71654, + "osc_pwm_depth": 100, + "osc_pwm_frequency": 5, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": -20, + "flt_hp_cutoff_upper": -20, + "flt_lp_cutoff_lower": 14.1732, + "flt_hp_cutoff_lower": -20, + "flt_hs_cutoff_eq": -20, + "flt_hs_boost_eq": -20, + "mix_gain_upper": -20, + "mix_gain_lower": 0, + "env_attack": 0.01, + "env_hold": 0.01, + "env_decay": 0.01, + "env_sustain": -60, + "env_release": 0.01, + "cho_enabled": 0, + "cho_depth": 0, + "cho_rate1": 3, + "cho_depth1": 0, + "cho_rate2": 0.3, + "cho_depth2": 0, + "cho_model": 0, + "master_gain": 10.5512, + "polyphony": 16 + } + }, + { + "name": "017-Hat-ish Hit", + "parameters": { + "osc_detune": 0.692913, + "osc_hp_cutoff_upper": 50.5512, + "osc_hp_cutoff_lower": 37.3228, + "osc_pwm_depth": 99.2126, + "osc_pwm_frequency": 5, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 102.362, + "flt_hp_cutoff_upper": 107.874, + "flt_lp_cutoff_lower": 120, + "flt_hp_cutoff_lower": 120, + "flt_hs_cutoff_eq": 114.488, + "flt_hs_boost_eq": 19.3701, + "mix_gain_upper": 0, + "mix_gain_lower": -7.55906, + "env_attack": 0.01, + "env_hold": 0.01, + "env_decay": 0.01, + "env_sustain": -60, + "env_release": 0.01, + "cho_enabled": 1, + "cho_depth": 100, + "cho_rate1": 9, + "cho_depth1": 100, + "cho_rate2": 0.9, + "cho_depth2": 99.2126, + "cho_model": 0, + "master_gain": 10.5512, + "polyphony": 16 + } + }, + { + "name": "018-Shaker (Mid C)", + "parameters": { + "osc_detune": 1, + "osc_hp_cutoff_upper": 42.3622, + "osc_hp_cutoff_lower": 36.6929, + "osc_pwm_depth": 99.2126, + "osc_pwm_frequency": 0.1, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 58.2677, + "flt_hp_cutoff_upper": 62.6772, + "flt_lp_cutoff_lower": 63.7795, + "flt_hp_cutoff_lower": 88.0315, + "flt_hs_cutoff_eq": 40.6299, + "flt_hs_boost_eq": 17.4803, + "mix_gain_upper": -12.9134, + "mix_gain_lower": -17.4803, + "env_attack": 0.167323, + "env_hold": 0.01, + "env_decay": 0.324646, + "env_sustain": -38.7402, + "env_release": 0.245984, + "cho_enabled": 1, + "cho_depth": 99.2126, + "cho_rate1": 9, + "cho_depth1": 99.2126, + "cho_rate2": 0.9, + "cho_depth2": 99.2126, + "cho_model": 1, + "master_gain": 0.472441, + "polyphony": 16 + } + }, + { + "name": "019-Snare-ish (3-4 keys-at-once)", + "parameters": { + "osc_detune": 1, + "osc_hp_cutoff_upper": 60, + "osc_hp_cutoff_lower": 38.5827, + "osc_pwm_depth": 100, + "osc_pwm_frequency": 5, + "osc_enhance_upper": 0, + "osc_enhance_lower": 0, + "flt_lp_cutoff_upper": 49.4488, + "flt_hp_cutoff_upper": 41.7323, + "flt_lp_cutoff_lower": 50.5512, + "flt_hp_cutoff_lower": 47.2441, + "flt_hs_cutoff_eq": 30.7087, + "flt_hs_boost_eq": 2.67717, + "mix_gain_upper": -10.0787, + "mix_gain_lower": -12.7559, + "env_attack": 0.01, + "env_hold": 0.01, + "env_decay": 0.245984, + "env_sustain": -60, + "env_release": 0.167323, + "cho_enabled": 1, + "cho_depth": 100, + "cho_rate1": 9, + "cho_depth1": 100, + "cho_rate2": 0.9, + "cho_depth2": 100, + "cho_model": 1, + "master_gain": 15.5906, + "polyphony": 16 + } + } + ] +} diff --git a/sources/MidiDefs.cpp b/sources/MidiDefs.cpp index 489393c..b4ca83a 100644 --- a/sources/MidiDefs.cpp +++ b/sources/MidiDefs.cpp @@ -27,6 +27,8 @@ const char **MidiNoteName = []() -> const char ** return names; }(); +//============================================================================== + static const float *MidiVolume10bit = []() -> const float * { static float volume[1024]; @@ -51,6 +53,8 @@ float MidiGetVolume14bit(unsigned cc14bit) return MidiVolume10bit[cc14bit >> 4]; } +//============================================================================== + static constexpr unsigned MaxPan10bit = 127 << 3; static const float *MidiPan10bit = []() -> const float * @@ -85,3 +89,33 @@ float MidiGetRightPan14bit(unsigned cc14bit) unsigned index10bit = (max14bit - std::min(cc14bit, max14bit)) >> 4; return MidiPan10bit[index10bit]; } + +//============================================================================== + +static const float *MidiVelocityVolume10bit = []() -> const float * +{ + static float volume[1024]; + + auto curve = [](double x) { + #pragma message("TODO(jpc) improve velocity formula") + // misbehaved near the zero, too loud in high values + const double a = 0.01; + const double b = -0.02; + double t = a * x + b; + return t * t; + }; + + double scaleFactor = 1.0 / curve(64); + + for (unsigned i = 0; i < 1024; ++i) { + double x = i * (128.0 / 1024.0); + volume[i] = scaleFactor * curve(x); + } + + return volume; +}(); + +float MidiGetVelocityVolume14bit(unsigned vel14bit) +{ + return MidiVelocityVolume10bit[vel14bit >> 4]; +} diff --git a/sources/MidiDefs.h b/sources/MidiDefs.h index b75d2a6..2c79207 100644 --- a/sources/MidiDefs.h +++ b/sources/MidiDefs.h @@ -7,6 +7,7 @@ extern const char **MidiNoteName/*[128]*/; float MidiGetVolume14bit(unsigned cc14bit); float MidiGetLeftPan14bit(unsigned cc14bit); float MidiGetRightPan14bit(unsigned cc14bit); +float MidiGetVelocityVolume14bit(unsigned vel14bit); enum { kStatusNoteOn = 0x90, @@ -24,6 +25,7 @@ enum { kCcVolumeLsb = 39, kCcPanLsb = 42, kCcExpressionLsb = 43, + kCcVelocityPrefix = 88, kCcNrpnLsb = 98, kCcNrpnMsb = 99, kCcRpnLsb = 100, diff --git a/sources/StringOsc.cpp b/sources/StringOsc.cpp index d113fc9..2f240f0 100644 --- a/sources/StringOsc.cpp +++ b/sources/StringOsc.cpp @@ -29,6 +29,7 @@ void StringOsc::process(float *const outputs[2], const float *const detune[2], f Settings settings = *fSettings; float nyquistFreq = 0.5 * fSampleRate; float hpCutoff[] = {settings.highpassUpperCutoff, settings.highpassLowerCutoff}; + float enhance[] = {settings.enhanceUpper, settings.enhanceLower}; double cutoffMin = 10.0; double cutoffMax = 0.9 * nyquistFreq; @@ -64,7 +65,7 @@ void StringOsc::process(float *const outputs[2], const float *const detune[2], f if (1) { AsymWaveshaper &shaper = fShaper[osc]; - shaper.set_amount(1.0f - settings.enhance); + shaper.set_amount(1.0f - enhance[osc]); shaper.process(output, output, count); } else { diff --git a/sources/StringOsc.h b/sources/StringOsc.h index 940f7a7..c74bddf 100644 --- a/sources/StringOsc.h +++ b/sources/StringOsc.h @@ -10,7 +10,8 @@ class StringOsc { float highpassLowerCutoff = 0; float pwmDepth = 0; float pwmFrequency = 0; - float enhance = 0; + float enhanceUpper = 0; + float enhanceLower = 0; }; void init(const Settings *settings, double sampleRate); diff --git a/sources/StringSynth.cpp b/sources/StringSynth.cpp index 12814b4..b51f5c7 100644 --- a/sources/StringSynth.cpp +++ b/sources/StringSynth.cpp @@ -1,5 +1,4 @@ #include "StringSynth.h" -#include "StringSynthDefs.h" #include "MidiDefs.h" #include #include @@ -50,6 +49,7 @@ void StringSynth::init(double sampleRate) voice.channel = 0; voice.note = 0; + voice.velocity14bit = 0; voice.bend = 1.0; voice.env.init(&fEnvSettings, sampleRate); @@ -109,6 +109,9 @@ void StringSynth::handleMessage(const uint8_t *msg) case kCcPanLsb: ctl.pan14bit = (ctl.pan14bit & (127 << 7)) | d2; break; + case kCcVelocityPrefix: + ctl.velocityPrefix = d2; + break; case kCcNrpnLsb: case kCcRpnLsb: ctl.rpnIdentifier.lsb = d2; @@ -148,6 +151,7 @@ void StringSynth::resetAllControllers(unsigned channel) ctl.volume14bit = 100u << 7; ctl.expression14bit = 127u << 7; ctl.pan14bit = 64u << 7; + ctl.velocityPrefix = 0; ctl.rpnIdentifier.registered = 1; ctl.rpnIdentifier.msb = 0; ctl.rpnIdentifier.lsb = 0; @@ -208,8 +212,14 @@ void StringSynth::generate(float *outputs[2], unsigned count) unsigned channel = voice.channel; const Controllers &ctl = fControllers[channel]; float bend = ctl.calcBendRatio(); + float volume = MidiGetVolume14bit((ctl.volume14bit * ctl.expression14bit) >> 14); +#pragma message("TODO(jpc) not sure I like this velocity formula, need to check it more") +#pragma message("TODO(jpc) also do the aftertouch") + if (0) + volume *= MidiGetVelocityVolume14bit(voice.velocity14bit); + #if STRING_SYNTH_USE_STEREO float volumeL = volume * MidiGetLeftPan14bit(ctl.pan14bit); float volumeR = volume * MidiGetRightPan14bit(ctl.pan14bit); @@ -255,9 +265,6 @@ void StringSynth::setPolyphony(int value) void StringSynth::noteOn(unsigned channel, unsigned note, unsigned vel) { - // TODO the key-on velocity - (void)vel; - Voice &voice = allocNewVoice(); TRACE_ALLOC("Play %u note=%s", voice.id, MidiNoteName[note]); @@ -265,6 +272,7 @@ void StringSynth::noteOn(unsigned channel, unsigned note, unsigned vel) voice.channel = channel; voice.note = note; + voice.velocity14bit = (vel << 7) | ctl.velocityPrefix; voice.osc.setFrequency(MidiPitch[note]); voice.env.trigger(); voice.bend = ctl.calcBendRatio(); diff --git a/sources/StringSynth.h b/sources/StringSynth.h index 002d3c0..7eb741c 100644 --- a/sources/StringSynth.h +++ b/sources/StringSynth.h @@ -3,17 +3,13 @@ #include "StringFilters.h" #include "SolinaChorus.h" #include "SolinaChorusStereo.h" +#include "StringSynthDefs.h" #include "dsp/AHDSREnvelope.h" #include "dsp/NoiseLFO.hpp" #include #include #include -// 1 to enable stereo, increase CPU usage requirement -#ifndef STRING_SYNTH_USE_STEREO -# define STRING_SYNTH_USE_STEREO 1 -#endif - class StringSynth { public: StringSynth(); @@ -64,6 +60,7 @@ class StringSynth { struct Voice { unsigned channel; unsigned note; + unsigned velocity14bit; float bend; unsigned release; // accumulated time in release phase, the greater the // more electible as a voice allocation target @@ -112,6 +109,7 @@ class StringSynth { unsigned volume14bit = 0; unsigned expression14bit = 0; unsigned pan14bit = 0; + unsigned velocityPrefix = 0; float calcBendRatio() const; }; Controllers fControllers[16]; diff --git a/sources/StringSynthDefs.h b/sources/StringSynthDefs.h index 9f5205f..ba53ec9 100644 --- a/sources/StringSynthDefs.h +++ b/sources/StringSynthDefs.h @@ -4,3 +4,8 @@ namespace StringSynthDefs { enum { BufferLimit = 64 }; enum { PolyphonyLimit = 32 }; }; + +// 1 to enable panning in the chorus, increase CPU usage requirement +#ifndef STRING_SYNTH_USE_STEREO +# define STRING_SYNTH_USE_STEREO 1 +#endif diff --git a/sources/dsp/Delay3PhaseDigital.dsp b/sources/dsp/Delay3PhaseDigital.dsp index 81c863a..634e0a6 100644 --- a/sources/dsp/Delay3PhaseDigital.dsp +++ b/sources/dsp/Delay3PhaseDigital.dsp @@ -7,16 +7,14 @@ processMono(in, mod1, mod2, mod3) = in : antiAlias <: (line1, line2, line3) with line1 = line(mod1); line2 = line(mod2); line3 = line(mod3); - line(mod) = de.fdelayltv(1, delaybufsize, delay) with { - delaybufsize = int(ceil(50e-3 * ma.SR)); - delay = (5e-3 + (1e-3 * mod)) * ma.SR; - }; }; -processStereo(inL, inR, mod1, mod2, mod3) = par(i, 2, in(i) : mono) with { - mono = processMono(mod1, mod2, mod3); - in(0) = inL; - in(1) = inR; +processStereo(inL, inR, mod1, mod2, mod3) = + processMono(inL, mod1, mod2, mod3), processMono(inR, mod1, mod2, mod3); + +line(mod) = de.fdelayltv(1, delaybufsize, delay) with { + delaybufsize = int(ceil(50e-3 * ma.SR)); + delay = (5e-3 + (1e-3 * mod)) * ma.SR; }; antiAlias = lpf1 : lpf2 : lpf3 with { diff --git a/sources/ui/components/PlotView.cpp b/sources/ui/components/PlotView.cpp index 385b374..4cdb6f7 100644 --- a/sources/ui/components/PlotView.cpp +++ b/sources/ui/components/PlotView.cpp @@ -1,10 +1,9 @@ #include "PlotView.hpp" -#include "Window.hpp" #include "Cairo.hpp" #include "ui/Cairo++.h" PlotView::PlotView(Widget *group) - : Widget(group) + : SubWidget(group) { } @@ -16,7 +15,7 @@ void PlotView::invalidateData() void PlotView::onDisplay() { - cairo_t *cr = getParentWindow().getGraphicsContext().cairo; + cairo_t *cr = static_cast(getGraphicsContext()).handle; unsigned w = getWidth(); unsigned h = getHeight(); diff --git a/sources/ui/components/PlotView.hpp b/sources/ui/components/PlotView.hpp index 4504b18..be0ca18 100644 --- a/sources/ui/components/PlotView.hpp +++ b/sources/ui/components/PlotView.hpp @@ -1,10 +1,10 @@ #pragma once -#include "Widget.hpp" +#include "SubWidget.hpp" #include "ui/Color.h" #include #include -class PlotView : public Widget { +class PlotView : public SubWidget { public: explicit PlotView(Widget *group); diff --git a/sources/ui/components/SkinIndicator.cpp b/sources/ui/components/SkinIndicator.cpp index bad7744..8aa65f3 100644 --- a/sources/ui/components/SkinIndicator.cpp +++ b/sources/ui/components/SkinIndicator.cpp @@ -1,10 +1,9 @@ #include "SkinIndicator.hpp" #include "KnobSkin.hpp" -#include "Window.hpp" #include "Cairo.hpp" SkinIndicator::SkinIndicator(const KnobSkin &skin, FontEngine &fe, Widget *group) - : Widget(group), fSkin(skin), fFontEngine(fe) + : SubWidget(group), fSkin(skin), fFontEngine(fe) { setSize(skin.getWidth(), skin.getHeight()); } @@ -55,7 +54,7 @@ void SkinIndicator::setTextFont(const Font &font) void SkinIndicator::onDisplay() { const KnobSkin &skin = fSkin; - cairo_t *cr = getParentWindow().getGraphicsContext().cairo; + cairo_t *cr = static_cast(getGraphicsContext()).handle; int w = getWidth(); int h = getHeight(); diff --git a/sources/ui/components/SkinIndicator.hpp b/sources/ui/components/SkinIndicator.hpp index f6162a6..bfef763 100644 --- a/sources/ui/components/SkinIndicator.hpp +++ b/sources/ui/components/SkinIndicator.hpp @@ -2,13 +2,13 @@ #include "ui/FontEngine.h" #include "ui/Color.h" #include "ui/Geometry.h" -#include "Widget.hpp" +#include "SubWidget.hpp" #include #include class KnobSkin; class FontEngine; -class SkinIndicator : public Widget { +class SkinIndicator : public SubWidget { public: SkinIndicator(const KnobSkin &skin, FontEngine &fe, Widget *group); diff --git a/sources/ui/components/SkinSlider.cpp b/sources/ui/components/SkinSlider.cpp index 2b3220b..955d433 100644 --- a/sources/ui/components/SkinSlider.cpp +++ b/sources/ui/components/SkinSlider.cpp @@ -1,11 +1,10 @@ #include "SkinSlider.hpp" #include "KnobSkin.hpp" -#include "Window.hpp" #include "Cairo.hpp" /// SkinSlider::SkinSlider(const KnobSkin &skin, Widget *group) - : Widget(group), fSkin(skin) + : SubWidget(group), fSkin(skin) { setSize(skin.getWidth(), skin.getHeight()); } @@ -52,7 +51,7 @@ void SkinSlider::setOrientation(Orientation ori) bool SkinSlider::onMouse(const MouseEvent &event) { DGL::Size wsize = getSize(); - DGL::Point mpos = event.pos; + DGL::Point mpos{(int)event.pos.getX(), (int)event.pos.getY()}; if (!fIsDragging && event.press && event.button == 1) { bool insideX = mpos.getX() >= 0 && (unsigned)mpos.getX() < wsize.getWidth(); @@ -86,7 +85,7 @@ bool SkinSlider::onMouse(const MouseEvent &event) bool SkinSlider::onMotion(const MotionEvent &event) { DGL::Size wsize = getSize(); - DGL::Point mpos = event.pos; + DGL::Point mpos{(int)event.pos.getX(), (int)event.pos.getY()}; if (fIsDragging) { double fill = 0; @@ -120,7 +119,7 @@ bool SkinSlider::onMotion(const MotionEvent &event) bool SkinSlider::onScroll(const ScrollEvent &event) { DGL::Size wsize = getSize(); - DGL::Point mpos = event.pos; + DGL::Point mpos{(int)event.pos.getX(), (int)event.pos.getY()}; bool inside = mpos.getX() >= 0 && mpos.getY() >= 0 && @@ -140,7 +139,7 @@ bool SkinSlider::onScroll(const ScrollEvent &event) void SkinSlider::onDisplay() { const KnobSkin &skin = fSkin; - cairo_t *cr = getParentWindow().getGraphicsContext().cairo; + cairo_t *cr = static_cast(getGraphicsContext()).handle; int w = getWidth(); int h = getHeight(); diff --git a/sources/ui/components/SkinSlider.hpp b/sources/ui/components/SkinSlider.hpp index a696783..eb984ac 100644 --- a/sources/ui/components/SkinSlider.hpp +++ b/sources/ui/components/SkinSlider.hpp @@ -1,9 +1,9 @@ #pragma once -#include "Widget.hpp" +#include "SubWidget.hpp" #include class KnobSkin; -class SkinSlider : public Widget { +class SkinSlider : public SubWidget { public: SkinSlider(const KnobSkin &skin, Widget *group); diff --git a/sources/ui/components/SkinToggleButton.cpp b/sources/ui/components/SkinToggleButton.cpp index 36401ee..58c943c 100644 --- a/sources/ui/components/SkinToggleButton.cpp +++ b/sources/ui/components/SkinToggleButton.cpp @@ -1,10 +1,9 @@ #include "SkinToggleButton.hpp" #include "KnobSkin.hpp" -#include "Window.hpp" #include "Cairo.hpp" SkinToggleButton::SkinToggleButton(const KnobSkin &skin, Widget *group) - : Widget(group), fSkin(skin) + : SubWidget(group), fSkin(skin) { setSize(skin.getWidth(), skin.getHeight()); } @@ -37,7 +36,7 @@ void SkinToggleButton::setHasInvertedAppearance(bool inv) bool SkinToggleButton::onMouse(const MouseEvent &event) { DGL::Size wsize = getSize(); - DGL::Point mpos = event.pos; + DGL::Point mpos{(int)event.pos.getX(), (int)event.pos.getY()}; bool inside = mpos.getX() >= 0 && mpos.getY() >= 0 && (unsigned)mpos.getX() < wsize.getWidth() && (unsigned)mpos.getY() < wsize.getHeight(); @@ -62,7 +61,7 @@ bool SkinToggleButton::onMouse(const MouseEvent &event) void SkinToggleButton::onDisplay() { const KnobSkin &skin = fSkin; - cairo_t *cr = getParentWindow().getGraphicsContext().cairo; + cairo_t *cr = static_cast(getGraphicsContext()).handle; int w = getWidth(); int h = getHeight(); diff --git a/sources/ui/components/SkinToggleButton.hpp b/sources/ui/components/SkinToggleButton.hpp index 98874ad..66c8c95 100644 --- a/sources/ui/components/SkinToggleButton.hpp +++ b/sources/ui/components/SkinToggleButton.hpp @@ -1,9 +1,9 @@ #pragma once -#include "Widget.hpp" +#include "SubWidget.hpp" #include class KnobSkin; -class SkinToggleButton : public Widget { +class SkinToggleButton : public SubWidget { public: SkinToggleButton(const KnobSkin &skin, Widget *group); diff --git a/sources/ui/components/SkinTriggerButton.cpp b/sources/ui/components/SkinTriggerButton.cpp index 5e2178f..9fb5cc5 100644 --- a/sources/ui/components/SkinTriggerButton.cpp +++ b/sources/ui/components/SkinTriggerButton.cpp @@ -1,10 +1,9 @@ #include "SkinTriggerButton.hpp" #include "KnobSkin.hpp" -#include "Window.hpp" #include "Cairo.hpp" SkinTriggerButton::SkinTriggerButton(const KnobSkin &skin, Widget *group) - : Widget(group), fSkin(skin) + : SubWidget(group), fSkin(skin) { setSize(skin.getWidth(), skin.getHeight()); } @@ -21,7 +20,7 @@ void SkinTriggerButton::setHasInvertedAppearance(bool inv) bool SkinTriggerButton::onMouse(const MouseEvent &event) { DGL::Size wsize = getSize(); - DGL::Point mpos = event.pos; + DGL::Point mpos{(int)event.pos.getX(), (int)event.pos.getY()}; bool inside = mpos.getX() >= 0 && mpos.getY() >= 0 && (unsigned)mpos.getX() < wsize.getWidth() && (unsigned)mpos.getY() < wsize.getHeight(); @@ -46,7 +45,7 @@ bool SkinTriggerButton::onMouse(const MouseEvent &event) void SkinTriggerButton::onDisplay() { const KnobSkin &skin = fSkin; - cairo_t *cr = getParentWindow().getGraphicsContext().cairo; + cairo_t *cr = static_cast(getGraphicsContext()).handle; int w = getWidth(); int h = getHeight(); diff --git a/sources/ui/components/SkinTriggerButton.hpp b/sources/ui/components/SkinTriggerButton.hpp index e99cd77..ffa8cbf 100644 --- a/sources/ui/components/SkinTriggerButton.hpp +++ b/sources/ui/components/SkinTriggerButton.hpp @@ -1,9 +1,9 @@ #pragma once -#include "Widget.hpp" +#include "SubWidget.hpp" #include class KnobSkin; -class SkinTriggerButton : public Widget { +class SkinTriggerButton : public SubWidget { public: SkinTriggerButton(const KnobSkin &skin, Widget *group); diff --git a/tools/benchmarks/LICENSE b/tools/benchmarks/LICENSE new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/tools/benchmarks/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/tools/benchmarks/Makefile b/tools/benchmarks/Makefile new file mode 100644 index 0000000..48c6185 --- /dev/null +++ b/tools/benchmarks/Makefile @@ -0,0 +1,49 @@ +CXX ?= g++ +CXXFLAGS ?= -O3 -ffast-math -g +LDFLAGS ?= + +CXXFLAGS += -std=c++11 +CXXFLAGS += -Wall -Wextra +CXXFLAGS += -MD -MP +CXXFLAGS += -Isources +CXXFLAGS += -Ithirdparty/blink + +CXXFLAGS += -Istring-machine/dpf/distrho +CXXFLAGS += -Istring-machine/sources -Istring-machine/gen -Istring-machine/plugins/string-machine -Istring-machine/plugins/string-machine/meta + +TARGET_MACHINE := $(shell $(CXX) -dumpmachine) +ifneq (,$(findstring mingw,$(TARGET_MACHINE))) +APP_EXT := .exe +LDFLAGS += -static +endif + +SOURCES := \ + sources/main.cpp \ + string-machine/plugins/string-machine/StringMachineShared.cpp \ + string-machine/sources/SolinaChorus.cpp \ + string-machine/sources/SolinaChorusStereo.cpp \ + string-machine/sources/bbd/bbd_line.cpp \ + string-machine/sources/bbd/bbd_filter.cpp \ + string-machine/sources/dsp/Delay3Phase.cpp \ + string-machine/sources/dsp/Delay3PhaseStereo.cpp \ + string-machine/gen/dsp/Delay3PhaseDigital.cpp \ + string-machine/gen/dsp/Delay3PhaseDigitalStereo.cpp \ + string-machine/gen/dsp/LFO3PhaseDual.cpp +OBJS := $(patsubst %.cpp,build/%.o,$(SOURCES)) + +all: bin/benchmarks$(APP_EXT) + +clean: + rm -rf bin build + +bin/benchmarks$(APP_EXT): $(OBJS) + @mkdir -p $(dir $@) + $(CXX) -o $@ $^ $(LDFLAGS) + +build/%.o: %.cpp + @mkdir -p $(dir $@) + $(CXX) -c -o $@ $< $(CXXFLAGS) + +.PHONY: all clean + +-include $(OBJS:%.o=%.d) diff --git a/tools/benchmarks/sources/main.cpp b/tools/benchmarks/sources/main.cpp new file mode 100644 index 0000000..90458ff --- /dev/null +++ b/tools/benchmarks/sources/main.cpp @@ -0,0 +1,131 @@ +#include "SolinaChorus.h" +#include "SolinaChorusStereo.h" +#include "StringSynthDefs.h" +#include "StringMachineShared.hpp" +#include "DenormalDisabler.h" +#include +#include +#include +namespace chr = std::chrono; + +static constexpr double SampleRate = 44100; +using StringSynthDefs::BufferLimit; + +template +double measureElapsed(F &&f) +{ + f(); // dummy run to reduce cache effects + chr::steady_clock::time_point t1 = chr::steady_clock::now(); + f(); + chr::steady_clock::time_point t2 = chr::steady_clock::now(); + return chr::duration_cast>(t2 - t1).count(); +} + +template +void runChorus(Chorus &chorus, double duration); + +template <> +void runChorus(SolinaChorus &chorus, double duration) +{ + uint32_t index = 0; + uint32_t totalFrames = std::ceil(duration * SampleRate); + const float input[BufferLimit] = {}; + float outputL[BufferLimit]; + float outputR[BufferLimit]; + while (index < totalFrames) { + uint32_t frames = std::min(totalFrames - index, BufferLimit); + float *outputs[] = {outputL, outputR}; + chorus.process(input, outputs, frames); + index += frames; + } +} + +template <> +void runChorus(SolinaChorusStereo &chorus, double duration) +{ + uint32_t index = 0; + uint32_t totalFrames = std::ceil(duration * SampleRate); + const float inputL[BufferLimit] = {}; + const float inputR[BufferLimit] = {}; + float outputL[BufferLimit]; + float outputR[BufferLimit]; + while (index < totalFrames) { + uint32_t frames = std::min(totalFrames - index, BufferLimit); + const float *inputs[] = {inputL, inputR}; + float *outputs[] = {outputL, outputR}; + chorus.process(inputs, outputs, frames); + index += frames; + } +} + +template +void setChorusParameter(Chorus &chorus, uint32_t id, float value) +{ + switch (id) { + case pIdChoEnabled: + chorus.setEnabled(value > 0.5f); + break; + case pIdChoDepth: + chorus.getLfo().set_globaldepth(value); + break; + case pIdChoRate1: + chorus.getLfo().set_rate1(value); + break; + case pIdChoDepth1: + chorus.getLfo().set_depth1(value); + break; + case pIdChoRate2: + chorus.getLfo().set_rate2(value); + break; + case pIdChoDepth2: + chorus.getLfo().set_depth2(value); + break; + case pIdChoModel: + chorus.setAnalogMode((int)value); + break; + } +} + +template +void setChorusDefaults(Chorus &chorus) +{ + for (uint32_t id = 0; id < Parameter_Count; ++id) { + Parameter param; + InitParameter(id, param); + setChorusParameter(chorus, id, param.ranges.def); + } +} + +int main(int argc, char *argv[]) +{ + WebCore::DenormalDisabler denormalsDisabled; + + SolinaChorus chorus1; + SolinaChorusStereo chorus2; + + chorus1.init(SampleRate); + chorus2.init(SampleRate); + + setChorusDefaults(chorus1); + setChorusDefaults(chorus2); + + double t1, t2; + double duration = 60.0; + + t1 = measureElapsed([&chorus1, duration]() { runChorus(chorus1, duration); }); + fprintf(stderr, "Analog Mono: %f\n", t1); + t2 = measureElapsed([&chorus2, duration]() { runChorus(chorus2, duration); }); + fprintf(stderr, "Analog Stereo: %f\n", t2); + fprintf(stderr, "Relative %+.2f%%\n", 100.0 * (t2 - t1) / t1); + + setChorusParameter(chorus1, pIdChoModel, 0.0); + setChorusParameter(chorus2, pIdChoModel, 0.0); + + t1 = measureElapsed([&chorus1, duration]() { runChorus(chorus1, duration); }); + fprintf(stderr, "Digital Mono: %f\n", t1); + t2 = measureElapsed([&chorus2, duration]() { runChorus(chorus2, duration); }); + fprintf(stderr, "Digital Stereo: %f\n", t2); + fprintf(stderr, "Relative %+.2f%%\n", 100.0 * (t2 - t1) / t1); + + return 0; +} diff --git a/tools/benchmarks/string-machine b/tools/benchmarks/string-machine new file mode 120000 index 0000000..c25bddb --- /dev/null +++ b/tools/benchmarks/string-machine @@ -0,0 +1 @@ +../.. \ No newline at end of file diff --git a/tools/benchmarks/thirdparty b/tools/benchmarks/thirdparty new file mode 120000 index 0000000..a3d9a05 --- /dev/null +++ b/tools/benchmarks/thirdparty @@ -0,0 +1 @@ +../../thirdparty \ No newline at end of file diff --git a/tools/presets/Makefile b/tools/presets/Makefile new file mode 100644 index 0000000..64994ab --- /dev/null +++ b/tools/presets/Makefile @@ -0,0 +1,34 @@ +CXX ?= g++ +CXXFLAGS ?= -O2 -g +LDFLAGS ?= + +CXXFLAGS += -std=c++11 +CXXFLAGS += -Wall -Wextra +CXXFLAGS += -MD -MP +CXXFLAGS += -Isources -Ithirdparty/nlohmann-json + +TARGET_MACHINE := $(shell $(CXX) -dumpmachine) +ifneq (,$(findstring mingw,$(TARGET_MACHINE))) +APP_EXT := .exe +LDFLAGS += -static +endif + +SOURCES := sources/main.cpp +OBJS := $(patsubst sources/%.cpp,build/%.o,$(SOURCES)) + +all: bin/presets$(APP_EXT) + +clean: + rm -rf bin build + +bin/presets$(APP_EXT): $(OBJS) + @mkdir -p bin + $(CXX) -o $@ $^ $(LDFLAGS) + +build/%.o: sources/%.cpp + @mkdir -p build + $(CXX) -c -o $@ $< $(CXXFLAGS) + +.PHONY: all clean + +-include $(OBJS:%.o=%.d) diff --git a/tools/presets/sources/main.cpp b/tools/presets/sources/main.cpp new file mode 100644 index 0000000..b5615c9 --- /dev/null +++ b/tools/presets/sources/main.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include + +static std::string ConvertSymbol(const std::string &sym) +{ + std::string result; + bool cap = true; + result.reserve(sym.size()); + for (char c : sym) { + if (c == '_') + cap = true; + else { + if (cap && c >= 'a' && c <= 'z') + c = c - 'a' + 'A'; + result.push_back(c); + cap = false; + } + } + return result; +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) + return 1; + + unsigned count = argc - 1; + std::unique_ptr documents{new nlohmann::json[count]}; + + for (unsigned i = 0; i < count; ++i) { + std::ifstream in(argv[i + 1]); + documents[i] = nlohmann::json::parse(in); + } + + for (unsigned i = 0; i < count; ++i) { + const nlohmann::json &doc = documents[i]; + printf("static const Preset::Group pg%u = {\"%s\"};\n", i, doc["group"].get().c_str()); + } + + for (unsigned i = 0; i < count; ++i) { + const nlohmann::json &presets = documents[i]["presets"]; + for (unsigned p = 0, pn = presets.size(); p < pn; ++p) { + const nlohmann::json &preset = presets[p]; + printf("static const Preset::Parameter pp%u_%u[] = {\n", i, p); + for (auto it : preset["parameters"].items()) + printf(" {pId%s, %g},\n", ConvertSymbol(it.key()).c_str(), it.value().get()); + printf(" {-1, 0},\n"); + printf("};\n"); + } + } + + + printf("const Preset Presets[] = {\n"); + for (unsigned i = 0; i < count; ++i) { + const nlohmann::json &presets = documents[i]["presets"]; + for (unsigned p = 0, pn = presets.size(); p < pn; ++p) { + const nlohmann::json &preset = presets[p]; + printf(" {\"%s\", &pg%u, pp%u_%u},\n", preset["name"].get().c_str(), i, i, p); + } + } + printf("};\n"); + + unsigned preset_count = 0; + for (unsigned i = 0; i < count; ++i) { + const nlohmann::json &presets = documents[i]["presets"]; + preset_count += presets.size(); + } + printf("const unsigned NumPresets = %u;\n", preset_count); + + return 0; +} diff --git a/tools/presets/thirdparty b/tools/presets/thirdparty new file mode 120000 index 0000000..a3d9a05 --- /dev/null +++ b/tools/presets/thirdparty @@ -0,0 +1 @@ +../../thirdparty \ No newline at end of file