diff options
Diffstat (limited to 'examples/luamoog.csd')
-rw-r--r-- | examples/luamoog.csd | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/examples/luamoog.csd b/examples/luamoog.csd new file mode 100644 index 0000000..e20eb5e --- /dev/null +++ b/examples/luamoog.csd @@ -0,0 +1,264 @@ +<CsoundSynthesizer> +<CsInstruments> +sr = 48000 +ksmps = 100 +nchnls = 1 + + gibegan rtclock + + lua_opdef "moogladder", {{ +local ffi = require("ffi") +local math = require("math") +local string = require("string") +local csoundApi = ffi.load('csound64.dll.5.2') +ffi.cdef[[ + int csoundGetKsmps(void *); + double csoundGetSr(void *); + struct moogladder_t { + double *out; + double *inp; + double *freq; + double *res; + double *istor; + double sr; + double ksmps; + double thermal; + double f; + double fc; + double fc2; + double fc3; + double fcr; + double acr; + double tune; + double res4; + double input; + double i; + double j; + double k; + double kk; + double stg[6]; + double delay[6]; + double tanhstg[6]; + }; +]] + +local moogladder_ct = ffi.typeof('struct moogladder_t *') + +function moogladder_init(csound, opcode, carguments) + local p = ffi.cast(moogladder_ct, carguments) + p.sr = csoundApi.csoundGetSr(csound) + p.ksmps = csoundApi.csoundGetKsmps(csound) + if p.istor[0] == 0 then + for i = 0, 5 do + p.delay[i] = 0.0 + end + for i = 0, 3 do + p.tanhstg[i] = 0.0 + end + end + return 0 +end + +function moogladder_kontrol(csound, opcode, carguments) + local p = ffi.cast(moogladder_ct, carguments) + -- transistor thermal voltage + p.thermal = 1.0 / 40000.0 + if p.res[0] < 0.0 then + p.res[0] = 0.0 + end + -- sr is half the actual filter sampling rate + p.fc = p.freq[0] / p.sr + p.f = p.fc / 2.0 + p.fc2 = p.fc * p.fc + p.fc3 = p.fc2 * p.fc + -- frequency & amplitude correction + p.fcr = 1.873 * p.fc3 + 0.4955 * p.fc2 - 0.6490 * p.fc + 0.9988 + p.acr = -3.9364 * p.fc2 + 1.8409 * p.fc + 0.9968 + -- filter tuning + p.tune = (1.0 - math.exp(-(2.0 * math.pi * p.f * p.fcr))) / p.thermal + p.res4 = 4.0 * p.res[0] * p.acr + -- Nested 'for' loops crash, not sure why. + -- Local loop variables also are problematic. + -- Lower-level loop constructs don't crash. + p.i = 0 + while p.i < p.ksmps do + p.j = 0 + while p.j < 2 do + p.k = 0 + while p.k < 4 do + if p.k == 0 then + p.input = p.inp[p.i] - p.res4 * p.delay[5] + p.stg[p.k] = p.delay[p.k] + p.tune * (math.tanh(p.input * p.thermal) - p.tanhstg[p.k]) + else + p.input = p.stg[p.k - 1] + p.tanhstg[p.k - 1] = math.tanh(p.input * p.thermal) + if p.k < 3 then + p.kk = p.tanhstg[p.k] + else + p.kk = math.tanh(p.delay[p.k] * p.thermal) + end + p.stg[p.k] = p.delay[p.k] + p.tune * (p.tanhstg[p.k - 1] - p.kk) + end + p.delay[p.k] = p.stg[p.k] + p.k = p.k + 1 + end + -- 1/2-sample delay for phase compensation + p.delay[5] = (p.stg[3] + p.delay[4]) * 0.5 + p.delay[4] = p.stg[3] + p.j = p.j + 1 + end + p.out[p.i] = p.delay[5] + p.i = p.i + 1 + end + return 0 +end +}} + +/* +Moogladder - An improved implementation of the Moog ladder filter + +DESCRIPTION +This is an new digital implementation of the Moog ladder filter based on the work of Antti Huovilainen, +described in the paper \"Non-Linear Digital Implementation of the Moog Ladder Filter\" (Proceedings of DaFX04, Univ of Napoli). +This implementation is probably a more accurate digital representation of the original analogue filter. +This is version 2 (revised 14/DEC/04), with improved amplitude/resonance scaling and frequency correction using a couple of polynomials,as suggested by Antti. + +SYNTAX +ar Moogladder asig, kcf, kres + +PERFORMANCE +asig - input signal +kcf - cutoff frequency (Hz) +kres - resonance (0 - 1). + +CREDITS +Victor Lazzarini +*/ + + opcode moogladderu, a, akk +asig, kcf, kres xin + setksmps 1 +ipi = 4 * taninv(1) +/* filter delays */ +az1 init 0 +az2 init 0 +az3 init 0 +az4 init 0 +az5 init 0 +ay4 init 0 +amf init 0 + if kres > 1 then +kres = 1 + elseif kres < 0 then +kres = 0 + endif +/* twice the \'thermal voltage of a transistor\' */ +i2v = 40000 +/* sr is half the actual filter sampling rate */ +kfc = kcf/sr +kf = kcf/(sr*2) +/* frequency & amplitude correction */ +kfcr = 1.8730 * (kfc^3) + 0.4955 * (kfc^2) - 0.6490 * kfc + 0.9988 +kacr = -3.9364 * (kfc^2) + 1.8409 * kfc + 0.9968; +/* filter tuning */ +k2vg = i2v * (1 - exp(-2 * ipi * kfcr * kf)) +/* cascade of 4 1st order sections */ +ay1 = az1 + k2vg * (tanh((asig - 4 * kres * amf * kacr) / i2v) - tanh(az1 / i2v)) +az1 = ay1 +ay2 = az2 + k2vg * (tanh(ay1 / i2v) - tanh(az2 / i2v )) +az2 = ay2 +ay3 = az3 + k2vg * (tanh(ay2 / i2v) - tanh(az3 / i2v)) +az3 = ay3 +ay4 = az4 + k2vg * (tanh(ay3 / i2v) - tanh(az4 / i2v)) +az4 = ay4 +/* 1/2-sample delay for phase compensation */ +amf = (ay4 + az5) *0.5 +az5 = ay4 +/* oversampling */ +ay1 = az1 + k2vg * (tanh((asig - 4 * kres * amf * kacr) / i2v) - tanh(az1 / i2v)) +az1 = ay1 +ay2 = az2 + k2vg * (tanh(ay1 / i2v) - tanh(az2 / i2v )) +az2 = ay2 +ay3 = az3 + k2vg * (tanh(ay2 / i2v) - tanh(az3 / i2v)) +az3 = ay3 +ay4 = az4 + k2vg * (tanh(ay3 / i2v) - tanh(az4 / i2v)) +az4 = ay4 +amf = (ay4 + az5) * 0.5 +az5 = ay4 + xout amf + endop + +instr 1 + prints "No filter.\n" + kfe expseg 500, p3*0.9, 1800, p3*0.1, 3000 + kenv linen 10000, 0.05, p3, 0.05 + asig buzz kenv, 100, sr/(200), 1 + ; afil moogladder asig, kfe, 1 + out asig +endin + +instr 2 + prints "Native moogladder.\n" + kfe expseg 500, p3*0.9, 1800, p3*0.1, 3000 + kenv linen 10000, 0.05, p3, 0.05 + asig buzz kenv, 100, sr/(200), 1 + afil moogladder asig, kfe, 1 + out afil +endin + +instr 3 + prints "UDO moogladder.\n" + kfe expseg 500, p3*0.9, 1800, p3*0.1, 3000 + kenv linen 10000, 0.05, p3, 0.05 + asig buzz kenv, 100, sr/(200), 1 + afil moogladderu asig, kfe, 1 + out afil +endin + +instr 4 + prints "Lua moogladder.\n" + kres init 1 + istor init 0 + kfe expseg 500, p3*0.9, 1800, p3*0.1, 3000 + kenv linen 10000, 0.05, p3, 0.05 + asig buzz kenv, 100, sr/(200), 1 + afil init 0 + lua_ikopcall "moogladder", afil, asig, kfe, kres, istor + out afil +endin + +instr 5 + giended rtclock + ielapsed = giended - gibegan + print ielapsed + gibegan rtclock +endin + +</CsInstruments> + +<CsScore> +f 1 0 65536 10 1 +i 5.1 0 1 +i 4 1 20 +i 5.2 21 1 +i 4 22 20 +i 5.3 42 1 +i 2 43 20 +i 5.4 63 1 +i 2 64 20 +i 5.5 84 1 +i 3 85 20 +i 5.6 105 1 +i 3 106 20 +i 5.7 126 1 +i 1 127 20 +i 5.8 147 1 +i 1 148 20 +i 5.9 168 1 +i 4 169 20 +i 4 170 20 +i 4 171 20 +e +</CsScore> + +</CsoundSynthesizer> |