diff options
Diffstat (limited to 'lib/Engine_Rhodes.sc')
-rw-r--r-- | lib/Engine_Rhodes.sc | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/lib/Engine_Rhodes.sc b/lib/Engine_Rhodes.sc new file mode 100644 index 0000000..02da1af --- /dev/null +++ b/lib/Engine_Rhodes.sc @@ -0,0 +1,75 @@ +// Adapted from https://sccode.org/1-522, which is adapted in +// turn from STK's 'rhodey', which is adapted from a TX81z +// algorithm. + +Engine_Rhodes : CroneEngine { + var <notes; + + *new { arg context, doneCallback; + ^super.new(context, doneCallback); + } + + *initClass { + // TODO store it as a classvar? + StartUp.add({ + SynthDef("Rhodes", + { + | // standard meanings + out = 0, freq = 440, gate = 1, pan = 0, amp = 0.1, + // all of these range from 0 to 1 + vel = 0.8, modIndex = 0.2, mix = 0.2, + lfoSpeed = 0.4, lfoDepth = 0.1 + | + var env1, env2, env3, env4; + var osc1, osc2, osc3, osc4, snd; + lfoSpeed = lfoSpeed * 12; + freq = freq * 2; + + env1 = EnvGen.ar(Env.adsr(0.001, 1.25, 0.0, 0.04, curve: \lin)); + env2 = EnvGen.ar(Env.adsr(0.001, 1.00, 0.0, 0.04, curve: \lin)); + env3 = EnvGen.ar(Env.adsr(0.001, 1.50, 0.0, 0.04, curve: \lin)); + env4 = EnvGen.ar(Env.adsr(0.001, 1.50, 0.0, 0.04, curve: \lin)); + + osc4 = SinOsc.ar(freq * 0.5) * 2pi * 2 * 0.535887 * modIndex * env4 * vel; + osc3 = SinOsc.ar(freq, osc4) * env3 * vel; + osc2 = SinOsc.ar(freq * 15) * 2pi * 0.108819 * env2 * vel; + osc1 = SinOsc.ar(freq, osc2) * env1 * vel; + snd = Mix((osc3 * (1 - mix)) + (osc1 * mix)); + snd = snd * (SinOsc.ar(lfoSpeed) * lfoDepth + 1); + + snd = snd * EnvGen.ar(Env.asr(0, 1, 0.2)); + snd = Pan2.ar(snd, pan, amp); + DetectSilence.ar(snd, doneAction: Done.freeSelf); + Out.ar(out, snd); + }).add; + }); + } + alloc { + notes = nil!128; + this.addCommand("note_on", "ii", { + arg msg; + var note = msg[1]; + var vel = msg[2]; + if(notes[note].isNil) { + notes[note] = Synth("Rhodes", + [ + \out, context.out_b, + \freq, note.midicps, + \vel, vel/127.0 + ], + target: context.xg); + } + }); + + this.addCommand("note_off", "f", { + arg msg; + var note = msg[1]; + if(notes[note].notNil) { + notes[note].release; + notes[note] = nil; + } + }); + } + free { + } +}
\ No newline at end of file |