Procházet zdrojové kódy

first commit for supercolider part

Farnoosh Rad před 7 měsíci
revize
db70dadffe

+ 15 - 0
1_environment_setup.scd

@@ -0,0 +1,15 @@
+// Basic environment setup
+s = Server.local;
+s.boot;
+
+// Test server connection
+s.doWhenBooted({
+    "SuperCollider server ready!".postln;
+
+    // Test simple sine wave
+    {
+        var sig = SinOsc.ar(440, 0, 0.5);
+        sig = sig * EnvGen.kr(Env.perc(0.01, 1), doneAction: 2);
+        sig!2
+    }.play;
+});

+ 45 - 0
2_oscillator_synthdefs.scd

@@ -0,0 +1,45 @@
+// Basic oscillator SynthDefs
+(
+// Pure sine tone
+SynthDef(\sineTone, { |out=0, freq=440, amp=0.1, pan=0, attack=0.01, release=1|
+    var sig, env;
+    env = EnvGen.kr(Env.perc(attack, release), doneAction: 2);
+    sig = SinOsc.ar(freq) * env * amp;
+    Out.ar(out, Pan2.ar(sig, pan));
+}).add;
+
+// Square wave tone
+SynthDef(\squareTone, { |out=0, freq=440, amp=0.1, pan=0, attack=0.01, release=1, width=0.5|
+    var sig, env;
+    env = EnvGen.kr(Env.perc(attack, release), doneAction: 2);
+    sig = Pulse.ar(freq, width) * env * amp;
+    Out.ar(out, Pan2.ar(sig, pan));
+}).add;
+
+// Sawtooth wave tone
+SynthDef(\sawTone, { |out=0, freq=440, amp=0.1, pan=0, attack=0.01, release=1|
+    var sig, env;
+    env = EnvGen.kr(Env.perc(attack, release), doneAction: 2);
+    sig = Saw.ar(freq) * env * amp;
+    Out.ar(out, Pan2.ar(sig, pan));
+}).add;
+
+// Triangle wave tone
+SynthDef(\triTone, { |out=0, freq=440, amp=0.1, pan=0, attack=0.01, release=1|
+    var sig, env;
+    env = EnvGen.kr(Env.perc(attack, release), doneAction: 2);
+    sig = LFTri.ar(freq) * env * amp;
+    Out.ar(out, Pan2.ar(sig, pan));
+}).add;
+
+// FM synthesis tone
+SynthDef(\fmTone, { |out=0, freq=440, amp=0.1, pan=0, attack=0.01, release=1, modRatio=2, modAmt=0.5|
+    var sig, env, mod;
+    env = EnvGen.kr(Env.perc(attack, release), doneAction: 2);
+    mod = SinOsc.ar(freq * modRatio, 0, freq * modAmt);
+    sig = SinOsc.ar(freq + mod) * env * amp;
+    Out.ar(out, Pan2.ar(sig, pan));
+}).add;
+
+"Oscillator SynthDefs loaded".postln;
+)

+ 44 - 0
3_effects_synthdefs.scd

@@ -0,0 +1,44 @@
+(
+// Simple reverb effect
+SynthDef(\reverb, { |in=0, out=0, mix=0.3, room=0.5, damp=0.5|
+    var sig, wet;
+    sig = In.ar(in, 2);
+    wet = FreeVerb.ar(sig, mix, room, damp);
+    Out.ar(out, wet);
+}).add;
+
+// Delay effect with feedback
+SynthDef(\delay, { |in=0, out=0, delaytime=0.5, feedback=0.5, mix=0.5|
+    var sig, wet, delayed;
+    sig = In.ar(in, 2);
+    delayed = CombL.ar(sig, 2.0, delaytime, feedback * 3);
+    wet = (sig * (1 - mix)) + (delayed * mix);
+    Out.ar(out, wet);
+}).add;
+
+// Low-pass filter effect
+SynthDef(\lpf, { |in=0, out=0, cutoff=1000, res=0.5|
+    var sig;
+    sig = In.ar(in, 2);
+    sig = RLPF.ar(sig, cutoff, res);
+    Out.ar(out, sig);
+}).add;
+
+// High-pass filter effect
+SynthDef(\hpf, { |in=0, out=0, cutoff=1000, res=0.5|
+    var sig;
+    sig = In.ar(in, 2);
+    sig = RHPF.ar(sig, cutoff, res);
+    Out.ar(out, sig);
+}).add;
+
+// Distortion effect
+SynthDef(\distortion, { |in=0, out=0, amount=0.5, mix=0.5|
+    var sig, dist;
+    sig = In.ar(in, 2);
+    dist = (sig * amount).tanh;
+    Out.ar(out, (sig * (1 - mix)) + (dist * mix));
+}).add;
+
+"Effects SynthDefs loaded".postln;
+)

+ 38 - 0
4_modulation_synthdefs.scd

@@ -0,0 +1,38 @@
+(
+// Low Frequency Oscillator for parameter modulation
+SynthDef(\lfo, { |out=0, freq=1, min=0, max=1, waveform=0|
+    var lfo;
+
+    // Select waveform based on parameter
+    lfo = Select.kr(waveform, [
+        SinOsc.kr(freq),        // Sine wave (waveform=0)
+        LFTri.kr(freq),         // Triangle wave (waveform=1)
+        LFSaw.kr(freq),         // Sawtooth wave (waveform=2)
+        LFPulse.kr(freq, 0, 0.5) // Square wave (waveform=3)
+    ]);
+
+    // Scale to range
+    lfo = lfo.range(min, max);
+
+    // Output to control bus
+    Out.kr(out, lfo);
+}).add;
+
+// ADSR envelope generator
+SynthDef(\envelope, { |out=0, gate=1, attack=0.01, decay=0.3, sustain=0.5, release=1|
+    var env = EnvGen.kr(
+        Env.adsr(attack, decay, sustain, release),
+        gate,
+        doneAction: 2
+    );
+    Out.kr(out, env);
+}).add;
+
+// Random value generator with controllable rate
+SynthDef(\randomGen, { |out=0, freq=1, min=0, max=1|
+    var rand = LFNoise2.kr(freq).range(min, max);
+    Out.kr(out, rand);
+}).add;
+
+"Modulation SynthDefs loaded".postln;
+)

+ 75 - 0
5_osc_communication.scd

@@ -0,0 +1,75 @@
+(
+// Clear any existing OSC definitions
+OSCdef.freeAll;
+
+// Define OSC responder for touch events
+OSCdef(\touchOSC, { |msg, time, addr, port|
+    var x = msg[1], y = msg[2], pressure = msg[3], color = msg[4];
+
+    // Map x, y coordinates to frequency and amplitude
+    var freq = x.linexp(0, 1, 100, 2000);
+    var amp = pressure.linlin(0, 1, 0.1, 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
+    );
+
+    // 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)
+    ]);
+
+    // Log the received data
+    ["Touch data:", x, y, pressure, color, "->", synthType, freq, amp].postln;
+}, '/touch');
+
+// OSC responder for control messages
+OSCdef(\controlOSC, { |msg, time, addr, port|
+    var control = msg[1].asSymbol, value = msg[2];
+
+    // Log the control change
+    ["Control change:", 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); }
+    );
+}, '/control');
+
+// OSC responder for system commands
+OSCdef(\systemOSC, { |msg, time, addr, port|
+    var command = msg[1].asSymbol;
+
+    ["System command:", command].postln;
+
+    switch(command,
+        \start_effects, { ~startEffectsChain.value; },
+        \stop_effects, { ~stopEffectsChain.value; },
+        \reset, { ~resetSystem.value; }
+    );
+}, '/system');
+
+// 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;
+)

+ 125 - 0
6_test_functions.scd

@@ -0,0 +1,125 @@
+(
+// 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;
+)
+

+ 14 - 0
main.scd

@@ -0,0 +1,14 @@
+// Initialize the system
+(
+s.waitForBoot({
+    "Initializing Interactive Sound Canvas...".postln;
+
+    // Start effects chain
+    ~startEffectsChain.value;
+
+    // System is ready for input
+    "System ready! Touch data can now be received via OSC.".postln;
+    "To test the system, run: ~runParameterTest.value".postln;
+    "To simulate touch input, run: ~runTouchSimulation.value(10)".postln;
+});
+)