| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- // 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 - FIXED VERSION
- ~startEffectsChain = {
- // Stop existing effects first
- ~stopEffectsChain.value;
-
- "Starting effects chain...".postln;
-
- // Create audio buses for effects chain
- ~sourceBus = 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 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({ |synth|
- if(synth.notNil, {
- try {
- synth.free;
- } { |error|
- // Silent cleanup
- };
- });
- });
- ~effectsChain = nil;
- });
-
- // 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;
-
- // Reset touch synths tracking
- ~touchSynths = ();
-
- "System reset complete".postln;
-
- // Restart effects chain
- SystemClock.sched(0.5, {
- ~startEffectsChain.value;
- nil;
- });
- };
- // 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
- 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 ? 0,
- \freq, freq,
- \amp, amp,
- \pan, pan,
- \ampAttack, attack,
- \ampRelease, release,
- \redAmt, ~synthParams.redAmt ? 0.5,
- \greenAmt, ~synthParams.greenAmt ? 0.5,
- \blueAmt, ~synthParams.blueAmt ? 0.5
- ]);
-
- // Change effect parameters for demonstration
- 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;
- };
-
- "Parameter test complete".postln;
- };
- // 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
- });
- };
-
- "Test sequence scheduled".postln;
- };
- // 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;
- });
- };
- // 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;
- };
- // 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;
- )
|