|
@@ -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 = {
|
|
~startEffectsChain = {
|
|
|
|
|
+ // Stop existing effects first
|
|
|
|
|
+ ~stopEffectsChain.value;
|
|
|
|
|
+
|
|
|
|
|
+ "Starting effects chain...".postln;
|
|
|
|
|
+
|
|
|
// Create audio buses for effects chain
|
|
// Create audio buses for effects chain
|
|
|
~sourceBus = Bus.audio(s, 2);
|
|
~sourceBus = Bus.audio(s, 2);
|
|
|
- ~filterBus = Bus.audio(s, 2);
|
|
|
|
|
- ~delayBus = Bus.audio(s, 2);
|
|
|
|
|
~reverbBus = Bus.audio(s, 2);
|
|
~reverbBus = Bus.audio(s, 2);
|
|
|
-
|
|
|
|
|
|
|
+ ~delayBus = Bus.audio(s, 2);
|
|
|
|
|
+ ~filterBus = Bus.audio(s, 2);
|
|
|
|
|
+
|
|
|
// Create control buses for modulation
|
|
// Create control buses for modulation
|
|
|
~lfoControlBus = Bus.control(s, 1);
|
|
~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
|
|
// Function to stop effects chain
|
|
|
~stopEffectsChain = {
|
|
~stopEffectsChain = {
|
|
|
if(~effectsChain.notNil, {
|
|
if(~effectsChain.notNil, {
|
|
|
- ~effectsChain.do(_.free);
|
|
|
|
|
|
|
+ ~effectsChain.do({ |synth|
|
|
|
|
|
+ if(synth.notNil, {
|
|
|
|
|
+ try {
|
|
|
|
|
+ synth.free;
|
|
|
|
|
+ } { |error|
|
|
|
|
|
+ // Silent cleanup
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
~effectsChain = nil;
|
|
~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
|
|
// Function to reset the entire system
|
|
|
~resetSystem = {
|
|
~resetSystem = {
|
|
|
|
|
+ // Stop all effects
|
|
|
~stopEffectsChain.value;
|
|
~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;
|
|
OSCdef.freeAll;
|
|
|
-
|
|
|
|
|
- // Reload OSC definitions
|
|
|
|
|
- thisProcess.interpreter.executeFile("5_osc_communication.scd");
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Reset touch synths tracking
|
|
|
|
|
+ ~touchSynths = ();
|
|
|
|
|
+
|
|
|
"System reset complete".postln;
|
|
"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 = {
|
|
~testParameters = {
|
|
|
// Start effects chain if not already running
|
|
// Start effects chain if not already running
|
|
|
if(~effectsChain.isNil, { ~startEffectsChain.value; });
|
|
if(~effectsChain.isNil, { ~startEffectsChain.value; });
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Test different oscillator types with varying parameters
|
|
// 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;
|
|
var synthType, freq, amp, pan, attack, release;
|
|
|
#synthType, freq, amp, pan, attack, release = params;
|
|
#synthType, freq, amp, pan, attack, release = params;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// Create the synth with the specified parameters
|
|
// Create the synth with the specified parameters
|
|
|
Synth(synthType, [
|
|
Synth(synthType, [
|
|
|
- \out, ~sourceBus,
|
|
|
|
|
|
|
+ \out, ~sourceBus ? 0,
|
|
|
\freq, freq,
|
|
\freq, freq,
|
|
|
\amp, amp,
|
|
\amp, amp,
|
|
|
\pan, pan,
|
|
\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
|
|
// 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
|
|
// Log the current sound
|
|
|
["Testing synth:", synthType, freq, amp].postln;
|
|
["Testing synth:", synthType, freq, amp].postln;
|
|
|
-
|
|
|
|
|
- // Wait between notes
|
|
|
|
|
- 0.8.wait;
|
|
|
|
|
};
|
|
};
|
|
|
-
|
|
|
|
|
- // Clean up
|
|
|
|
|
|
|
+
|
|
|
"Parameter test complete".postln;
|
|
"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;
|
|
|
|
|
+)
|