( // Function to start effects chain ~startEffectsChain = { // Create audio buses for effects chain ~sourceBus = Bus.audio(s, 2); ~reverbBus = Bus.audio(s, 2); ~delayBus = Bus.audio(s, 2); // Create effects synths in chain ~filterSynth = Synth(\lpf, [\in, ~sourceBus, \out, ~delayBus, \cutoff, 1000, \res, 0.5]); ~delaySynth = Synth(\delay, [\in, ~delayBus, \out, ~reverbBus, \delaytime, 0.4, \feedback, 0.3, \mix, 0.3], ~filterSynth, \addAfter); ~reverbSynth = Synth(\reverb, [\in, ~reverbBus, \out, 0, \mix, 0.2, \room, 0.5, \damp, 0.5], ~delaySynth, \addAfter); // Store the effects chain nodes in an array for easy access ~effectsChain = [~filterSynth, ~delaySynth, ~reverbSynth]; "Effects chain started".postln; }; // Function to stop effects chain ~stopEffectsChain = { if(~effectsChain.notNil, { ~effectsChain.do(_.free); ~effectsChain = nil; }); if(~sourceBus.notNil, { ~sourceBus.free; ~sourceBus = nil; }); if(~reverbBus.notNil, { ~reverbBus.free; ~reverbBus = nil; }); if(~delayBus.notNil, { ~delayBus.free; ~delayBus = nil; }); "Effects chain stopped".postln; }; // Function to reset the entire system ~resetSystem = { ~stopEffectsChain.value; OSCdef.freeAll; // Reload OSC definitions thisProcess.interpreter.executeFile("5_osc_communication.scd"); "System reset complete".postln; }; // Test function for parameter changes ~testParameters = { // Start effects chain if not already running if(~effectsChain.isNil, { ~startEffectsChain.value; }); // Test different oscillator types with varying parameters [ [\sineTone, 440, 0.3, -0.5, 0.05, 0.5], [\squareTone, 330, 0.2, 0, 0.01, 0.8], [\sawTone, 220, 0.15, 0.5, 0.1, 1.2], [\triTone, 550, 0.25, -0.2, 0.02, 0.7], [\fmTone, 660, 0.2, 0.3, 0.05, 1.0] ].do { |params, i| var synthType, freq, amp, pan, attack, release; #synthType, freq, amp, pan, attack, release = params; // Create the synth with the specified parameters Synth(synthType, [ \out, ~sourceBus, \freq, freq, \amp, amp, \pan, pan, \attack, attack, \release, release ]); // Change effect parameters for demonstration ~filterSynth.set(\cutoff, 500 + (i * 1000)); ~delaySynth.set(\mix, 0.2 + (i * 0.1)); ~reverbSynth.set(\room, 0.3 + (i * 0.1)); // Log the current sound ["Testing synth:", synthType, freq, amp].postln; // Wait between notes 0.8.wait; }; // Clean up "Parameter test complete".postln; }; // Function to simulate Arduino touch input ~simulateTouch = { |numTouches=10, duration=5| var endTime = SystemClock.seconds + duration; "Starting touch simulation for % seconds".format(duration).postln; // Start the effects chain ~startEffectsChain.value; // Generate random touches until the duration expires while { SystemClock.seconds < endTime } { var x = 1.0.rand; var y = 1.0.rand; var pressure = 0.3 + 0.7.rand; var color = 5.rand; // 0-4 for different synth types // Send the simulated touch data through our OSC handler OSCdef(\touchOSC).value(['/touch', x, y, pressure, color], nil, nil, nil); // Random wait time between touches (0.1 + 0.3.rand).wait; }; "Touch simulation complete".postln; }; // Run parameter test in a Routine ~runParameterTest = { Routine(~testParameters).play; }; // Run touch simulation in a Routine ~runTouchSimulation = { |duration=5| Routine({ ~simulateTouch.value(10, duration) }).play; }; "Test functions loaded".postln; )