LuigiBiasi-Athenagroup hace 6 meses
padre
commit
001e7c87d4
Se han modificado 41 ficheros con 392 adiciones y 1388 borrados
  1. BIN
      .DS_Store
  2. 1 0
      .gitignore
  3. 0 15
      1_environment_setup.scd
  4. 0 106
      5_osc_communication.scd
  5. 0 96
      JUCE/CMLSProject/Source/CMLSChorus.cpp
  6. 0 47
      JUCE/CMLSProject/Source/CMLSChorus.h
  7. 0 98
      JUCE/CMLSProject/Source/CMLSDelay.cpp
  8. 0 56
      JUCE/CMLSProject/Source/CMLSDelay.h
  9. 0 40
      JUCE/CMLSProject/Source/CMLSDistortion.cpp
  10. 0 23
      JUCE/CMLSProject/Source/CMLSDistortion.h
  11. 0 36
      JUCE/CMLSProject/Source/CMLSEqualizer.cpp
  12. 0 21
      JUCE/CMLSProject/Source/CMLSEqualizer.h
  13. 0 70
      JUCE/CMLSProject/Source/CMLSProcessorChain.cpp
  14. 0 32
      JUCE/CMLSProject/Source/CMLSProcessorChain.h
  15. 0 56
      JUCE/CMLSProject/Source/CMLSReverb.cpp
  16. 0 24
      JUCE/CMLSProject/Source/CMLSReverb.h
  17. 0 34
      JUCE/CMLSProject/Source/OSCReceiverWrapper.cpp
  18. 0 25
      JUCE/CMLSProject/Source/OSCReceiverWrapper.h
  19. 0 187
      JUCE/CMLSProject/Source/PluginEditor.cpp
  20. 0 70
      JUCE/CMLSProject/Source/PluginEditor.h
  21. 0 251
      JUCE/CMLSProject/Source/PluginProcessor.cpp
  22. 0 101
      JUCE/CMLSProject/Source/PluginProcessor.h
  23. 21 0
      SC/1_environment_setup.scd
  24. 0 0
      SC/2_oscillator_synthdefs.scd
  25. 0 0
      SC/2b_rgb_synthdefs.scd
  26. 0 0
      SC/3_effects_synthdefs.scd
  27. 0 0
      SC/4_modulation_synthdefs.scd
  28. 0 0
      SC/4b_lfo_effects.scd
  29. 183 0
      SC/5_osc_communication.scd
  30. 0 0
      SC/6_test_functions.scd
  31. 0 0
      SC/6b_effect_presets.scd
  32. 0 0
      SC/7_idraw_connection.scd
  33. 0 0
      SC/8_mobile_connection.scd
  34. 0 0
      SC/main.scd
  35. 187 0
      documentation/application_workflow.md
  36. 0 0
      documentation/iDraw_OSC_documentation.pdf
  37. 0 0
      documentation/midi_receiver_example.scd
  38. 0 0
      documentation/osc_receiver_example.scd
  39. BIN
      documentation/rsc/drawing_area.jpeg
  40. BIN
      documentation/rsc/pens.png
  41. BIN
      resources for sc and juce/osc addresses and values.pdf

BIN
.DS_Store


+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+.DS_Store

+ 0 - 15
1_environment_setup.scd

@@ -1,15 +0,0 @@
-// Basic environment setup
-s = Server.local;
-s.boot;
-
-// Test server connection
-s.doWhenBooted({
-    "SuperCollider server ready!".postln;
-
-    // Test simple sine wave
-    {
-        var sig = SinOsc.ar(440, 0, 0.5);
-        sig = sig * EnvGen.kr(Env.perc(0.01, 1), doneAction: 2);
-        sig!2
-    }.play;
-});

+ 0 - 106
5_osc_communication.scd

@@ -1,106 +0,0 @@
-(
-// Clear any existing OSC definitions
-OSCdef.freeAll;
-
-// Define OSC responder for mobile touch events
-// Mobile touch data format will likely be different from Arduino
-OSCdef(\touchOSC, { |msg, time, addr, port|
-    // Typical mobile touch data might include:
-    // - touch ID (for multi-touch)
-    // - x position (normalized 0-1)
-    // - y position (normalized 0-1)
-    // - touch state (began, moved, ended)
-    // - pressure/force (if supported)
-
-    var touchId = msg[1];
-    var x = msg[2];
-    var y = msg[3];
-    var state = msg[4];
-    var pressure = if(msg[5].notNil, { msg[5] }, { 0.7 }); // Default if not provided
-
-    // Convert mobile screen coordinates to parameters
-    var freq = x.linexp(0, 1, 100, 2000);
-    var amp = pressure.linlin(0, 1, 0.1, 0.8);
-    var pan = y.linlin(0, 1, -0.8, 0.8);
-
-    // Log the received data
-    ["Mobile touch:", touchId, x, y, state, pressure].postln;
-
-    // Handle touch based on state
-    switch(state,
-        // Touch began - start a new synth
-        \began, {
-            var synthType = (touchId % 5).switch(
-                0, { \sineTone },
-                1, { \squareTone },
-                2, { \sawTone },
-                3, { \triTone },
-                4, { \fmTone }
-            );
-
-            // Create a new synth and store it by ID
-            ~touchSynths = ~touchSynths ? ();
-            ~touchSynths[touchId] = Synth(synthType, [
-                \out, ~sourceBus ? 0,
-                \freq, freq,
-                \amp, amp,
-                \pan, pan,
-                \attack, 0.05,
-                \release, 1.0
-            ]);
-
-            ["Touch began:", touchId, synthType, freq, amp].postln;
-        },
-
-        // Touch moved - update existing synth
-        \moved, {
-            if(~touchSynths[touchId].notNil, {
-                ~touchSynths[touchId].set(\freq, freq, \amp, amp, \pan, pan);
-            });
-        },
-
-        // Touch ended - release synth
-        \ended, {
-            if(~touchSynths[touchId].notNil, {
-                ~touchSynths[touchId].release;
-                ~touchSynths[touchId] = nil;
-            });
-        }
-    );
-}, '/touch');
-
-// OSC responder for mobile control messages (e.g., UI controls)
-OSCdef(\controlOSC, { |msg, time, addr, port|
-    var control = msg[1].asSymbol;
-    var value = msg[2];
-
-    ["Mobile control:", control, value].postln;
-
-    // Handle different control parameters
-    switch(control,
-        \reverb_mix, { ~reverbSynth.set(\mix, value); },
-        \reverb_room, { ~reverbSynth.set(\room, value); },
-        \delay_time, { ~delaySynth.set(\delaytime, value); },
-        \delay_feedback, { ~delaySynth.set(\feedback, value); },
-        \filter_cutoff, { ~filterSynth.set(\cutoff, value.linexp(0, 1, 200, 10000)); }
-    );
-}, '/control');
-
-// Add a separate responder for color changes from mobile UI
-OSCdef(\colorOSC, { |msg, time, addr, port|
-    var colorIndex = msg[1].asInteger;
-
-    // Store the current color for new touches
-    ~currentColor = colorIndex;
-
-    ["Color changed:", colorIndex].postln;
-}, '/color');
-
-// Start the OSC server on port 57120 (default SuperCollider port)
-thisProcess.openUDPPort(57120);
-"OSC server ready on port 57120".postln;
-"Registered OSC commands: /touch, /control, /color".postln;
-
-// Print the local IP address for connecting the mobile device
-"Connect mobile device to: %:%".format(Platform.myHostName, 57120).postln;
-)

+ 0 - 96
JUCE/CMLSProject/Source/CMLSChorus.cpp

@@ -1,96 +0,0 @@
-/*
-  ==============================================================================
-
-    CMLSChorus.cpp
-    Created: 1 May 2025 11:04:18pm
-    Author:  Luigi
-
-  ==============================================================================
-*/
-
-#include "CMLSChorus.h"
-
-CMLSChorus::CMLSChorus() {
-    freqRange = new juce::NormalisableRange<float>(LFO_MIN_FREQ, LFO_MAX_FREQ);
-    depthRange = new juce::NormalisableRange<float>(LFO_MIN_DEPTH, LFO_MAX_DEPTH);
-}
-
-CMLSChorus::~CMLSChorus() {}
-
-void CMLSChorus::reset() {
-    delayLine1.reset();
-    delayLine2.reset();
-    dryWetMixer.reset();
-}
-
-void CMLSChorus::prepare(const juce::dsp::ProcessSpec& spec) {
-    delayLine1.prepare(spec);
-    delayLine2.prepare(spec);
-    delayLine1.setMix(1.0f);
-    delayLine2.setMix(1.0f);
-
-    delayLine1.setCentreDelay(DELAY_CENTER);
-    delayLine2.setCentreDelay(DELAY_CENTER);
-    delayLine1.setRate(LFO_MIN_FREQ);
-    delayLine1.setRate(LFO_MIN_FREQ + LFO_FREQ_DELTA);
-    delayLine1.setDepth(LFO_MIN_DEPTH);
-    delayLine2.setDepth(LFO_MIN_FREQ);
-
-    dryWetMixer.prepare(spec);
-    dryWetMixer.setMixingRule(juce::dsp::DryWetMixingRule::linear);
-}
-
-void CMLSChorus::process(const juce::dsp::ProcessContextReplacing<float>& context) {
-	auto audioBlock = context.getOutputBlock();
-	auto numChannels = audioBlock.getNumChannels();
-    const auto numSamples = audioBlock.getNumSamples();
-
-    // Initialize audio buffers
-    juce::AudioBuffer<float> firstStageWetBuffer(numChannels, numSamples);
-	juce::dsp::AudioBlock<float> firstStageWetBlock(firstStageWetBuffer);
-
-	juce::AudioBuffer<float> secondStageWetBuffer(numChannels, numSamples);
-	juce::dsp::AudioBlock<float> secondStageWetBlock(secondStageWetBuffer);
-
-    // Calculate wet signal
-    delayLine1.process(
-        juce::dsp::ProcessContextNonReplacing<float>(audioBlock, firstStageWetBlock)
-    );
-	delayLine2.process(
-		juce::dsp::ProcessContextNonReplacing<float>(audioBlock, secondStageWetBlock)
-	);
-
-    secondStageWetBlock += firstStageWetBlock;
-
-	// Apply the dry/wet mix
-    dryWetMixer.pushDrySamples(audioBlock);
-    dryWetMixer.mixWetSamples(secondStageWetBlock);
-
-    for (int channel = 0; channel < numChannels; ++channel) {
-        for (int sample = 0; sample < numSamples; ++sample) {
-            audioBlock.setSample(channel, sample, secondStageWetBlock.getSample(channel, sample));
-        }
-    }
-}
-
-void CMLSChorus::setDryWet(float value) {
-    dryWetMixer.setWetMixProportion(value);
-}
-
-void CMLSChorus::setAmount(float value) {
-    float freq = freqRange->convertFrom0to1(value);
-    float depth = depthRange->convertFrom0to1(value);
-
-    delayLine1.setRate(freq);
-    delayLine2.setRate(freq); //+ LFO_FREQ_DELTA
-    delayLine1.setDepth(depth);
-    delayLine2.setDepth(depth);
-}
-
-const float CMLSChorus::getDryWet() {
-	return this->dryWetProp;
-}
-
-const float CMLSChorus::getAmount() {
-	return this->amount;
-}

+ 0 - 47
JUCE/CMLSProject/Source/CMLSChorus.h

@@ -1,47 +0,0 @@
-/*
-  ==============================================================================
-
-    CMLSChorus.h
-    Created: 1 May 2025 11:04:18pm
-    Author:  Luigi
-
-  ==============================================================================
-*/
-
-#pragma once
-
-#include <JuceHeader.h>
-
-#define DELAY_CENTER 0.015 // Center for delay in seconds
-#define LFO_MIN_FREQ 0.0f // Minimum frequency of the LFO
-#define LFO_MAX_FREQ 5.0f // Maximum frequency of the LFO
-#define LFO_FREQ_DELTA 0.3f // Frequency delta between the two LFOs
-#define LFO_MIN_DEPTH 0.0f // Minimum depth of the LFO
-#define LFO_MAX_DEPTH 5.0f // Maximum depth of the LFO
-
-class CMLSChorus : public juce::dsp::ProcessorBase {
-    public:
-		CMLSChorus();
-		~CMLSChorus() override;
-
-        void reset() override;
-        void prepare(const juce::dsp::ProcessSpec&);
-        void process(const juce::dsp::ProcessContextReplacing<float>&);
-
-        // Parameter getters and setters
-        void setDryWet(float value);
-        void setAmount(float value);
-
-        const float getDryWet();
-        const float getAmount();
-
-    private:
-        float dryWetProp = 0.0;
-		float amount = 0.0;
-
-        juce::dsp::Chorus<float> delayLine1; // 1st chorus delayline
-        juce::dsp::Chorus<float> delayLine2; // 2nd chorus delayline
-        juce::dsp::DryWetMixer<float> dryWetMixer; // Dry/Wet mixer
-        juce::NormalisableRange<float>* freqRange; // Range for LFOs frequencies
-        juce::NormalisableRange<float>* depthRange; // Range for LFOs depth
-};

+ 0 - 98
JUCE/CMLSProject/Source/CMLSDelay.cpp

@@ -1,98 +0,0 @@
-/*
-  ==============================================================================
-
-    CMLSDelay.cpp
-    Created: 3 May 2025 5:39:35pm
-    Author:  Luigi
-
-  ==============================================================================
-*/
-
-#include "CMLSDelay.h"
-
-CMLSDelay::CMLSDelay() {
-	delayLengthRange = new juce::NormalisableRange<float>(0, MAX_DELAY_LENGTH);
-	feedbackRange = new juce::NormalisableRange<float>(MIN_FEEDBACK, MAX_FEEDBACK);
-
-	this->delayLength = 0.0f;
-	this->feedback = 0.0f;
-	this->amount = 0.0f;
-	this->dryWetProp = 0.0f;
-}
-
-CMLSDelay::~CMLSDelay() {}
-
-void CMLSDelay::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->delayLine.prepare(spec);
-	this->linearDelay.prepare(spec);
-	this->mixer.prepare(spec);
-
-	for (auto& volume : this->delayFeedbackVolume) {
-		volume.reset(spec.sampleRate, 0.05f);
-	}
-
-	this->mixer.reset();
-	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) {
-	auto audioBlock = context.getOutputBlock();
-	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.mixWetSamples(output);
-}
-
-void CMLSDelay::setDryWet(float value) {
-	this->dryWetProp = value;
-	this->mixer.setWetMixProportion(this->dryWetProp);
-}
-
-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);
-	}
-}
-
-const float CMLSDelay::getDryWet() {
-	return this->dryWetProp;
-}
-
-const float CMLSDelay::getAmount() {
-	return this->amount;
-}

+ 0 - 56
JUCE/CMLSProject/Source/CMLSDelay.h

@@ -1,56 +0,0 @@
-/*
-  ==============================================================================
-
-    CMLSDelay.h
-    Created: 3 May 2025 5:39:35pm
-    Author:  Luigi
-	Ref. https://github.com/flipbug/simple-delay/tree/master
-
-  ==============================================================================
-*/
-
-#pragma once
-#include <JuceHeader.h>
-
-#define MAX_DELAY_LENGTH 1.0f // Maximum delay time in seconds
-#define MIN_FEEDBACK -100.0f
-#define MAX_FEEDBACK 0.0f
-
-class CMLSDelay : public juce::dsp::ProcessorBase
-{
-	public:
-		CMLSDelay();
-		~CMLSDelay() override;
-
-		void reset() override;
-		void prepare(const juce::dsp::ProcessSpec&) override;
-		void process(const juce::dsp::ProcessContextReplacing<float>&) override;
-	
-		// Parameter getters and setters
-		void setDryWet(float value);
-		void setAmount(float value);
-		const float getDryWet();
-		const float getAmount();
-
-	private:
-		float effectDelaySamples;
-
-		//Paramters
-		float dryWetProp;
-		float feedback;
-		float delayLength;
-		float amount;
-
-		// Normaliosable range
-		juce::NormalisableRange<float>* delayLengthRange;
-		juce::NormalisableRange<float>* feedbackRange;
-
-		//Delay Lines
-		juce::dsp::DelayLine<float> delayLine;
-		juce::dsp::DelayLine<float, juce::dsp::DelayLineInterpolationTypes::Linear> linearDelay;
-		juce::dsp::DryWetMixer<float> mixer;
-
-		std::array<float, 2> delayValue;
-		std::array<float, 2> lastDelayOutput;
-		std::array<juce::LinearSmoothedValue<float>, 2> delayFeedbackVolume;
-};

+ 0 - 40
JUCE/CMLSProject/Source/CMLSDistortion.cpp

@@ -1,40 +0,0 @@
-#include "CMLSDistortion.h"
-
-CMLSDistortion::CMLSDistortion() {}
-
-void CMLSDistortion::prepare(const juce::dsp::ProcessSpec& spec) {
-    inputGain.prepare(spec);
-    outputGain.prepare(spec);
-    inputGain.setGainDecibels(0.0f);
-    outputGain.setGainDecibels(0.0f);
-}
-
-void CMLSDistortion::reset() {
-    inputGain.reset();
-    outputGain.reset();
-}
-
-void CMLSDistortion::process(const juce::dsp::ProcessContextReplacing<float>& context) {
-    auto& block = context.getOutputBlock();
-    inputGain.process(context);
-
-    for (size_t ch = 0; ch < block.getNumChannels(); ++ch) {
-        auto* data = block.getChannelPointer(ch);
-        for (size_t i = 0; i < block.getNumSamples(); ++i) {
-            float dry = data[i];
-            float wet = std::tanh(data[i] * drive);  // soft clipping
-            data[i] = dry * (1.0f - mix) + wet * mix; // apply mix
-        }
-    }
-
-    outputGain.process(context);
-}
-
-void CMLSDistortion::setDrive(float newDrive) {
-    drive = newDrive;
-}
-
-void CMLSDistortion::setMix(float newMix)
-{
-    mix = juce::jlimit(0.0f, 1.0f, newMix); // between 0.0 and 1.0
-}

+ 0 - 23
JUCE/CMLSProject/Source/CMLSDistortion.h

@@ -1,23 +0,0 @@
-#pragma once
-
-#include <JuceHeader.h>
-
-class CMLSDistortion : public juce::dsp::ProcessorBase {
-public:
-    CMLSDistortion();
-    ~CMLSDistortion() override = default;
-
-    void prepare(const juce::dsp::ProcessSpec&) override;
-    void reset() override;
-    void process(const juce::dsp::ProcessContextReplacing<float>&) override;
-
-    void setDrive(float drive); // controls intensity
-    void setMix(float mix);     // controls the dry/wet mix ratio,how much of the distorted signal is mixed with the original signal
-                                // 0.0 = dry, 1.0 = full distortion
-
-private:
-    float drive = 1.0f;
-    float mix = 1.0f;
-
-    juce::dsp::Gain<float> inputGain, outputGain;
-};

+ 0 - 36
JUCE/CMLSProject/Source/CMLSEqualizer.cpp

@@ -1,36 +0,0 @@
-#include "CMLSEqualizer.h"
-
-CMLSEqualizer::CMLSEqualizer() {}
-
-void CMLSEqualizer::prepare(const juce::dsp::ProcessSpec& spec) {
-    sampleRate = spec.sampleRate;
-
-    lowBand.prepare(spec);
-    highBand.prepare(spec);
-
-    lowBand.reset();
-    highBand.reset();
-
-    setEqLowGain(0.0f);
-    setEqHighGain(0.0f);
-}
-
-void CMLSEqualizer::reset() {
-    lowBand.reset();
-    highBand.reset();
-}
-
-void CMLSEqualizer::process(const juce::dsp::ProcessContextReplacing<float>& context) {
-    lowBand.process(context);
-    highBand.process(context);
-}
-
-void CMLSEqualizer::setEqLowGain(float gain) {
-    *lowBand.state = *juce::dsp::IIR::Coefficients<float>::makeLowShelf(
-        sampleRate, 200.0f, 0.7f, juce::Decibels::decibelsToGain(gain));
-}
-
-void CMLSEqualizer::setEqHighGain(float gain) {
-    *highBand.state = *juce::dsp::IIR::Coefficients<float>::makeHighShelf(
-        sampleRate, 5000.0f, 0.7f, juce::Decibels::decibelsToGain(gain));
-}

+ 0 - 21
JUCE/CMLSProject/Source/CMLSEqualizer.h

@@ -1,21 +0,0 @@
-#pragma once
-
-#include <JuceHeader.h>
-
-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 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;
-};

+ 0 - 70
JUCE/CMLSProject/Source/CMLSProcessorChain.cpp

@@ -1,70 +0,0 @@
-/*
-  ==============================================================================
-
-    CMLSProcessorChain.cpp
-    Created: 12 May 2025 10:05:40am
-    Author:  Luigi
-
-  ==============================================================================
-*/
-
-#include "CMLSProcessorChain.h"
-
-CMLSProcessorChain::CMLSProcessorChain()
-{}
-
-CMLSProcessorChain::~CMLSProcessorChain()
-{}
-
-void CMLSProcessorChain::reset()
-{
-	for (auto& processor : chain)
-	{
-		if (processor)
-			processor->reset();
-	}
-}
-
-void CMLSProcessorChain::prepare(const juce::dsp::ProcessSpec& spec)
-{
-	for (auto& processor : chain)
-	{
-		if (processor)
-			processor->prepare(spec);
-	}
-}
-
-void CMLSProcessorChain::process(const juce::dsp::ProcessContextReplacing<float>& context)
-{
-	for (int i = 0; i < this->chain.size(); ++i)
-	{
-		if (this->chain[i] && this->slots[i] == true)
-			this->chain[i]->process(context);
-	}
-}
-
-int CMLSProcessorChain::pushProcessor(juce::dsp::ProcessorBase& processor)
-{
-	chain.push_back(&processor);
-	slots.push_back(true);
-	return chain.size() - 1;
-}
-
-void CMLSProcessorChain::muteProcessrInSlot(int slot)
-{
-	slots[slot] = false;
-}
-
-void CMLSProcessorChain::unmuteProcessrInSlot(int slot)
-{
-	slots[slot] = true;
-}
-
-void CMLSProcessorChain::swapPlaces(int slot1, int slot2)
-{
-	if (slot1 < 0 || slot2 < 0 || slot1 >= chain.size() || slot2 >= chain.size())
-		return;
-
-	std::swap(chain[slot1], chain[slot2]);
-	std::swap(slots[slot1], slots[slot2]);
-}

+ 0 - 32
JUCE/CMLSProject/Source/CMLSProcessorChain.h

@@ -1,32 +0,0 @@
-/*
-  ==============================================================================
-
-    CMLSProcessorChain.h
-    Created: 12 May 2025 10:05:40am
-    Author:  Luigi
-
-  ==============================================================================
-*/
-
-#pragma once
-#include <JuceHeader.h>
-
-class CMLSProcessorChain
-{
-	public:
-		CMLSProcessorChain();
-		~CMLSProcessorChain();
-
-		void reset();
-		void prepare(const juce::dsp::ProcessSpec&);
-		void process(const juce::dsp::ProcessContextReplacing<float>&);
-		
-		int pushProcessor(juce::dsp::ProcessorBase& processor);
-		void muteProcessrInSlot(int slot);
-		void unmuteProcessrInSlot(int slot);
-		void swapPlaces(int slot1, int slot2);
-	
-	private:
-		std::vector<bool> slots;
-		std::vector<juce::dsp::ProcessorBase*> chain;
-};

+ 0 - 56
JUCE/CMLSProject/Source/CMLSReverb.cpp

@@ -1,56 +0,0 @@
-#include "CMLSReverb.h";
-
-CMLSReverb::CMLSReverb()
-{
-    // Default parameters declaration
-    this->reverbParams.dryLevel = 1.0f;
-	this->reverbParams.wetLevel = 0.0f;
-	this->reverbParams.roomSize = 0.0f;
-	this->reverbParams.damping = 0.5f;
-	this->reverbParams.width = 0.0f;
-
-	this->reverb.setParameters(this->reverbParams);
-}
-
-CMLSReverb::~CMLSReverb() {}
-
-void CMLSReverb::reset() {
-	this->reverb.reset();
-}
-
-void CMLSReverb::prepare(const juce::dsp::ProcessSpec& spec) {
-	this->reverb.setSampleRate(spec.sampleRate);
-}
-
-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());
-}
-
-void CMLSReverb::setDryWet(float value)
-{
-	// Set the dry/wet mix value
-	this->reverbParams.wetLevel = value;
-	this->reverbParams.dryLevel = 1.0f - value;
-    this->reverb.setParameters(this->reverbParams);
-}
-
-void CMLSReverb::setRoomSize(float value)
-{
-	// Set the room size value
-	this->reverbParams.roomSize = value;
-    this->reverbParams.width = value / 2;
-	this->reverb.setParameters(this->reverbParams);
-}
-
-const float CMLSReverb::getDryWet()
-{
-	// Get the dry/wet mix value
-	return this->reverbParams.wetLevel;
-}
-
-const float CMLSReverb::getRoomSize()
-{
-	// Get the room size value
-	return this->reverbParams.roomSize;
-}

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

@@ -1,24 +0,0 @@
-#pragma once
-
-#include <JuceHeader.h>
-
-class CMLSReverb : public juce::dsp::ProcessorBase {
-    public:
-        CMLSReverb();
-        ~CMLSReverb() override;
-
-	    void reset() override;
-        void prepare(const juce::dsp::ProcessSpec&) override;
-		void process(const juce::dsp::ProcessContextReplacing<float>&) override;
-
-        // Parameter setters
-        void setDryWet(float value);
-        void setRoomSize(float value);
-
-        // Parameter getters
-	    const float getDryWet();
-	    const float getRoomSize();
-    private:
-        juce::Reverb reverb;
-        juce::Reverb::Parameters reverbParams;
-};

+ 0 - 34
JUCE/CMLSProject/Source/OSCReceiverWrapper.cpp

@@ -1,34 +0,0 @@
-/*
-  ==============================================================================
-
-    OSCReceiverWrapper.cpp
-    Created: 5 May 2025 2:34:15pm
-    Author:  Luigi
-
-  ==============================================================================
-*/
-
-#include "OSCReceiverWrapper.h"
-
-OSCReceiverWrapper::OSCReceiverWrapper(int port, juce::AudioProcessor* pluginProcessor) {
-    this->connect(port);
-	this->pluginProcessor = pluginProcessor;
-}
-
-OSCReceiverWrapper::~OSCReceiverWrapper() {}
-
-void OSCReceiverWrapper::oscMessageReceived(const juce::OSCMessage& message)
-{
-    if (!message.isEmpty() && message.size() == 1) {
-	    auto address = message.getAddressPattern().toString();
-        auto argument = message[0].getString();
-
-        // Interpret each message
-		if (address == "/") {
-            //this->pluginProcessor->getCallbackLock...
-        }
-    }
-}
-
-void OSCReceiverWrapper::oscConnectionError(const juce::String& errorMessage)
-{}

+ 0 - 25
JUCE/CMLSProject/Source/OSCReceiverWrapper.h

@@ -1,25 +0,0 @@
-/*
-  ==============================================================================
-
-    OSCReceiverWrapper.h
-    Created: 5 May 2025 2:34:15pm
-    Author:  Luigi
-
-  ==============================================================================
-*/
-
-#pragma once
-#include <JuceHeader.h>
-
-class OSCReceiverWrapper : public juce::OSCReceiver,
-    private juce::OSCReceiver::ListenerWithOSCAddress<juce::String>
-{
-    public:
-        OSCReceiverWrapper(int port, juce::AudioProcessor* pluginProcessor);
-        ~OSCReceiverWrapper();
-
-		void oscMessageReceived(const juce::OSCMessage& message) override;
-		void oscConnectionError(const juce::String& errorMessage);
-    private:
-		juce::AudioProcessor* pluginProcessor;
-};

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

@@ -1,187 +0,0 @@
-/*
-  ==============================================================================
-
-    This file contains the basic framework code for a JUCE plugin editor.
-
-  ==============================================================================
-*/
-
-#include "PluginProcessor.h"
-#include "PluginEditor.h"
-
-//==============================================================================
-CMLSProjectAudioProcessorEditor::CMLSProjectAudioProcessorEditor (CMLSProjectAudioProcessor& p)
-    : AudioProcessorEditor (&p), audioProcessor (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);
-
-    // Add aliders to the editor (Equalizer)
-    this->equalizerLowGainSlider.setRange(0.0, 1.0);
-    this->equalizerLowGainSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->equalizerLowGainSlider.addListener(this);
-    this->equalizerLowGainLabel.setText("Equalizer Low Gain", juce::dontSendNotification);
-
-    addAndMakeVisible(this->equalizerLowGainSlider);
-    addAndMakeVisible(this->equalizerLowGainLabel);
-
-    this->equalizerHighGainSlider.setRange(0.0, 1.0);
-    this->equalizerHighGainSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->equalizerHighGainSlider.addListener(this);
-    this->equalizerHighGainLabel.setText("Equalizer High Gain", juce::dontSendNotification);
-
-    addAndMakeVisible(this->equalizerHighGainSlider);
-    addAndMakeVisible(this->equalizerHighGainLabel);
-
-    // Add aliders to the editor (Distortion)
-    this->distortionDriveSlider.setRange(0.0, 1.0);
-    this->distortionDriveSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->distortionDriveSlider.addListener(this);
-    this->distortionDriveLabel.setText("Distortion Drive", juce::dontSendNotification);
-
-    addAndMakeVisible(this->distortionDriveSlider);
-    addAndMakeVisible(this->distortionDriveLabel);
-
-    this->distortionMixSlider.setRange(0.0, 1.0);
-    this->distortionMixSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->distortionMixSlider.addListener(this);
-    this->distortionMixLabel.setText("Distortion Mix", juce::dontSendNotification);
-
-    addAndMakeVisible(this->distortionMixSlider);
-    addAndMakeVisible(this->distortionMixLabel);
-
-	// Add aliders to the editor (Chorus)
-    this->chorusDryWetSlider.setRange(0.0, 1.0);
-    this->chorusDryWetSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->chorusDryWetSlider.addListener(this);
-    this->chorusDryWetLabel.setText("Chorus Dry/Wet", juce::dontSendNotification);
-
-    addAndMakeVisible(this->chorusDryWetSlider);
-    addAndMakeVisible(this->chorusDryWetLabel);
-
-    this->chorusAmountSlider.setRange(0.0, 1.0);
-    this->chorusAmountSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->chorusAmountSlider.addListener(this);
-    this->chorusAmountLabel.setText("Chorus Amount", juce::dontSendNotification);
-
-    addAndMakeVisible(this->chorusAmountSlider);
-    addAndMakeVisible(this->chorusAmountLabel);
-
-    // Add sliders to the editor (Reverb)
-    this->reverbDryWetSlider.setRange(0.0, 1.0);
-    this->reverbDryWetSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->reverbDryWetSlider.addListener(this);
-    this->reverbDryWetLabel.setText("Reverb Dry/Wet", juce::dontSendNotification);
-
-    addAndMakeVisible(this->reverbDryWetSlider);
-    addAndMakeVisible(this->reverbDryWetLabel);
-
-    this->reverbRoomSizeSlider.setRange(0.0, 1.0);
-    this->reverbRoomSizeSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->reverbRoomSizeSlider.addListener(this);
-    this->reverbRoomSizeLabel.setText("Reverb Room Size", juce::dontSendNotification);
-
-    addAndMakeVisible(this->reverbRoomSizeSlider);
-    addAndMakeVisible(this->reverbRoomSizeLabel);
-
-	// Add sliders to the editor (Delay)
-    this->delayDryWetSlider.setRange(0.0, 1.0);
-    this->delayDryWetSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->delayDryWetSlider.addListener(this);
-    this->delayDryWetLabel.setText("Delay Dry/Wet", juce::dontSendNotification);
-
-    addAndMakeVisible(this->delayDryWetSlider);
-    addAndMakeVisible(this->delayDryWetLabel);
-
-    this->delayAmountSlider.setRange(0.0, 1.0);
-    this->delayAmountSlider.setTextBoxStyle(juce::Slider::TextBoxRight, false, 100, 20);
-    this->delayAmountSlider.addListener(this);
-    this->delayAmountLabel.setText("Delay Amount", juce::dontSendNotification);
-
-    addAndMakeVisible(this->delayAmountSlider);
-    addAndMakeVisible(this->delayAmountLabel);
-}
-
-CMLSProjectAudioProcessorEditor::~CMLSProjectAudioProcessorEditor()
-{
-}
-
-//==============================================================================
-void CMLSProjectAudioProcessorEditor::paint (juce::Graphics& g)
-{
-    // (Our component is opaque, so we must completely fill the background with a solid colour)
-    g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
-}
-
-void CMLSProjectAudioProcessorEditor::resized()
-{
-	//titleLabel.setBounds(10, 10, getWidth() - 20, 20);
-    equalizerLowGainSlider.setBounds(130, 10, getWidth() - 130, 20);
-    equalizerLowGainLabel.setBounds(10, 10, 100, 20);
-    equalizerHighGainSlider.setBounds(130, 30, getWidth() - 130, 20);
-    equalizerHighGainLabel.setBounds(10, 30, 100, 20);
-
-    distortionDriveSlider.setBounds(130, 70, getWidth() - 130, 20);
-    distortionDriveLabel.setBounds(10, 70, 100, 20);
-    distortionMixSlider.setBounds(130, 90, getWidth() - 130, 20);
-    distortionMixLabel.setBounds(10, 90, 100, 20);
-
-    chorusDryWetSlider.setBounds(130, 130, getWidth() - 130, 20);
-    chorusDryWetLabel.setBounds(10, 130, 100, 20);
-    chorusAmountSlider.setBounds(130, 150, getWidth() - 130, 20);
-	chorusAmountLabel.setBounds(10, 150, 100, 20);
-
-    reverbDryWetSlider.setBounds(130, 190, getWidth() - 130, 20);
-	reverbDryWetLabel.setBounds(10, 190, 100, 20);
-    reverbRoomSizeSlider.setBounds(130, 210, getWidth() - 130, 20);
-	reverbRoomSizeLabel.setBounds(10, 210, 100, 20);
-
-    delayDryWetSlider.setBounds(130, 250, getWidth() - 130, 20);
-	delayDryWetLabel.setBounds(10, 250, 100, 20);
-    delayAmountSlider.setBounds(130, 270, getWidth() - 130, 20);
-	delayAmountLabel.setBounds(10, 270, 100, 20);
-}
-
-void CMLSProjectAudioProcessorEditor::sliderValueChanged(juce::Slider* slider){
-	if (slider == &this->chorusDryWetSlider)
-	{
-		this->audioProcessor.setChorusDryWet(slider->getValue());
-	}
-	else if (slider == &this->chorusAmountSlider)
-	{
-		this->audioProcessor.setChorusAmount(slider->getValue());
-	}
-	else if (slider == &this->reverbDryWetSlider)
-	{
-		this->audioProcessor.setReverbDryWet(slider->getValue());
-	}
-	else if (slider == &this->reverbRoomSizeSlider)
-	{
-		this->audioProcessor.setReverbRoomSize(slider->getValue());
-	}
-	else if (slider == &this->delayDryWetSlider)
-	{
-		this->audioProcessor.setDelayDryWet(slider->getValue());
-	}
-	else if (slider == &this->delayAmountSlider)
-	{
-		this->audioProcessor.setDelayAmount(slider->getValue());
-	}
-    else if (slider == &this->equalizerLowGainSlider)
-    {
-        this->audioProcessor.setEqLowGain(slider->getValue());
-    }
-    else if (slider == &this->equalizerHighGainSlider)
-    {
-        this->audioProcessor.setEqHighGain(slider->getValue());
-    }
-    else if (slider == &this->distortionDriveSlider)
-    {
-        this->audioProcessor.setDistortionDrive(slider->getValue());
-    }
-    else if (slider == &this->distortionMixSlider)
-    {
-        this->audioProcessor.setDistortionMix(slider->getValue());
-    }
-}

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

@@ -1,70 +0,0 @@
-/*
-  ==============================================================================
-
-    This file contains the basic framework code for a JUCE plugin editor.
-
-  ==============================================================================
-*/
-
-#pragma once
-
-#include <JuceHeader.h>
-#include "PluginProcessor.h"
-
-//==============================================================================
-/**
-*/
-class CMLSProjectAudioProcessorEditor  : public juce::AudioProcessorEditor,
-                                         public juce::Slider::Listener
-{
-public:
-    CMLSProjectAudioProcessorEditor (CMLSProjectAudioProcessor&);
-    ~CMLSProjectAudioProcessorEditor() override;
-
-    //==============================================================================
-    void paint (juce::Graphics&) override;
-    void resized() override;
-
-private:
-    // This reference is provided as a quick way for your editor to
-    // access the processor object that created it.
-    CMLSProjectAudioProcessor& audioProcessor;
-
-    // Title
-	juce::Label titleLabel;
-
-    // Equalizer
-    juce::Slider equalizerLowGainSlider;
-    juce::Label equalizerLowGainLabel;
-    juce::Slider equalizerHighGainSlider;
-    juce::Label equalizerHighGainLabel;
-
-    // Distortion
-    juce::Slider distortionDriveSlider;
-    juce::Label distortionDriveLabel;
-    juce::Slider distortionMixSlider;
-    juce::Label distortionMixLabel;
-
-    // Chorus
-    juce::Slider chorusDryWetSlider;
-    juce::Label chorusDryWetLabel;
-    juce::Slider chorusAmountSlider;
-    juce::Label chorusAmountLabel;
-
-    // Reverb
-	juce::Slider reverbDryWetSlider;
-	juce::Label reverbDryWetLabel;
-	juce::Slider reverbRoomSizeSlider;
-	juce::Label reverbRoomSizeLabel;
-
-	// Delay
-	juce::Slider delayDryWetSlider;
-	juce::Label delayDryWetLabel;
-	juce::Slider delayAmountSlider;
-	juce::Label delayAmountLabel;
-
-    // Method to call when the slider value changes
-    void sliderValueChanged(juce::Slider* slider) override;
-
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CMLSProjectAudioProcessorEditor)
-};

+ 0 - 251
JUCE/CMLSProject/Source/PluginProcessor.cpp

@@ -1,251 +0,0 @@
-/*
-  ==============================================================================
-
-    This file contains the basic framework code for a JUCE plugin processor.
-
-  ==============================================================================
-*/
-
-#include "PluginProcessor.h"
-#include "PluginEditor.h"
-
-//==============================================================================
-CMLSProjectAudioProcessor::CMLSProjectAudioProcessor()
-#ifndef JucePlugin_PreferredChannelConfigurations
-     : AudioProcessor (BusesProperties()
-                     #if ! JucePlugin_IsMidiEffect
-                      #if ! JucePlugin_IsSynth
-                       .withInput  ("Input",  juce::AudioChannelSet::stereo(), true)
-                      #endif
-                       .withOutput ("Output", juce::AudioChannelSet::stereo(), true)
-                     #endif
-                       )
-#endif
-{
-    // Chaining the effects
-	this->equalizer = new CMLSEqualizer();
-    this->distortion = new CMLSDistortion();
-    this->chorus = new CMLSChorus();
-    this->delay = new CMLSDelay();
-    this->reverb = new CMLSReverb();
-
-    this->processorChain.pushProcessor(*equalizer);
-    this->processorChain.pushProcessor(*distortion);
-    this->processorChain.pushProcessor(*chorus);
-    this->processorChain.pushProcessor(*delay);
-    this->processorChain.pushProcessor(*reverb);
-
-    this->processorChain.reset();
-}
-
-CMLSProjectAudioProcessor::~CMLSProjectAudioProcessor()
-{
-}
-
-//==============================================================================
-const juce::String CMLSProjectAudioProcessor::getName() const
-{
-    return JucePlugin_Name;
-}
-
-bool CMLSProjectAudioProcessor::acceptsMidi() const
-{
-   #if JucePlugin_WantsMidiInput
-    return true;
-   #else
-    return false;
-   #endif
-}
-
-bool CMLSProjectAudioProcessor::producesMidi() const
-{
-   #if JucePlugin_ProducesMidiOutput
-    return true;
-   #else
-    return false;
-   #endif
-}
-
-bool CMLSProjectAudioProcessor::isMidiEffect() const
-{
-   #if JucePlugin_IsMidiEffect
-    return true;
-   #else
-    return false;
-   #endif
-}
-
-double CMLSProjectAudioProcessor::getTailLengthSeconds() const
-{
-    return 0.0;
-}
-
-int CMLSProjectAudioProcessor::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.
-}
-
-int CMLSProjectAudioProcessor::getCurrentProgram()
-{
-    return 0;
-}
-
-void CMLSProjectAudioProcessor::setCurrentProgram (int index)
-{
-}
-
-const juce::String CMLSProjectAudioProcessor::getProgramName (int index)
-{
-    return {};
-}
-
-void CMLSProjectAudioProcessor::changeProgramName (int index, const juce::String& newName)
-{
-}
-
-//==============================================================================
-void CMLSProjectAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
-{
-    // Use this method as the place to do any pre-playback
-    // initialisation that you need..
-    juce::dsp::ProcessSpec spec;
-    spec.maximumBlockSize = samplesPerBlock;
-    spec.numChannels = getTotalNumOutputChannels();
-    spec.sampleRate = sampleRate;
-
-	this->processorChain.prepare(spec);
-}
-
-void CMLSProjectAudioProcessor::releaseResources()
-{
-    // When playback stops, you can use this as an opportunity to free up any
-    // spare memory, etc.
-}
-
-#ifndef JucePlugin_PreferredChannelConfigurations
-bool CMLSProjectAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
-{
-  #if JucePlugin_IsMidiEffect
-    juce::ignoreUnused (layouts);
-    return true;
-  #else
-    // This is the place where you check if the layout is supported.
-    // In this template code we only support mono or stereo.
-    // Some plugin hosts, such as certain GarageBand versions, will only
-    // load plugins that support stereo bus layouts.
-    if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
-     && layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
-        return false;
-
-    // This checks if the input layout matches the output layout
-   #if ! JucePlugin_IsSynth
-    if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
-        return false;
-   #endif
-
-    return true;
-  #endif
-}
-#endif
-
-void CMLSProjectAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
-{
-    juce::ScopedNoDenormals noDenormals;
-    auto totalNumInputChannels  = getTotalNumInputChannels();
-    auto totalNumOutputChannels = getTotalNumOutputChannels();
-
-    const auto numChannels = juce::jmax(totalNumInputChannels, totalNumOutputChannels);
-
-    auto audioBlock = juce::dsp::AudioBlock<float>(buffer).getSubsetChannelBlock(0, (int)numChannels);
-    auto context = juce::dsp::ProcessContextReplacing<float>(audioBlock);
-
-    /* Processing */
-	this->processorChain.process(context);
-}
-
-//==============================================================================
-bool CMLSProjectAudioProcessor::hasEditor() const
-{
-    return true; // (change this to false if you choose to not supply an editor)
-}
-
-juce::AudioProcessorEditor* CMLSProjectAudioProcessor::createEditor()
-{
-    return new CMLSProjectAudioProcessorEditor (*this);
-}
-
-//==============================================================================
-void CMLSProjectAudioProcessor::getStateInformation (juce::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.
-}
-
-void CMLSProjectAudioProcessor::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.
-}
-
-void CMLSProjectAudioProcessor::muteEffectInSlot(int slot) {
-    this->processorChain.muteProcessrInSlot(slot);
-}
-
-void CMLSProjectAudioProcessor::unmuteEffectInSlot(int slot) {
-    this->processorChain.unmuteProcessrInSlot(slot);
-}
-
-void CMLSProjectAudioProcessor::swapEffectInSlot(int slot1, int slot2) {
-	this->processorChain.swapPlaces(slot1, slot2);
-}
-
-void CMLSProjectAudioProcessor::setEqLowGain(float value) {
-	((CMLSEqualizer*)this->equalizer)->setEqLowGain(value);
-}
-
-void CMLSProjectAudioProcessor::setEqHighGain(float value) {
-    ((CMLSEqualizer*)this->equalizer)->setEqHighGain(value);
-}
-
-void CMLSProjectAudioProcessor::setDistortionDrive(float value) {
-    ((CMLSDistortion*)this->distortion)->setDrive(value);
-}
-
-void CMLSProjectAudioProcessor::setDistortionMix(float value) {
-	((CMLSDistortion*)this->distortion)->setMix(value);
-}
-
-void CMLSProjectAudioProcessor::setChorusDryWet(float value) {
-    //auto& instance = this->processorChain.template get<0>();
-	//instance.setDryWet(value);
-	((CMLSChorus*)this->chorus)->setDryWet(value);
-}
-
-void CMLSProjectAudioProcessor::setChorusAmount(float value) {
-	((CMLSChorus*)this->chorus)->setAmount(value);
-}
-
-void CMLSProjectAudioProcessor::setReverbDryWet(float value) {
-    ((CMLSReverb*)this->reverb)->setDryWet(value);
-}
-
-void CMLSProjectAudioProcessor::setReverbRoomSize(float value) {
-	((CMLSReverb*)this->reverb)->setRoomSize(value);
-}
-
-void CMLSProjectAudioProcessor::setDelayDryWet(float value) {
-    ((CMLSDelay*)this->delay)->setDryWet(value);
-}
-
-void CMLSProjectAudioProcessor::setDelayAmount(float value) {
-    ((CMLSDelay*)this->delay)->setAmount(value);
-}
-
-//==============================================================================
-// This creates new instances of the plugin..
-juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
-{
-    return new CMLSProjectAudioProcessor();
-}

+ 0 - 101
JUCE/CMLSProject/Source/PluginProcessor.h

@@ -1,101 +0,0 @@
-/*
-  ==============================================================================
-
-    This file contains the basic framework code for a JUCE plugin processor.
-
-  ==============================================================================
-*/
-
-#pragma once
-
-#include <JuceHeader.h>
-#include "CMLSReverb.h"
-#include "CMLSDelay.h"
-#include "CMLSChorus.h"
-#include "CMLSProcessorChain.h"
-#include "CMLSEqualizer.h"
-#include "CMLSDistortion.h"
-
-//==============================================================================
-/**
-*/
-class CMLSProjectAudioProcessor  : public juce::AudioProcessor
-{
-public:
-    //==============================================================================
-    CMLSProjectAudioProcessor();
-    ~CMLSProjectAudioProcessor() override;
-
-    //==============================================================================
-    void prepareToPlay (double sampleRate, int samplesPerBlock) override;
-    void releaseResources() override;
-
-   #ifndef JucePlugin_PreferredChannelConfigurations
-    bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
-   #endif
-
-    void processBlock (juce::AudioBuffer<float>&, juce::MidiBuffer&) override;
-
-    //==============================================================================
-    juce::AudioProcessorEditor* createEditor() override;
-    bool hasEditor() const override;
-
-    //==============================================================================
-    const juce::String getName() const override;
-
-    bool acceptsMidi() const override;
-    bool producesMidi() const override;
-    bool isMidiEffect() const override;
-    double getTailLengthSeconds() const override;
-
-    //==============================================================================
-    int getNumPrograms() override;
-    int getCurrentProgram() override;
-    void setCurrentProgram (int index) override;
-    const juce::String getProgramName (int index) override;
-    void changeProgramName (int index, const juce::String& newName) override;
-
-    //==============================================================================
-    void getStateInformation (juce::MemoryBlock& destData) override;
-    void setStateInformation (const void* data, int sizeInBytes) override;
-
-    // Mute/unmute slot by number
-    void muteEffectInSlot(int slot);
-    void unmuteEffectInSlot(int slot);
-	void swapEffectInSlot(int slot1, int slot2);
-
-    // Parameter controls
-    void setEqLowGain(float value);
-    void setEqHighGain(float value);
-
-    void setDistortionDrive(float value);
-    void setDistortionMix(float value);
-
-	void setChorusDryWet(float value);
-	void setChorusAmount(float value);
-
-	void setReverbDryWet(float value);
-	void setReverbRoomSize(float value);
-
-	void setDelayDryWet(float value);
-	void setDelayAmount(float value);
-
-private:
-    //==============================================================================
-    
-    // OSC message receiver
-	juce::OSCReceiver oscReceiver;
-
-    // Buffer for the incoming audio from the generators
-
-    // Effects processing chain
-    juce::dsp::ProcessorBase* equalizer;
-	juce::dsp::ProcessorBase* distortion;
-    juce::dsp::ProcessorBase* chorus;
-    juce::dsp::ProcessorBase* delay;
-    juce::dsp::ProcessorBase* reverb;
-
-	CMLSProcessorChain processorChain;
-
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CMLSProjectAudioProcessor)
-};

+ 21 - 0
SC/1_environment_setup.scd

@@ -0,0 +1,21 @@
+// Server configuration
+s = Server.local;
+ServerOptions.devices;  // List available audio devices if needed
+
+// Server boot with status reporting
+(
+s.waitForBoot({
+    "SuperCollider server ready!".postln;
+    "Available audio inputs: %".format(ServerOptions.inDevices).postln;
+    "Available audio outputs: %".format(ServerOptions.outDevices).postln;
+    "Sample rate: % Hz".format(s.sampleRate).postln;
+    "Audio latency: % ms".format(s.options.blockSize / s.sampleRate * 1000).postln;
+
+    // Run a quick audio test
+    {
+        var sig = SinOsc.ar(440, 0, 0.2);
+        sig = sig * EnvGen.kr(Env.perc(0.01, 1), doneAction: 2);
+        sig!2  // Stereo output
+    }.play;
+});
+)

+ 0 - 0
2_oscillator_synthdefs.scd → SC/2_oscillator_synthdefs.scd


+ 0 - 0
SC/2b_rgb_synthdefs.scd


+ 0 - 0
3_effects_synthdefs.scd → SC/3_effects_synthdefs.scd


+ 0 - 0
4_modulation_synthdefs.scd → SC/4_modulation_synthdefs.scd


+ 0 - 0
SC/4b_lfo_effects.scd


+ 183 - 0
SC/5_osc_communication.scd

@@ -0,0 +1,183 @@
+// Module 5: OSC Communication Setup - MODIFIED FOR IDRAW OSC
+// Save as "5_osc_communication.scd"
+
+(
+// Clear any existing OSC definitions
+OSCdef.freeAll;
+
+// Variables to track current pen type and color
+~currentPenType = \pen;
+~currentColor = (r: 0, g: 0, b: 1); // Default blue
+
+// Define OSC responder for iDraw touch data
+OSCdef(\touchOSC, { |msg, time, addr, port|
+    var x = msg[1].asFloat;
+    var y = msg[2].asFloat;
+    var pressure = msg[3].asFloat;
+
+    // Log the received data
+    ["Touch data:", x, y, pressure, ~currentPenType, ~currentColor].postln;
+
+    // Handle touch based on current pen type
+    switch(~currentPenType,
+        // Pen - Controls amplitude envelope
+        \pen, {
+            var attack = x.linlin(-0.5, 0.5, 0, 5);
+            var release = y.linlin(-0.5, 0.5, 0, 10);
+            var freq = x.linexp(-0.5, 0.5, 100, 2000);
+
+            // Generate sound with RGB-controlled waveform mix
+            var synth = Synth(\rgbSynth, [
+                \out, ~sourceBus ? 0,
+                \freq, freq,
+                \amp, pressure.linlin(1, 8, 0.1, 0.8),
+                \attack, attack,
+                \release, release,
+                \redAmt, ~currentColor.r,
+                \greenAmt, ~currentColor.g,
+                \blueAmt, ~currentColor.b
+            ]);
+
+            ["Amplitude envelope:", attack, release].postln;
+        },
+
+        // Monoline - Controls filter envelope
+        \monoline, {
+            var attack = x.linlin(-0.5, 0.5, 0, 5);
+            var release = y.linlin(-0.5, 0.5, 0, 10);
+            var freq = x.linexp(-0.5, 0.5, 100, 2000);
+
+            // Generate sound with filter envelope
+            var synth = Synth(\rgbFilterSynth, [
+                \out, ~sourceBus ? 0,
+                \freq, freq,
+                \amp, pressure.linlin(1, 8, 0.1, 0.8),
+                \attack, attack,
+                \release, release,
+                \filterAttack, attack,
+                \filterRelease, release,
+                \redAmt, ~currentColor.r,
+                \greenAmt, ~currentColor.g,
+                \blueAmt, ~currentColor.b
+            ]);
+
+            ["Filter envelope:", attack, release].postln;
+        },
+
+        // Marker - Controls pitch envelope
+        \marker, {
+            var attack = x.linlin(-0.5, 0.5, 0, 5);
+            var release = y.linlin(-0.5, 0.5, 0, 10);
+            var freq = x.linexp(-0.5, 0.5, 100, 2000);
+
+            // Generate sound with pitch envelope
+            var synth = Synth(\rgbPitchSynth, [
+                \out, ~sourceBus ? 0,
+                \freq, freq,
+                \amp, pressure.linlin(1, 8, 0.1, 0.8),
+                \attack, attack,
+                \release, release,
+                \pitchAttack, attack,
+                \pitchRelease, release,
+                \redAmt, ~currentColor.r,
+                \greenAmt, ~currentColor.g,
+                \blueAmt, ~currentColor.b
+            ]);
+
+            ["Pitch envelope:", attack, release].postln;
+        },
+
+        // Pencil - Effect preset 1
+        \pencil, {
+            // Apply Preset 1 effects
+            ~filterSynth.set(
+                \cutoff, x.linexp(-0.5, 0.5, 20, 18000),
+                \res, y.linlin(-0.5, 0.5, 0, 1)
+            );
+
+            ~lfoSynth.set(
+                \freq, x.linlin(-0.5, 0.5, 0, 15),
+                \intensity, pressure.linlin(1, 8, 0, 1)
+            );
+
+            ~reverbSynth.set(
+                \roomsize, y.linlin(-0.5, 0.5, 0.1, 0.9)
+            );
+
+            ["Pencil preset:", "Cutoff", x.linexp(-0.5, 0.5, 20, 18000), "LFO", x.linlin(-0.5, 0.5, 0, 15)].postln;
+        },
+
+        // Crayon - Effect preset 2
+        \crayon, {
+            // Apply Preset 2 effects
+            ~lfoSynth.set(
+                \freq, x.linlin(-0.5, 0.5, 15, 1),
+                \intensity, x.linlin(-0.5, 0.5, 0, 1)
+            );
+
+            ~delaySynth.set(
+                \delaytime, x.linlin(-0.5, 0.5, 0.01, 1.0)
+            );
+
+            ~filterSynth.set(
+                \cutoff, y.linexp(-0.5, 0.5, 20, 18000),
+                \res, pressure.linlin(1, 5, 0, 1)
+            );
+
+            ~reverbSynth.set(
+                \mix, y.linlin(-0.5, 0.5, 0, 1)
+            );
+
+            ["Crayon preset:", "LFO", x.linlin(-0.5, 0.5, 15, 1), "Filter", y.linexp(-0.5, 0.5, 20, 18000)].postln;
+        },
+
+        // Fountain pen - Effect preset 3 (placeholder)
+        \fountainPen, {
+            // Apply Preset 3 effects (TBD in documentation)
+            ["Fountain pen preset (TBD)"].postln;
+        },
+
+        // Water color - Effect preset 4 (placeholder)
+        \waterColor, {
+            // Apply Preset 4 effects (TBD in documentation)
+            ["Water color preset (TBD)"].postln;
+        }
+    );
+}, '/touch');
+
+// OSC responder for pen type selection
+OSCdef(\penTypeOSC, { |msg, time, addr, port|
+    var penType = msg[1].asSymbol;
+
+    // Update current pen type
+    ~currentPenType = penType;
+
+    ["Pen type changed:", penType].postln;
+
+    // Initialize relevant effects based on pen type
+    switch(penType,
+        \pencil, { ~initializePreset1.value; },
+        \crayon, { ~initializePreset2.value; },
+        \fountainPen, { ~initializePreset3.value; },
+        \waterColor, { ~initializePreset4.value; }
+    );
+}, '/pen');
+
+// OSC responder for color changes
+OSCdef(\colorOSC, { |msg, time, addr, port|
+    var r = msg[1].asFloat;
+    var g = msg[2].asFloat;
+    var b = msg[3].asFloat;
+
+    // Update current color
+    ~currentColor = (r: r, g: g, b: b);
+
+    ["Color changed:", r, g, b].postln;
+}, '/color');
+
+// Start the OSC server on port 57120 (default SuperCollider port)
+thisProcess.openUDPPort(57120);
+"OSC server ready on port 57120".postln;
+"Registered OSC commands: /touch, /pen, /color".postln;
+"Ready to receive data from iDraw OSC app".postln;
+)

+ 0 - 0
6_test_functions.scd → SC/6_test_functions.scd


+ 0 - 0
SC/6b_effect_presets.scd


+ 0 - 0
SC/7_idraw_connection.scd


+ 0 - 0
7_mobile_connection.s → SC/8_mobile_connection.scd


+ 0 - 0
main.scd → SC/main.scd


+ 187 - 0
documentation/application_workflow.md

@@ -0,0 +1,187 @@
+Application workflow
+==============
+
+
+This is a proposal for how we can control the sound synthesis and effects via a drawing application. Here will be discussed the ways for the users to interact with the synthesizer and the effects using the drawing application **iDraw OSC** for Apple devices.
+
+The two possible types of interactions are:
+
+- drawing in the drawing area;
+- choosing the tool (especially the pens) and the color to draw with.
+
+The drawing area is represented in the following figure, with the 2 parameters describing the position of the pen (X coordinate and Y coordinate) and the pressure applied to the screen. Note that if the users are drawing with the finger instead of the pen, **the pressure variable is automatically set to 1 by default**.
+
+![Drawing area](rsc/drawing_area.jpeg)
+
+The different tools available and the sound parameters they control are represented in the following figure.
+
+![Different types of pens](rsc/pens.png)
+
+
+In the following sections we will describe in detail all the parameters that can be controlled by the users using the drawing application. In particular, we will talk about:
+
+- Sound synthesis: how to control the sound timbre using colors;
+- Envelopes: how to control one or many envelopes using different pens;
+- Effects: how to apply and control the effects by drawing
+
+
+
+# 1) Sound synthesis
+
+The timbre of a sound is often referred to as its color. Using this analogy, we could modify the timbre of the synth by changing the color of the pen. The color is defined by its three RGB components (red, green, blue). Let's use R, G and B to control three different waveforms, which are the three main components of our sound.
+
+
+| Color         | Sound        |
+| :------------ | :----------- |
+| Red           | Waveform 1   |
+| Green         | Waveform 2   |
+| Blue          | Waveform 3   |
+
+
+The output sound is the mix between Waveform 1, Waveform 2 and Waveform 3, with volumes corresponding to the intensity of the color component associated. For example using triangle, sawtooth and square as the three waveforms, we can imagine a combination like this:
+
+> **(R, G, B) = (0.2, 0.5, 0.9) --> Output = (20% triangle, 50% sawtooth, 90% square)**
+
+
+
+#### - Proposal 1
+The choice of the waveforms is up to the users. The application lets the users choose which waveform they want to put for red, green and blue among a set of predefined waveforms. The GUI implements a way for the users to map the three RGB components to the desired waveform.
+
+#### - Proposal 2 (Easier)
+The users do not have the choice of the waveforms, they are predefined and can not be changed. In that case the waveforms should at least be very different from each other to allow the users create complex sounds.
+
+
+
+# 2) Envelopes
+
+Envelopes are often referred to as ADSR, standing for the four parameters Attack, Decay, Sustain, Release. While all these parameters allow the users to shape the sound as best as possible, implementing a way to control them by drawing on a pad is not an esay task, especially because the pad allows for the control of only 3 parameters: the X coordinate, the Y coordinate and the pressure. Therefore there is no way to directly map the pad parameters and the 4 parameters of the envelope.
+
+However, we can stick to a more basic envelope, called AR (Attack, Release). This way, we can imagine the following mapping:
+
+| Pad parameter | OSC address | Envelope parameter  | OSC range    | Envelope parameter range |
+| :------------ | :---------- | :------------------ | :----------- | :----------------------- |
+| X axis        | /aspectX    | Attack              | [-0.5; 0.5]  | [0; 5] seconds           |
+| Y axis        | /aspectY    | Release             | [-0.5; 0.5]  | [0; 10] seconds          |
+
+The control of the envelope can be done by selecting the appropriate pen (see below).
+
+#### - Proposal 1
+We can create 3 AR envelopes, each one controlled via a different type of pen, as follows:
+
+| Envelope name | Envelope type | Description                                     | Pen type |
+| :------------ | :----------   | :---------------------------------------------  | :------- |
+| Amp. Env.     | Amplitude     | Modulates the amplitude of the sound            | Pen      |
+| Filt. Env.    | Modulation    | Modulates the cutoff frequency of the LP filter | Monoline |
+| Pitch. Env.   | Modulation    | Modulates the pitch of the oscillators          | Marker   |
+
+
+#### - Proposal 2 (Easier)
+We only create one AR amplitude envelope, controlling the amplitude of the sound, controllable with the "pen" type of pen.
+
+
+
+# 3) Effects control
+
+The effects can change drastically the final sound. Using the drawing surface we can apply effects and modify their parameters live. By effects we mean:
+
+- **On SuperCollider side (applied DURING the synthesis):**
+  - Low Frequency Oscillator (LFO) modulating pitch or filter;
+  - Resonant filter (low-pass and high-pass)
+- **On JUCE side (applied AFTER the synthesis):**
+  - Distortion;
+  - Reverb;
+  - Chorus;
+  - EQ;
+  - Delay.
+
+
+Let's synthesize in the following table all the possible parameters that can be modified for each one of these effects:
+
+| Effect                | Parameters       | Description                                    |
+| :-------------------- | :--------------- | :--------------------------------------------- |
+| **LFO**               | LFO Rate         | Frequency of the LFO (e.g. 0.01Hz to 20Hz)
+|                       | LFO Intensity    | Controls which amount of modulation we want
+|                       | LFO Waveform     | Waveform for the LFO
+|                       | LFO Target       | Target of the LFO
+| **Filter (HP or LP)** | Cutoff frequency | Cutoff frequency
+|                       | Resonance        | Q factor of the filter
+| **Distortion**        | Input level      | Level of the input signal (before distortion)
+|                       | Drive            | Shape of the distortion (soft, hard...)
+|                       | Dry/wet          | Controls the mix between dry and wet signal
+| **Reverb**            | Room size        | How long should the reverb go
+|                       | Dry/wet          | Controls the mix between dry and wet signal
+| **Chorus**            | Amount           | Frequency and depth of the chorus 
+|                       | Dry/wet          | Controls the mix between dry and wet signal
+| **EQ**                | Type             | Type of filter (shelf, peak/notch, ...)
+|                       | Frequency        | Central frequency of the filter
+|                       | Gain             | Gain to apply
+| **Delay**             | Amount           | Controls the amount of delay we want to apply
+|                       | Dry/wet          | Controls the mix between dry and wet signal
+
+
+Since the colors are used for the sound synthesis, we are left with the following controls:
+
+- **Controls for live performance (continuous):**
+  - X coordinate of the pen;
+  - Y coordinate of the pen;
+  - Pressure applied on the screen;
+- **Controls for selection/adjusting (sent only once):**
+  - Pen type;
+  - Pen thickness;
+  - Pen opacity;
+
+A creative and fun interaction design is to create custom presets consisting of a combination of effects that can be modified simultaneously using the pen. Each preset can be selected using a different type of pen, thus offering 4 possibilities of presets (3 out of the 7 pen types are already used for the envelopes). The following sections describe a possible set of presets that can be good-sounding and fun for the users.
+
+
+
+### Preset 1 - Pencil (/pencil)
+
+This effect preset uses the LFO, the filter and the reverb as follows. The parameter ranges are given as examples but may be adjusted a posteriori.
+
+| Pad parameter | OSC address   | Effect parameter | OSC range    | Parameter range       |
+| :------------ | :------------ | :--------------- | :----------- | :-------------------- |
+| X axis        | /aspectX      | Filter cutoff    | [-0.5; 0.5]  | [20; 18000] Hz
+| X axis        | /aspectX      | LFO Rate         | [-0.5; 0.5]  | [0; 15] Hz
+| Y axis        | /aspectY      | Filter resonance | [-0.5; 0.5]  | [0; max]
+| Y axis        | /aspectY      | Reverb room size | [-0.5; 0.5]  | [min; max]
+| Pen pressure  | /pressure     | LFO intensity    | [1; 8]       | [0; max]
+
+When this preset is selected, the following parameters are set and remain the same (they are not changed in any way by the pen):
+
+| Effect parameter | Value               |
+| :--------------- | :------------------ |
+| LFO Waveform     | Decreasing sawtooth |
+| LFO Target       | Filter cutoff       |
+
+
+### Preset 2 - Crayon (/crayon)
+
+This effect preset uses the LFO, the filter, the reverb and the delay as follows. The parameter ranges are given as examples but may be adjusted a posteriori.
+
+| Pad parameter | OSC parameter | Effect parameter | OSC range    | Parameter range       |
+| :------------ | :------------ | :--------------- | :----------- | :-------------------- |
+| X axis        | /aspectX      | LFO Rate         | [-0.5; 0.5]  | [15; 1] Hz
+| X axis        | /aspectX      | LFO Intensity    | [-0.5; 0.5]  | [0; max]
+| X axis        | /aspectX      | Delay amount     | [-0.5; 0.5]  | [0; max]
+| Y axis        | /aspectY      | Filter cutoff    | [-0.5; 0.5]  | [20; 18000] Hz
+| Y axis        | /aspectY      | Reverb dry/wet   | [-0.5; 0.5]  | [dry; dry+wet]
+| Pen pressure  | /pressure     | Filter resonance | [1; 5]       | [0; max]
+
+When this preset is selected, the following parameters are set and remain the same (they are not changed in any way by the pen):
+
+| Effect parameter | Value               |
+| :--------------- | :------------------ |
+| LFO Waveform     | Square              |
+| LFO Target       | Filter cutoff       |
+
+
+
+### Preset 3 - Fountain Pen (/fountainPen)
+
+TBD
+
+
+### Preset 4 - Water Color (/waterColor)
+
+TBD
+

+ 0 - 0
resources for sc and juce/osc addresses and values for iDraw OSC.pdf → documentation/iDraw_OSC_documentation.pdf


+ 0 - 0
resources for sc and juce/midi_receiver_example.scd → documentation/midi_receiver_example.scd


+ 0 - 0
resources for sc and juce/osc_receiver_example.scd → documentation/osc_receiver_example.scd


BIN
documentation/rsc/drawing_area.jpeg


BIN
documentation/rsc/pens.png


BIN
resources for sc and juce/osc addresses and values.pdf