瀏覽代碼

JUCE Multieffect Updated with assignable parameters

LuigiBiasi-Athenagroup 6 月之前
父節點
當前提交
dd8dbba8e0

+ 68 - 0
JUCE/CMLSProject/Source/APVTSListeners.cpp

@@ -0,0 +1,68 @@
+/*
+  ==============================================================================
+
+    APVTSListener.cpp
+    Created: 24 May 2025 11:10:36am
+    Author:  Luigi
+
+  ==============================================================================
+*/
+
+#include "APVTSListeners.h"
+
+APVTSListeners::APVTSListeners() {}
+
+APVTSListeners::~APVTSListeners() {}
+
+void APVTSListeners::setEqualizerProcessor(CMLSEqualizer* equalizer) {
+    this->equalizerProcessor = equalizer;
+}
+
+void APVTSListeners::setDistortionProcssor(CMLSDistortion* distortion) {
+    this->distortionProcessor = distortion;
+}
+
+void APVTSListeners::setChorusProcessor(CMLSChorus* chorus) {
+    this->chorusProcessor = chorus;
+}
+
+void APVTSListeners::setDelayProcessor(CMLSDelay* delay) {
+    this->delayProcessor = delay;
+}
+
+void APVTSListeners::setReverbProcessor(CMLSReverb* reverbProcessor) {
+    this->reverbProcessor = reverbProcessor;
+}
+
+void APVTSListeners::parameterChanged(const juce::String& parameterID, float newValue) {
+    if (parameterID == "EQLOWBANDGAIN") {
+        this->equalizerProcessor->setEqLowGain(newValue);
+    }
+    else if (parameterID == "EQHIGHBANDGAIN") {
+        this->equalizerProcessor->setEqHighGain(newValue);
+    }
+    else if (parameterID == "DISTORTIONDRIVE") {
+        this->distortionProcessor->setDrive(newValue);
+    }
+    else if (parameterID == "DISTORTIONMIX") {
+        this->distortionProcessor->setMix(newValue);
+    }
+    else if (parameterID == "CHORUSDRYWET") {
+        this->chorusProcessor->setDryWet(newValue);
+    }
+    else if (parameterID == "CHORUSAMOUNT") {
+        this->chorusProcessor->setAmount(newValue);
+    }
+    else if (parameterID == "DELAYDRYWET") {
+        this->delayProcessor->setDryWet(newValue);
+    }
+    else if (parameterID == "DELAYAMOUNT") {
+        this->delayProcessor->setAmount(newValue);
+    }
+    else if (parameterID == "REVERBROOMSIZE") {
+		this->reverbProcessor->setRoomSize(newValue);
+	}
+    else if (parameterID == "REVERBDRYWET") {
+		this->reverbProcessor->setDryWet(newValue);
+    }
+}

+ 39 - 0
JUCE/CMLSProject/Source/APVTSListeners.h

@@ -0,0 +1,39 @@
+/*
+  ==============================================================================
+
+    APVTSListener.h
+    Created: 24 May 2025 11:10:36am
+    Author:  Luigi
+
+  ==============================================================================
+*/
+#pragma once
+#include <JuceHeader.h>
+#include "CMLSReverb.h"
+#include "CMLSDelay.h"
+#include "CMLSChorus.h"
+#include "CMLSEqualizer.h"
+#include "CMLSDistortion.h"
+
+class APVTSListeners : public juce::AudioProcessorValueTreeState::Listener {
+    public:
+        APVTSListeners();
+        ~APVTSListeners() override;
+
+        // Setters for processors
+        void setEqualizerProcessor(CMLSEqualizer* equalizer);
+        void setDistortionProcssor(CMLSDistortion* distortion);
+        void setChorusProcessor(CMLSChorus* chorus);
+        void setDelayProcessor(CMLSDelay* delay);
+        void setReverbProcessor(CMLSReverb* reverb);
+
+        //Callback method
+        void parameterChanged(const juce::String& parameterID, float newValue) override;
+
+    private:
+        CMLSEqualizer* equalizerProcessor = nullptr;
+        CMLSDistortion* distortionProcessor = nullptr;
+        CMLSChorus* chorusProcessor = nullptr;
+        CMLSDelay* delayProcessor = nullptr;
+		CMLSReverb* reverbProcessor = nullptr;
+};

+ 24 - 42
JUCE/CMLSProject/Source/CMLSDelay.cpp

@@ -11,8 +11,7 @@
 #include "CMLSDelay.h"
 
 CMLSDelay::CMLSDelay() {
-	delayLengthRange = new juce::NormalisableRange<float>(0, MAX_DELAY_LENGTH);
-	feedbackRange = new juce::NormalisableRange<float>(MIN_FEEDBACK, MAX_FEEDBACK);
+	//feedbackRange = new juce::NormalisableRange<float>(MIN_FEEDBACK, MAX_FEEDBACK);
 
 	this->delayLength = 0.0f;
 	this->feedback = 0.0f;
@@ -23,26 +22,20 @@ CMLSDelay::CMLSDelay() {
 CMLSDelay::~CMLSDelay() {}
 
 void CMLSDelay::reset() {
+	this->delayLine.reset();
+	this->mixer.reset();
 }
 
 void CMLSDelay::prepare(const juce::dsp::ProcessSpec& spec) {
-	this->effectDelaySamples = spec.sampleRate * MAX_DELAY_LENGTH;
-	this->delayLine.setMaximumDelayInSamples(this->effectDelaySamples);
-	this->linearDelay.setMaximumDelayInSamples(this->effectDelaySamples);
-
+	this->maximumDelaySamples = spec.sampleRate * MAX_DELAY_LENGTH;
+	this->delayRange = new juce::NormalisableRange<float>(0, this->maximumDelaySamples);
+	this->delayRange
+	
 	this->delayLine.prepare(spec);
-	this->linearDelay.prepare(spec);
-	this->mixer.prepare(spec);
-
-	for (auto& volume : this->delayFeedbackVolume) {
-		volume.reset(spec.sampleRate, 0.05f);
-	}
+	this->delayLine.setMaximumDelayInSamples(this->maximumDelaySamples);
 
-	this->mixer.reset();
+	this->mixer.prepare(spec);
 	this->mixer.setMixingRule(juce::dsp::DryWetMixingRule::linear);
-
-	std::fill(this->delayValue.begin(), this->delayValue.end(), 0.0f);
-	std::fill(this->lastDelayOutput.begin(), this->lastDelayOutput.end(), 0.0f);
 }
 
 void CMLSDelay::process(const juce::dsp::ProcessContextReplacing<float>& context) {
@@ -50,28 +43,23 @@ void CMLSDelay::process(const juce::dsp::ProcessContextReplacing<float>& context
 	auto numChannels = audioBlock.getNumChannels();
 	const auto numSamples = audioBlock.getNumSamples();
 
-	const auto& input = context.getInputBlock();
-	const auto& output = context.getOutputBlock();
-
-	this->mixer.pushDrySamples(input);
-
-	for (size_t channel = 0; channel < numChannels; ++channel) {
-		auto* samplesIn = input.getChannelPointer(channel);
-		auto* samplesOut = output.getChannelPointer(channel);
-
-		for (size_t sample = 0; sample < input.getNumSamples(); ++sample) {
-			auto input = samplesIn[sample] - this->lastDelayOutput[channel];
-			auto delayAmount = this->delayValue[channel];
-
-			this->linearDelay.pushSample(channel, input);
-			this->linearDelay.setDelay(delayAmount);
-			samplesOut[sample] = this->linearDelay.popSample(channel);
-
-			this->lastDelayOutput[channel] = samplesOut[sample] * this->delayFeedbackVolume[channel].getNextValue();
+	this->mixer.pushDrySamples(context.getInputBlock());
+
+	for (int channel = 0; channel < numChannels; ++channel)
+	{
+		for (int i = 0; i < numSamples; i++)
+		{
+			this->delayLine.pushSample(channel, context.getInputBlock().getSample(channel, i));
+			audioBlock.setSample(
+				channel,
+				i,
+				this->delayLine.popSample(channel, this->delayLength)
+			);
 		}
 	}
 
-	this->mixer.mixWetSamples(output);
+	// Adding wet (elaborated) signal
+	this->mixer.mixWetSamples(audioBlock);
 }
 
 void CMLSDelay::setDryWet(float value) {
@@ -80,13 +68,7 @@ void CMLSDelay::setDryWet(float value) {
 }
 
 void CMLSDelay::setAmount(float value) {
-	this->delayLength = this->delayLengthRange->convertFrom0to1(value);
-	this->feedback = this->feedbackRange->convertFrom0to1(value);
-
-	std::fill(this->delayValue.begin(), this->delayValue.end(), this->delayLength * this->effectDelaySamples);
-	for (auto& volume : this->delayFeedbackVolume) {
-		volume.setTargetValue(this->feedback);
-	}
+	this->delayLength = this->delayRange->convertFrom0to1(value);
 }
 
 const float CMLSDelay::getDryWet() {

+ 10 - 12
JUCE/CMLSProject/Source/CMLSDelay.h

@@ -33,24 +33,22 @@ class CMLSDelay : public juce::dsp::ProcessorBase
 		const float getAmount();
 
 	private:
-		float effectDelaySamples;
-
-		//Paramters
+		//Parameters
 		float dryWetProp;
 		float feedback;
 		float delayLength;
 		float amount;
 
-		// Normaliosable range
-		juce::NormalisableRange<float>* delayLengthRange;
-		juce::NormalisableRange<float>* feedbackRange;
+		int maximumDelaySamples = 0;
 
-		//Delay Lines
-		juce::dsp::DelayLine<float> delayLine;
-		juce::dsp::DelayLine<float, juce::dsp::DelayLineInterpolationTypes::Linear> linearDelay;
+		// Dry/Wet mixer
 		juce::dsp::DryWetMixer<float> mixer;
 
-		std::array<float, 2> delayValue;
-		std::array<float, 2> lastDelayOutput;
-		std::array<juce::LinearSmoothedValue<float>, 2> delayFeedbackVolume;
+		// DelayLine
+		juce::dsp::DelayLine<float, juce::dsp::DelayLineInterpolationTypes::Linear> delayLine;
+		juce::dsp::DelayLine<float, juce::dsp::DelayLineInterpolationTypes::Linear> delayLine2;
+
+		// Range converters
+		juce::NormalisableRange<float>* delayRange;
+		juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear>* delaySmoothing;
 };

+ 14 - 13
JUCE/CMLSProject/Source/CMLSEqualizer.h

@@ -2,20 +2,21 @@
 
 #include <JuceHeader.h>
 
-class CMLSEqualizer : public juce::dsp::ProcessorBase {
-public:
-    CMLSEqualizer();
-    ~CMLSEqualizer() override = default;
+class CMLSEqualizer : public juce::dsp::ProcessorBase
+{
+    public:
+        CMLSEqualizer();
+        ~CMLSEqualizer() override = default;
 
-    void prepare(const juce::dsp::ProcessSpec&) override;
-    void reset() override;
-    void process(const juce::dsp::ProcessContextReplacing<float>&) override;
+        void prepare(const juce::dsp::ProcessSpec&) override;
+        void reset() override;
+        void process(const juce::dsp::ProcessContextReplacing<float>&) override;
 
-    void setEqLowGain(float);
-    void setEqHighGain(float);
+        void setEqLowGain(float);
+        void setEqHighGain(float);
 
-private:
-    double sampleRate = 44100.0; // default, will be updated
-    juce::dsp::ProcessorDuplicator<juce::dsp::IIR::Filter<float>,
-        juce::dsp::IIR::Coefficients<float>> lowBand, highBand;
+    private:
+        double sampleRate = 44100.0; // default, will be updated
+        juce::dsp::ProcessorDuplicator<juce::dsp::IIR::Filter<float>,
+            juce::dsp::IIR::Coefficients<float>> lowBand, highBand;
 };

+ 1 - 1
JUCE/CMLSProject/Source/CMLSReverb.cpp

@@ -24,7 +24,7 @@ void CMLSReverb::prepare(const juce::dsp::ProcessSpec& spec) {
 
 void CMLSReverb::process(const juce::dsp::ProcessContextReplacing<float>& context) {
 	juce::dsp::AudioBlock<float> buffer = context.getOutputBlock();
-    this->reverb.processStereo(buffer.getChannelPointer(0), buffer.getChannelPointer(1), buffer.getNumSamples());
+	this->reverb.processStereo(buffer.getChannelPointer(0), buffer.getChannelPointer(1), buffer.getNumSamples());
 }
 
 void CMLSReverb::setDryWet(float value)

+ 1 - 0
JUCE/CMLSProject/Source/CMLSReverb.h

@@ -18,6 +18,7 @@ class CMLSReverb : public juce::dsp::ProcessorBase {
         // Parameter getters
 	    const float getDryWet();
 	    const float getRoomSize();
+    
     private:
         juce::Reverb reverb;
         juce::Reverb::Parameters reverbParams;

+ 45 - 6
JUCE/CMLSProject/Source/OSCReceiverWrapper.cpp

@@ -9,6 +9,7 @@
 */
 
 #include "OSCReceiverWrapper.h"
+#include <windows.h>
 
 OSCReceiverWrapper::OSCReceiverWrapper(int port, juce::AudioProcessor* pluginProcessor) {
 	this->pluginProcessor = (CMLSProjectAudioProcessor*)pluginProcessor;
@@ -16,15 +17,52 @@ OSCReceiverWrapper::OSCReceiverWrapper(int port, juce::AudioProcessor* pluginPro
     if (!this->connect(port)) {
         this->oscConnectionError();
     }
+
+    // Declaring the listeners for the iDraw OSC paths
+    addListener(this, "/r");
+    addListener(this, "/g");
+    addListener(this, "/b");
+    addListener(this, "/a");
+    addListener(this, "/pen");
+    addListener(this, "/pencil");
+    addListener(this, "/marker");
+    addListener(this, "/monoline");
+    addListener(this, "/crayon");
+    addListener(this, "/fountainPen");
+    addListener(this, "/waterColor");
+    addListener(this, "/bitmapEraser");
+    addListener(this, "/vectorEraser");
+    addListener(this, "/canvasWidth");
+    addListener(this, "/canvasHeight");
+    addListener(this, "/drawingWidth");
+    addListener(this, "/eraserWidth");
+    addListener(this, "/x");
+    addListener(this, "/y");
+    addListener(this, "/pressure");
+    addListener(this, "/aspectX");
+    addListener(this, "/aspectY");
+
+    std::string test = "Connection opened\n";
+    OutputDebugString(test.c_str());
 }
 
 OSCReceiverWrapper::~OSCReceiverWrapper() {}
 
 void OSCReceiverWrapper::oscMessageReceived(const juce::OSCMessage& message)
 {
+    std::string debugString = "=== OSC Message at address: " + message.getAddressPattern().toString().toStdString() + " ===\n";
+    OutputDebugString(debugString.c_str());
+    
     if (!message.isEmpty() && message.size() == 1) {
 	    auto address = message.getAddressPattern().toString();
-        auto argument = message[0].getFloat32();
+        float argument = 0.0;
+
+        try {
+            argument = message[0].getFloat32();
+        }
+        catch (const std::exception e) {
+			return; // Bypass packet intepretation because the argument is not a float
+        }
 
         if (address == "/r") {
             // Unused
@@ -42,7 +80,7 @@ void OSCReceiverWrapper::oscMessageReceived(const juce::OSCMessage& message)
         else if (address == "/pen") {
             // Unused
         }
-        else if (address == "/pencil") {
+        else if (address == "/pencil" && argument == 1.0) {
             this->currentPreset = Preset::PENCIL;
         }
         else if (address == "/marker") {
@@ -51,13 +89,13 @@ void OSCReceiverWrapper::oscMessageReceived(const juce::OSCMessage& message)
         else if (address == "/monoline") {
             // Unused
         }
-        else if (address == "/crayon") {
+        else if (address == "/crayon" && argument == 1.0) {
             this->currentPreset = Preset::CRAYON;
         }
         else if (address == "/fountainPen") {
             // Preset #3
         }
-        else if (address == "/waterColor") {
+        else if (address == "/waterColor" && argument == 1.0) {
             this->currentPreset = Preset::WATERCOLOR;
         }
         else if (address == "/bitmapEraser") {
@@ -91,8 +129,9 @@ void OSCReceiverWrapper::oscMessageReceived(const juce::OSCMessage& message)
     }
 }
 
-void OSCReceiverWrapper::oscConnectionError()
-{}
+void OSCReceiverWrapper::oscConnectionError() {
+    return;
+}
 
 void OSCReceiverWrapper::processMessage() {
     if (this->currentPreset == Preset::PENCIL) {

+ 2 - 2
JUCE/CMLSProject/Source/OSCReceiverWrapper.h

@@ -25,7 +25,7 @@ enum Preset {
 
 class OSCReceiverWrapper : public juce::Component,
                            private juce::OSCReceiver,
-                           private juce::OSCReceiver::ListenerWithOSCAddress<juce::String>
+                           private juce::OSCReceiver::ListenerWithOSCAddress<juce::OSCReceiver::MessageLoopCallback>
 {
     public:
         OSCReceiverWrapper(int port, juce::AudioProcessor* pluginProcessor);
@@ -44,5 +44,5 @@ class OSCReceiverWrapper : public juce::Component,
         float pressure;
         float thickness;
 
-        CMLSProjectAudioProcessor* pluginProcessor;
+        CMLSProjectAudioProcessor *pluginProcessor;
 };

+ 3 - 0
JUCE/CMLSProject/Source/PluginEditor.cpp

@@ -13,6 +13,9 @@
 CMLSProjectAudioProcessorEditor::CMLSProjectAudioProcessorEditor (CMLSProjectAudioProcessor& p)
     : AudioProcessorEditor (&p), audioProcessor (p)
 {
+    // OSC receiver
+    this->oscReceiver = new OSCReceiverWrapper(57120, &p);
+
     // Make sure that before the constructor has finished, you've set the
     // editor's size to whatever you need it to be.
     setSize (400, 300);

+ 4 - 0
JUCE/CMLSProject/Source/PluginEditor.h

@@ -10,6 +10,7 @@
 
 #include <JuceHeader.h>
 #include "PluginProcessor.h"
+#include "OSCReceiverWrapper.h"
 
 //==============================================================================
 /**
@@ -30,6 +31,9 @@ private:
     // access the processor object that created it.
     CMLSProjectAudioProcessor& audioProcessor;
 
+	// Create an instance of the OSCReceiver
+	OSCReceiverWrapper *oscReceiver;
+
     // Title
 	juce::Label titleLabel;
 

+ 105 - 2
JUCE/CMLSProject/Source/PluginProcessor.cpp

@@ -19,7 +19,7 @@ CMLSProjectAudioProcessor::CMLSProjectAudioProcessor()
                       #endif
                        .withOutput ("Output", juce::AudioChannelSet::stereo(), true)
                      #endif
-                       )
+                       ), apvts(*this, nullptr, "Parameters", createParameters())
 #endif
 {
     // Chaining the effects
@@ -29,6 +29,23 @@ CMLSProjectAudioProcessor::CMLSProjectAudioProcessor()
     this->delay = new CMLSDelay();
     this->reverb = new CMLSReverb();
 
+    this->apvtsListeners.setEqualizerProcessor((CMLSEqualizer*)this->equalizer);
+    this->apvtsListeners.setDistortionProcssor((CMLSDistortion*)this->distortion);
+    this->apvtsListeners.setChorusProcessor((CMLSChorus*)this->chorus);
+    this->apvtsListeners.setDelayProcessor((CMLSDelay*)this->delay);
+    this->apvtsListeners.setReverbProcessor((CMLSReverb*)this->reverb);
+
+    this->apvts.addParameterListener("EQLOWBANDGAIN", &apvtsListeners);
+    this->apvts.addParameterListener("EQHIGHBANDGAIN", &apvtsListeners);
+    this->apvts.addParameterListener("DISTORTIONDRIVE", &apvtsListeners);
+    this->apvts.addParameterListener("DISTORTIONMIX", &apvtsListeners);
+    this->apvts.addParameterListener("CHORUSDRYWET", &apvtsListeners);
+    this->apvts.addParameterListener("CHORUSAMOUNT", &apvtsListeners);
+    this->apvts.addParameterListener("DELAYDRYWET", &apvtsListeners);
+    this->apvts.addParameterListener("DELAYAMOUNT", &apvtsListeners);
+    this->apvts.addParameterListener("REVERBROOMSIZE", &apvtsListeners);
+    this->apvts.addParameterListener("REVERBDRYWET", &apvtsListeners);
+
     this->processorChain.pushProcessor(*equalizer);
     this->processorChain.pushProcessor(*distortion);
     this->processorChain.pushProcessor(*chorus);
@@ -172,7 +189,7 @@ bool CMLSProjectAudioProcessor::hasEditor() const
 
 juce::AudioProcessorEditor* CMLSProjectAudioProcessor::createEditor()
 {
-    return new CMLSProjectAudioProcessorEditor (*this);
+    return new juce::GenericAudioProcessorEditor (*this);
 }
 
 //==============================================================================
@@ -249,3 +266,89 @@ juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
 {
     return new CMLSProjectAudioProcessor();
 }
+
+juce::AudioProcessorValueTreeState::ParameterLayout CMLSProjectAudioProcessor::createParameters() {
+    std::vector<std::unique_ptr<juce::RangedAudioParameter>> params;
+    
+    // Equalizer parameters
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "EQLOWBANDGAIN",
+        "EqLowBandGain",
+        -60.0f,
+        5.0f,
+        0.0f
+    ));
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "EQHIGHBANDGAIN",
+        "EqHighBandGain",
+        -60.0f,
+        5.0f,
+        0.0f
+    ));
+
+    // Distortion parameter
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "DISTORTIONDRIVE",
+        "DistortionDrive",
+        0.0f,
+        1.0f,
+        0.0f
+    ));
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "DISTORTIONMIX",
+        "DistortionMix",
+        0.0f,
+        1.0f,
+        0.0f
+    ));
+
+    // Chorus parameter
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "CHORUSDRYWET",
+        "ChorusDryWet",
+        0.0f,
+        1.0f,
+        0.0f
+    ));
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "CHORUSAMOUNT",
+        "ChorusAmount",
+        0.0f,
+        1.0f,
+        0.0f
+    ));
+
+    // Delay parameter
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "DELAYDRYWET",
+        "DelayDryWet",
+        0.0f,
+        1.0f,
+        0.0f
+    ));
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "DELAYAMOUNT",
+        "DelayAmount",
+        0.0f,
+        1.0f,
+        0.0f
+    ));
+
+    // Reverb parameters
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "REVERBROOMSIZE",
+        "ReverbRoomSize",
+        0.0f,
+        1.0f,
+        0.0f
+    ));
+    params.push_back(std::make_unique<juce::AudioParameterFloat>(
+        "REVERBDRYWET",
+        "ReverbDryWet",
+        0.0f,
+        1.0f,
+        0.0f
+    ));
+
+    return { params.begin(), params.end() };
+}

+ 7 - 5
JUCE/CMLSProject/Source/PluginProcessor.h

@@ -15,6 +15,7 @@
 #include "CMLSProcessorChain.h"
 #include "CMLSEqualizer.h"
 #include "CMLSDistortion.h"
+#include "APVTSListeners.h"
 
 //==============================================================================
 /**
@@ -80,13 +81,11 @@ public:
 	void setDelayDryWet(float value);
 	void setDelayAmount(float value);
 
+	// Value Tree State for parameters
+    juce::AudioProcessorValueTreeState apvts;
+
 private:
     //==============================================================================
-    
-    // OSC message receiver
-	juce::OSCReceiver oscReceiver;
-
-    // Buffer for the incoming audio from the generators
 
     // Effects processing chain
     juce::dsp::ProcessorBase* equalizer;
@@ -96,6 +95,9 @@ private:
     juce::dsp::ProcessorBase* reverb;
 
 	CMLSProcessorChain processorChain;
+	APVTSListeners apvtsListeners;
+
+	juce::AudioProcessorValueTreeState::ParameterLayout createParameters();
 
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CMLSProjectAudioProcessor)
 };