|
@@ -1,5 +1,5 @@
|
|
|
-// Module 5: OSC Communication Setup - FIXED FOR MEMORY MANAGEMENT
|
|
|
|
|
-// Save as "5_osc_communication.scd"
|
|
|
|
|
|
|
+// Module 5: OSC Communication Setup - FIXED FOR PROPER TOUCH MANAGEMENT
|
|
|
|
|
+// Save as "5_osc_communication.scd" (REPLACE THE PREVIOUS VERSION)
|
|
|
|
|
|
|
|
(
|
|
(
|
|
|
// Clear any existing OSC definitions
|
|
// Clear any existing OSC definitions
|
|
@@ -10,9 +10,13 @@ OSCdef.freeAll;
|
|
|
~currentColor = (r: 0.0, g: 0.0, b: 1.0); // Default blue
|
|
~currentColor = (r: 0.0, g: 0.0, b: 1.0); // Default blue
|
|
|
~currentPadValues = (x: 0.0, y: 0.0, pressure: 1.0); //Default pad values
|
|
~currentPadValues = (x: 0.0, y: 0.0, pressure: 1.0); //Default pad values
|
|
|
|
|
|
|
|
-// Track active synths to prevent memory leaks
|
|
|
|
|
-~activeSynths = IdentityDictionary.new;
|
|
|
|
|
-~synthCounter = 0;
|
|
|
|
|
|
|
+// Touch state management
|
|
|
|
|
+~touchState = (
|
|
|
|
|
+ isActive: false,
|
|
|
|
|
+ currentSynth: nil,
|
|
|
|
|
+ lastTriggerTime: 0,
|
|
|
|
|
+ minTriggerInterval: 0.1 // Minimum time between new synths (100ms)
|
|
|
|
|
+);
|
|
|
|
|
|
|
|
~synthParams = (
|
|
~synthParams = (
|
|
|
out: 0,
|
|
out: 0,
|
|
@@ -32,6 +36,10 @@ OSCdef.freeAll;
|
|
|
blueAmt: 0.5
|
|
blueAmt: 0.5
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
|
|
+// Track active synths to prevent memory leaks
|
|
|
|
|
+~activeSynths = IdentityDictionary.new;
|
|
|
|
|
+~synthCounter = 0;
|
|
|
|
|
+
|
|
|
// Function to clean up old synths
|
|
// Function to clean up old synths
|
|
|
~cleanupSynths = {
|
|
~cleanupSynths = {
|
|
|
~activeSynths.keysValuesDo({ |key, synth|
|
|
~activeSynths.keysValuesDo({ |key, synth|
|
|
@@ -41,8 +49,8 @@ OSCdef.freeAll;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
// If too many synths are active, force cleanup of oldest ones
|
|
// If too many synths are active, force cleanup of oldest ones
|
|
|
- if(~activeSynths.size > 10, {
|
|
|
|
|
- var oldestKeys = ~activeSynths.keys.asArray.sort.copyRange(0, ~activeSynths.size - 6);
|
|
|
|
|
|
|
+ if(~activeSynths.size > 5, { // Reduced from 10 to 5
|
|
|
|
|
+ var oldestKeys = ~activeSynths.keys.asArray.sort.copyRange(0, ~activeSynths.size - 3);
|
|
|
oldestKeys.do({ |key|
|
|
oldestKeys.do({ |key|
|
|
|
if(~activeSynths[key].notNil, {
|
|
if(~activeSynths[key].notNil, {
|
|
|
~activeSynths[key].set(\gate, 0);
|
|
~activeSynths[key].set(\gate, 0);
|
|
@@ -52,7 +60,7 @@ OSCdef.freeAll;
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-// Function to create a new synth safely
|
|
|
|
|
|
|
+// Function to create a new synth safely (only when needed)
|
|
|
~createSafeSynth = { |synthType = \rgbSynth, args|
|
|
~createSafeSynth = { |synthType = \rgbSynth, args|
|
|
|
var synth, synthId;
|
|
var synth, synthId;
|
|
|
|
|
|
|
@@ -91,23 +99,84 @@ OSCdef.freeAll;
|
|
|
synth;
|
|
synth;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-// Define OSC responder for creating sounds (only for envelope-controlling pens)
|
|
|
|
|
-~triggerSound = {
|
|
|
|
|
|
|
+// Function to handle touch begin (creates new synth)
|
|
|
|
|
+~handleTouchBegin = {
|
|
|
var x = ~currentPadValues.x;
|
|
var x = ~currentPadValues.x;
|
|
|
var y = ~currentPadValues.y;
|
|
var y = ~currentPadValues.y;
|
|
|
var pressure = ~currentPadValues.pressure;
|
|
var pressure = ~currentPadValues.pressure;
|
|
|
var freq = x.linexp(-0.5, 0.5, 100, 2000);
|
|
var freq = x.linexp(-0.5, 0.5, 100, 2000);
|
|
|
- var amp = pressure.linlin(1, 8, 0.1, 0.8);
|
|
|
|
|
|
|
+ var amp = pressure.linlin(1, 8, 0.1, 0.5); // Reduced max amplitude
|
|
|
|
|
|
|
|
// Only create sounds for envelope-controlling pen types
|
|
// Only create sounds for envelope-controlling pen types
|
|
|
if([\pen, \monoline, \marker].includes(~currentPenType.asSymbol), {
|
|
if([\pen, \monoline, \marker].includes(~currentPenType.asSymbol), {
|
|
|
- ~createSafeSynth.value(\rgbSynth, [
|
|
|
|
|
|
|
+ // Release previous synth if it exists
|
|
|
|
|
+ if(~touchState.currentSynth.notNil, {
|
|
|
|
|
+ ~touchState.currentSynth.set(\gate, 0);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Create new synth
|
|
|
|
|
+ ~touchState.currentSynth = ~createSafeSynth.value(\rgbSynth, [
|
|
|
\out, ~sourceBus ? 0,
|
|
\out, ~sourceBus ? 0,
|
|
|
\freq, freq,
|
|
\freq, freq,
|
|
|
\amp, amp
|
|
\amp, amp
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
- ["Sound triggered:", ~currentPenType, freq, amp].postln;
|
|
|
|
|
|
|
+ ~touchState.isActive = true;
|
|
|
|
|
+ ~touchState.lastTriggerTime = SystemClock.seconds;
|
|
|
|
|
+
|
|
|
|
|
+ ["Touch BEGIN - Sound triggered:", ~currentPenType, freq, amp].postln;
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// Function to handle touch movement (updates existing synth)
|
|
|
|
|
+~handleTouchMove = {
|
|
|
|
|
+ var x = ~currentPadValues.x;
|
|
|
|
|
+ var y = ~currentPadValues.y;
|
|
|
|
|
+ var pressure = ~currentPadValues.pressure;
|
|
|
|
|
+ var freq = x.linexp(-0.5, 0.5, 100, 2000);
|
|
|
|
|
+ var amp = pressure.linlin(1, 8, 0.1, 0.5);
|
|
|
|
|
+
|
|
|
|
|
+ // Only update if we have an active touch for envelope-controlling pens
|
|
|
|
|
+ if(~touchState.isActive and: { ~touchState.currentSynth.notNil } and: {
|
|
|
|
|
+ [\pen, \monoline, \marker].includes(~currentPenType.asSymbol)
|
|
|
|
|
+ }, {
|
|
|
|
|
+ // Update the existing synth parameters
|
|
|
|
|
+ if(~touchState.currentSynth.isPlaying, {
|
|
|
|
|
+ ~touchState.currentSynth.set(\freq, freq, \amp, amp);
|
|
|
|
|
+ // Don't log every movement to avoid spam
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// Function to handle touch end (releases synth)
|
|
|
|
|
+~handleTouchEnd = {
|
|
|
|
|
+ if(~touchState.currentSynth.notNil, {
|
|
|
|
|
+ ~touchState.currentSynth.set(\gate, 0);
|
|
|
|
|
+ ~touchState.currentSynth = nil;
|
|
|
|
|
+ ~touchState.isActive = false;
|
|
|
|
|
+
|
|
|
|
|
+ ["Touch END - Sound released"].postln;
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// Smart trigger function that decides what to do based on pressure changes
|
|
|
|
|
+~smartTriggerSound = {
|
|
|
|
|
+ var currentTime = SystemClock.seconds;
|
|
|
|
|
+ var pressure = ~currentPadValues.pressure;
|
|
|
|
|
+
|
|
|
|
|
+ // Detect touch begin: pressure goes from low to high
|
|
|
|
|
+ if(pressure > 2 and: { ~touchState.isActive.not }, {
|
|
|
|
|
+ ~handleTouchBegin.value;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Detect touch movement: pressure stays high and we have active touch
|
|
|
|
|
+ if(pressure > 1 and: { ~touchState.isActive }, {
|
|
|
|
|
+ ~handleTouchMove.value;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // Detect touch end: pressure goes to very low or zero
|
|
|
|
|
+ if(pressure <= 1 and: { ~touchState.isActive }, {
|
|
|
|
|
+ ~handleTouchEnd.value;
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -117,10 +186,7 @@ OSCdef.freeAll;
|
|
|
var y = ~currentPadValues.y;
|
|
var y = ~currentPadValues.y;
|
|
|
var pressure = ~currentPadValues.pressure;
|
|
var pressure = ~currentPadValues.pressure;
|
|
|
|
|
|
|
|
- // Log the received data
|
|
|
|
|
- ["Touch data:", x, y, pressure, ~currentPenType, ~currentColor].postln;
|
|
|
|
|
-
|
|
|
|
|
- // Handle touch based on current pen type
|
|
|
|
|
|
|
+ // Update synthesis parameters but DON'T log every change to avoid spam
|
|
|
switch(~currentPenType.asSymbol,
|
|
switch(~currentPenType.asSymbol,
|
|
|
// Pen - Controls amplitude envelope
|
|
// Pen - Controls amplitude envelope
|
|
|
\pen, {
|
|
\pen, {
|
|
@@ -129,8 +195,6 @@ OSCdef.freeAll;
|
|
|
|
|
|
|
|
~synthParams.ampAttack = ampAttack;
|
|
~synthParams.ampAttack = ampAttack;
|
|
|
~synthParams.ampRelease = ampRelease;
|
|
~synthParams.ampRelease = ampRelease;
|
|
|
-
|
|
|
|
|
- ["Amplitude envelope:", ampAttack, ampRelease].postln;
|
|
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
// Monoline - Controls filter envelope
|
|
// Monoline - Controls filter envelope
|
|
@@ -140,8 +204,6 @@ OSCdef.freeAll;
|
|
|
|
|
|
|
|
~synthParams.filterAttack = filterAttack;
|
|
~synthParams.filterAttack = filterAttack;
|
|
|
~synthParams.filterRelease = filterRelease;
|
|
~synthParams.filterRelease = filterRelease;
|
|
|
-
|
|
|
|
|
- ["Filter envelope:", filterAttack, filterRelease].postln;
|
|
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
// Marker - Controls pitch envelope
|
|
// Marker - Controls pitch envelope
|
|
@@ -151,8 +213,6 @@ OSCdef.freeAll;
|
|
|
|
|
|
|
|
~synthParams.pitchAttack = pitchAttack;
|
|
~synthParams.pitchAttack = pitchAttack;
|
|
|
~synthParams.pitchRelease = pitchRelease;
|
|
~synthParams.pitchRelease = pitchRelease;
|
|
|
-
|
|
|
|
|
- ["Pitch envelope:", pitchAttack, pitchRelease].postln;
|
|
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
// Pencil - Effect preset 1
|
|
// Pencil - Effect preset 1
|
|
@@ -177,8 +237,6 @@ OSCdef.freeAll;
|
|
|
\room, y.linlin(-0.5, 0.5, 0.1, 0.9)
|
|
\room, 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 - Effect preset 2
|
|
@@ -209,20 +267,16 @@ OSCdef.freeAll;
|
|
|
\mix, y.linlin(-0.5, 0.5, 0, 1)
|
|
\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)
|
|
// Fountain pen - Effect preset 3 (placeholder)
|
|
|
\fountainPen, {
|
|
\fountainPen, {
|
|
|
// Apply Preset 3 effects (TBD in documentation)
|
|
// Apply Preset 3 effects (TBD in documentation)
|
|
|
- ["Fountain pen preset (TBD)"].postln;
|
|
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
// Water color - Effect preset 4 (placeholder)
|
|
// Water color - Effect preset 4 (placeholder)
|
|
|
\waterColor, {
|
|
\waterColor, {
|
|
|
// Apply Preset 4 effects (TBD in documentation)
|
|
// Apply Preset 4 effects (TBD in documentation)
|
|
|
- ["Water color preset (TBD)"].postln;
|
|
|
|
|
}
|
|
}
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|
|
@@ -235,6 +289,11 @@ OSCdef(\xOSC, { |msg, time, addr, port|
|
|
|
// Update current pad value and change effects
|
|
// Update current pad value and change effects
|
|
|
~currentPadValues.x = x;
|
|
~currentPadValues.x = x;
|
|
|
~changeEffectParams.value;
|
|
~changeEffectParams.value;
|
|
|
|
|
+
|
|
|
|
|
+ // Handle touch movement if active
|
|
|
|
|
+ if(~touchState.isActive, {
|
|
|
|
|
+ ~handleTouchMove.value;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
}, '/aspectX');
|
|
}, '/aspectX');
|
|
|
|
|
|
|
@@ -245,10 +304,15 @@ OSCdef(\yOSC, { |msg, time, addr, port|
|
|
|
// Update current pad value and change effects
|
|
// Update current pad value and change effects
|
|
|
~currentPadValues.y = y;
|
|
~currentPadValues.y = y;
|
|
|
~changeEffectParams.value;
|
|
~changeEffectParams.value;
|
|
|
|
|
+
|
|
|
|
|
+ // Handle touch movement if active
|
|
|
|
|
+ if(~touchState.isActive, {
|
|
|
|
|
+ ~handleTouchMove.value;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
}, '/aspectY');
|
|
}, '/aspectY');
|
|
|
|
|
|
|
|
-// OSC responder for pressure coordinate
|
|
|
|
|
|
|
+// OSC responder for pressure coordinate - THIS IS THE KEY ONE
|
|
|
OSCdef(\pressureOSC, { |msg, time, addr, port|
|
|
OSCdef(\pressureOSC, { |msg, time, addr, port|
|
|
|
var pressure = msg[1].asFloat;
|
|
var pressure = msg[1].asFloat;
|
|
|
|
|
|
|
@@ -256,140 +320,121 @@ OSCdef(\pressureOSC, { |msg, time, addr, port|
|
|
|
~currentPadValues.pressure = pressure;
|
|
~currentPadValues.pressure = pressure;
|
|
|
~changeEffectParams.value;
|
|
~changeEffectParams.value;
|
|
|
|
|
|
|
|
- // Trigger sound for envelope-controlling pens
|
|
|
|
|
- ~triggerSound.value;
|
|
|
|
|
|
|
+ // Use smart trigger logic instead of always creating new synths
|
|
|
|
|
+ ~smartTriggerSound.value;
|
|
|
|
|
|
|
|
}, '/pressure');
|
|
}, '/pressure');
|
|
|
|
|
|
|
|
-// ----- OSC Pen Types -----
|
|
|
|
|
-// OSC responder for pen
|
|
|
|
|
|
|
+// ----- OSC Pen Types ----- (unchanged)
|
|
|
OSCdef(\penOSC, { |msg, time, addr, port|
|
|
OSCdef(\penOSC, { |msg, time, addr, port|
|
|
|
var penType = msg[1].asFloat;
|
|
var penType = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
if (penType == 1.0) {
|
|
if (penType == 1.0) {
|
|
|
~currentPenType = \pen;
|
|
~currentPenType = \pen;
|
|
|
["Current pen type:", ~currentPenType].postln;
|
|
["Current pen type:", ~currentPenType].postln;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}, '/pen');
|
|
}, '/pen');
|
|
|
|
|
|
|
|
-// OSC responder for monoline
|
|
|
|
|
OSCdef(\monolineOSC, { |msg, time, addr, port|
|
|
OSCdef(\monolineOSC, { |msg, time, addr, port|
|
|
|
var penType = msg[1].asFloat;
|
|
var penType = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
if (penType == 1.0) {
|
|
if (penType == 1.0) {
|
|
|
~currentPenType = \monoline;
|
|
~currentPenType = \monoline;
|
|
|
["Current pen type:", ~currentPenType].postln;
|
|
["Current pen type:", ~currentPenType].postln;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}, '/monoline');
|
|
}, '/monoline');
|
|
|
|
|
|
|
|
-// OSC responder for marker
|
|
|
|
|
OSCdef(\markerOSC, { |msg, time, addr, port|
|
|
OSCdef(\markerOSC, { |msg, time, addr, port|
|
|
|
var penType = msg[1].asFloat;
|
|
var penType = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
if (penType == 1.0) {
|
|
if (penType == 1.0) {
|
|
|
~currentPenType = \marker;
|
|
~currentPenType = \marker;
|
|
|
["Current pen type:", ~currentPenType].postln;
|
|
["Current pen type:", ~currentPenType].postln;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}, '/marker');
|
|
}, '/marker');
|
|
|
|
|
|
|
|
-// OSC responder for pencil
|
|
|
|
|
OSCdef(\pencilOSC, { |msg, time, addr, port|
|
|
OSCdef(\pencilOSC, { |msg, time, addr, port|
|
|
|
var penType = msg[1].asFloat;
|
|
var penType = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
if (penType == 1.0) {
|
|
if (penType == 1.0) {
|
|
|
~currentPenType = \pencil;
|
|
~currentPenType = \pencil;
|
|
|
if(~initializePreset1.notNil, { ~initializePreset1.value; });
|
|
if(~initializePreset1.notNil, { ~initializePreset1.value; });
|
|
|
["Current pen type:", ~currentPenType].postln;
|
|
["Current pen type:", ~currentPenType].postln;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}, '/pencil');
|
|
}, '/pencil');
|
|
|
|
|
|
|
|
-// OSC responder for crayon
|
|
|
|
|
OSCdef(\crayonOSC, { |msg, time, addr, port|
|
|
OSCdef(\crayonOSC, { |msg, time, addr, port|
|
|
|
var penType = msg[1].asFloat;
|
|
var penType = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
if (penType == 1.0) {
|
|
if (penType == 1.0) {
|
|
|
~currentPenType = \crayon;
|
|
~currentPenType = \crayon;
|
|
|
if(~initializePreset2.notNil, { ~initializePreset2.value; });
|
|
if(~initializePreset2.notNil, { ~initializePreset2.value; });
|
|
|
["Current pen type:", ~currentPenType].postln;
|
|
["Current pen type:", ~currentPenType].postln;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}, '/crayon');
|
|
}, '/crayon');
|
|
|
|
|
|
|
|
-// OSC responder for fountainPen
|
|
|
|
|
OSCdef(\fountainPenOSC, { |msg, time, addr, port|
|
|
OSCdef(\fountainPenOSC, { |msg, time, addr, port|
|
|
|
var penType = msg[1].asFloat;
|
|
var penType = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
if (penType == 1.0) {
|
|
if (penType == 1.0) {
|
|
|
~currentPenType = \fountainPen;
|
|
~currentPenType = \fountainPen;
|
|
|
if(~initializePreset3.notNil, { ~initializePreset3.value; });
|
|
if(~initializePreset3.notNil, { ~initializePreset3.value; });
|
|
|
["Current pen type:", ~currentPenType].postln;
|
|
["Current pen type:", ~currentPenType].postln;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}, '/fountainPen');
|
|
}, '/fountainPen');
|
|
|
|
|
|
|
|
-// OSC responder for waterColor
|
|
|
|
|
OSCdef(\waterColorOSC, { |msg, time, addr, port|
|
|
OSCdef(\waterColorOSC, { |msg, time, addr, port|
|
|
|
var penType = msg[1].asFloat;
|
|
var penType = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
if (penType == 1.0) {
|
|
if (penType == 1.0) {
|
|
|
~currentPenType = \waterColor;
|
|
~currentPenType = \waterColor;
|
|
|
if(~initializePreset4.notNil, { ~initializePreset4.value; });
|
|
if(~initializePreset4.notNil, { ~initializePreset4.value; });
|
|
|
["Current pen type:", ~currentPenType].postln;
|
|
["Current pen type:", ~currentPenType].postln;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}, '/waterColor');
|
|
}, '/waterColor');
|
|
|
|
|
|
|
|
-// ----- OSC RGB Colors -----
|
|
|
|
|
-// OSC responder for red changes
|
|
|
|
|
|
|
+// ----- OSC RGB Colors ----- (unchanged)
|
|
|
OSCdef(\redOSC, { |msg, time, addr, port|
|
|
OSCdef(\redOSC, { |msg, time, addr, port|
|
|
|
var component = msg[1].asFloat;
|
|
var component = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
- // Update current color
|
|
|
|
|
~currentColor.r = component;
|
|
~currentColor.r = component;
|
|
|
~synthParams.redAmt = component;
|
|
~synthParams.redAmt = component;
|
|
|
-
|
|
|
|
|
["Color changed:", ~currentColor].postln;
|
|
["Color changed:", ~currentColor].postln;
|
|
|
}, '/r');
|
|
}, '/r');
|
|
|
|
|
|
|
|
-// OSC responder for green changes
|
|
|
|
|
OSCdef(\greenOSC, { |msg, time, addr, port|
|
|
OSCdef(\greenOSC, { |msg, time, addr, port|
|
|
|
var component = msg[1].asFloat;
|
|
var component = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
- // Update current color
|
|
|
|
|
~currentColor.g = component;
|
|
~currentColor.g = component;
|
|
|
~synthParams.greenAmt = component;
|
|
~synthParams.greenAmt = component;
|
|
|
-
|
|
|
|
|
["Color changed:", ~currentColor].postln;
|
|
["Color changed:", ~currentColor].postln;
|
|
|
}, '/g');
|
|
}, '/g');
|
|
|
|
|
|
|
|
-// OSC responder for blue changes
|
|
|
|
|
OSCdef(\blueOSC, { |msg, time, addr, port|
|
|
OSCdef(\blueOSC, { |msg, time, addr, port|
|
|
|
var component = msg[1].asFloat;
|
|
var component = msg[1].asFloat;
|
|
|
-
|
|
|
|
|
- // Update current color
|
|
|
|
|
~currentColor.b = component;
|
|
~currentColor.b = component;
|
|
|
~synthParams.blueAmt = component;
|
|
~synthParams.blueAmt = component;
|
|
|
-
|
|
|
|
|
["Color changed:", ~currentColor].postln;
|
|
["Color changed:", ~currentColor].postln;
|
|
|
}, '/b');
|
|
}, '/b');
|
|
|
|
|
|
|
|
// Cleanup function
|
|
// Cleanup function
|
|
|
~cleanupOSCSystem = {
|
|
~cleanupOSCSystem = {
|
|
|
|
|
+ // End any active touch
|
|
|
|
|
+ ~handleTouchEnd.value;
|
|
|
|
|
+
|
|
|
|
|
+ // Clean up all synths
|
|
|
~activeSynths.keysValuesDo({ |key, synth|
|
|
~activeSynths.keysValuesDo({ |key, synth|
|
|
|
synth.set(\gate, 0);
|
|
synth.set(\gate, 0);
|
|
|
});
|
|
});
|
|
|
~activeSynths.clear;
|
|
~activeSynths.clear;
|
|
|
|
|
+
|
|
|
|
|
+ // Reset touch state
|
|
|
|
|
+ ~touchState.isActive = false;
|
|
|
|
|
+ ~touchState.currentSynth = nil;
|
|
|
|
|
+
|
|
|
"OSC system cleaned up".postln;
|
|
"OSC system cleaned up".postln;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// Register cleanup with CmdPeriod
|
|
|
|
|
+CmdPeriod.add({
|
|
|
|
|
+ ~cleanupOSCSystem.value;
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
// Start the OSC server on port 57120 (default SuperCollider port)
|
|
// Start the OSC server on port 57120 (default SuperCollider port)
|
|
|
thisProcess.openUDPPort(57120);
|
|
thisProcess.openUDPPort(57120);
|
|
|
-"OSC server ready on port 57120".postln;
|
|
|
|
|
-"Registered OSC commands for pad values, pen types, and colors".postln;
|
|
|
|
|
|
|
+"OSC server ready on port 57120 - FIXED FOR TOUCH MANAGEMENT".postln;
|
|
|
|
|
+"Now only creates synths on touch BEGIN, updates on MOVE, releases on END".postln;
|
|
|
"Ready to receive data from iDraw OSC app".postln;
|
|
"Ready to receive data from iDraw OSC app".postln;
|
|
|
"To cleanup system, run: ~cleanupOSCSystem.value".postln;
|
|
"To cleanup system, run: ~cleanupOSCSystem.value".postln;
|
|
|
)
|
|
)
|