diff --git a/resources/Delay.h b/resources/Delay.h
index d2ac2a9..6e3f44b 100644
--- a/resources/Delay.h
+++ b/resources/Delay.h
@@ -50,7 +50,7 @@ class Delay : private ProcessorBase
Delay()
{
}
- ~Delay() {}
+ ~Delay() {} ;
void setDelayTime (float delayTimeInSeconds)
{
diff --git a/source/PluginProcessor.cpp b/source/PluginProcessor.cpp
index c6e6587..dac5b70 100644
--- a/source/PluginProcessor.cpp
+++ b/source/PluginProcessor.cpp
@@ -1,34 +1,50 @@
-/*
- ==============================================================================
- PluginProcessor.cpp
- Author: Thomas Deppisch & Simon Beck
-
- Copyright (c) 2019 - Austrian Audio GmbH
- www.austrian.audio
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- ==============================================================================
- */
+ /*
+==============================================================================
+PluginProcessor.cpp
+Author: Thomas Deppisch & Simon Beck
+
+Copyright (c) 2019 - Austrian Audio GmbH
+www.austrian.audio
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+==============================================================================
+*/
#include "PluginProcessor.h"
#include "PluginEditor.h"
+#include
+
+ static inline bool doublesEquivalent(double a, double b)
+ {
+ return fabs(a - b) < DBL_EPSILON;
+ }
+
+ static inline bool floatsEquivalent(double a, double b)
+ {
+ return fabs(a - b) < FLT_EPSILON;
+ }
+
+
+/* We use versionHint of ParameterID from now on - rigorously! */
+#define PD_PARAMETER_V1 1
+
//==============================================================================
PolarDesignerAudioProcessor::PolarDesignerAudioProcessor() : AudioProcessor (BusesProperties()
- .withInput ("Input", AudioChannelSet::stereo(), true)
- .withOutput ("Output", AudioChannelSet::stereo(), true)
- ),
+ .withInput ("Input", AudioChannelSet::stereo(), true)
+ .withOutput ("Output", AudioChannelSet::stereo(), true)
+ ),
layerA(nodeA),
layerB(nodeB),
saveStates(saveTree),
@@ -36,91 +52,91 @@ PolarDesignerAudioProcessor::PolarDesignerAudioProcessor() : AudioProcessor (Bus
termControlWaveform(1),
nBands(5),
vtsParams(*this, &undoManager, "AAPolarDesigner",
- {
- std::make_unique (ParameterID {"xOverF1", 1}, "Xover1", NormalisableRange(0.0f, 1.0f, 0.0001f),
- hzToZeroToOne(0, INIT_XOVER_FREQS_5B[0]), "",
- AudioProcessorParameter::genericParameter,
- [&](float value, int maximumStringLength) {return String(std::roundf(hzFromZeroToOne(0, value))) + " Hz";},
- nullptr),
- std::make_unique (ParameterID {"xOverF2", 1}, "Xover2", NormalisableRange(0.0f, 1.0f, 0.0001f),
- hzToZeroToOne(1, INIT_XOVER_FREQS_5B[1]), "",
- AudioProcessorParameter::genericParameter,
- [&](float value, int maximumStringLength) {return String(std::roundf(hzFromZeroToOne(1, value))) + " Hz";},
- nullptr),
- std::make_unique (ParameterID {"xOverF3", 1}, "Xover3", NormalisableRange(0.0f, 1.0f, 0.0001f),
- hzToZeroToOne(2, INIT_XOVER_FREQS_5B[2]), "",
- AudioProcessorParameter::genericParameter,
- [&](float value, int maximumStringLength) {return String(std::roundf(hzFromZeroToOne(2, value))) + " Hz";},
- nullptr),
- std::make_unique (ParameterID {"xOverF4", 1}, "Xover4", NormalisableRange(0.0f, 1.0f, 0.0001f),
- hzToZeroToOne(3, INIT_XOVER_FREQS_5B[3]), "",
- AudioProcessorParameter::genericParameter,
- [&](float value, int maximumStringLength) {return String(std::roundf(hzFromZeroToOne(3, value))) + " Hz";},
- nullptr),
- std::make_unique (ParameterID {"alpha1", 1}, "Polar1", NormalisableRange(-0.5f, 1.0f, 0.01f),
- 0.0f, "", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 2); }, nullptr),
- std::make_unique (ParameterID {"alpha2", 1}, "Polar2", NormalisableRange(-0.5f, 1.0f, 0.01f),
- 0.0f, "", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 2); }, nullptr),
- std::make_unique (ParameterID {"alpha3", 1}, "Polar3", NormalisableRange(-0.5f, 1.0f, 0.01f),
- 0.0f, "", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 2); }, nullptr),
- std::make_unique (ParameterID {"alpha4", 1}, "Polar4", NormalisableRange(-0.5f, 1.0f, 0.01f),
- 0.0f, "", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 2); }, nullptr),
- std::make_unique (ParameterID {"alpha5", 1}, "Polar5", NormalisableRange(-0.5f, 1.0f, 0.01f),
- 0.0f, "", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 2); }, nullptr),
- std::make_unique (ParameterID {"solo1", 1}, "Solo1", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"solo2", 1}, "Solo2", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"solo3", 1}, "Solo3", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"solo4", 1}, "Solo4", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"solo5", 1}, "Solo5", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"mute1", 1}, "Mute1", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"mute2", 1}, "Mute2", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"mute3", 1}, "Mute3", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"mute4", 1}, "Mute4", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"mute5", 1}, "Mute5", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"gain1", 1}, "Gain1", NormalisableRange(-24.0f, 18.0f, 0.1f),
- 0.0f, "dB", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 1); }, nullptr),
- std::make_unique (ParameterID {"gain2", 1}, "Gain2", NormalisableRange(-24.0f, 18.0f, 0.1f),
- 0.0f, "dB", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 1); }, nullptr),
- std::make_unique (ParameterID {"gain3", 1}, "Gain3", NormalisableRange(-24.0f, 18.0f, 0.1f),
- 0.0f, "dB", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 1); }, nullptr),
- std::make_unique (ParameterID {"gain4", 1}, "Gain4", NormalisableRange(-24.0f, 18.0f, 0.1f),
- 0.0f, "dB", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 1); }, nullptr),
- std::make_unique (ParameterID {"gain5", 1}, "Gain5", NormalisableRange(-24.0f, 18.0f, 0.1f),
- 0.0f, "dB", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return String(value, 1); }, nullptr),
- std::make_unique (ParameterID {"nrBands", 1}, "Nr. of Bands", 0, 4, 4, "",
- [](int value, int maximumStringLength) {return String(value + 1);}, nullptr),
- std::make_unique (ParameterID {"allowBackwardsPattern", 1}, "Allow Reverse Patterns", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"proximity", 1}, "Proximity", NormalisableRange(-1.0f, 1.0f, 0.001f),
- 0.0f, "", AudioProcessorParameter::genericParameter,
- [](float value, int maximumStringLength) { return std::abs(value) < 0.05f ? "0.00" : String(value, 2); }, nullptr),
- std::make_unique (ParameterID {"proximityOnOff", 1}, "ProximityOnOff", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off"; }, nullptr),
- std::make_unique (ParameterID {"zeroDelayMode", 1}, "Zero Latency", false, "",
- [](bool value, int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
- std::make_unique (ParameterID {"syncChannel", 1}, "Sync to Channel", 0, 4, 0, "",
- [](int value, int maximumStringLength) {return value == 0 ? "none" : String(value);}, nullptr)
- }),
+ {
+ std::make_unique (ParameterID {"xOverF1", PD_PARAMETER_V1}, "Xover1", NormalisableRange(0.0f, 1.0f, 0.0001f),
+ hzToZeroToOne(0, INIT_XOVER_FREQS_5B[0]), "",
+ AudioProcessorParameter::genericParameter,
+ [&](float value, [[maybe_unused]]int maximumStringLength) {return String(std::roundf(hzFromZeroToOne(0, value))) + " Hz";},
+ nullptr),
+ std::make_unique (ParameterID {"xOverF2", PD_PARAMETER_V1}, "Xover2", NormalisableRange(0.0f, 1.0f, 0.0001f),
+ hzToZeroToOne(1, INIT_XOVER_FREQS_5B[1]), "",
+ AudioProcessorParameter::genericParameter,
+ [&](float value, [[maybe_unused]]int maximumStringLength) {return String(std::roundf(hzFromZeroToOne(1, value))) + " Hz";},
+ nullptr),
+ std::make_unique (ParameterID {"xOverF3", PD_PARAMETER_V1}, "Xover3", NormalisableRange(0.0f, 1.0f, 0.0001f),
+ hzToZeroToOne(2, INIT_XOVER_FREQS_5B[2]), "",
+ AudioProcessorParameter::genericParameter,
+ [&](float value, [[maybe_unused]]int maximumStringLength) {return String(std::roundf(hzFromZeroToOne(2, value))) + " Hz";},
+ nullptr),
+ std::make_unique (ParameterID {"xOverF4", PD_PARAMETER_V1}, "Xover4", NormalisableRange(0.0f, 1.0f, 0.0001f),
+ hzToZeroToOne(3, INIT_XOVER_FREQS_5B[3]), "",
+ AudioProcessorParameter::genericParameter,
+ [&](float value, [[maybe_unused]]int maximumStringLength) {return String(std::roundf(hzFromZeroToOne(3, value))) + " Hz";},
+ nullptr),
+ std::make_unique (ParameterID {"alpha1", PD_PARAMETER_V1}, "Polar1", NormalisableRange(-0.5f, 1.0f, 0.01f),
+ 0.0f, "", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 2); }, nullptr),
+ std::make_unique (ParameterID {"alpha2", PD_PARAMETER_V1}, "Polar2", NormalisableRange(-0.5f, 1.0f, 0.01f),
+ 0.0f, "", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 2); }, nullptr),
+ std::make_unique (ParameterID {"alpha3", PD_PARAMETER_V1}, "Polar3", NormalisableRange(-0.5f, 1.0f, 0.01f),
+ 0.0f, "", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 2); }, nullptr),
+ std::make_unique (ParameterID {"alpha4", PD_PARAMETER_V1}, "Polar4", NormalisableRange(-0.5f, 1.0f, 0.01f),
+ 0.0f, "", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 2); }, nullptr),
+ std::make_unique (ParameterID {"alpha5", PD_PARAMETER_V1}, "Polar5", NormalisableRange(-0.5f, 1.0f, 0.01f),
+ 0.0f, "", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 2); }, nullptr),
+ std::make_unique (ParameterID {"solo1", PD_PARAMETER_V1}, "Solo1", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"solo2", PD_PARAMETER_V1}, "Solo2", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"solo3", PD_PARAMETER_V1}, "Solo3", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"solo4", PD_PARAMETER_V1}, "Solo4", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"solo5", PD_PARAMETER_V1}, "Solo5", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"mute1", PD_PARAMETER_V1}, "Mute1", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"mute2", PD_PARAMETER_V1}, "Mute2", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"mute3", PD_PARAMETER_V1}, "Mute3", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"mute4", PD_PARAMETER_V1}, "Mute4", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"mute5", PD_PARAMETER_V1}, "Mute5", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"gain1", PD_PARAMETER_V1}, "Gain1", NormalisableRange(-24.0f, 18.0f, 0.1f),
+ 0.0f, "dB", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 1); }, nullptr),
+ std::make_unique (ParameterID {"gain2", PD_PARAMETER_V1}, "Gain2", NormalisableRange(-24.0f, 18.0f, 0.1f),
+ 0.0f, "dB", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 1); }, nullptr),
+ std::make_unique (ParameterID {"gain3", PD_PARAMETER_V1}, "Gain3", NormalisableRange(-24.0f, 18.0f, 0.1f),
+ 0.0f, "dB", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 1); }, nullptr),
+ std::make_unique (ParameterID {"gain4", PD_PARAMETER_V1}, "Gain4", NormalisableRange(-24.0f, 18.0f, 0.1f),
+ 0.0f, "dB", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 1); }, nullptr),
+ std::make_unique (ParameterID {"gain5", PD_PARAMETER_V1}, "Gain5", NormalisableRange(-24.0f, 18.0f, 0.1f),
+ 0.0f, "dB", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return String(value, 1); }, nullptr),
+ std::make_unique (ParameterID {"nrBands", PD_PARAMETER_V1}, "Nr. of Bands", 0, 4, 4, "",
+ [](int value, [[maybe_unused]]int maximumStringLength) {return String(value + 1);}, nullptr),
+ std::make_unique (ParameterID {"allowBackwardsPattern", PD_PARAMETER_V1}, "Allow Reverse Patterns", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"proximity", PD_PARAMETER_V1}, "Proximity", NormalisableRange(-1.0f, 1.0f, 0.001f),
+ 0.0f, "", AudioProcessorParameter::genericParameter,
+ [](float value, [[maybe_unused]]int maximumStringLength) { return std::abs(value) < 0.05f ? "0.00" : String(value, 2); }, nullptr),
+ std::make_unique (ParameterID {"proximityOnOff", PD_PARAMETER_V1}, "ProximityOnOff", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off"; }, nullptr),
+ std::make_unique (ParameterID {"zeroDelayMode", PD_PARAMETER_V1}, "Zero Latency", false, "",
+ [](bool value, [[maybe_unused]]int maximumStringLength) {return (value) ? "on" : "off";}, nullptr),
+ std::make_unique (ParameterID {"syncChannel", PD_PARAMETER_V1}, "Sync to Channel", 0, 4, 0, "",
+ [](int value, [[maybe_unused]]int maximumStringLength) {return value == 0 ? "none" : String(value);}, nullptr)
+ }),
firLen(FILTER_BANK_IR_LENGTH_AT_NATIVE_SAMPLE_RATE),
dfEqOmniBuffer(1, DF_EQ_LEN), dfEqEightBuffer(1, DF_EQ_LEN),
ffEqOmniBuffer(1, FF_EQ_LEN), ffEqEightBuffer(1, FF_EQ_LEN),
@@ -132,66 +148,66 @@ PolarDesignerAudioProcessor::PolarDesignerAudioProcessor() : AudioProcessor (Bus
signalRecorded(false),
currentSampleRate(48000)
{
-
- vtsParams.addParameterListener("xOverF1", this);
- vtsParams.addParameterListener("xOverF2", this);
- vtsParams.addParameterListener("xOverF3", this);
- vtsParams.addParameterListener("xOverF4", this);
- xOverFreqs[0] = vtsParams.getRawParameterValue("xOverF1");
- xOverFreqs[1] = vtsParams.getRawParameterValue("xOverF2");
- xOverFreqs[2] = vtsParams.getRawParameterValue("xOverF3");
- xOverFreqs[3] = vtsParams.getRawParameterValue("xOverF4");
- for (int i = 0; i < 5; ++i)
- {
- vtsParams.addParameterListener("alpha"+String(i+1), this);
- dirFactors[i] = vtsParams.getRawParameterValue("alpha"+String(i+1));
-
- vtsParams.addParameterListener("solo"+String(i+1), this);
- soloBand[i] = vtsParams.getRawParameterValue("solo"+String(i+1));
-
- vtsParams.addParameterListener("mute"+String(i+1), this);
- muteBand[i] = vtsParams.getRawParameterValue("mute"+String(i+1));
-
- vtsParams.addParameterListener("gain"+String(i+1), this);
- bandGains[i] = vtsParams.getRawParameterValue("gain"+String(i+1));
- }
- vtsParams.addParameterListener("nrBands", this);
- nBandsPtr = vtsParams.getRawParameterValue("nrBands");
- vtsParams.addParameterListener("allowBackwardsPattern", this);
- allowBackwardsPattern = vtsParams.getRawParameterValue("allowBackwardsPattern");
- vtsParams.addParameterListener("proximity", this);
- proxDistance = vtsParams.getRawParameterValue("proximity");
- vtsParams.addParameterListener("proximityOnOff", this);
- proxOnOff = vtsParams.getRawParameterValue("proximityOnOff");
- vtsParams.addParameterListener("zeroDelayMode", this);
- zeroDelayMode = vtsParams.getRawParameterValue("zeroDelayMode");
- vtsParams.addParameterListener("syncChannel", this);
- syncChannelPtr = vtsParams.getRawParameterValue("syncChannel");
-
- // properties file: saves user preset folder location
- PropertiesFile::Options options;
- options.applicationName = "PolarDesigner";
- options.filenameSuffix = "settings";
- options.folderName = "AustrianAudio";
- options.osxLibrarySubFolder = "Preferences";
-
- properties = std::unique_ptr(new PropertiesFile (options));
- lastDir = File(properties->getValue ("presetFolder"));
-
- dfEqOmniBuffer.copyFrom(0, 0, DFEQ_COEFFS_OMNI, DF_EQ_LEN);
- dfEqEightBuffer.copyFrom(0, 0, DFEQ_COEFFS_EIGHT, DF_EQ_LEN);
- ffEqOmniBuffer.copyFrom(0, 0, FFEQ_COEFFS_OMNI, FF_EQ_LEN);
- ffEqEightBuffer.copyFrom(0, 0, FFEQ_COEFFS_EIGHT, FF_EQ_LEN);
-
- updateLatency();
- delay.setDelayTime (std::ceilf(static_cast(FILTER_BANK_IR_LENGTH_AT_NATIVE_SAMPLE_RATE) / 2 - 1) / FILTER_BANK_NATIVE_SAMPLE_RATE);
-
- oldProxDistance = proxDistance->load();
-
- termControlWaveform.setRepaintRate(30);
- termControlWaveform.setBufferSize(256);
-
- startTimer(50);
+
+ vtsParams.addParameterListener("xOverF1", this);
+ vtsParams.addParameterListener("xOverF2", this);
+ vtsParams.addParameterListener("xOverF3", this);
+ vtsParams.addParameterListener("xOverF4", this);
+ xOverFreqs[0] = vtsParams.getRawParameterValue("xOverF1");
+ xOverFreqs[1] = vtsParams.getRawParameterValue("xOverF2");
+ xOverFreqs[2] = vtsParams.getRawParameterValue("xOverF3");
+ xOverFreqs[3] = vtsParams.getRawParameterValue("xOverF4");
+ for (int i = 0; i < 5; ++i)
+ {
+ vtsParams.addParameterListener("alpha"+String(i+1), this);
+ dirFactors[i] = vtsParams.getRawParameterValue("alpha"+String(i+1));
+
+ vtsParams.addParameterListener("solo"+String(i+1), this);
+ soloBand[i] = vtsParams.getRawParameterValue("solo"+String(i+1));
+
+ vtsParams.addParameterListener("mute"+String(i+1), this);
+ muteBand[i] = vtsParams.getRawParameterValue("mute"+String(i+1));
+
+ vtsParams.addParameterListener("gain"+String(i+1), this);
+ bandGains[i] = vtsParams.getRawParameterValue("gain"+String(i+1));
+ }
+ vtsParams.addParameterListener("nrBands", this);
+ nBandsPtr = vtsParams.getRawParameterValue("nrBands");
+ vtsParams.addParameterListener("allowBackwardsPattern", this);
+ allowBackwardsPattern = vtsParams.getRawParameterValue("allowBackwardsPattern");
+ vtsParams.addParameterListener("proximity", this);
+ proxDistance = vtsParams.getRawParameterValue("proximity");
+ vtsParams.addParameterListener("proximityOnOff", this);
+ proxOnOff = vtsParams.getRawParameterValue("proximityOnOff");
+ vtsParams.addParameterListener("zeroDelayMode", this);
+ zeroDelayMode = vtsParams.getRawParameterValue("zeroDelayMode");
+ vtsParams.addParameterListener("syncChannel", this);
+ syncChannelPtr = vtsParams.getRawParameterValue("syncChannel");
+
+ // properties file: saves user preset folder location
+ PropertiesFile::Options options;
+ options.applicationName = "PolarDesigner";
+ options.filenameSuffix = "settings";
+ options.folderName = "AustrianAudio";
+ options.osxLibrarySubFolder = "Preferences";
+
+ properties = std::unique_ptr(new PropertiesFile (options));
+ lastDir = File(properties->getValue ("presetFolder"));
+
+ dfEqOmniBuffer.copyFrom(0, 0, DFEQ_COEFFS_OMNI, DF_EQ_LEN);
+ dfEqEightBuffer.copyFrom(0, 0, DFEQ_COEFFS_EIGHT, DF_EQ_LEN);
+ ffEqOmniBuffer.copyFrom(0, 0, FFEQ_COEFFS_OMNI, FF_EQ_LEN);
+ ffEqEightBuffer.copyFrom(0, 0, FFEQ_COEFFS_EIGHT, FF_EQ_LEN);
+
+ updateLatency();
+ delay.setDelayTime (std::ceilf(static_cast(FILTER_BANK_IR_LENGTH_AT_NATIVE_SAMPLE_RATE) / 2 - 1) / FILTER_BANK_NATIVE_SAMPLE_RATE);
+
+ oldProxDistance = proxDistance->load();
+
+ termControlWaveform.setRepaintRate(30);
+ termControlWaveform.setBufferSize(256);
+
+ startTimer(50);
}
PolarDesignerAudioProcessor::~PolarDesignerAudioProcessor()
@@ -201,1364 +217,1367 @@ PolarDesignerAudioProcessor::~PolarDesignerAudioProcessor()
//==============================================================================
const String PolarDesignerAudioProcessor::getName() const
{
- return JucePlugin_Name;
+ return JucePlugin_Name;
}
bool PolarDesignerAudioProcessor::acceptsMidi() const
{
#if JucePlugin_WantsMidiInput
- return true;
+ return true;
#else
- return false;
+ return false;
#endif
}
bool PolarDesignerAudioProcessor::producesMidi() const
{
#if JucePlugin_ProducesMidiOutput
- return true;
+ return true;
#else
- return false;
+ return false;
#endif
}
bool PolarDesignerAudioProcessor::isMidiEffect() const
{
#if JucePlugin_IsMidiEffect
- return true;
+ return true;
#else
- return false;
+ return false;
#endif
}
double PolarDesignerAudioProcessor::getTailLengthSeconds() const
{
- return 0.0;
+ return 0.0;
}
int PolarDesignerAudioProcessor::getNumPrograms()
{
- return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,
- // so this should be at least 1, even if you're not really implementing programs.
+ return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,
+ // so this should be at least 1, even if you're not really implementing programs.
}
int PolarDesignerAudioProcessor::getCurrentProgram()
{
- return 0;
+ return 0;
}
-void PolarDesignerAudioProcessor::setCurrentProgram (int index)
+void PolarDesignerAudioProcessor::setCurrentProgram ([[maybe_unused]]int index)
{
}
-const String PolarDesignerAudioProcessor::getProgramName (int index)
+const String PolarDesignerAudioProcessor::getProgramName ([[maybe_unused]]int index)
{
- return {};
+ return {};
}
-void PolarDesignerAudioProcessor::changeProgramName (int index, const String& newName)
+void PolarDesignerAudioProcessor::changeProgramName ([[maybe_unused]]int index, [[maybe_unused]]const String& newName)
{
}
//==============================================================================
void PolarDesignerAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
- if (sampleRate != currentSampleRate)
- {
- firLen = std::ceil(static_cast(FILTER_BANK_IR_LENGTH_AT_NATIVE_SAMPLE_RATE) / FILTER_BANK_NATIVE_SAMPLE_RATE * sampleRate);
- if (firLen % 2 == 0) // make sure firLen is odd
- firLen++;
-
- updateLatency();
- }
-
- currentBlockSize = samplesPerBlock;
- currentSampleRate = sampleRate;
-
- dsp::ProcessSpec delaySpec {currentSampleRate, static_cast(currentBlockSize), 1};
- delay.prepare (delaySpec);
- delayBuffer.clear();
- delayBuffer.setSize(1, currentBlockSize);
-
- // filter bank
- filterBankBuffer.setSize(N_CH_IN * 5, currentBlockSize);
- filterBankBuffer.clear();
- firFilterBuffer.setSize(5, firLen);
- firFilterBuffer.clear();
- omniEightBuffer.setSize(2, currentBlockSize);
- omniEightBuffer.clear();
-
- computeAllFilterCoefficients();
- initAllConvolvers();
- for (auto &conv : convolvers)
- {
- conv.reset();
- }
-
- // diffuse field eq
- dsp::ProcessSpec eqSpec {currentSampleRate, static_cast(currentBlockSize), 1};
- dfEqOmniConv.prepare (eqSpec); // must be called before loading an ir
- dfEqOmniConv.loadImpulseResponse(std::move(dfEqOmniBuffer), EQ_SAMPLE_RATE, dsp::Convolution::Stereo::no, dsp::Convolution::Trim::no, dsp::Convolution::Normalise::no);
-
- dsp::ProcessSpec eqSpec2{ currentSampleRate, static_cast(currentBlockSize), 1 };
- dfEqEightConv.prepare (eqSpec2);
- dfEqOmniConv.loadImpulseResponse(std::move(dfEqEightBuffer), EQ_SAMPLE_RATE, dsp::Convolution::Stereo::no, dsp::Convolution::Trim::no, dsp::Convolution::Normalise::no);
-
- dsp::ProcessSpec eqSpec3{ currentSampleRate, static_cast(currentBlockSize), 1 };
- ffEqOmniConv.prepare (eqSpec3); // must be called before loading an ir
- dfEqOmniConv.loadImpulseResponse(std::move(ffEqOmniBuffer), EQ_SAMPLE_RATE, dsp::Convolution::Stereo::no, dsp::Convolution::Trim::no, dsp::Convolution::Normalise::no);
-
- dsp::ProcessSpec eqSpec4{ currentSampleRate, static_cast(currentBlockSize), 1 };
- ffEqEightConv.prepare (eqSpec4);
- dfEqOmniConv.loadImpulseResponse(std::move(dfEqEightBuffer), EQ_SAMPLE_RATE, dsp::Convolution::Stereo::no, dsp::Convolution::Trim::no, dsp::Convolution::Normalise::no);
-
- dfEqOmniConv.reset();
- dfEqEightConv.reset();
- ffEqOmniConv.reset();
- ffEqEightConv.reset();
-
- for (int i = 0; i < 5; ++i)
- {
- oldDirFactors[i] = dirFactors[i]->load();
- oldBandGains[i] = bandGains[i]->load();
- }
-
- // proximity compensation IIR
- dsp::ProcessSpec specProx { currentSampleRate, static_cast (currentBlockSize), 1 };
- proxCompIIR.prepare(specProx);
-
- proxCompIIR.reset();
- setProxCompCoefficients(proxDistance->load());
-
+ if (!doublesEquivalent(sampleRate, currentSampleRate))
+ {
+ firLen = static_cast (std::ceil (static_cast (FILTER_BANK_IR_LENGTH_AT_NATIVE_SAMPLE_RATE) / FILTER_BANK_NATIVE_SAMPLE_RATE * sampleRate));
+ if (firLen % 2 == 0) // make sure firLen is odd
+ firLen++;
+
+ updateLatency();
+ }
+
+ currentBlockSize = samplesPerBlock;
+ currentSampleRate = sampleRate;
+
+ dsp::ProcessSpec delaySpec {currentSampleRate, static_cast(currentBlockSize), 1};
+ delay.prepare (delaySpec);
+ delayBuffer.clear();
+ delayBuffer.setSize(1, currentBlockSize);
+
+ // filter bank
+ filterBankBuffer.setSize(N_CH_IN * 5, currentBlockSize);
+ filterBankBuffer.clear();
+ firFilterBuffer.setSize(5, firLen);
+ firFilterBuffer.clear();
+ omniEightBuffer.setSize(2, currentBlockSize);
+ omniEightBuffer.clear();
+
+ computeAllFilterCoefficients();
+ initAllConvolvers();
+ for (auto &conv : convolvers)
+ {
+ conv.reset();
+ }
+
+ // diffuse field eq
+ dsp::ProcessSpec eqSpec {currentSampleRate, static_cast(currentBlockSize), 1};
+ dfEqOmniConv.prepare (eqSpec); // must be called before loading an ir
+ dfEqOmniConv.loadImpulseResponse(std::move(dfEqOmniBuffer), EQ_SAMPLE_RATE, dsp::Convolution::Stereo::no, dsp::Convolution::Trim::no, dsp::Convolution::Normalise::no);
+
+ dsp::ProcessSpec eqSpec2{ currentSampleRate, static_cast(currentBlockSize), 1 };
+ dfEqEightConv.prepare (eqSpec2);
+ dfEqOmniConv.loadImpulseResponse(std::move(dfEqEightBuffer), EQ_SAMPLE_RATE, dsp::Convolution::Stereo::no, dsp::Convolution::Trim::no, dsp::Convolution::Normalise::no);
+
+ dsp::ProcessSpec eqSpec3{ currentSampleRate, static_cast(currentBlockSize), 1 };
+ ffEqOmniConv.prepare (eqSpec3); // must be called before loading an ir
+ dfEqOmniConv.loadImpulseResponse(std::move(ffEqOmniBuffer), EQ_SAMPLE_RATE, dsp::Convolution::Stereo::no, dsp::Convolution::Trim::no, dsp::Convolution::Normalise::no);
+
+ dsp::ProcessSpec eqSpec4{ currentSampleRate, static_cast(currentBlockSize), 1 };
+ ffEqEightConv.prepare (eqSpec4);
+ dfEqOmniConv.loadImpulseResponse(std::move(dfEqEightBuffer), EQ_SAMPLE_RATE, dsp::Convolution::Stereo::no, dsp::Convolution::Trim::no, dsp::Convolution::Normalise::no);
+
+ dfEqOmniConv.reset();
+ dfEqEightConv.reset();
+ ffEqOmniConv.reset();
+ ffEqEightConv.reset();
+
+ for (int i = 0; i < 5; ++i)
+ {
+ oldDirFactors[i] = dirFactors[i]->load();
+ oldBandGains[i] = bandGains[i]->load();
+ }
+
+ // proximity compensation IIR
+ dsp::ProcessSpec specProx { currentSampleRate, static_cast (currentBlockSize), 1 };
+ proxCompIIR.prepare(specProx);
+
+ proxCompIIR.reset();
+ setProxCompCoefficients(proxDistance->load());
+
}
void PolarDesignerAudioProcessor::releaseResources()
{
- // When playback stops, you can use this as an opportunity to free up any
- // spare memory, etc.
+ // When playback stops, you can use this as an opportunity to free up any
+ // spare memory, etc.
}
bool PolarDesignerAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
{
- if ((layouts.getMainOutputChannelSet() != AudioChannelSet::mono()
- && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
- || layouts.getMainInputChannelSet() != AudioChannelSet::stereo())
- return false;
-
- if (layouts.getMainInputChannelSet().isDisabled())
- return false;
-
- if (layouts.getMainOutputChannelSet().isDisabled())
- return false;
-
- return true;
+ if ((layouts.getMainOutputChannelSet() != AudioChannelSet::mono()
+ && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
+ || layouts.getMainInputChannelSet() != AudioChannelSet::stereo())
+ return false;
+
+ if (layouts.getMainInputChannelSet().isDisabled())
+ return false;
+
+ if (layouts.getMainOutputChannelSet().isDisabled())
+ return false;
+
+ return true;
}
-void PolarDesignerAudioProcessor::processBlock (AudioBuffer& buffer, MidiBuffer& midiMessages)
+void PolarDesignerAudioProcessor::processBlock (AudioBuffer& buffer, [[maybe_unused]]MidiBuffer& midiMessages)
{
- ScopedNoDenormals noDenormals;
-
- if (isBypassed) {
- isBypassed = false;
- updateLatency();
- }
-
- int numSamples = buffer.getNumSamples();
-
- // create omni and eight signals
- createOmniAndEightSignals (buffer);
-
- // proximity compensation filter
- auto proximity = (proxOnOff->load() == 1.f) ? proxDistance->load() : 0.f;
- if (zeroDelayMode->load() < 0.5f && proximity < -0.05) // reduce proximity effect only on figure-of-eight
- {
- float* writePointerEight = omniEightBuffer.getWritePointer (1);
- dsp::AudioBlock eightBlock(&writePointerEight, 1, numSamples);
- dsp::ProcessContextReplacing contextProxEight(eightBlock);
- proxCompIIR.process(contextProxEight);
- }
- else if (zeroDelayMode->load() < 0.5f && proximity > 0.05) // apply proximity to omni
- {
- float* writePointerOmni = omniEightBuffer.getWritePointer (0);
- dsp::AudioBlock omniBlock(&writePointerOmni, 1, numSamples);
- dsp::ProcessContextReplacing contextProxOmni(omniBlock);
- proxCompIIR.process(contextProxOmni);
- }
-
- if (doEq == 1 && zeroDelayMode->load() < 0.5f )
- {
- // free field equalization
- float* writePointerOmni = omniEightBuffer.getWritePointer (0);
- dsp::AudioBlock ffEqOmniBlk(&writePointerOmni, 1, numSamples);
- dsp::ProcessContextReplacing ffEqOmniCtx (ffEqOmniBlk);
- ffEqOmniConv.process(ffEqOmniCtx);
-
- float* writePointerEight = omniEightBuffer.getWritePointer (1);
- dsp::AudioBlock ffEqEightBlk(&writePointerEight, 1, numSamples);
- dsp::ProcessContextReplacing ffEqEightCtx (ffEqEightBlk);
- ffEqEightConv.process(ffEqEightCtx);
- }
- else if (doEq == 2 && zeroDelayMode->load() < 0.5f )
- {
- // diffuse field equalization
- float* writePointerOmni = omniEightBuffer.getWritePointer (0);
- dsp::AudioBlock dfEqOmniBlk(&writePointerOmni, 1, numSamples);
- dsp::ProcessContextReplacing dfEqOmniCtx (dfEqOmniBlk);
- dfEqOmniConv.process(dfEqOmniCtx);
-
- float* writePointerEight = omniEightBuffer.getWritePointer (1);
- dsp::AudioBlock dfEqEightBlk(&writePointerEight, 1, numSamples);
- dsp::ProcessContextReplacing dfEqEightCtx (dfEqEightBlk);
- dfEqEightConv.process(dfEqEightCtx);
- }
-
- int nActiveBands = nBands;
-
- // 1-band EQ
- if (zeroDelayMode->load() > 0.5f )
- nActiveBands = 1;
-
- for (int i = 0; i < nActiveBands; ++i)
- {
- // copy input buffer for each band
- filterBankBuffer.copyFrom (2*i, 0, omniEightBuffer, 0, 0, numSamples);
- filterBankBuffer.copyFrom (2*i+1, 0, omniEightBuffer, 1, 0, numSamples);
- }
-
- // 5-band EQ
- if (zeroDelayMode->load() < 0.5f && nActiveBands > 1)
- {
- if (!convolversReady)
- {
- return;
- }
-
- // CODEREVIEW TODO: evaluate convolver use of FFT in JUCE::dsp to determine latency effects - Can we Replace with our own convolver code?
-
- for (int i = 0; i < nActiveBands; ++i)
- {
- // omni
- float* writePointerOmni = filterBankBuffer.getWritePointer (2 * i);
- dsp::AudioBlock subBlk (&writePointerOmni, 1, numSamples);
- dsp::ProcessContextReplacing filterCtx (subBlk);
- convolvers[2 * i].process (filterCtx); // mono processing
-
- // eight
- float* writePointerEight = filterBankBuffer.getWritePointer (2 * i + 1);
- dsp::AudioBlock subBlk2 (&writePointerEight, 1, numSamples);
- dsp::ProcessContextReplacing filterCtx2 (subBlk2);
- convolvers[2 * i + 1].process (filterCtx2); // mono processing
- }
- convolversReady = true;
- }
-
- // !J! Deprecated:
-// getPlayHead()->getCurrentPosition(info);
- getPlayHead()->getPosition();
- termControlWaveform.pushBuffer(buffer);
-
- if (trackingActive)
- trackSignalEnergy();
-
- createPolarPatterns (buffer);
+ ScopedNoDenormals noDenormals;
+
+ if (isBypassed) {
+ isBypassed = false;
+ updateLatency();
+ }
+
+ int numSamples = buffer.getNumSamples();
+
+ // create omni and eight signals
+ createOmniAndEightSignals (buffer);
+
+ // proximity compensation filter
+ auto proximity = (proxOnOff->load() == 1.f) ? proxDistance->load() : 0.f;
+ if (zeroDelayMode->load() < 0.5f && proximity < -0.05) // reduce proximity effect only on figure-of-eight
+ {
+ float* writePointerEight = omniEightBuffer.getWritePointer (1);
+ dsp::AudioBlock eightBlock(&writePointerEight, 1, static_cast (numSamples));
+ dsp::ProcessContextReplacing contextProxEight(eightBlock);
+ proxCompIIR.process(contextProxEight);
+ }
+ else if (zeroDelayMode->load() < 0.5f && proximity > 0.05) // apply proximity to omni
+ {
+ float* writePointerOmni = omniEightBuffer.getWritePointer (0);
+ dsp::AudioBlock omniBlock(&writePointerOmni, 1, static_cast (numSamples));
+ dsp::ProcessContextReplacing contextProxOmni(omniBlock);
+ proxCompIIR.process(contextProxOmni);
+ }
+
+ if (doEq == 1 && zeroDelayMode->load() < 0.5f )
+ {
+ // free field equalization
+ float* writePointerOmni = omniEightBuffer.getWritePointer (0);
+ dsp::AudioBlock ffEqOmniBlk(&writePointerOmni, 1, static_cast (numSamples));
+ dsp::ProcessContextReplacing ffEqOmniCtx (ffEqOmniBlk);
+ ffEqOmniConv.process(ffEqOmniCtx);
+
+ float* writePointerEight = omniEightBuffer.getWritePointer (1);
+ dsp::AudioBlock ffEqEightBlk(&writePointerEight, 1, static_cast (numSamples));
+ dsp::ProcessContextReplacing ffEqEightCtx (ffEqEightBlk);
+ ffEqEightConv.process(ffEqEightCtx);
+ }
+ else if (doEq == 2 && zeroDelayMode->load() < 0.5f )
+ {
+ // diffuse field equalization
+ float* writePointerOmni = omniEightBuffer.getWritePointer (0);
+ dsp::AudioBlock dfEqOmniBlk(&writePointerOmni, 1, static_cast (numSamples));
+ dsp::ProcessContextReplacing dfEqOmniCtx (dfEqOmniBlk);
+ dfEqOmniConv.process(dfEqOmniCtx);
+
+ float* writePointerEight = omniEightBuffer.getWritePointer (1);
+ dsp::AudioBlock dfEqEightBlk(&writePointerEight, 1, static_cast (numSamples));
+ dsp::ProcessContextReplacing dfEqEightCtx (dfEqEightBlk);
+ dfEqEightConv.process(dfEqEightCtx);
+ }
+
+ int nActiveBands = nBands;
+
+ // 1-band EQ
+ if (zeroDelayMode->load() > 0.5f )
+ nActiveBands = 1;
+
+ for (int i = 0; i < nActiveBands; ++i)
+ {
+ // copy input buffer for each band
+ filterBankBuffer.copyFrom (2*i, 0, omniEightBuffer, 0, 0, numSamples);
+ filterBankBuffer.copyFrom (2*i+1, 0, omniEightBuffer, 1, 0, numSamples);
+ }
+
+ // 5-band EQ
+ if (zeroDelayMode->load() < 0.5f && nActiveBands > 1)
+ {
+ if (!convolversReady)
+ {
+ return;
+ }
+
+ // CODEREVIEW TODO: evaluate convolver use of FFT in JUCE::dsp to determine latency effects - Can we Replace with our own convolver code?
+
+ for (int i = 0; i < nActiveBands; ++i)
+ {
+ // omni
+ float* writePointerOmni = filterBankBuffer.getWritePointer (2 * i);
+ dsp::AudioBlock subBlk (&writePointerOmni, 1, static_cast (numSamples));
+ dsp::ProcessContextReplacing filterCtx (subBlk);
+ convolvers[2 * i].process (filterCtx); // mono processing
+
+ // eight
+ float* writePointerEight = filterBankBuffer.getWritePointer (2 * i + 1);
+ dsp::AudioBlock subBlk2 (&writePointerEight, 1, static_cast (numSamples));
+ dsp::ProcessContextReplacing filterCtx2 (subBlk2);
+ convolvers[2 * i + 1].process (filterCtx2); // mono processing
+ }
+ convolversReady = true;
+ }
+
+ // !J! Deprecated:
+ // getPlayHead()->getCurrentPosition(info);
+ getPlayHead()->getPosition();
+ termControlWaveform.pushBuffer(buffer);
+
+ if (trackingActive)
+ trackSignalEnergy();
+
+ createPolarPatterns (buffer);
}
-void PolarDesignerAudioProcessor::processBlockBypassed (AudioBuffer& buffer, MidiBuffer& midiMessages)
+void PolarDesignerAudioProcessor::processBlockBypassed (AudioBuffer& buffer, [[maybe_unused]]MidiBuffer& midiMessages)
{
- if (!isBypassed) {
- isBypassed = true;
- updateLatency();
- }
-
- jassert (getLatencySamples() == 0);
-
- for (int ch = getMainBusNumInputChannels(); ch < getTotalNumOutputChannels(); ++ch)
- buffer.clear (ch, 0, buffer.getNumSamples());
+ if (!isBypassed) {
+ isBypassed = true;
+ updateLatency();
+ }
+
+ jassert (getLatencySamples() == 0);
+
+ for (int ch = getMainBusNumInputChannels(); ch < getTotalNumOutputChannels(); ++ch)
+ buffer.clear (ch, 0, buffer.getNumSamples());
}
//==============================================================================
bool PolarDesignerAudioProcessor::hasEditor() const
{
- return true; // (change this to false if you choose to not supply an editor)
+ return true; // (change this to false if you choose to not supply an editor)
}
AudioProcessorEditor* PolarDesignerAudioProcessor::createEditor()
{
- return new PolarDesignerAudioProcessorEditor (*this, vtsParams);
+ return new PolarDesignerAudioProcessorEditor (*this, vtsParams);
}
//==============================================================================
void PolarDesignerAudioProcessor::getStateInformation (MemoryBlock& destData)
{
- // You should use this method to store your parameters in the memory block.
- // You could do that either as raw data, or use the XML or ValueTree classes
- // as intermediaries to make it easy to save and load complex data.
- vtsParams.state.setProperty("ffDfEq", var(doEq), nullptr);
- vtsParams.state.setProperty("oldProxDistance", var(oldProxDistance), nullptr);
-
- if (abLayerState == 1)
- {
- layerA = vtsParams.copyState();
- doEqA = doEq;
- if (proxDistance->load() != 0) { oldProxDistanceA = proxDistance->load(); }
- }
- if (abLayerState == 0)
- {
- layerB = vtsParams.copyState();
- doEqB = doEq;
- if (proxDistance->load() != 0) { oldProxDistanceB = proxDistance->load(); }
- }
-
- layerA.setProperty("ffDfEq", var(doEqA), nullptr);
- layerA.setProperty("oldProxDistance", var(oldProxDistanceA), nullptr);
- layerB.setProperty("ffDfEq", var(doEqB), nullptr);
- layerB.setProperty("oldProxDistance", var(oldProxDistanceB), nullptr);
-
- ValueTree vtsState = vtsParams.copyState();
- ValueTree AState = layerA.createCopy();
- ValueTree BState = layerB.createCopy();
-
- saveStates.removeAllChildren(nullptr);
- saveStates.addChild(vtsState, 0, nullptr);
- saveStates.addChild(AState, 1, nullptr);
- saveStates.addChild(BState, 2, nullptr);
-
- std::unique_ptr xml (saveStates.createXml());
- copyXmlToBinary (*xml, destData);
+ // You should use this method to store your parameters in the memory block.
+ // You could do that either as raw data, or use the XML or ValueTree classes
+ // as intermediaries to make it easy to save and load complex data.
+ vtsParams.state.setProperty("ffDfEq", var(doEq), nullptr);
+ vtsParams.state.setProperty("oldProxDistance", var(oldProxDistance), nullptr);
+
+ if (abLayerState == 1)
+ {
+ layerA = vtsParams.copyState();
+ doEqA = doEq;
+ if (proxDistance->load() != 0.0f) { oldProxDistanceA = proxDistance->load(); }
+ }
+ if (abLayerState == 0)
+ {
+ layerB = vtsParams.copyState();
+ doEqB = doEq;
+ if (proxDistance->load() != 0.0f) { oldProxDistanceB = proxDistance->load(); }
+ }
+
+ layerA.setProperty("ffDfEq", var(doEqA), nullptr);
+ layerA.setProperty("oldProxDistance", var(oldProxDistanceA), nullptr);
+ layerB.setProperty("ffDfEq", var(doEqB), nullptr);
+ layerB.setProperty("oldProxDistance", var(oldProxDistanceB), nullptr);
+
+ ValueTree vtsState = vtsParams.copyState();
+ ValueTree AState = layerA.createCopy();
+ ValueTree BState = layerB.createCopy();
+
+ saveStates.removeAllChildren(nullptr);
+ saveStates.addChild(vtsState, 0, nullptr);
+ saveStates.addChild(AState, 1, nullptr);
+ saveStates.addChild(BState, 2, nullptr);
+
+ std::unique_ptr xml (saveStates.createXml());
+ copyXmlToBinary (*xml, destData);
}
void PolarDesignerAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
- // You should use this method to restore your parameters from this memory block,
- // whose contents will have been created by the getStateInformation() call.
- std::unique_ptr xmlState (getXmlFromBinary (data, sizeInBytes));
- if (xmlState != nullptr)
- {
- if (xmlState->hasTagName (saveStates.getType()))
- {
- saveStates = ValueTree::fromXml (*xmlState);
- vtsParams.replaceState(saveStates.getChild(1));
- }
- else if (xmlState->hasTagName (vtsParams.state.getType()))
- {
- vtsParams.state = ValueTree::fromXml (*xmlState);
- }
- }
-
- layerB = saveStates.getChild(2).createCopy();
-
- if (vtsParams.state.hasProperty("ffDfEq"))
- {
- Value val = vtsParams.state.getPropertyAsValue("ffDfEq", nullptr);
- if (val.getValue().toString() != "")
- {
- doEq = static_cast(val.getValue());
- }
- }
- if (vtsParams.state.hasProperty("oldProxDistance"))
- {
- Value val = vtsParams.state.getPropertyAsValue("oldProxDistance", nullptr);
- if (val.getValue().toString() != "")
- {
- oldProxDistance = static_cast(val.getValue());
- }
- }
-
- if (layerB.hasProperty("ffDfEq"))
- {
- Value val = layerB.getPropertyAsValue("ffDfEq", nullptr);
- if (val.getValue().toString() != "")
- {
- doEqB = static_cast(val.getValue());
- }
- }
- if (layerB.hasProperty("oldProxDistance"))
- {
- Value val = layerB.getPropertyAsValue("oldProxDistance", nullptr);
- if (val.getValue().toString() != "")
- {
- oldProxDistanceB = static_cast(val.getValue());
- }
- }
- nBands = static_cast(nBandsPtr->load()) + 1;
- activeBandsChanged = true;
- zeroDelayModeChanged = true;
- ffDfEqChanged = true;
- computeAllFilterCoefficients();
- initAllConvolvers();
- repaintDEQ = true;
+ // You should use this method to restore your parameters from this memory block,
+ // whose contents will have been created by the getStateInformation() call.
+ std::unique_ptr xmlState (getXmlFromBinary (data, sizeInBytes));
+ if (xmlState != nullptr)
+ {
+ if (xmlState->hasTagName (saveStates.getType()))
+ {
+ saveStates = ValueTree::fromXml (*xmlState);
+ vtsParams.replaceState(saveStates.getChild(1));
+ }
+ else if (xmlState->hasTagName (vtsParams.state.getType()))
+ {
+ vtsParams.state = ValueTree::fromXml (*xmlState);
+ }
+ }
+
+ layerB = saveStates.getChild(2).createCopy();
+
+ if (vtsParams.state.hasProperty("ffDfEq"))
+ {
+ Value val = vtsParams.state.getPropertyAsValue("ffDfEq", nullptr);
+ if (val.getValue().toString() != "")
+ {
+ doEq = static_cast(val.getValue());
+ }
+ }
+ if (vtsParams.state.hasProperty("oldProxDistance"))
+ {
+ Value val = vtsParams.state.getPropertyAsValue("oldProxDistance", nullptr);
+ if (val.getValue().toString() != "")
+ {
+ oldProxDistance = static_cast(val.getValue());
+ }
+ }
+
+ if (layerB.hasProperty("ffDfEq"))
+ {
+ Value val = layerB.getPropertyAsValue("ffDfEq", nullptr);
+ if (val.getValue().toString() != "")
+ {
+ doEqB = static_cast(val.getValue());
+ }
+ }
+ if (layerB.hasProperty("oldProxDistance"))
+ {
+ Value val = layerB.getPropertyAsValue("oldProxDistance", nullptr);
+ if (val.getValue().toString() != "")
+ {
+ oldProxDistanceB = static_cast(val.getValue());
+ }
+ }
+ nBands = static_cast(nBandsPtr->load()) + 1;
+ activeBandsChanged = true;
+ zeroDelayModeChanged = true;
+ ffDfEqChanged = true;
+ computeAllFilterCoefficients();
+ initAllConvolvers();
+ repaintDEQ = true;
}
void PolarDesignerAudioProcessor::parameterChanged (const String ¶meterID, float newValue)
{
- if (parameterID.startsWith("xOverF") && !loadingFile)
- {
- int idx = parameterID.getTrailingIntValue() - 1;
- computeFilterCoefficients(idx);
- initConvolver(idx);
- repaintDEQ = true;
- }
- else if (parameterID.startsWith("solo"))
- {
- soloActive = false;
- for (int i = 0; iload() >= 0.5)
- soloActive = true;
- }
- }
- else if (parameterID.startsWith("alpha"))
- {
- repaintDEQ = true;
- }
- else if (parameterID == "nrBands")
- {
- nBands = static_cast (nBandsPtr->load()) + 1;
- resetXoverFreqs();
- activeBandsChanged = true;
- computeAllFilterCoefficients();
- initAllConvolvers();
- }
- else if (parameterID == "proximity")
- {
- setProxCompCoefficients(proxDistance->load());
- }
- else if (parameterID == "zeroDelayMode")
- {
- updateLatency();
-
- if (newValue == 0)
- {
- if (abLayerState == 0)
- {
- vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameter("proximity")->convertTo0to1(oldProxDistanceB));
- }
- else
- {
- vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameter("proximity")->convertTo0to1(oldProxDistanceA));
- }
- zeroDelayModeChanged = true;
- computeAllFilterCoefficients();
- initAllConvolvers();
- }
- else
- {
- if (abLayerState == 0 && !abLayerChanged.get())
- {
- oldProxDistanceB = proxDistance->load();
- }
- else if (abLayerState == 1 && !abLayerChanged.get())
- {
- oldProxDistanceA = proxDistance->load();
- }
- vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameter("proximity")->convertTo0to1(0));
- zeroDelayModeChanged = true;
- }
- }
- else if (parameterID == "syncChannel" && syncChannelPtr->load() >= 0.5f)
- {
- int ch = (int) syncChannelPtr->load() - 1;
- ParamsToSync& paramsToSync = sharedParams.get().syncParams.getReference(ch);
-
- if (!paramsToSync.paramsValid) // init all params
- {
- for (int i = 0; i < 5; ++i)
- {
- paramsToSync.solo[i] = soloBand[i]->load();
- paramsToSync.mute[i] = muteBand[i]->load();
- paramsToSync.dirFactors[i] = dirFactors[i]->load();
- paramsToSync.gains[i] = bandGains[i]->load();
-
- if (i < 4)
- paramsToSync.xOverFreqs[i] = xOverFreqs[i]->load();
- }
-
- paramsToSync.nrActiveBands = nBandsPtr->load();
- paramsToSync.proximity = proxDistance->load();
- paramsToSync.proximityOnOff = proxOnOff->load();
-
- paramsToSync.allowBackwardsPattern = allowBackwardsPattern->load();
-
- if(!readingSharedParams)
- {
- paramsToSync.zeroDelayMode = zeroDelayMode->load();
- paramsToSync.ffDfEq = doEq;
- }
- }
- }
-
- // if parameters are synced -> set sharedParams
- if (syncChannelPtr->load() >= 0.5f && !readingSharedParams)
- {
- int ch = (int) syncChannelPtr->load() - 1;
- ParamsToSync& paramsToSync = sharedParams.get().syncParams.getReference(ch);
-
- if (parameterID.startsWith("xOverF") && !loadingFile)
- {
- int idx = parameterID.getTrailingIntValue() - 1;
- paramsToSync.xOverFreqs[idx] = xOverFreqs[idx]->load();
- }
- else if (parameterID.startsWith("solo"))
- {
- int idx = parameterID.getTrailingIntValue() - 1;
- paramsToSync.solo[idx] = soloBand[idx]->load();
- }
- else if (parameterID.startsWith("mute"))
- {
- int idx = parameterID.getTrailingIntValue() - 1;
- paramsToSync.mute[idx] = muteBand[idx]->load();
- }
- else if (parameterID.startsWith("alpha"))
- {
- int idx = parameterID.getTrailingIntValue() - 1;
- paramsToSync.dirFactors[idx] = dirFactors[idx]->load();
- }
- else if (parameterID == "nrBands")
- {
- paramsToSync.nrActiveBands = nBandsPtr->load();
- }
- else if (parameterID == "proximity")
- {
- paramsToSync.proximity = proxDistance->load();
- }
- else if (parameterID == "proximityOnOff")
- {
- paramsToSync.proximityOnOff = proxOnOff->load();
- }
- else if (parameterID == "zeroDelayMode")
- {
- paramsToSync.zeroDelayMode = zeroDelayMode->load();
- }
- else if (parameterID.startsWith("gain"))
- {
- int idx = parameterID.getTrailingIntValue() - 1;
- paramsToSync.gains[idx] = bandGains[idx]->load();
- }
- else if (parameterID == "allowBackwardsPattern")
- {
- paramsToSync.allowBackwardsPattern = allowBackwardsPattern->load();
- }
-
- }
+ if (parameterID.startsWith("xOverF") && !loadingFile)
+ {
+ int idx = parameterID.getTrailingIntValue() - 1;
+ computeFilterCoefficients(idx);
+ initConvolver(idx);
+ repaintDEQ = true;
+ }
+ else if (parameterID.startsWith("solo"))
+ {
+ soloActive = false;
+ for (int i = 0; iload() >= 0.5)
+ soloActive = true;
+ }
+ }
+ else if (parameterID.startsWith("alpha"))
+ {
+ repaintDEQ = true;
+ }
+ else if (parameterID == "nrBands")
+ {
+ nBands = static_cast (nBandsPtr->load()) + 1;
+ resetXoverFreqs();
+ activeBandsChanged = true;
+ computeAllFilterCoefficients();
+ initAllConvolvers();
+ }
+ else if (parameterID == "proximity")
+ {
+ setProxCompCoefficients(proxDistance->load());
+ }
+ else if (parameterID == "zeroDelayMode")
+ {
+ updateLatency();
+
+ if (newValue == 0.0f)
+ {
+ if (abLayerState == 0)
+ {
+ vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameter("proximity")->convertTo0to1(oldProxDistanceB));
+ }
+ else
+ {
+ vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameter("proximity")->convertTo0to1(oldProxDistanceA));
+ }
+ zeroDelayModeChanged = true;
+ computeAllFilterCoefficients();
+ initAllConvolvers();
+ }
+ else
+ {
+ if (abLayerState == 0 && !abLayerChanged.get())
+ {
+ oldProxDistanceB = proxDistance->load();
+ }
+ else if (abLayerState == 1 && !abLayerChanged.get())
+ {
+ oldProxDistanceA = proxDistance->load();
+ }
+ vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameter("proximity")->convertTo0to1(0));
+ zeroDelayModeChanged = true;
+ }
+ }
+ else if (parameterID == "syncChannel" && syncChannelPtr->load() >= 0.5f)
+ {
+ int ch = (int) syncChannelPtr->load() - 1;
+ ParamsToSync& paramsToSync = sharedParams.get().syncParams.getReference(ch);
+
+ if (!paramsToSync.paramsValid) // init all params
+ {
+ for (int i = 0; i < 5; ++i)
+ {
+ paramsToSync.solo[i] = static_cast (soloBand[i]->load());
+ paramsToSync.mute[i] = static_cast (muteBand[i]->load());
+ paramsToSync.dirFactors[i] = dirFactors[i]->load();
+ paramsToSync.gains[i] = bandGains[i]->load();
+
+ if (i < 4)
+ paramsToSync.xOverFreqs[i] = xOverFreqs[i]->load();
+ }
+
+ paramsToSync.nrActiveBands = static_cast (nBandsPtr->load());
+ paramsToSync.proximity = proxDistance->load();
+ paramsToSync.proximityOnOff = static_cast (proxOnOff->load());
+
+ paramsToSync.allowBackwardsPattern = static_cast (allowBackwardsPattern->load());
+
+ if(!readingSharedParams)
+ {
+ paramsToSync.zeroDelayMode = static_cast (zeroDelayMode->load());
+ paramsToSync.ffDfEq = doEq;
+ }
+ }
+ }
+
+ // if parameters are synced -> set sharedParams
+ if (syncChannelPtr->load() >= 0.5f && !readingSharedParams)
+ {
+ int ch = (int) syncChannelPtr->load() - 1;
+ ParamsToSync& paramsToSync = sharedParams.get().syncParams.getReference(ch);
+
+ if (parameterID.startsWith("xOverF") && !loadingFile)
+ {
+ int idx = parameterID.getTrailingIntValue() - 1;
+ paramsToSync.xOverFreqs[idx] = xOverFreqs[idx]->load();
+ }
+ else if (parameterID.startsWith("solo"))
+ {
+ int idx = parameterID.getTrailingIntValue() - 1;
+ paramsToSync.solo[idx] = static_cast (soloBand[idx]->load());
+ }
+ else if (parameterID.startsWith("mute"))
+ {
+ int idx = parameterID.getTrailingIntValue() - 1;
+ paramsToSync.mute[idx] = static_cast (muteBand[idx]->load());
+ }
+ else if (parameterID.startsWith("alpha"))
+ {
+ int idx = parameterID.getTrailingIntValue() - 1;
+ paramsToSync.dirFactors[idx] = dirFactors[idx]->load();
+ }
+ else if (parameterID == "nrBands")
+ {
+ paramsToSync.nrActiveBands = static_cast (nBandsPtr->load());
+ }
+ else if (parameterID == "proximity")
+ {
+ paramsToSync.proximity = proxDistance->load();
+ }
+ else if (parameterID == "proximityOnOff")
+ {
+ paramsToSync.proximityOnOff = static_cast (proxOnOff->load());
+ }
+ else if (parameterID == "zeroDelayMode")
+ {
+ paramsToSync.zeroDelayMode = static_cast (zeroDelayMode->load());
+ }
+ else if (parameterID.startsWith("gain"))
+ {
+ int idx = parameterID.getTrailingIntValue() - 1;
+ paramsToSync.gains[idx] = bandGains[idx]->load();
+ }
+ else if (parameterID == "allowBackwardsPattern")
+ {
+ paramsToSync.allowBackwardsPattern = static_cast (allowBackwardsPattern->load());
+ }
+
+ }
}
void PolarDesignerAudioProcessor::setEqState(int idx)
{
- doEq = idx;
-
- if (syncChannelPtr->load() >= 0.5f && !readingSharedParams)
- {
- int ch = (int) syncChannelPtr->load() - 1;
- ParamsToSync& paramsToSync = sharedParams.get().syncParams.getReference(ch);
- paramsToSync.ffDfEq = doEq;
- }
+ doEq = idx;
+
+ if (syncChannelPtr->load() >= 0.5f && !readingSharedParams)
+ {
+ int ch = (int) syncChannelPtr->load() - 1;
+ ParamsToSync& paramsToSync = sharedParams.get().syncParams.getReference(ch);
+ paramsToSync.ffDfEq = doEq;
+ }
}
void PolarDesignerAudioProcessor::setAbLayer(bool state)
{
- abLayerState = state;
- changeAbLayerState();
+ abLayerState = state;
+ changeAbLayerState();
}
void PolarDesignerAudioProcessor::resetXoverFreqs()
{
- switch (nBands) {
- case 1:
- break;
-
- case 2:
- for (int i = 0; i < nBands - 1; ++i)
- {
- vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, INIT_XOVER_FREQS_2B[i]));
- }
- break;
-
- case 3:
- for (int i = 0; i < nBands - 1; ++i)
- {
- vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, INIT_XOVER_FREQS_3B[i]));
- }
- break;
-
- case 4:
- for (int i = 0; i < nBands - 1; ++i)
- {
- vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, INIT_XOVER_FREQS_4B[i]));
- }
- break;
-
- case 5:
- for (int i = 0; i < nBands - 1; ++i)
- {
- vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, INIT_XOVER_FREQS_5B[i]));
- }
- break;
-
- default:
- jassert(false);
- break;
- }
+ switch (nBands) {
+ case 1:
+ break;
+
+ case 2:
+ for (int i = 0; i < nBands - 1; ++i)
+ {
+ vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, INIT_XOVER_FREQS_2B[i]));
+ }
+ break;
+
+ case 3:
+ for (int i = 0; i < nBands - 1; ++i)
+ {
+ vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, INIT_XOVER_FREQS_3B[i]));
+ }
+ break;
+
+ case 4:
+ for (int i = 0; i < nBands - 1; ++i)
+ {
+ vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, INIT_XOVER_FREQS_4B[i]));
+ }
+ break;
+
+ case 5:
+ for (int i = 0; i < nBands - 1; ++i)
+ {
+ vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, INIT_XOVER_FREQS_5B[i]));
+ }
+ break;
+
+ default:
+ jassert(false);
+ break;
+ }
}
// compute filter bank filter coeffs and store in firFilterBuffer
void PolarDesignerAudioProcessor::computeAllFilterCoefficients()
{
- for (int i = 0; i < 4; ++i)
- {
- computeFilterCoefficients(i);
- }
+ for (int i = 0; i < 4; ++i)
+ {
+ computeFilterCoefficients(i);
+ }
}
void PolarDesignerAudioProcessor::computeFilterCoefficients(int crossoverNr)
{
- // only one band: no filtering
- if (nBands == 1)
- return;
-
- // lowest band is simple lowpass
- if (crossoverNr == 0)
- {
- dsp::FilterDesign::FIRCoefficientsPtr lowpass = dsp::FilterDesign::designFIRLowpassWindowMethod(hzFromZeroToOne(0, xOverFreqs[0]->load()), currentSampleRate, firLen - 1, dsp::WindowingFunction::WindowingMethod::hamming);
- float* lpCoeffs = lowpass->getRawCoefficients();
- firFilterBuffer.copyFrom(0, 0, lpCoeffs, firLen);
- }
-
- // all the other bands are bandpass filters
- for (int i = std::max(1, crossoverNr); i < std::min(crossoverNr + 2, nBands - 1); ++i)
- {
- float halfBandwidth = (hzFromZeroToOne(i, xOverFreqs[i]->load()) - hzFromZeroToOne(i-1, xOverFreqs[i-1]->load())) / 2;
- dsp::FilterDesign::FIRCoefficientsPtr lp2bp = dsp::FilterDesign::designFIRLowpassWindowMethod(halfBandwidth, currentSampleRate, firLen - 1, dsp::WindowingFunction::WindowingMethod::hamming);
- float* lp2bpCoeffs = lp2bp->getRawCoefficients();
- auto* filterBufferPointer = firFilterBuffer.getWritePointer(i);
- for (int j=0; jload());
- // write bandpass transformed fir coeffs to buffer
- *(filterBufferPointer+j) = 2 * *(lp2bpCoeffs+j) * std::cosf(MathConstants::twoPi * fCenter / currentSampleRate * (j - (firLen - 1) / 2));
- }
- }
-
- if (crossoverNr == nBands - 2)
- {
- // highest band is highpass (via frequency transform)
- float hpBandwidth = currentSampleRate / 2 - hzFromZeroToOne(nBands - 2, xOverFreqs[nBands-2]->load());
- auto* filterBufferPointer = firFilterBuffer.getWritePointer(nBands-1);
- dsp::FilterDesign::FIRCoefficientsPtr lp2hp = dsp::FilterDesign::designFIRLowpassWindowMethod(hpBandwidth, currentSampleRate, firLen - 1, dsp::WindowingFunction::WindowingMethod::hamming);
- float* lp2hpCoeffs = lp2hp->getRawCoefficients();
- for (int i=0; i::pi * (i - (firLen - 1) / 2));
- }
- }
-
+ // only one band: no filtering
+ if (nBands == 1)
+ return;
+
+ // lowest band is simple lowpass
+ if (crossoverNr == 0)
+ {
+ dsp::FilterDesign::FIRCoefficientsPtr lowpass = dsp::FilterDesign::designFIRLowpassWindowMethod(hzFromZeroToOne(0, xOverFreqs[0]->load()), currentSampleRate, static_cast (firLen - 1.0f), dsp::WindowingFunction::WindowingMethod::hamming);
+ float* lpCoeffs = lowpass->getRawCoefficients();
+ firFilterBuffer.copyFrom(0, 0, lpCoeffs, firLen);
+ }
+
+ // all the other bands are bandpass filters
+ for (int i = std::max(1, crossoverNr); i < std::min(crossoverNr + 2, nBands - 1); ++i)
+ {
+ float halfBandwidth = (hzFromZeroToOne(i, xOverFreqs[i]->load()) - hzFromZeroToOne(i-1, xOverFreqs[i-1]->load())) / 2;
+ dsp::FilterDesign::FIRCoefficientsPtr lp2bp = dsp::FilterDesign::designFIRLowpassWindowMethod(halfBandwidth, currentSampleRate, static_cast (firLen - 1.0f), dsp::WindowingFunction::WindowingMethod::hamming);
+ float* lp2bpCoeffs = lp2bp->getRawCoefficients();
+ auto* filterBufferPointer = firFilterBuffer.getWritePointer(i);
+ for (int j=0; jload());
+ // write bandpass transformed fir coeffs to buffer
+ *(filterBufferPointer+j) = 2 * *(lp2bpCoeffs+j) * std::cosf(static_cast (MathConstants::twoPi * fCenter / currentSampleRate * (j - (firLen - 1.0f) / 2.0f)));
+ }
+ }
+
+ if (crossoverNr == nBands - 2)
+ {
+ // highest band is highpass (via frequency transform)
+ float hpBandwidth = static_cast (currentSampleRate / 2 - hzFromZeroToOne (nBands - 2, xOverFreqs[nBands - 2]->load()));
+ auto* filterBufferPointer = firFilterBuffer.getWritePointer(nBands-1);
+ dsp::FilterDesign::FIRCoefficientsPtr lp2hp = dsp::FilterDesign::designFIRLowpassWindowMethod(hpBandwidth, currentSampleRate, static_cast(firLen - 1.0f), dsp::WindowingFunction::WindowingMethod::hamming);
+ float* lp2hpCoeffs = lp2hp->getRawCoefficients();
+ for (int i=0; i::pi * (i - (firLen - 1) / 2));
+ }
+ }
+
}
void PolarDesignerAudioProcessor::initAllConvolvers()
{
- convolversReady = false;
-
- // build filters and fill firFilterBuffer
- dsp::AudioBlock convBlk (firFilterBuffer);
- dsp::ProcessSpec convSpec {currentSampleRate, static_cast(currentBlockSize), 1};
- for (int i = 0; i < nBands; ++i) // prepare nBands mono convolvers
- {
- AudioBuffer convSingleBuffOmni(1, firLen);
- convSingleBuffOmni.copyFrom(0, 0, firFilterBuffer, i, 0, firLen);
-
- AudioBuffer convSingleBuffEight(1, firLen);
- convSingleBuffEight.copyFrom(0, 0, firFilterBuffer, i, 0, firLen);
-
- // omni convolver
- convolvers[2 * i].prepare (convSpec); // must be called before loading IR
- convolvers[2 * i].loadImpulseResponse(std::move(convSingleBuffOmni), currentSampleRate, Convolution::Stereo::no, Convolution::Trim::no, Convolution::Normalise::no);
-
- // eight convolver
- convolvers[2 * i + 1].prepare (convSpec); // must be called before loading IR
- convolvers[2 * i + 1].loadImpulseResponse(std::move(convSingleBuffEight), currentSampleRate, Convolution::Stereo::no, Convolution::Trim::no, Convolution::Normalise::no);
- }
- convolversReady = true;
+ convolversReady = false;
+
+ // build filters and fill firFilterBuffer
+ dsp::AudioBlock convBlk (firFilterBuffer);
+ dsp::ProcessSpec convSpec {currentSampleRate, static_cast(currentBlockSize), 1};
+ for (int i = 0; i < nBands; ++i) // prepare nBands mono convolvers
+ {
+ AudioBuffer convSingleBuffOmni(1, firLen);
+ convSingleBuffOmni.copyFrom(0, 0, firFilterBuffer, i, 0, firLen);
+
+ AudioBuffer convSingleBuffEight(1, firLen);
+ convSingleBuffEight.copyFrom(0, 0, firFilterBuffer, i, 0, firLen);
+
+ // omni convolver
+ convolvers[2 * i].prepare (convSpec); // must be called before loading IR
+ convolvers[2 * i].loadImpulseResponse(std::move(convSingleBuffOmni), currentSampleRate, Convolution::Stereo::no, Convolution::Trim::no, Convolution::Normalise::no);
+
+ // eight convolver
+ convolvers[2 * i + 1].prepare (convSpec); // must be called before loading IR
+ convolvers[2 * i + 1].loadImpulseResponse(std::move(convSingleBuffEight), currentSampleRate, Convolution::Stereo::no, Convolution::Trim::no, Convolution::Normalise::no);
+ }
+ convolversReady = true;
}
void PolarDesignerAudioProcessor::initConvolver(int convNr)
{
- convolversReady = false;
-
- // build filters and fill firFilterBuffer
- dsp::AudioBlock convBlk (firFilterBuffer);
- dsp::ProcessSpec convSpec {currentSampleRate, static_cast(currentBlockSize), 1};
-
- // update two convolvers: if one crossover frequency changes, two neighbouring bands need new filters
- for (int i = convNr; i < convNr + 2; ++i)
- {
- AudioBuffer convSingleBuffOmni(1, firLen);
- convSingleBuffOmni.copyFrom(0, 0, firFilterBuffer, i, 0, firLen);
-
- AudioBuffer convSingleBuffEight(1, firLen);
- convSingleBuffEight.copyFrom(0, 0, firFilterBuffer, i, 0, firLen);
-
- // omni convolver
- convolvers[2 * i].prepare (convSpec); // must be called before loading IR
- convolvers[2 * i].loadImpulseResponse(std::move(convSingleBuffOmni), currentSampleRate, Convolution::Stereo::no, Convolution::Trim::no, Convolution::Normalise::no);
-
- // eight convolver
- convolvers[2 * i + 1].prepare (convSpec); // must be called before loading IR
- convolvers[2 * i + 1].loadImpulseResponse(std::move(convSingleBuffEight), currentSampleRate, Convolution::Stereo::no, Convolution::Trim::no, Convolution::Normalise::no);
- }
- convolversReady = true;
+ convolversReady = false;
+
+ // build filters and fill firFilterBuffer
+ dsp::AudioBlock convBlk (firFilterBuffer);
+ dsp::ProcessSpec convSpec {currentSampleRate, static_cast(currentBlockSize), 1};
+
+ // update two convolvers: if one crossover frequency changes, two neighbouring bands need new filters
+ for (int i = convNr; i < convNr + 2; ++i)
+ {
+ AudioBuffer convSingleBuffOmni(1, firLen);
+ convSingleBuffOmni.copyFrom(0, 0, firFilterBuffer, i, 0, firLen);
+
+ AudioBuffer convSingleBuffEight(1, firLen);
+ convSingleBuffEight.copyFrom(0, 0, firFilterBuffer, i, 0, firLen);
+
+ // omni convolver
+ convolvers[2 * i].prepare (convSpec); // must be called before loading IR
+ convolvers[2 * i].loadImpulseResponse(std::move(convSingleBuffOmni), currentSampleRate, Convolution::Stereo::no, Convolution::Trim::no, Convolution::Normalise::no);
+
+ // eight convolver
+ convolvers[2 * i + 1].prepare (convSpec); // must be called before loading IR
+ convolvers[2 * i + 1].loadImpulseResponse(std::move(convSingleBuffEight), currentSampleRate, Convolution::Stereo::no, Convolution::Trim::no, Convolution::Normalise::no);
+ }
+ convolversReady = true;
}
void PolarDesignerAudioProcessor::createOmniAndEightSignals (AudioBuffer& buffer)
{
- int numSamples = buffer.getNumSamples();
- // calculate omni part
- const float* readPointerFront = buffer.getReadPointer (0);
- const float* readPointerBack = buffer.getReadPointer (1);
- float* writePointerOmni = omniEightBuffer.getWritePointer (0);
- FloatVectorOperations::copy (writePointerOmni, readPointerFront, numSamples);
- FloatVectorOperations::add (writePointerOmni, readPointerBack, numSamples);
-
- // calculate fig-of-eight part
- float* writePointerEight = omniEightBuffer.getWritePointer (1);
- FloatVectorOperations::copy (writePointerEight, readPointerFront, numSamples);
- FloatVectorOperations::subtract (writePointerEight, readPointerBack, numSamples);
+ int numSamples = buffer.getNumSamples();
+ // calculate omni part
+ const float* readPointerFront = buffer.getReadPointer (0);
+ const float* readPointerBack = buffer.getReadPointer (1);
+ float* writePointerOmni = omniEightBuffer.getWritePointer (0);
+ FloatVectorOperations::copy (writePointerOmni, readPointerFront, numSamples);
+ FloatVectorOperations::add (writePointerOmni, readPointerBack, numSamples);
+
+ // calculate fig-of-eight part
+ float* writePointerEight = omniEightBuffer.getWritePointer (1);
+ FloatVectorOperations::copy (writePointerEight, readPointerFront, numSamples);
+ FloatVectorOperations::subtract (writePointerEight, readPointerBack, numSamples);
}
void PolarDesignerAudioProcessor::createPolarPatterns(AudioBuffer& buffer)
{
- int numSamples = buffer.getNumSamples();
- buffer.clear();
-
- int nActiveBands = nBands;
- if (zeroDelayMode->load() > 0.5f)
- nActiveBands = 1;
-
- for (int i = 0; i < nActiveBands; ++i)
- {
- if ((muteBand[i]->load() > 0.5 && soloBand[i]->load() < 0.5) || (soloActive && soloBand[i]->load() < 0.5))
- continue;
-
- // calculate patterns and add to output buffer
- const float* readPointerOmni = filterBankBuffer.getReadPointer (2 * i);
- const float* readPointerEight = filterBankBuffer.getReadPointer (2 * i + 1);
-
- float oldGain = Decibels::decibelsToGain(oldBandGains[i], -59.91f);
- float gain = Decibels::decibelsToGain(bandGains[i]->load(), -59.91f);
-
- // add with ramp to prevent crackling noises
- buffer.addFromWithRamp(0, 0, readPointerOmni, numSamples,
- (1 - std::abs (oldDirFactors[i])) * oldGain,
- (1 - std::abs (dirFactors[i]->load())) * gain);
- buffer.addFromWithRamp(0, 0, readPointerEight, numSamples,
- oldDirFactors[i] * oldGain,
- dirFactors[i]->load() * gain);
-
- oldDirFactors[i] = dirFactors[i]->load();
- oldBandGains[i] = bandGains[i]->load();
- }
-
- // delay needs to be running constantly to prevent clicks
- delayBuffer.copyFrom(0, 0, buffer, 0, 0, numSamples);
- dsp::AudioBlock delayBlock(delayBuffer);
- dsp::ProcessContextReplacing delayContext(delayBlock);
- delay.process(delayContext);
-
- if (nActiveBands == 1 && zeroDelayMode->load() < 0.5f) {
- buffer.copyFrom(0, 0, delayBuffer, 0, 0, numSamples);
- }
-
- // copy to second output channel -> this generates loud glitches in pro tools if mono output configuration is used
- // -> check getMainBusNumOutputChannels()
- if (buffer.getNumChannels() == 2 && getMainBusNumOutputChannels() == 2)
- buffer.copyFrom(1, 0, buffer, 0, 0, numSamples);
+ int numSamples = buffer.getNumSamples();
+ buffer.clear();
+
+ int nActiveBands = nBands;
+ if (zeroDelayMode->load() > 0.5f)
+ nActiveBands = 1;
+
+ for (int i = 0; i < nActiveBands; ++i)
+ {
+ if ((muteBand[i]->load() > 0.5 && soloBand[i]->load() < 0.5) || (soloActive && soloBand[i]->load() < 0.5))
+ continue;
+
+ // calculate patterns and add to output buffer
+ const float* readPointerOmni = filterBankBuffer.getReadPointer (2 * i);
+ const float* readPointerEight = filterBankBuffer.getReadPointer (2 * i + 1);
+
+ float oldGain = Decibels::decibelsToGain(oldBandGains[i], -59.91f);
+ float gain = Decibels::decibelsToGain(bandGains[i]->load(), -59.91f);
+
+ // add with ramp to prevent crackling noises
+ buffer.addFromWithRamp(0, 0, readPointerOmni, numSamples,
+ (1 - std::abs (oldDirFactors[i])) * oldGain,
+ (1 - std::abs (dirFactors[i]->load())) * gain);
+ buffer.addFromWithRamp(0, 0, readPointerEight, numSamples,
+ oldDirFactors[i] * oldGain,
+ dirFactors[i]->load() * gain);
+
+ oldDirFactors[i] = dirFactors[i]->load();
+ oldBandGains[i] = bandGains[i]->load();
+ }
+
+ // delay needs to be running constantly to prevent clicks
+ delayBuffer.copyFrom(0, 0, buffer, 0, 0, numSamples);
+ dsp::AudioBlock delayBlock(delayBuffer);
+ dsp::ProcessContextReplacing delayContext(delayBlock);
+ delay.process(delayContext);
+
+ if (nActiveBands == 1 && zeroDelayMode->load() < 0.5f) {
+ buffer.copyFrom(0, 0, delayBuffer, 0, 0, numSamples);
+ }
+
+ // copy to second output channel -> this generates loud glitches in pro tools if mono output configuration is used
+ // -> check getMainBusNumOutputChannels()
+ if (buffer.getNumChannels() == 2 && getMainBusNumOutputChannels() == 2)
+ buffer.copyFrom(1, 0, buffer, 0, 0, numSamples);
}
void PolarDesignerAudioProcessor::setLastDir(File newLastDir)
{
- lastDir = newLastDir;
- const var v (lastDir.getFullPathName());
- properties->setValue ("presetFolder", v);
+ lastDir = newLastDir;
+ const var v (lastDir.getFullPathName());
+ properties->setValue ("presetFolder", v);
}
Result PolarDesignerAudioProcessor::loadPreset(const File& presetFile)
{
- var parsedJson;
- if (!presetFile.exists())
- return Result::fail ("File does not exist!");
-
- String jsonString = presetFile.loadFileAsString();
- Result result = JSON::parse (jsonString, parsedJson);
- if (!result.wasOk())
- return Result::fail ("File could not be parsed: Please provide valid JSON!");
-
- for (auto &it : presetProperties)
- {
- if (!parsedJson.hasProperty (it))
- return Result::fail ("Corrupt preset file: No '" + it + "' property found.");
- }
-
- loadingFile = true;
-
- float x = parsedJson.getProperty ("nrActiveBands", parsedJson);
- vtsParams.getParameter ("nrBands")->setValueNotifyingHost (vtsParams.getParameter ("nrBands")->convertTo0to1(x - 1));
-
- for (int i = 0; i < 4; ++i)
- {
- x = parsedJson.getProperty ("xOverF" + String(i+1), parsedJson);
- vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, x));
- }
-
- NormalisableRange dfRange = vtsParams.getParameter("alpha1")->getNormalisableRange();
-
- for (int i = 0; i < 5; ++i)
- {
- x = parsedJson.getProperty ("dirFactor" + String(i+1), parsedJson);
- if (x < dfRange.start || x > dfRange.end)
- return Result::fail ("DirFactor" + String(i+1) + " needs to be between " + String(dfRange.start) + " and " + String(dfRange.end) + ".");
- vtsParams.getParameter ("alpha" + String(i+1))->setValueNotifyingHost (dfRange.convertTo0to1(x));
-
- x = parsedJson.getProperty ("gain" + String(i+1), parsedJson);
- vtsParams.getParameter ("gain" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("gain1")->convertTo0to1(x));
-
- x = parsedJson.getProperty ("solo" + String(i+1), parsedJson);
- vtsParams.getParameter ("solo" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("solo1")->convertTo0to1(x));
-
- x = parsedJson.getProperty ("mute" + String(i+1), parsedJson);
- vtsParams.getParameter ("mute" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("solo1")->convertTo0to1(x));
- }
-
- doEq = parsedJson.getProperty ("ffDfEq", parsedJson);
-
- x = parsedJson.getProperty ("proximity", parsedJson);
- vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameter("proximity")->convertTo0to1(x));
-
- x = parsedJson.getProperty("proximityOnOff", parsedJson);
- vtsParams.getParameter("proximityOnOff")->setValueNotifyingHost(vtsParams.getParameter("proximityOnOff")->convertTo0to1(x));
-
- loadingFile = false;
-
- // set parameters
- nBands = static_cast(nBandsPtr->load()) + 1;
- activeBandsChanged = true;
- computeAllFilterCoefficients();
- initAllConvolvers();
- repaintDEQ = true;
-
- return Result::ok();
+ var parsedJson;
+ if (!presetFile.exists())
+ return Result::fail ("File does not exist!");
+
+ String jsonString = presetFile.loadFileAsString();
+ Result result = JSON::parse (jsonString, parsedJson);
+ if (!result.wasOk())
+ return Result::fail ("File could not be parsed: Please provide valid JSON!");
+
+ for (auto &it : presetProperties)
+ {
+ if (!parsedJson.hasProperty (it))
+ return Result::fail ("Corrupt preset file: No '" + it + "' property found.");
+ }
+
+ loadingFile = true;
+
+ float x = parsedJson.getProperty ("nrActiveBands", parsedJson);
+ vtsParams.getParameter ("nrBands")->setValueNotifyingHost (vtsParams.getParameter ("nrBands")->convertTo0to1(x - 1));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ x = parsedJson.getProperty ("xOverF" + String(i+1), parsedJson);
+ vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (hzToZeroToOne(i, x));
+ }
+
+ NormalisableRange dfRange = vtsParams.getParameter("alpha1")->getNormalisableRange();
+
+ for (int i = 0; i < 5; ++i)
+ {
+ x = parsedJson.getProperty ("dirFactor" + String(i+1), parsedJson);
+ if (x < dfRange.start || x > dfRange.end)
+ return Result::fail ("DirFactor" + String(i+1) + " needs to be between " + String(dfRange.start) + " and " + String(dfRange.end) + ".");
+ vtsParams.getParameter ("alpha" + String(i+1))->setValueNotifyingHost (dfRange.convertTo0to1(x));
+
+ x = parsedJson.getProperty ("gain" + String(i+1), parsedJson);
+ vtsParams.getParameter ("gain" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("gain1")->convertTo0to1(x));
+
+ x = parsedJson.getProperty ("solo" + String(i+1), parsedJson);
+ vtsParams.getParameter ("solo" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("solo1")->convertTo0to1(x));
+
+ x = parsedJson.getProperty ("mute" + String(i+1), parsedJson);
+ vtsParams.getParameter ("mute" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("solo1")->convertTo0to1(x));
+ }
+
+ doEq = parsedJson.getProperty ("ffDfEq", parsedJson);
+
+ x = parsedJson.getProperty ("proximity", parsedJson);
+ vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameter("proximity")->convertTo0to1(x));
+
+ x = parsedJson.getProperty("proximityOnOff", parsedJson);
+ vtsParams.getParameter("proximityOnOff")->setValueNotifyingHost(vtsParams.getParameter("proximityOnOff")->convertTo0to1(x));
+
+ loadingFile = false;
+
+ // set parameters
+ nBands = static_cast(nBandsPtr->load()) + 1;
+ activeBandsChanged = true;
+ computeAllFilterCoefficients();
+ initAllConvolvers();
+ repaintDEQ = true;
+
+ return Result::ok();
}
Result PolarDesignerAudioProcessor::savePreset (File destination)
{
- DynamicObject* jsonObj = new DynamicObject();
- char versionString[10];
- strcpy(versionString, "v");
- strcat(versionString, JucePlugin_VersionString);
- jsonObj->setProperty("Description", var("This preset file was created with the Austrian Audio PolarDesigner plugin "
- + String(versionString) + ", for more information see www.austrian.audio ."));
- jsonObj->setProperty ("nrActiveBands", nBands);
- jsonObj->setProperty ("xOverF1", static_cast(hzFromZeroToOne(0, xOverFreqs[0]->load())));
- jsonObj->setProperty ("xOverF2", static_cast(hzFromZeroToOne(1, xOverFreqs[1]->load())));
- jsonObj->setProperty ("xOverF3", static_cast(hzFromZeroToOne(2, xOverFreqs[2]->load())));
- jsonObj->setProperty ("xOverF4", static_cast(hzFromZeroToOne(3, xOverFreqs[3]->load())));
- jsonObj->setProperty ("dirFactor1", dirFactors[0]->load());
- jsonObj->setProperty ("dirFactor2", dirFactors[1]->load());
- jsonObj->setProperty ("dirFactor3", dirFactors[2]->load());
- jsonObj->setProperty ("dirFactor4", dirFactors[3]->load());
- jsonObj->setProperty ("dirFactor5", dirFactors[4]->load());
- jsonObj->setProperty ("gain1", bandGains[0]->load());
- jsonObj->setProperty ("gain2", bandGains[1]->load());
- jsonObj->setProperty ("gain3", bandGains[2]->load());
- jsonObj->setProperty ("gain4", bandGains[3]->load());
- jsonObj->setProperty ("gain5", bandGains[4]->load());
- jsonObj->setProperty ("solo1", soloBand[0]->load());
- jsonObj->setProperty ("solo2", soloBand[1]->load());
- jsonObj->setProperty ("solo3", soloBand[2]->load());
- jsonObj->setProperty ("solo4", soloBand[3]->load());
- jsonObj->setProperty ("solo5", soloBand[4]->load());
- jsonObj->setProperty ("mute1", muteBand[0]->load());
- jsonObj->setProperty ("mute2", muteBand[1]->load());
- jsonObj->setProperty ("mute3", muteBand[2]->load());
- jsonObj->setProperty ("mute4", muteBand[3]->load());
- jsonObj->setProperty ("mute5", muteBand[4]->load());
- jsonObj->setProperty ("ffDfEq", doEq);
- jsonObj->setProperty ("proximity", proxDistance->load());
- jsonObj->setProperty("proximityOnOff", proxOnOff->load());
-
- String jsonString = JSON::toString (var (jsonObj), false, 2);
- if (destination.replaceWithText (jsonString))
- return Result::ok();
- else
- return Result::fail ("Could not write preset file. Check file access permissions.");
+ DynamicObject* jsonObj = new DynamicObject();
+ char versionString[10];
+ strcpy(versionString, "v");
+ strcat(versionString, JucePlugin_VersionString);
+ jsonObj->setProperty("Description", var("This preset file was created with the Austrian Audio PolarDesigner plugin "
+ + String(versionString) + ", for more information see www.austrian.audio ."));
+ jsonObj->setProperty ("nrActiveBands", nBands);
+ jsonObj->setProperty ("xOverF1", static_cast(hzFromZeroToOne(0, xOverFreqs[0]->load())));
+ jsonObj->setProperty ("xOverF2", static_cast(hzFromZeroToOne(1, xOverFreqs[1]->load())));
+ jsonObj->setProperty ("xOverF3", static_cast(hzFromZeroToOne(2, xOverFreqs[2]->load())));
+ jsonObj->setProperty ("xOverF4", static_cast(hzFromZeroToOne(3, xOverFreqs[3]->load())));
+ jsonObj->setProperty ("dirFactor1", dirFactors[0]->load());
+ jsonObj->setProperty ("dirFactor2", dirFactors[1]->load());
+ jsonObj->setProperty ("dirFactor3", dirFactors[2]->load());
+ jsonObj->setProperty ("dirFactor4", dirFactors[3]->load());
+ jsonObj->setProperty ("dirFactor5", dirFactors[4]->load());
+ jsonObj->setProperty ("gain1", bandGains[0]->load());
+ jsonObj->setProperty ("gain2", bandGains[1]->load());
+ jsonObj->setProperty ("gain3", bandGains[2]->load());
+ jsonObj->setProperty ("gain4", bandGains[3]->load());
+ jsonObj->setProperty ("gain5", bandGains[4]->load());
+ jsonObj->setProperty ("solo1", soloBand[0]->load());
+ jsonObj->setProperty ("solo2", soloBand[1]->load());
+ jsonObj->setProperty ("solo3", soloBand[2]->load());
+ jsonObj->setProperty ("solo4", soloBand[3]->load());
+ jsonObj->setProperty ("solo5", soloBand[4]->load());
+ jsonObj->setProperty ("mute1", muteBand[0]->load());
+ jsonObj->setProperty ("mute2", muteBand[1]->load());
+ jsonObj->setProperty ("mute3", muteBand[2]->load());
+ jsonObj->setProperty ("mute4", muteBand[3]->load());
+ jsonObj->setProperty ("mute5", muteBand[4]->load());
+ jsonObj->setProperty ("ffDfEq", doEq);
+ jsonObj->setProperty ("proximity", proxDistance->load());
+ jsonObj->setProperty("proximityOnOff", proxOnOff->load());
+
+ String jsonString = JSON::toString (var (jsonObj), false, 2);
+ if (destination.replaceWithText (jsonString))
+ return Result::ok();
+ else
+ return Result::fail ("Could not write preset file. Check file access permissions.");
}
float PolarDesignerAudioProcessor::hzToZeroToOne(int idx, float hz)
{
- switch (nBands) {
- case 1:
- return 0;
- break;
-
- case 2:
- return (hz - XOVER_RANGE_START_2B[idx]) / (XOVER_RANGE_END_2B[idx] - XOVER_RANGE_START_2B[idx]);
- break;
-
- case 3:
- return (hz - XOVER_RANGE_START_3B[idx]) / (XOVER_RANGE_END_3B[idx] - XOVER_RANGE_START_3B[idx]);
- break;
-
- case 4:
- return (hz - XOVER_RANGE_START_4B[idx]) / (XOVER_RANGE_END_4B[idx] - XOVER_RANGE_START_4B[idx]);
- break;
-
- case 5:
- return (hz - XOVER_RANGE_START_5B[idx]) / (XOVER_RANGE_END_5B[idx] - XOVER_RANGE_START_5B[idx]);
- break;
-
- default:
- jassert(false);
- break;
- }
- return 0;
+ switch (nBands) {
+ case 1:
+ return 0;
+ break;
+
+ case 2:
+ return (hz - XOVER_RANGE_START_2B[idx]) / (XOVER_RANGE_END_2B[idx] - XOVER_RANGE_START_2B[idx]);
+ break;
+
+ case 3:
+ return (hz - XOVER_RANGE_START_3B[idx]) / (XOVER_RANGE_END_3B[idx] - XOVER_RANGE_START_3B[idx]);
+ break;
+
+ case 4:
+ return (hz - XOVER_RANGE_START_4B[idx]) / (XOVER_RANGE_END_4B[idx] - XOVER_RANGE_START_4B[idx]);
+ break;
+
+ case 5:
+ return (hz - XOVER_RANGE_START_5B[idx]) / (XOVER_RANGE_END_5B[idx] - XOVER_RANGE_START_5B[idx]);
+ break;
+
+ default:
+ jassert(false);
+ break;
+ }
+ return 0;
}
float PolarDesignerAudioProcessor::hzFromZeroToOne(int idx, float val)
{
- switch (nBands) {
- case 1:
- return 0;
- break;
-
- case 2:
- return XOVER_RANGE_START_2B[idx] + val * (XOVER_RANGE_END_2B[idx] - XOVER_RANGE_START_2B[idx]);
- break;
-
- case 3:
- return XOVER_RANGE_START_3B[idx] + val * (XOVER_RANGE_END_3B[idx] - XOVER_RANGE_START_3B[idx]);
- break;
-
- case 4:
- return XOVER_RANGE_START_4B[idx] + val * (XOVER_RANGE_END_4B[idx] - XOVER_RANGE_START_4B[idx]);
- break;
-
- case 5:
- return XOVER_RANGE_START_5B[idx] + val * (XOVER_RANGE_END_5B[idx] - XOVER_RANGE_START_5B[idx]);
- break;
-
- default:
- jassert(false);
- break;
- }
- return 0;
+ switch (nBands) {
+ case 1:
+ return 0;
+ break;
+
+ case 2:
+ return XOVER_RANGE_START_2B[idx] + val * (XOVER_RANGE_END_2B[idx] - XOVER_RANGE_START_2B[idx]);
+ break;
+
+ case 3:
+ return XOVER_RANGE_START_3B[idx] + val * (XOVER_RANGE_END_3B[idx] - XOVER_RANGE_START_3B[idx]);
+ break;
+
+ case 4:
+ return XOVER_RANGE_START_4B[idx] + val * (XOVER_RANGE_END_4B[idx] - XOVER_RANGE_START_4B[idx]);
+ break;
+
+ case 5:
+ return XOVER_RANGE_START_5B[idx] + val * (XOVER_RANGE_END_5B[idx] - XOVER_RANGE_START_5B[idx]);
+ break;
+
+ default:
+ jassert(false);
+ break;
+ }
+ return 0;
}
float PolarDesignerAudioProcessor::getXoverSliderRangeStart (int sliderNum)
{
- switch (nBands) {
- case 2:
- return XOVER_RANGE_START_2B[sliderNum];
- break;
-
- case 3:
- return XOVER_RANGE_START_3B[sliderNum];
- break;
-
- case 4:
- return XOVER_RANGE_START_4B[sliderNum];
- break;
-
- case 5:
- return XOVER_RANGE_START_5B[sliderNum];
- break;
-
- default:
- jassert(false);
- break;
- }
- return 0;
+ switch (nBands) {
+ case 2:
+ return XOVER_RANGE_START_2B[sliderNum];
+ break;
+
+ case 3:
+ return XOVER_RANGE_START_3B[sliderNum];
+ break;
+
+ case 4:
+ return XOVER_RANGE_START_4B[sliderNum];
+ break;
+
+ case 5:
+ return XOVER_RANGE_START_5B[sliderNum];
+ break;
+
+ default:
+ jassert(false);
+ break;
+ }
+ return 0;
}
float PolarDesignerAudioProcessor::getXoverSliderRangeEnd (int sliderNum)
{
- switch (nBands) {
- case 2:
- return XOVER_RANGE_END_2B[sliderNum];
- break;
-
- case 3:
- return XOVER_RANGE_END_3B[sliderNum];
- break;
-
- case 4:
- return XOVER_RANGE_END_4B[sliderNum];
- break;
-
- case 5:
- return XOVER_RANGE_END_5B[sliderNum];
- break;
-
- default:
- jassert(false);
- break;
- }
- return 0;
+ switch (nBands) {
+ case 2:
+ return XOVER_RANGE_END_2B[sliderNum];
+ break;
+
+ case 3:
+ return XOVER_RANGE_END_3B[sliderNum];
+ break;
+
+ case 4:
+ return XOVER_RANGE_END_4B[sliderNum];
+ break;
+
+ case 5:
+ return XOVER_RANGE_END_5B[sliderNum];
+ break;
+
+ default:
+ jassert(false);
+ break;
+ }
+ return 0;
}
void PolarDesignerAudioProcessor::startTracking(bool trackDisturber)
{
- if (trackDisturber)
- {
- trackingDisturber = true;
- for (int i = 0; i < 5; ++i)
- {
- omniSqSumDist[i] = 0.0f;
- eightSqSumDist[i] = 0.0f;
- omniEightSumDist[i] = 0.0f;
- }
- }
- else
- {
- trackingDisturber = false;
- for (int i = 0; i < 5; ++i)
- {
- omniSqSumSig[i] = 0.0f;
- eightSqSumSig[i] = 0.0f;
- omniEightSumSig[i] = 0.0f;
- }
- }
-
- nrBlocksRecorded = 0;
- trackingActive = true;
+ if (trackDisturber)
+ {
+ trackingDisturber = true;
+ for (int i = 0; i < 5; ++i)
+ {
+ omniSqSumDist[i] = 0.0f;
+ eightSqSumDist[i] = 0.0f;
+ omniEightSumDist[i] = 0.0f;
+ }
+ }
+ else
+ {
+ trackingDisturber = false;
+ for (int i = 0; i < 5; ++i)
+ {
+ omniSqSumSig[i] = 0.0f;
+ eightSqSumSig[i] = 0.0f;
+ omniEightSumSig[i] = 0.0f;
+ }
+ }
+
+ nrBlocksRecorded = 0;
+ trackingActive = true;
}
void PolarDesignerAudioProcessor::stopTracking(int applyOptimalPattern)
{
- trackingActive = false;
- if (applyOptimalPattern == 1)
- {
- if (trackingDisturber)
- {
- if (nrBlocksRecorded != 0)
- {
- for (int i = 0; i < 5; ++i)
- {
- omniSqSumDist[i] = omniSqSumDist[i]/nrBlocksRecorded;
- eightSqSumDist[i] = eightSqSumDist[i]/nrBlocksRecorded;
- omniEightSumDist[i] = omniEightSumDist[i]/nrBlocksRecorded;
- }
- }
- setMinimumDisturbancePattern();
- }
- else
- {
- if (nrBlocksRecorded != 0)
- {
- for (int i = 0; i < 5; ++i)
- {
- omniSqSumSig[i] = omniSqSumSig[i]/nrBlocksRecorded;
- eightSqSumSig[i] = eightSqSumSig[i]/nrBlocksRecorded;
- omniEightSumSig[i] = omniEightSumSig[i]/nrBlocksRecorded;
- }
- }
- setMaximumSignalPattern();
- }
- }
- else if (applyOptimalPattern == 2) // max sig-to-dist
- {
- if (trackingDisturber)
- {
- if (nrBlocksRecorded != 0)
- {
- for (int i = 0; i < 5; ++i)
- {
- omniSqSumDist[i] = omniSqSumDist[i]/nrBlocksRecorded;
- eightSqSumDist[i] = eightSqSumDist[i]/nrBlocksRecorded;
- omniEightSumDist[i] = omniEightSumDist[i]/nrBlocksRecorded;
- }
- }
- disturberRecorded = true;
- }
- else
- {
- if (nrBlocksRecorded != 0)
- {
- for (int i = 0; i < 5; ++i)
- {
- omniSqSumSig[i] = omniSqSumSig[i]/nrBlocksRecorded;
- eightSqSumSig[i] = eightSqSumSig[i]/nrBlocksRecorded;
- omniEightSumSig[i] = omniEightSumSig[i]/nrBlocksRecorded;
- }
- }
- signalRecorded = true;
- }
- maximizeSigToDistRatio();
- }
+ trackingActive = false;
+ if (applyOptimalPattern == 1)
+ {
+ if (trackingDisturber)
+ {
+ if (nrBlocksRecorded != 0)
+ {
+ for (int i = 0; i < 5; ++i)
+ {
+ omniSqSumDist[i] = omniSqSumDist[i]/nrBlocksRecorded;
+ eightSqSumDist[i] = eightSqSumDist[i]/nrBlocksRecorded;
+ omniEightSumDist[i] = omniEightSumDist[i]/nrBlocksRecorded;
+ }
+ }
+ setMinimumDisturbancePattern();
+ }
+ else
+ {
+ if (nrBlocksRecorded != 0)
+ {
+ for (int i = 0; i < 5; ++i)
+ {
+ omniSqSumSig[i] = omniSqSumSig[i]/nrBlocksRecorded;
+ eightSqSumSig[i] = eightSqSumSig[i]/nrBlocksRecorded;
+ omniEightSumSig[i] = omniEightSumSig[i]/nrBlocksRecorded;
+ }
+ }
+ setMaximumSignalPattern();
+ }
+ }
+ else if (applyOptimalPattern == 2) // max sig-to-dist
+ {
+ if (trackingDisturber)
+ {
+ if (nrBlocksRecorded != 0)
+ {
+ for (int i = 0; i < 5; ++i)
+ {
+ omniSqSumDist[i] = omniSqSumDist[i]/nrBlocksRecorded;
+ eightSqSumDist[i] = eightSqSumDist[i]/nrBlocksRecorded;
+ omniEightSumDist[i] = omniEightSumDist[i]/nrBlocksRecorded;
+ }
+ }
+ disturberRecorded = true;
+ }
+ else
+ {
+ if (nrBlocksRecorded != 0)
+ {
+ for (int i = 0; i < 5; ++i)
+ {
+ omniSqSumSig[i] = omniSqSumSig[i]/nrBlocksRecorded;
+ eightSqSumSig[i] = eightSqSumSig[i]/nrBlocksRecorded;
+ omniEightSumSig[i] = omniEightSumSig[i]/nrBlocksRecorded;
+ }
+ }
+ signalRecorded = true;
+ }
+ maximizeSigToDistRatio();
+ }
}
void PolarDesignerAudioProcessor::trackSignalEnergy()
{
- int numSamples = filterBankBuffer.getNumSamples();
- for (int i = 0; i < nBands; ++i)
- {
- const float* readPointerOmni = filterBankBuffer.getReadPointer (2*i);
- const float* readPointerEight = filterBankBuffer.getReadPointer (2*i+1);
- if (trackingDisturber)
- {
- for (int j = 0; j < numSamples; ++j)
- {
- float omniSample = readPointerOmni[j];
- omniSqSumDist[i] += omniSample * omniSample / numSamples;
- float eightSample = readPointerEight[j];
- eightSqSumDist[i] += eightSample * eightSample / numSamples;
- omniEightSumDist[i] += omniSample * eightSample / numSamples;
- }
- }
- else
- {
- for (int j = 0; j < numSamples; ++j)
- {
- float omniSample = readPointerOmni[j];
- omniSqSumSig[i] += omniSample * omniSample / numSamples;
- float eightSample = readPointerEight[j];
- eightSqSumSig[i] += eightSample * eightSample / numSamples;
- omniEightSumSig[i] += omniSample * eightSample / numSamples;
- }
- }
- }
- ++nrBlocksRecorded;
+ int numSamples = filterBankBuffer.getNumSamples();
+ for (int i = 0; i < nBands; ++i)
+ {
+ const float* readPointerOmni = filterBankBuffer.getReadPointer (2*i);
+ const float* readPointerEight = filterBankBuffer.getReadPointer (2*i+1);
+ if (trackingDisturber)
+ {
+ for (int j = 0; j < numSamples; ++j)
+ {
+ float omniSample = readPointerOmni[j];
+ omniSqSumDist[i] += omniSample * omniSample / numSamples;
+ float eightSample = readPointerEight[j];
+ eightSqSumDist[i] += eightSample * eightSample / numSamples;
+ omniEightSumDist[i] += omniSample * eightSample / numSamples;
+ }
+ }
+ else
+ {
+ for (int j = 0; j < numSamples; ++j)
+ {
+ float omniSample = readPointerOmni[j];
+ omniSqSumSig[i] += omniSample * omniSample / numSamples;
+ float eightSample = readPointerEight[j];
+ eightSqSumSig[i] += eightSample * eightSample / numSamples;
+ omniEightSumSig[i] += omniSample * eightSample / numSamples;
+ }
+ }
+ }
+ ++nrBlocksRecorded;
}
+
+
void PolarDesignerAudioProcessor::setMinimumDisturbancePattern()
{
- float disturberPower;
- float minPowerAlpha;
- float alphaStart = 0.0f;
- if (allowBackwardsPattern->load() == 1.0f)
- alphaStart = -0.5f;
-
- for (int i = 0; isetValueNotifyingHost (vtsParams.getParameter("alpha1")->convertTo0to1 (minPowerAlpha));
- disturberRecorded = true;
- }
- }
+ float disturberPower = 0.0f;
+ float minPowerAlpha = 0.0f;
+ float alphaStart = 0.0f;
+ if (allowBackwardsPattern->load() == 1.0f)
+ alphaStart = -0.5f;
+
+ for (int i = 0; isetValueNotifyingHost (vtsParams.getParameter("alpha1")->convertTo0to1 (minPowerAlpha));
+ disturberRecorded = true;
+ }
+ }
}
void PolarDesignerAudioProcessor::setMaximumSignalPattern()
{
- float signalPower;
- float maxPowerAlpha;
- float alphaStart = 0.0f;
- if (allowBackwardsPattern->load() == 1.0f)
- alphaStart = -0.5f;
-
- for (int i = 0; i < nBands; ++i)
- {
- for (float alpha = alphaStart; alpha <= 1.0f; alpha += 0.01f)
- {
- float currentPower = std::pow((1-std::abs(alpha)), 2) * omniSqSumSig[i] + std::pow(alpha, 2) * eightSqSumSig[i] + 2 * (1-std::abs(alpha)) * alpha * omniEightSumSig[i];
- if (alpha == alphaStart || currentPower > signalPower)
- {
- signalPower = currentPower;
- maxPowerAlpha = alpha;
- }
- }
- if (signalPower != 0.0f)
- {
- vtsParams.getParameter ("alpha" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("alpha1")->convertTo0to1 (maxPowerAlpha));
- signalRecorded = true;
- }
- }
+ float signalPower = 0.0f;
+ float maxPowerAlpha = 0.0f;
+ float alphaStart = 0.0f;
+ if (allowBackwardsPattern->load() == 1.0f)
+ alphaStart = -0.5f;
+
+ for (int i = 0; i < nBands; ++i)
+ {
+ for (float alpha = alphaStart; alpha <= 1.0f; alpha += 0.01f)
+ {
+ float currentPower = std::pow((1.0f-std::abs(alpha)), 2.0f) * omniSqSumSig[i] + std::pow(alpha, 2.0f) * eightSqSumSig[i] + 2.0f * (1.0f-std::abs(alpha)) * alpha * omniEightSumSig[i];
+ if ((floatsEquivalent(alpha, alphaStart)) || currentPower > signalPower)
+ {
+ signalPower = currentPower;
+ maxPowerAlpha = alpha;
+ }
+ }
+ if (signalPower != 0.0f)
+ {
+ vtsParams.getParameter ("alpha" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("alpha1")->convertTo0to1 (maxPowerAlpha));
+ signalRecorded = true;
+ }
+ }
}
void PolarDesignerAudioProcessor::maximizeSigToDistRatio()
{
- float distToSigRatio;
- float maxDistToSigAlpha;
- float alphaStart = 0.0f;
- if (allowBackwardsPattern->load() == 1.0f)
- alphaStart = -0.5f;
-
- for (int i = 0; i distToSigRatio)
- {
- distToSigRatio = currentRatio;
- maxDistToSigAlpha = alpha;
- }
- }
- if (distToSigRatio != 0.0f)
- vtsParams.getParameter ("alpha" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("alpha1")->convertTo0to1 (maxDistToSigAlpha));
- }
+ float distToSigRatio = 0.0f;
+ float maxDistToSigAlpha = 0.0f;
+ float alphaStart = 0.0f;
+ if (allowBackwardsPattern->load() == 1.0f)
+ alphaStart = -0.5f;
+
+ for (int i = 0; i distToSigRatio)
+ {
+ distToSigRatio = currentRatio;
+ maxDistToSigAlpha = alpha;
+ }
+ }
+ if (distToSigRatio != 0.0f)
+ vtsParams.getParameter ("alpha" + String(i+1))->setValueNotifyingHost (vtsParams.getParameter("alpha1")->convertTo0to1 (maxDistToSigAlpha));
+ }
}
void PolarDesignerAudioProcessor::setProxCompCoefficients(float distance)
{
- int c = 343;
- double fs = getSampleRate();
-
- // float b0 = -c / (fs * 4 * distance) + 1;
- // float b1 = -exp(-c / (fs * 2 * distance)) * (1 + c / (fs * 4 * distance));
- // float a0 = 1;
- // float a1 = -exp(-c / (fs * 2 * distance));
-
- // use logarithmic fader impact: equation is for fader between -1.0 .. 1.0
- // returns values between 1 .. 0.1
- float a = (0.05f - 1.0f) / (-log(1.1f) + log(0.1f));
- float b = 1 + a * log(0.1f);
- float r = -a * log(std::abs(distance) + 0.1) + b;
-
- float b0, b1, a0, a1;
-
- // normalized to r_ref = 1m
- if (distance <= 0) //bass cut
- {
- if (r < 0.01)
- r = 0.01;
-
- b0 = c * (r - 1) / (fs * 2 * r) + 1;
- b1 = -exp(-c / (fs * r)) * (1 - c * (r - 1) / (fs * 2 * r));
- a0 = 1;
- a1 = -exp(-c / (fs * r));
- }
- else // bass boost, careful: instable for r<0.05
- {
- if (r < 0.05)
- r = 0.05;
-
- b0 = c * (1 - r) / (fs * 2 * r) + 1;
- b1 = -exp(-c / fs) * (1 - c * (1 - r) / (fs * 2 * r));
- a0 = 1;
- a1 = -exp(-c / fs);
- }
-
- *proxCompIIR.coefficients = dsp::IIR::Coefficients(b0,b1,a0,a1);
+ // The speed of sound at standard air pressure/20C - meters per second
+ const float c = 343.0f;
+ float fs = (float)getSampleRate();
+
+ // float b0 = -c / (fs * 4 * distance) + 1;
+ // float b1 = -exp(-c / (fs * 2 * distance)) * (1 + c / (fs * 4 * distance));
+ // float a0 = 1;
+ // float a1 = -exp(-c / (fs * 2 * distance));
+
+ // use logarithmic fader impact: equation is for fader between -1.0 .. 1.0
+ // returns values between 1 .. 0.1
+ float a = (0.05f - 1.0f) / (-log(1.1f) + log(0.1f));
+ float b = 1.0f + a * log(0.1f);
+ float r = -a * log(std::abs(distance) + 0.1f) + b;
+
+ float b0, b1, a0, a1;
+
+ // normalized to r_ref = 1m
+ if (distance <= 0) //bass cut
+ {
+ if (r < 0.01f)
+ r = 0.01f;
+
+ b0 = c * (r - 1.0f) / (fs * 2.0f * r) + 1.0f;
+ b1 = -exp(-c / (fs * r)) * (1.0f - c * (r - 1.0f) / (fs * 2.0f * r));
+ a0 = 1.0f;
+ a1 = -exp(-c / (fs * r));
+ }
+ else // bass boost, careful: instable for r<0.05
+ {
+ if (r < 0.05f)
+ r = 0.05f;
+
+ b0 = c * (1.0f - r) / (fs * 2.0f * r) + 1.0f;
+ b1 = -exp(-c / fs) * (1.0f - c * (1.0f - r) / (fs * 2.0f * r));
+ a0 = 1.0f;
+ a1 = -exp(-c / fs);
+ }
+
+ *proxCompIIR.coefficients = dsp::IIR::Coefficients(b0,b1,a0,a1);
}
void PolarDesignerAudioProcessor::timerCallback()
{
- if (syncChannelPtr->load() > 0.5f)
- {
- readingSharedParams = true;
-
- int ch = (int) syncChannelPtr->load() - 1;
- ParamsToSync& paramsToSync = sharedParams.get().syncParams.getReference(ch);
-
- if (nBandsPtr->load() != paramsToSync.nrActiveBands)
- vtsParams.getParameter ("nrBands")->setValueNotifyingHost (vtsParams.getParameterRange ("nrBands").convertTo0to1 (paramsToSync.nrActiveBands));
-
- for (int i = 0; i < 5; ++i)
- {
- if (dirFactors[i]->load() != paramsToSync.dirFactors[i])
- vtsParams.getParameter ("alpha" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("alpha" + String(i+1)).convertTo0to1 (paramsToSync.dirFactors[i]));
-
- if (soloBand[i]->load() != paramsToSync.solo[i])
- vtsParams.getParameter ("solo" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("solo" + String(i+1)).convertTo0to1 (paramsToSync.solo[i]));
-
- if (muteBand[i]->load() != paramsToSync.mute[i])
- vtsParams.getParameter ("mute" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("mute" + String(i+1)).convertTo0to1 (paramsToSync.mute[i]));
-
- if (bandGains[i]->load() != paramsToSync.gains[i])
- vtsParams.getParameter ("gain" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("gain" + String(i+1)).convertTo0to1 (paramsToSync.gains[i]));
-
- if (i < 4 && xOverFreqs[i]->load() != paramsToSync.xOverFreqs[i])
- vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("xOverF" + String(i+1)).convertTo0to1 (paramsToSync.xOverFreqs[i]));
-
-
- }
-
- if (proxDistance->load() != paramsToSync.proximity)
- vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameterRange ("proximity").convertTo0to1 (paramsToSync.proximity));
-
- if (zeroDelayMode->load() != paramsToSync.zeroDelayMode)
- vtsParams.getParameter ("zeroDelayMode")->setValueNotifyingHost (vtsParams.getParameterRange ("zeroDelayMode").convertTo0to1 (paramsToSync.zeroDelayMode));
-
- if (allowBackwardsPattern->load() != paramsToSync.allowBackwardsPattern)
- vtsParams.getParameter ("allowBackwardsPattern")->setValueNotifyingHost (vtsParams.getParameterRange ("allowBackwardsPattern").convertTo0to1 (paramsToSync.allowBackwardsPattern));
-
- if (proxOnOff->load() != paramsToSync.proximityOnOff)
- vtsParams.getParameter("proximityOnOff")->setValueNotifyingHost(vtsParams.getParameterRange("proximityOnOff").convertTo0to1(paramsToSync.proximityOnOff));
-
- if (paramsToSync.ffDfEq != doEq)
- {
- setEqState(paramsToSync.ffDfEq);
- ffDfEqChanged = true;
- }
-
- readingSharedParams = false;
- }
+ if (syncChannelPtr->load() > 0.5f)
+ {
+ readingSharedParams = true;
+
+ int ch = (int) syncChannelPtr->load() - 1;
+ ParamsToSync& paramsToSync = sharedParams.get().syncParams.getReference(ch);
+
+ if ((int)nBandsPtr->load() != paramsToSync.nrActiveBands)
+ vtsParams.getParameter ("nrBands")->setValueNotifyingHost (vtsParams.getParameterRange ("nrBands").convertTo0to1 (paramsToSync.nrActiveBands));
+
+ for (int i = 0; i < 5; ++i)
+ {
+ if (!floatsEquivalent(dirFactors[i]->load(), paramsToSync.dirFactors[i]))
+ vtsParams.getParameter ("alpha" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("alpha" + String(i+1)).convertTo0to1 (paramsToSync.dirFactors[i]));
+
+ if ((int)soloBand[i]->load() != paramsToSync.solo[i])
+ vtsParams.getParameter ("solo" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("solo" + String(i+1)).convertTo0to1 (paramsToSync.solo[i]));
+
+ if ((int)muteBand[i]->load() != paramsToSync.mute[i])
+ vtsParams.getParameter ("mute" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("mute" + String(i+1)).convertTo0to1 (paramsToSync.mute[i]));
+
+ if (!floatsEquivalent(bandGains[i]->load(), paramsToSync.gains[i]))
+ vtsParams.getParameter ("gain" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("gain" + String(i+1)).convertTo0to1 (paramsToSync.gains[i]));
+
+ if ((i < 4) && (!floatsEquivalent(xOverFreqs[i]->load(), paramsToSync.xOverFreqs[i])))
+ vtsParams.getParameter ("xOverF" + String(i+1))->setValueNotifyingHost (vtsParams.getParameterRange ("xOverF" + String(i+1)).convertTo0to1 (paramsToSync.xOverFreqs[i]));
+
+
+ }
+
+ if (!floatsEquivalent(proxDistance->load(), paramsToSync.proximity))
+ vtsParams.getParameter ("proximity")->setValueNotifyingHost (vtsParams.getParameterRange ("proximity").convertTo0to1 (paramsToSync.proximity));
+
+ if ((int)zeroDelayMode->load() != paramsToSync.zeroDelayMode)
+ vtsParams.getParameter ("zeroDelayMode")->setValueNotifyingHost (vtsParams.getParameterRange ("zeroDelayMode").convertTo0to1 (paramsToSync.zeroDelayMode));
+
+ if ((int)allowBackwardsPattern->load() != paramsToSync.allowBackwardsPattern)
+ vtsParams.getParameter ("allowBackwardsPattern")->setValueNotifyingHost (vtsParams.getParameterRange ("allowBackwardsPattern").convertTo0to1 (paramsToSync.allowBackwardsPattern));
+
+ if ((int)proxOnOff->load() != paramsToSync.proximityOnOff)
+ vtsParams.getParameter("proximityOnOff")->setValueNotifyingHost(vtsParams.getParameterRange("proximityOnOff").convertTo0to1(paramsToSync.proximityOnOff));
+
+ if (paramsToSync.ffDfEq != doEq)
+ {
+ setEqState(paramsToSync.ffDfEq);
+ ffDfEqChanged = true;
+ }
+
+ readingSharedParams = false;
+ }
}
void PolarDesignerAudioProcessor::updateLatency() {
- if (isBypassed)
- {
- setLatencySamples(0);
- }
- else
- {
- // set delay compensation to FIR_LEN/2-1 if FIR_LEN even and FIR_LEN/2 if odd
- if (zeroDelayMode->load() < 0.5f)
- setLatencySamples(std::ceilf(static_cast(firLen) / 2 - 1));
- else
- setLatencySamples(0);
- }
+ if (isBypassed)
+ {
+ setLatencySamples(0);
+ }
+ else
+ {
+ // set delay compensation to FIR_LEN/2-1 if FIR_LEN even and FIR_LEN/2 if odd
+ if (zeroDelayMode->load() < 0.5f)
+ setLatencySamples(static_cast