// 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.0, g: 0.0, b: 1.0); // Default blue ~currentPadValues = (x: 0.0, y: 0.0, pressure: 1.0, a: 1.0); //Default pad values // Define OSC responder for iDraw touch data ~changeEffectParams = { var x = ~currentPadValues.x; var y = ~currentPadValues.y; var pressure = ~currentPadValues.pressure; var a = ~currentPadValues.a; // 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 ampAttack = y.linexp(-0.5, 0.5, 0.001, 5); var ampRelease = x.linexp(-0.5, 0.5, 0.001, 10); ~setSynthsParam.(\ampAttack, ampAttack); ~setSynthsParam.(\ampRelease, ampRelease); //["Amplitude envelope:", ampAttack, ampRelease].postln; }, // Monoline - Controls filter envelope "/monoline", { var filterAttack = y.linexp(-0.5, 0.5, 0.001, 5); var filterDecay = x.linexp(-0.5, 0.5, 0.001, 10); var envDepth = a.linlin(0, 1, 50, 0.001); ~filterEnv.set(\attack, filterAttack); ~filterEnv.set(\decay, filterDecay); ~filter.set(\envDepth, envDepth); //["Filter envelope:", filterAttack, filterDecay, envDepth].postln; }, // Marker - Controls pitch envelope "/marker", { var pitchAttack = y.linexp(-0.5, 0.5, 0.001, 5); var pitchDecay = x.linexp(-0.5, 0.5, 0.001, 10); var pitchRatio = a.linexp(0, 1, 10, 1); ~setSynthsParam.(\pitchAttack, pitchAttack); ~setSynthsParam.(\pitchDecay, pitchDecay); ~setSynthsParam.(\pitchRatio, pitchRatio); //["Pitch envelope:", pitchAttack, pitchDecay, pitchRatio].postln; }, // Pencil - Effect preset 1 "/pencil", { // Apply Preset 1 effects ~filter.set( \cutoff, x.linexp(-0.5, 0.5, 100, 18000), \resonance, y.linlin(-0.5, 0.5, 0, 1), \lfoDepth, pressure.linlin(1, 8, 0, 4) ); ~lfo.set( \freq, x.linlin(-0.5, 0.5, 0, 15), \waveform, 2 ); ~ctl.set(8, y.linlin(-0.5, 0.5, 0, 1)); ~ctl.set(9, 0.5); //["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 ~lfo.set( \freq, x.linlin(-0.5, 0.5, 15, 1), \waveform, 3 ); ~filter.set( \cutoff, y.linexp(-0.5, 0.5, 20, 18000), \resonance, pressure.linlin(1, 5, 0, 1), \lfoDepth, x.linlin(-0.5, 0.5, 0, 3) ); ~ctl.set(9, y.linlin(-0.5, 0.5, 0, 0.5)); // Reverb dry/wet ~ctl.set(7, x.linlin(-0.5, 0.5, 0.001, 1.0)); // Delay amount ~ctl.set(9, 0.8); //["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 ~lfo.set( \freq, x.linlin(-0.5, 0.5, 1, 15), \waveform, 0 ); ~filter.set( \lfoDepth, 0 ); ~setSynthsParam.(\lfoDepth, pressure.linlin(1, 5, 0, 0.5)); //["fountainPen preset:", "LFO Depth", pressure.linlin(1, 5, 0, 0.5), "LFO Freq", x.linlin(-0.5, 0.5, 1, 15)].postln; }, // Water color - Effect preset 4 (placeholder) "/waterColor", { // Apply Preset 4 effects (TBD in documentation) if (a >= 0 && a < 0.20) { ~ctl.set(0, x.linlin(-0.5, 0.5, -60, 20)); ~ctl.set(1, y.linlin(-0.5, 0.5, -60, 20)); ["Set:", y.linlin(-0.5, 0.5, -60, 20)].postln; }; if (a >= 0.20 && a < 0.40) { ~ctl.set(2, x.linlin(-0.5, 0.5, 1, 15)); ~ctl.set(3, y.linlin(-0.5, 0.5, 0, 1)); }; if (a >= 0.40 && a < 0.60) { ~ctl.set(4, x.linlin(-0.5, 0.5, 0, 1)); ~ctl.set(5, y.linlin(-0.5, 0.5, 0, 1)); }; if (a >= 0.60 && a < 0.80) { ~ctl.set(6, x.linlin(-0.5, 0.5, 0, 1)); ~ctl.set(7, y.linlin(-0.5, 0.5, 0, 1)); }; if (a >= 0.80) { ~ctl.set(8, x.linlin(-0.5, 0.5, 0, 1)); ~ctl.set(9, y.linlin(-0.5, 0.5, 0, 1)); }; } ); }; // ----- OSC Pad Vaues ----- // OSC responder for x coordinate OSCdef(\xOSC, { |msg, time, addr, port| var x = msg[1].asFloat; // Update current pad value and change effects ~currentPadValues.x = x; ~changeEffectParams.value; }, '/aspectX'); // OSC responder for y coordinate OSCdef(\yOSC, { |msg, time, addr, port| var y = msg[1].asFloat; // Update current pad value and change effects ~currentPadValues.y = y; ~changeEffectParams.value; }, '/aspectY'); // OSC responder for pressure coordinate OSCdef(\pressureOSC, { |msg, time, addr, port| var pressure = msg[1].asFloat; // Update current pad value and change effects ~currentPadValues.pressure = pressure; ~changeEffectParams.value; }, '/pressure'); // ----- OSC Pen Types ----- // OSC responder for pen OSCdef(\penOSC, { |msg, time, addr, port| var penType = msg[1].asFloat; if (penType == 1.0) { ~currentPenType = msg[0].asString; ["Current pen type:", ~currentPenType].postln; } }, '/pen'); // OSC responder for monoline OSCdef(\monolineOSC, { |msg, time, addr, port| var penType = msg[1].asFloat; if (penType == 1.0) { ~currentPenType = msg[0].asString; ["Current pen type:", ~currentPenType].postln; } }, '/monoline'); // OSC responder for marker OSCdef(\markerOSC, { |msg, time, addr, port| var penType = msg[1].asFloat; if (penType == 1.0) { ~currentPenType = msg[0].asString; ["Current pen type:", ~currentPenType].postln; } }, '/marker'); // OSC responder for pencil OSCdef(\pencilOSC, { |msg, time, addr, port| var penType = msg[1].asFloat; if (penType == 1.0) { ~currentPenType = msg[0].asString; ["Current pen type:", ~currentPenType].postln; } }, '/pencil'); // OSC responder for crayon OSCdef(\crayonOSC, { |msg, time, addr, port| var penType = msg[1].asFloat; if (penType == 1.0) { ~currentPenType = msg[0].asString; ["Current pen type:", ~currentPenType].postln; } }, '/crayon'); // OSC responder for fountainPen OSCdef(\fountainPenOSC, { |msg, time, addr, port| var penType = msg[1].asFloat; if (penType == 1.0) { ~currentPenType = msg[0].asString; ["Current pen type:", ~currentPenType].postln; } }, '/fountainPen'); // OSC responder for waterColor OSCdef(\waterColorOSC, { |msg, time, addr, port| var penType = msg[1].asFloat; if (penType == 1.0) { ~currentPenType = msg[0].asString; ["Current pen type:", ~currentPenType].postln; } }, '/waterColor'); // ----- OSC Drawing Width ----- OSCdef(\opacityOSC, { |msg, time, addr, port| var a = msg[1].asFloat; ~currentPadValues.a = a; }, '/a'); // ----- OSC RGB Colors ----- // OSC responder for red changes OSCdef(\redOSC, { |msg, time, addr, port| var component = msg[1].asFloat; // Update current color ~currentColor.r = component; ~setSynthsParam.(\redAmt, component); //["Color changed:", ~currentColor].postln; }, '/r'); // OSC responder for green changes OSCdef(\greenOSC, { |msg, time, addr, port| var component = msg[1].asFloat; // Update current color ~currentColor.g = component; ~setSynthsParam.(\greenAmt, component); //["Color changed:", ~currentColor].postln; }, '/g'); // OSC responder for blue changes OSCdef(\blueOSC, { |msg, time, addr, port| var component = msg[1].asFloat; // Update current color ~currentColor.b = component; ~setSynthsParam.(\blueAmt, component); //["Color changed:", ~currentColor].postln; }, '/b'); // Start the OSC server on port 57120 (default SuperCollider port) thisProcess.openUDPPort(57120); "OSC server ready on port 57120".postln; "Ready to receive data from iDraw OSC app".postln; )