Skip to content

Instantly share code, notes, and snippets.

@liquidcitizen

liquidcitizen/Engine_organ.sc Secret

Last active Jan 5, 2020
Embed
What would you like to do?
Engine_organ
// CroneEngine_organ
//
// Based on Engine_polytemplate v1.0.0 Mark Eats
// https://gist.github.com/markwheeler/b88b4f7b0f2870567b55cbc36abbd5ea
Engine_organX : CroneEngine {
classvar maxNumVoices = 8;
var voiceGroup;
var voiceList;
var pitchBendRatio = 1;
var channelPressure = 0;
var channelTimbre = 0;
var vrate = 3;
var amp = 0.7;
var bass = 1;
var quint = 1;
var fundamental = 1;
var oct = 1;
var nazard = 1;
var blockFlute = 1;
var tierce = 1;
var larigot = 1;
var sifflute = 1;
*new { arg context, doneCallback;
^super.new(context, doneCallback);
}
alloc {
voiceGroup = Group.new(context.xg);
voiceList = List.new();
// Synth voice
// based on Tonewheel1 from SynthDEFaults - A Collection of Tradicional SynthDefs- //under GNU GPL 3 as per SuperCollider license //Organized by Zé Craum
// http://sccode.org/1-5aD
SynthDef(\organ_tonewheel1, {
arg out, freq = 440, pitchBendRatio = 1, gate = 0, killGate = 1, amp = amp, atk = 0.001, dec = 0.1, sus = 0.2, rel = 0.01, pan = 0,
bass, quint, fundamental, oct, nazard, blockFlute, tierce, larigot, sifflute, //organ voices (drawbars) amplitudes
vrate, vdepth = 0.008, vdelay = 0.1, vonset = 0, vrateVariation = 0.1, vdepthVariation = 0.1; //vibrato arguments;
var signal, envelope, vibrato, killEnvelope;
killGate = killGate + Impulse.kr(0); // Make sure doneAction fires
envelope = EnvGen.ar(envelope: Env.adsr( atk, dec, sus, rel), gate: gate, doneAction: Done.freeSelf);
vibrato = Vibrato.kr(DC.kr(freq), DC.kr(vrate), DC.kr(vdepth), DC.kr(vdelay), DC.kr(vonset), DC.kr(vrateVariation), DC.kr(vdepthVariation));
killEnvelope = EnvGen.ar(envelope: Env.asr( 0, 1, 0.01), gate: killGate, doneAction: Done.freeSelf);
signal = DynKlang.ar(`[[-12, 7, 0, 12, 19, 24, 28, 31, 36].midiratio, ([DC.ar(bass) , DC.ar(quint), DC.ar(fundamental), DC.ar(oct), DC.ar(nazard), DC.ar(blockFlute), DC.ar(tierce), DC.ar(larigot), DC.ar(sifflute)].normalizeSum), nil], vibrato) * envelope * killEnvelope;
Out.ar(0, Pan2.ar(signal, pan, 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: \organ_tonewheel1, args: [
\out, context.out_b,
\freq, freq,
\pitchBendRatio, pitchBendRatio,
\bass, bass,
\quint, quint,
\fundamental, fundamental,
\oct, oct,
\nazard, nazard,
\blockFlute, blockFlute,
\tierce, tierce,
\larigot, larigot,
\sifflute, sifflute,
\vrate, vrate,
\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);
});
this.addCommand(\vrate, "f", { arg msg;
vrate = msg[1];
voiceGroup.set(\vrate, vrate);
});
this.addCommand(\amp, "f", { arg msg;
amp = msg[1];
voiceGroup.set(\amp, amp);
});
this.addCommand(\bass, "f", { arg msg;
bass = msg[1];
voiceGroup.set(\bass, bass);
});
this.addCommand(\quint, "f", { arg msg;
quint = msg[1];
voiceGroup.set(\quint, quint);
});
this.addCommand(\fundamental, "f", { arg msg;
fundamental = msg[1];
voiceGroup.set(\fundamental, fundamental);
});
this.addCommand(\oct, "f", { arg msg;
oct = msg[1];
voiceGroup.set(\oct, oct);
});
this.addCommand(\nazard, "f", { arg msg;
nazard = msg[1];
voiceGroup.set(\nazard, nazard);
});
this.addCommand(\blockFlute, "f", { arg msg;
blockFlute = msg[1];
voiceGroup.set(\blockFlute, blockFlute);
});
this.addCommand(\tierce, "f", { arg msg;
tierce = msg[1];
voiceGroup.set(\tierce, tierce);
});
this.addCommand(\larigot, "f", { arg msg;
larigot = msg[1];
voiceGroup.set(\larigot, larigot);
});
this.addCommand(\sifflute, "f", { arg msg;
sifflute = msg[1];
voiceGroup.set(\sifflute, sifflute);
});
}
free {
voiceGroup.free;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment