//Oscillator
//Amplitude Follower
//Band-pass filter
//Input

SynthDef("vocoderPartial", {arg freq, gate=1;
	var in, amp, out, env;
	
	env = EnvGen.kr(Env.asr(0,1,0), gate, doneAction:2);  //a little envelope over the sound (also forces the synth to kill itself upon completion
	
	in = SoundIn.ar(0);  //the input
	
	in = BPF.ar(in, freq, 0.1);  //a band pass filter over the desired freq band
	
	amp = Amplitude.kr(in);  //the amplitude of the frequency band
	
	out = SinOsc.ar(freq, 0, amp);  //the output - a sine wave at the desired frequency
	
	Out.ar(0, out*env*0.1);  
}).load(s);

(
var freq, noteDictionary, numPartials, partialArray, note;

	noteDictionary = IdentityDictionary.new;  //the identity dictionary holds an array of partials for each note played

	numPartials = 7;

	r = NoteOnResponder({ |src,chan,note,vel|
			[src,chan,note,vel].postln;
		
			freq = note.midicps;  //convert the midi note to frequency
			
			partialArray = List.new;  //the list of partials
			
			//add the desired partials to the list of partions
			(1..numPartials).do{arg i;
				partialArray.add(Synth("vocoderPartial",[\freq, freq*i]));
			};	
			
			noteDictionary.put(note, partialArray);  //put the list of partials into the dictionary so we can kill it with a note off
		},
		nil, // any source
		nil, // any channel
		nil, // any note
		nil // any vel
	);

	t = NoteOffResponder({ |src,chan,note,vel|
			"off".postln;
			noteDictionary.at(note).do{arg item; item.postln; item.set(\gate, 0)};  //kill the partials of the note
			noteDictionary.put(note, nil);  //remove the note fromt the dictionary
		},
		nil,nil,nil,nil);

)

r.remove; t.remove;  //remove the responders when done