aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgretchen <gretchen@gnar.cool>2019-11-18 22:47:46 -0800
committergretchen <gretchen@gnar.cool>2019-11-18 22:47:46 -0800
commitadb657e192e3396cd06de9da50e08d29d60b26d2 (patch)
tree8233c9239a6e27560b4853ef7bcf2f37b01976fd
downloadrhodes-adb657e192e3396cd06de9da50e08d29d60b26d2.tar.gz
rhodes-adb657e192e3396cd06de9da50e08d29d60b26d2.zip
fm rhodes for nornsv0.1
-rw-r--r--Makefile9
-rw-r--r--README.org7
-rw-r--r--lib/Engine_Rhodes.sc75
-rw-r--r--rhodes.lua28
4 files changed, 119 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..874f48e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+
+all:
+
+upload: rhodes.lua lib/Engine_Rhodes.sc
+ find . -not -path '*/\.*' -type f | xargs -P 5 -n 1 norns_upload gretchen/rhodes
+ norns_load gretchen/rhodes rhodes.lua
+
+.PHONY: all upload
+
diff --git a/README.org b/README.org
new file mode 100644
index 0000000..d385e1b
--- /dev/null
+++ b/README.org
@@ -0,0 +1,7 @@
+* rhodes
+
+FM rhodes simulation for norns.
+
+Adapted for norns from [[https://sccode.org/1-522][this supercollider snippet]] by user 'snapizz', which is adapted from [[https://github.com/thestk/stk/blob/master/include/Rhodey.h][STK's rhodey]], which Perry R. Cook and Gary P. Scavone adapted from a Yamaha TX81z algorithm.
+
+Needs some visualization, and some parameters (tremolo and vibrato? chorus? brightness?). Email patches to [[mailto:gretchen@gnar.cool][<gretchen@gnar.cool>]].
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
diff --git a/rhodes.lua b/rhodes.lua
new file mode 100644
index 0000000..d9a1ee1
--- /dev/null
+++ b/rhodes.lua
@@ -0,0 +1,28 @@
+engine.name = "Rhodes"
+
+local MusicUtil = require "musicutil"
+
+function redraw()
+ screen.clear()
+ screen.move(64, 32)
+ screen.text_center("rhodes.")
+ screen.update()
+end
+
+function init ()
+ redraw()
+ m = midi.connect(1)
+ m.event = function (a)
+ b = midi.to_msg(a)
+ if b.type == "note_on" then
+ engine.note_on(b.note, b.vel or 60)
+ elseif b.type == "note_off" then
+ engine.note_off(b.note)
+ end
+ end
+end
+
+
+-- Local Variables:
+-- compile-command: "make upload"
+-- End: