( // 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; )