浏览代码

removed s.sync in the test module

Farnoosh Rad 6 月之前
父节点
当前提交
77bcf2a387
共有 1 个文件被更改,包括 341 次插入114 次删除
  1. 341 114
      SC/6_test_functions.scd

+ 341 - 114
SC/6_test_functions.scd

@@ -1,163 +1,390 @@
+// Module 6: Test Functions & Effect Chain Setup - FIXED (No s.sync)
+// Save as "6_test_functions.scd" (REPLACE YOUR EXISTING VERSION)
+
 (
-// Function to start effects chain
+// Function to start effects chain - FIXED VERSION
 ~startEffectsChain = {
+    // Stop existing effects first
+    ~stopEffectsChain.value;
+    
+    "Starting effects chain...".postln;
+    
     // Create audio buses for effects chain
     ~sourceBus = Bus.audio(s, 2);
-    ~filterBus = Bus.audio(s, 2);
-    ~delayBus = Bus.audio(s, 2);
     ~reverbBus = Bus.audio(s, 2);
-
+    ~delayBus = Bus.audio(s, 2);
+    ~filterBus = Bus.audio(s, 2);
+    
     // Create control buses for modulation
     ~lfoControlBus = Bus.control(s, 1);
-
-    // Create effects synths in chain
-    ~lfoSynth = Synth(\lfoEffect, [
-        \out, ~lfoControlBus,
-        \freq, 1,
-        \min, 100,
-        \max, 5000,
-        \waveform, 0,
-        \target, 0
-    ]);
-
-    ~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);
-
-    // Create a mapping for the LFO to control the filter
-    s.sync;
-    ~lfoControlBus.asMap.postln;
-    ~filterSynth.map(\cutoff, ~lfoControlBus);
-
-    // Store the effects chain nodes in an array for easy access
-    ~effectsChain = [~lfoSynth, ~filterSynth, ~delaySynth, ~reverbSynth];
-
-    "Effects chain started with LFO mapping".postln;
+    
+    // Create effects synths in chain with error handling
+    try {
+        ~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);
+        
+        // Create LFO separately
+        ~lfoSynth = Synth(\lfoEffect, [
+            \out, ~lfoControlBus, 
+            \freq, 1, 
+            \min, 100, 
+            \max, 5000,
+            \waveform, 0
+        ]);
+        
+        // Schedule LFO mapping after a short delay (instead of s.sync)
+        SystemClock.sched(0.1, {
+            if(~filterSynth.notNil and: { ~lfoControlBus.notNil }, {
+                try {
+                    ~filterSynth.map(\cutoff, ~lfoControlBus);
+                    "LFO mapped to filter cutoff".postln;
+                } { |error|
+                    "Warning: Could not map LFO to filter: %".format(error).postln;
+                };
+            });
+            nil; // Don't reschedule
+        });
+        
+        // Store the effects chain nodes in an array for easy access
+        ~effectsChain = [~filterSynth, ~delaySynth, ~reverbSynth, ~lfoSynth];
+        
+        "Effects chain started successfully".postln;
+        "Chain includes: Filter -> Delay -> Reverb + LFO".postln;
+        
+    } { |error|
+        "Error starting effects chain: %".format(error).postln;
+        ~stopEffectsChain.value;
+    };
 };
+
 // Function to stop effects chain
 ~stopEffectsChain = {
     if(~effectsChain.notNil, {
-        ~effectsChain.do(_.free);
+        ~effectsChain.do({ |synth|
+            if(synth.notNil, {
+                try {
+                    synth.free;
+                } { |error|
+                    // Silent cleanup
+                };
+            });
+        });
         ~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;
+    
+    // Free individual synth references
+    [~filterSynth, ~delaySynth, ~reverbSynth, ~lfoSynth].do({ |synth|
+        if(synth.notNil, {
+            try {
+                synth.free;
+            } { |error|
+                // Silent cleanup
+            };
+        });
+    });
+    
+    ~filterSynth = nil;
+    ~delaySynth = nil;
+    ~reverbSynth = nil;
+    ~lfoSynth = nil;
+    
+    // Free buses
+    [~sourceBus, ~reverbBus, ~delayBus, ~filterBus, ~lfoControlBus].do({ |bus|
+        if(bus.notNil, {
+            try {
+                bus.free;
+            } { |error|
+                // Silent cleanup
+            };
+        });
+    });
+    
+    ~sourceBus = nil;
+    ~reverbBus = nil;
+    ~delayBus = nil;
+    ~filterBus = nil;
+    ~lfoControlBus = nil;
+    
+    "Effects chain stopped and cleaned up".postln;
 };
 
 // Function to reset the entire system
 ~resetSystem = {
+    // Stop all effects
     ~stopEffectsChain.value;
+    
+    // Clear OSC system if it exists
+    if(~cleanupOSCSystem.notNil, { 
+        try { ~cleanupOSCSystem.value; } { |error| };
+    });
+    
+    // Clear MIDI system if it exists
+    if(~cleanupAllMIDI.notNil, { 
+        try { ~cleanupAllMIDI.value; } { |error| };
+    });
+    
+    // Clear synth pool if it exists
+    if(~cleanupSynthPool.notNil, { 
+        try { ~cleanupSynthPool.value; } { |error| };
+    });
+    
+    // Clear all OSC definitions
     OSCdef.freeAll;
-
-    // Reload OSC definitions
-    thisProcess.interpreter.executeFile("5_osc_communication.scd");
-
+    
+    // Reset touch synths tracking
+    ~touchSynths = ();
+    
     "System reset complete".postln;
-	~touchSynths = ();  // Clear any active touch synths
-
+    
+    // Restart effects chain
+    SystemClock.sched(0.5, {
+        ~startEffectsChain.value;
+        nil;
+    });
 };
 
-// Test function for parameter changes
+// Test function for parameter changes - FIXED to not use problematic timing
 ~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 testParams = [
+        [\rgbSynth, 440, 0.2, -0.5, 0.05, 0.5],
+        [\rgbSynth, 330, 0.15, 0, 0.01, 0.8],
+        [\rgbSynth, 220, 0.1, 0.5, 0.1, 1.2],
+        [\rgbSynth, 550, 0.18, -0.2, 0.02, 0.7],
+        [\rgbSynth, 660, 0.15, 0.3, 0.05, 1.0]
+    ];
+    
+    testParams.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,
+            \out, ~sourceBus ? 0,
             \freq, freq,
             \amp, amp,
             \pan, pan,
-            \attack, attack,
-            \release, release
+            \ampAttack, attack,
+            \ampRelease, release,
+            \redAmt, ~synthParams.redAmt ? 0.5,
+            \greenAmt, ~synthParams.greenAmt ? 0.5,
+            \blueAmt, ~synthParams.blueAmt ? 0.5
         ]);
-
+        
         // 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));
-
+        if(~filterSynth.notNil, {
+            try {
+                ~filterSynth.set(\cutoff, 500 + (i * 1000));
+            } { |error| };
+        });
+        if(~delaySynth.notNil, {
+            try {
+                ~delaySynth.set(\mix, 0.2 + (i * 0.1));
+            } { |error| };
+        });
+        if(~reverbSynth.notNil, {
+            try {
+                ~reverbSynth.set(\room, 0.3 + (i * 0.1));
+            } { |error| };
+        });
+        
         // 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;
+// Test function that creates sounds with scheduled timing (safer approach)
+~testSequence = {
+    var sounds = [
+        [440, 0.2, 0.1, 1.0],
+        [330, 0.15, 0.2, 0.8],
+        [550, 0.18, 0.3, 0.7],
+        [660, 0.12, 0.4, 0.9],
+        [220, 0.25, 0.5, 1.2]
+    ];
+    
+    // Start effects chain if needed
+    if(~effectsChain.isNil, { ~startEffectsChain.value; });
+    
+    sounds.do { |params, i|
+        var freq, amp, delay, release;
+        #freq, amp, delay, release = params;
+        
+        // Schedule each sound with SystemClock (safer than Routine)
+        SystemClock.sched(delay * i, {
+            Synth(\rgbSynth, [
+                \out, ~sourceBus ? 0,
+                \freq, freq,
+                \amp, amp,
+                \ampRelease, release,
+                \redAmt, ~synthParams.redAmt ? 0.5,
+                \greenAmt, ~synthParams.greenAmt ? 0.5,
+                \blueAmt, ~synthParams.blueAmt ? 0.5
+            ]);
+            
+            ["Scheduled sound:", freq, amp].postln;
+            nil; // Don't reschedule
+        });
     };
-
-    "Touch simulation complete".postln;
+    
+    "Test sequence scheduled".postln;
 };
 
-// Run parameter test in a Routine
-~runParameterTest = {
-    Routine(~testParameters).play;
+// Function to simulate touch input safely
+~simulateTouch = { |count=5|
+    var touchCount = 0;
+    
+    "Simulating % touch events".format(count).postln;
+    
+    // Start the effects chain if needed
+    if(~effectsChain.isNil, { ~startEffectsChain.value; });
+    
+    // Schedule touch events
+    count.do { |i|
+        SystemClock.sched(i * 0.5, {
+            var x = (-0.5 + 1.0.rand);
+            var y = (-0.5 + 1.0.rand);
+            var pressure = 1 + 7.rand;
+            
+            // Update pad values
+            ~currentPadValues.x = x;
+            ~currentPadValues.y = y;
+            ~currentPadValues.pressure = pressure;
+            
+            // Trigger the change effect params function
+            if(~changeEffectParams.notNil, {
+                try {
+                    ~changeEffectParams.value;
+                } { |error|
+                    "Error in changeEffectParams: %".format(error).postln;
+                };
+            });
+            
+            // Trigger sound if using appropriate pen type
+            if(~smartTriggerSound.notNil, {
+                try {
+                    ~smartTriggerSound.value;
+                } { |error|
+                    "Error in smartTriggerSound: %".format(error).postln;
+                };
+            });
+            
+            touchCount = touchCount + 1;
+            ["Simulated touch #%: x=%, y=%, pressure=%".format(touchCount, x.round(0.01), y.round(0.01), pressure.round(0.01))].postln;
+            
+            nil; // Don't reschedule
+        });
+    };
+    
+    // Schedule completion message
+    SystemClock.sched(count * 0.5 + 1, {
+        "Touch simulation complete".postln;
+        nil;
+    });
 };
 
-// Run touch simulation in a Routine
-~runTouchSimulation = { |duration=5|
-    Routine({ ~simulateTouch.value(10, duration) }).play;
+// Memory monitoring function
+~checkMemory = {
+    var activeSynths = s.numSynths;
+    var activeGroups = s.numGroups;
+    
+    "=== Memory Status ===".postln;
+    "Active synths: %".format(activeSynths).postln;
+    "Active groups: %".format(activeGroups).postln;
+    
+    if(~midiNoteKeys.notNil, {
+        "Active MIDI notes: %".format(~midiNoteKeys.size).postln;
+    });
+    
+    if(~activeSynths.notNil, {
+        "Active pool synths: %".format(~activeSynths.size).postln;
+    });
+    
+    if(~effectsChain.notNil, {
+        "Effects chain active: true".postln;
+    }, {
+        "Effects chain active: false".postln;
+    });
+    
+    // Warning if too many synths
+    if(activeSynths > 50, {
+        "WARNING: High number of active synths (%). Consider running cleanup.".format(activeSynths).postln;
+    });
+    
+    "===================".postln;
 };
 
-"Test functions loaded".postln;
-)
+// Emergency cleanup function
+~emergencyCleanup = {
+    "EMERGENCY CLEANUP - Stopping all sounds".postln;
+    
+    // Free all synths on server
+    s.freeAll;
+    
+    // Clear all tracking dictionaries
+    if(~midiNoteKeys.notNil, { ~midiNoteKeys.clear; });
+    if(~activeSynths.notNil, { ~activeSynths.clear; });
+    if(~touchSynths.notNil, { ~touchSynths.clear; });
+    
+    // Clear buses and effects
+    ~stopEffectsChain.value;
+    
+    // Reset pool if it exists
+    if(~cleanupSynthPool.notNil, {
+        try {
+            ~cleanupSynthPool.value;
+        } { |error|
+            "Error during pool cleanup: %".format(error).postln;
+        };
+    });
+    
+    "Emergency cleanup complete".postln;
+    
+    // Wait a moment then restart effects
+    SystemClock.sched(1, {
+        ~startEffectsChain.value;
+        nil;
+    });
+};
 
+// Register emergency cleanup with Cmd+Period
+CmdPeriod.add({
+    ~emergencyCleanup.value;
+});
+
+"Test functions loaded with NO S.SYNC CALLS.".postln;
+"Available test functions:".postln;
+"  ~startEffectsChain.value      - Start the effects chain".postln;
+"  ~stopEffectsChain.value       - Stop the effects chain".postln;
+"  ~testParameters.value         - Test different synth parameters".postln;
+"  ~testSequence.value           - Test scheduled sound sequence".postln;
+"  ~simulateTouch.value(10)      - Simulate 10 touch events".postln;
+"  ~checkMemory.value            - Check current memory usage".postln;
+"  ~emergencyCleanup.value       - Emergency cleanup all sounds".postln;
+"  ~resetSystem.value            - Complete system reset".postln;
+)