aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-05-21 21:44:23 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-05-21 21:44:23 +0300
commit9cb11fff02c23ea8c6cc337fbc4d763153bf74ae (patch)
treea4b72a5c1d3f74fdaa8d3573eabafc9213a18380
parentdb3a945c7d4a618a4fcf959571933a498820f772 (diff)
downloadapplause2-9cb11fff02c23ea8c6cc337fbc4d763153bf74ae.tar.gz
added the Sheppard-Rice-Glissando example: this can also be run in batch mode
-rw-r--r--examples/shepard.lua52
1 files changed, 52 insertions, 0 deletions
diff --git a/examples/shepard.lua b/examples/shepard.lua
new file mode 100644
index 0000000..06958d0
--- /dev/null
+++ b/examples/shepard.lua
@@ -0,0 +1,52 @@
+--
+-- adapted from ChucK's shepard.ck (Ge Wang, 2016)
+--
+local min, max, exp = math.min, math.max, math.exp
+
+local function dbtorms(f)
+ f = min(max(f, 0), 485)
+ return exp((2.302585092994 * 0.05) * (f-100))
+end
+
+local SQRT_PI2 = math.sqrt(2*math.pi)
+local function gauss(x, mu, sd)
+ return (1.0 / (sd*SQRT_PI2)) * exp(-(x-mu)^2 / (2*sd^2))
+end
+
+-- built-in mtof() caches all 128 MIDI notes
+local function mtof_raw(note)
+ return 440 * 2^((note - 69)/12)
+end
+
+-- mean for normal intensity curve
+local MU = 66
+-- standard deviation for normal intensity curve
+local SIGMA = 42
+-- normalize to 1.0 at x==MU
+local SCALE = 1 / gauss(MU, MU, SIGMA)
+-- increment per sample (use negative for descending)
+--local INC = tostream(.004 / msec(1))
+local INC = EvdevStream("TrackPoint"):evrel('REL_X'):scale(-0.008, 0.008):div(msec(1)):cache()
+
+-- starting pitches (in MIDI note numbers, octaves apart)
+local pitches = {12, 24, 36, 48, 60, 72, 84, 96, 108}
+
+local function mtoamp(note)
+ -- compute loundess for each tone
+ local intensity = gauss(note, MU, SIGMA)*SCALE
+ -- map intensity to amplitude
+ return dbtorms(intensity*96)
+end
+
+tostream(pitches):map(function(m)
+ local tone = INC:scan(function(last, inc)
+ local next = (last or m)+inc
+ if next > 120 then
+ next = next - 108
+ elseif next < 12 then
+ next = next + 108
+ end
+ return next
+ end):cache()
+ return tone:map(mtof_raw):TriOsc() * tone:map(mtoamp)
+end):fold(function(a, b) return a+b end):ravel():gain(1/#pitches):play()