|
|
@@ -2,74 +2,105 @@
|
|
|
// Clear any existing OSC definitions
|
|
|
OSCdef.freeAll;
|
|
|
|
|
|
-// Define OSC responder for touch events
|
|
|
+// Define OSC responder for mobile touch events
|
|
|
+// Mobile touch data format will likely be different from Arduino
|
|
|
OSCdef(\touchOSC, { |msg, time, addr, port|
|
|
|
- var x = msg[1], y = msg[2], pressure = msg[3], color = msg[4];
|
|
|
+ // 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)
|
|
|
|
|
|
- // Map x, y coordinates to frequency and amplitude
|
|
|
+ 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);
|
|
|
|
|
|
- // Use color to select sound type (assuming color is an integer)
|
|
|
- var synthType = switch(color.asInteger,
|
|
|
- 0, { \sineTone },
|
|
|
- 1, { \squareTone },
|
|
|
- 2, { \sawTone },
|
|
|
- 3, { \triTone },
|
|
|
- 4, { \fmTone },
|
|
|
- { \sineTone } // default
|
|
|
- );
|
|
|
+ // Log the received data
|
|
|
+ ["Mobile touch:", touchId, x, y, state, pressure].postln;
|
|
|
|
|
|
- // Create synth with mapped parameters
|
|
|
- Synth(synthType, [
|
|
|
- \freq, freq,
|
|
|
- \amp, amp,
|
|
|
- \pan, y.linlin(0, 1, -0.8, 0.8),
|
|
|
- \attack, 0.01,
|
|
|
- \release, y.linlin(0, 1, 0.2, 2.0)
|
|
|
- ]);
|
|
|
+ // 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 }
|
|
|
+ );
|
|
|
|
|
|
- // Log the received data
|
|
|
- ["Touch data:", x, y, pressure, color, "->", synthType, freq, amp].postln;
|
|
|
+ // 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 control messages
|
|
|
+// OSC responder for mobile control messages (e.g., UI controls)
|
|
|
OSCdef(\controlOSC, { |msg, time, addr, port|
|
|
|
- var control = msg[1].asSymbol, value = msg[2];
|
|
|
+ var control = msg[1].asSymbol;
|
|
|
+ var value = msg[2];
|
|
|
|
|
|
- // Log the control change
|
|
|
- ["Control change:", control, value].postln;
|
|
|
+ ["Mobile control:", control, value].postln;
|
|
|
|
|
|
// Handle different control parameters
|
|
|
switch(control,
|
|
|
\reverb_mix, { ~reverbSynth.set(\mix, value); },
|
|
|
\reverb_room, { ~reverbSynth.set(\room, value); },
|
|
|
- \reverb_damp, { ~reverbSynth.set(\damp, value); },
|
|
|
-
|
|
|
\delay_time, { ~delaySynth.set(\delaytime, value); },
|
|
|
\delay_feedback, { ~delaySynth.set(\feedback, value); },
|
|
|
- \delay_mix, { ~delaySynth.set(\mix, value); },
|
|
|
-
|
|
|
- \filter_cutoff, { ~filterSynth.set(\cutoff, value.linexp(0, 1, 200, 10000)); },
|
|
|
- \filter_res, { ~filterSynth.set(\res, value); }
|
|
|
+ \filter_cutoff, { ~filterSynth.set(\cutoff, value.linexp(0, 1, 200, 10000)); }
|
|
|
);
|
|
|
}, '/control');
|
|
|
|
|
|
-// OSC responder for system commands
|
|
|
-OSCdef(\systemOSC, { |msg, time, addr, port|
|
|
|
- var command = msg[1].asSymbol;
|
|
|
+// Add a separate responder for color changes from mobile UI
|
|
|
+OSCdef(\colorOSC, { |msg, time, addr, port|
|
|
|
+ var colorIndex = msg[1].asInteger;
|
|
|
|
|
|
- ["System command:", command].postln;
|
|
|
+ // Store the current color for new touches
|
|
|
+ ~currentColor = colorIndex;
|
|
|
|
|
|
- switch(command,
|
|
|
- \start_effects, { ~startEffectsChain.value; },
|
|
|
- \stop_effects, { ~stopEffectsChain.value; },
|
|
|
- \reset, { ~resetSystem.value; }
|
|
|
- );
|
|
|
-}, '/system');
|
|
|
+ ["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, /system".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;
|
|
|
)
|