Farnoosh Rad 6 ay önce
ebeveyn
işleme
f8eb77bb62
2 değiştirilmiş dosya ile 53 ekleme ve 29 silme
  1. 24 14
      SC/2b_rgb_synthdefs.scd
  2. 29 15
      SC/9_midi_controller.scd

+ 24 - 14
SC/2b_rgb_synthdefs.scd

@@ -1,22 +1,34 @@
+// Module 2b: RGB-controlled synthesizer - FIXED VERSION
+// Save as "2b_rgb_synthdefs.scd" (REPLACE YOUR EXISTING VERSION)
+
 (
-// RGB-controlled synthesizer with amplitude envelope
-SynthDef(\rgbSynth, { |out=0, freq=440, amp=0.5, ampAttack=0.01, ampRelease=1,
+// RGB-controlled synthesizer with proper gate handling
+SynthDef(\rgbSynth, { |out=0, freq=440, amp=0.5, gate=1,
+	ampAttack=0.01, ampRelease=1,
 	filterAttack=0, filterRelease=0, filterMin=200, filterMax=5000,
 	pitchAttack=0, pitchRelease=0, pitchRatio=2,
 	redAmt=0.5, greenAmt=0.5, blueAmt=0.5|
 
-    var env, gate, filterEnv, pitchEnv, red, green, blue, sig;
-
-	gate = \gate.kr(1);
+    var ampEnv, filterEnv, pitchEnv, red, green, blue, sig;
 
-    // Amplitude envelope
-    env = EnvGen.kr(Env.adsr(ampAttack, 0, 1, ampRelease), gate, doneAction: 2);
+    // Amplitude envelope - CRITICAL: This must respond to gate
+    ampEnv = EnvGen.kr(
+        Env.adsr(ampAttack, 0.1, 0.8, ampRelease), 
+        gate, 
+        doneAction: 2  // Free the synth when envelope finishes
+    );
 
     // Filter envelope
-    filterEnv = EnvGen.kr(Env.adsr(filterAttack, 0, 1, filterRelease), gate);
+    filterEnv = EnvGen.kr(
+        Env.adsr(filterAttack, 0.1, 0.8, filterRelease), 
+        gate
+    );
 
     // Pitch envelope
-    pitchEnv = EnvGen.kr(Env.adsr(pitchAttack, 0, 1, pitchRelease), gate);
+    pitchEnv = EnvGen.kr(
+        Env.adsr(pitchAttack, 0.1, 0.8, pitchRelease), 
+        gate
+    );
 
     // Calculate modulated frequency
     freq = freq * (1 + (pitchEnv * (pitchRatio - 1)));
@@ -32,12 +44,10 @@ SynthDef(\rgbSynth, { |out=0, freq=440, amp=0.5, ampAttack=0.01, ampRelease=1,
     // Apply filter with envelope control
     sig = RLPF.ar(sig, filterEnv.linexp(0, 1, filterMin, filterMax), 0.8);
 
-    // Apply envelope and output
-    sig = sig * env * amp;
+    // Apply amplitude envelope and output
+    sig = sig * ampEnv * amp;
     Out.ar(out, sig!2);
 }).add;
 
-
-
-"RGB-controlled synthesizer loaded".postln;
+"RGB-controlled synthesizer loaded with proper gate handling".postln;
 )

+ 29 - 15
SC/9_midi_controller.scd

@@ -1,4 +1,4 @@
-// Module 9: MIDI Controller - Modified to use Synth Pool
+// Module 9: MIDI Controller - FIXED VERSION
 // Save as "9_midi_controller.scd" (REPLACE YOUR EXISTING VERSION)
 
 (
@@ -20,25 +20,33 @@ MIDIdef.noteOn(\noteOn, { |vel, num, chan, src|
     if (vel > 0) {
 		// Check if note is already playing and release it first
 		if(~midiNoteKeys[num].notNil, {
-			~returnSynthToPool.value(~midiNoteKeys[num]);
+			if(~returnSynthToPool.notNil, {
+				~returnSynthToPool.value(~midiNoteKeys[num]);
+			});
 			~midiNoteKeys.removeAt(num);
 		});
 		
 		// Get a synth from the pool instead of creating new one
-		var synth = ~startPoolSynth.value(noteKey, freq, amp);
-		
-		if(synth.notNil, {
-			// Track this note
-			~midiNoteKeys[num] = noteKey;
-			// Uncomment for debugging: ["MIDI Note ON: % - Got synth from pool".format(num)].postln;
+		if(~startPoolSynth.notNil, {
+			var synth = ~startPoolSynth.value(noteKey, freq, amp);
+			
+			if(synth.notNil, {
+				// Track this note
+				~midiNoteKeys[num] = noteKey;
+				// Uncomment for debugging: ["MIDI Note ON: % - Got synth from pool".format(num)].postln;
+			}, {
+				["MIDI Note ON: % - No free synths available!".format(num)].postln;
+			});
 		}, {
-			["MIDI Note ON: % - No free synths available!".format(num)].postln;
+			"ERROR: Synth pool not initialized! Run ~initializeSynthPool.value first".postln;
 		});
 
     } { 
 		// Treat as noteOff if it is a noteOn with velocity 0
 		if(~midiNoteKeys[num].notNil, {
-			~returnSynthToPool.value(~midiNoteKeys[num]);
+			if(~returnSynthToPool.notNil, {
+				~returnSynthToPool.value(~midiNoteKeys[num]);
+			});
 			~midiNoteKeys.removeAt(num);
 			// Uncomment for debugging: ["MIDI Note OFF: % (vel 0)".format(num)].postln;
 		});
@@ -48,7 +56,9 @@ MIDIdef.noteOn(\noteOn, { |vel, num, chan, src|
 // Note Off: return synth to pool instead of setting gate
 MIDIdef.noteOff(\noteOff, { |vel, num, chan, src|
 	if(~midiNoteKeys[num].notNil, {
-		~returnSynthToPool.value(~midiNoteKeys[num]);
+		if(~returnSynthToPool.notNil, {
+			~returnSynthToPool.value(~midiNoteKeys[num]);
+		});
 		~midiNoteKeys.removeAt(num);
 		// Uncomment for debugging: ["MIDI Note OFF: %".format(num)].postln;
 	});
@@ -57,8 +67,10 @@ MIDIdef.noteOff(\noteOff, { |vel, num, chan, src|
 // All Notes Off (MIDI Panic) - return all MIDI synths to pool
 MIDIdef.cc(\allNotesOff, { |val, num, chan, src|
 	if(num == 123, {  // All Notes Off CC
-		~midiNoteKeys.keysValuesDo({ |noteNum, noteKey|
-			~returnSynthToPool.value(noteKey);
+		if(~returnSynthToPool.notNil, {
+			~midiNoteKeys.keysValuesDo({ |noteNum, noteKey|
+				~returnSynthToPool.value(noteKey);
+			});
 		});
 		~midiNoteKeys.clear;
 		"MIDI: All notes off - All synths returned to pool".postln;
@@ -67,8 +79,10 @@ MIDIdef.cc(\allNotesOff, { |val, num, chan, src|
 
 // Cleanup all MIDI synths function
 ~cleanupAllMIDI = {
-	~midiNoteKeys.keysValuesDo({ |noteNum, noteKey|
-		~returnSynthToPool.value(noteKey);
+	if(~returnSynthToPool.notNil, {
+		~midiNoteKeys.keysValuesDo({ |noteNum, noteKey|
+			~returnSynthToPool.value(noteKey);
+		});
 	});
 	~midiNoteKeys.clear;
 	"All MIDI synths returned to pool".postln;