Poly synth SC engine template
| // CroneEngine_PolyTemplate | |
| // | |
| // v1.0.0 Mark Eats | |
| Engine_PolyTemplate : CroneEngine { | |
| classvar maxNumVoices = 3; | |
| var voiceGroup; | |
| var voiceList; | |
| var pitchBendRatio = 1; | |
| var channelPressure = 0; | |
| var channelTimbre = 0; | |
| *new { arg context, doneCallback; | |
| ^super.new(context, doneCallback); | |
| } | |
| alloc { | |
| voiceGroup = Group.new(context.xg); | |
| voiceList = List.new(); | |
| // Synth voice | |
| SynthDef(\simpleSine, { | |
| arg out, freq = 440, pitchBendRatio = 1, gate = 0, killGate = 1, amp = 1; | |
| var signal, envelope, killEnvelope; | |
| killGate = killGate + Impulse.kr(0); // Make sure doneAction fires | |
| envelope = EnvGen.ar(envelope: Env.adsr( 0.01, 0.3, 0.3, 3.0), gate: gate, doneAction: Done.freeSelf); | |
| killEnvelope = EnvGen.ar(envelope: Env.asr( 0, 1, 0.01), gate: killGate, doneAction: Done.freeSelf); | |
| signal = SinOsc.ar(freq: freq * pitchBendRatio) * envelope * killEnvelope; | |
| Out.ar(out, signal.dup * 0.3 * amp); | |
| }).add; | |
| // Commands | |
| // noteOn(id, freq, vel) | |
| this.addCommand(\noteOn, "iff", { arg msg; | |
| var id = msg[1], freq = msg[2], vel = msg[3]; | |
| var voiceToRemove, newVoice; | |
| // Remove voice if ID matches or there are too many | |
| voiceToRemove = voiceList.detect{arg item; item.id == id}; | |
| if(voiceToRemove.isNil && (voiceList.size >= maxNumVoices), { | |
| voiceToRemove = voiceList.detect{arg v; v.gate == 0}; | |
| if(voiceToRemove.isNil, { | |
| voiceToRemove = voiceList.last; | |
| }); | |
| }); | |
| if(voiceToRemove.notNil, { | |
| voiceToRemove.theSynth.set(\killGate, 0); | |
| voiceList.remove(voiceToRemove); | |
| }); | |
| // Add new voice | |
| newVoice = (id: id, theSynth: Synth.new(defName: \simpleSine, args: [ | |
| \out, context.out_b, | |
| \freq, freq, | |
| \pitchBendRatio, pitchBendRatio, | |
| \gate, 1, | |
| \amp, vel.linlin(0, 1, 0.5, 1) | |
| ], target: voiceGroup).onFree({ voiceList.remove(newVoice); }), gate: 1); | |
| voiceList.addFirst(newVoice); | |
| }); | |
| // noteOff(id) | |
| this.addCommand(\noteOff, "i", { arg msg; | |
| var voice = voiceList.detect{arg v; v.id == msg[1]}; | |
| if(voice.notNil, { | |
| voice.theSynth.set(\gate, 0); | |
| voice.gate = 0; | |
| }); | |
| }); | |
| // noteOffAll() | |
| this.addCommand(\noteOffAll, "", { arg msg; | |
| voiceGroup.set(\gate, 0); | |
| voiceList.do({ arg v; v.gate = 0; }); | |
| }); | |
| // noteKill(id) | |
| this.addCommand(\noteKill, "i", { arg msg; | |
| var voice = voiceList.detect{arg v; v.id == msg[1]}; | |
| if(voice.notNil, { | |
| voice.theSynth.set(\killGate, 0); | |
| voiceList.remove(voice); | |
| }); | |
| }); | |
| // noteKillAll() | |
| this.addCommand(\noteKillAll, "", { arg msg; | |
| voiceGroup.set(\killGate, 0); | |
| voiceList.clear; | |
| }); | |
| // pitchBend(id, ratio) | |
| this.addCommand(\pitchBend, "if", { arg msg; | |
| var voice = voiceList.detect{arg v; v.id == msg[1]}; | |
| if(voice.notNil, { | |
| voice.theSynth.set(\pitchBendRatio, msg[2]); | |
| }); | |
| }); | |
| // pitchBendAll(ratio) | |
| this.addCommand(\pitchBendAll, "f", { arg msg; | |
| pitchBendRatio = msg[1]; | |
| voiceGroup.set(\pitchBendRatio, pitchBendRatio); | |
| }); | |
| // pressure(id, pressure) | |
| this.addCommand(\pressure, "if", { arg msg; | |
| var voice = voiceList.detect{arg v; v.id == msg[1]}; | |
| if(voice.notNil, { | |
| // voice.theSynth.set(\pressure, msg[2]); | |
| }); | |
| }); | |
| // pressureAll(pressure) | |
| this.addCommand(\pressureAll, "f", { arg msg; | |
| channelPressure = msg[1]; | |
| // voiceGroup.set(\pressure, channelPressure); | |
| }); | |
| // timbre(id, timbre) | |
| this.addCommand(\timbre, "if", { arg msg; | |
| var voice = voiceList.detect{arg v; v.id == msg[1]}; | |
| if(voice.notNil, { | |
| // voice.theSynth.set(\timbre, msg[2]); | |
| }); | |
| }); | |
| // timbreAll(timbre) | |
| this.addCommand(\timbreAll, "f", { arg msg; | |
| channelTimbre = msg[1]; | |
| // voiceGroup.set(\timbre, channelTimbre); | |
| }); | |
| } | |
| free { | |
| voiceGroup.free; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment