From decb2dc0e9f1167d5cd8fb4d455305be6b9fdfbe Mon Sep 17 00:00:00 2001 From: Richard Date: Tue, 4 Oct 2022 00:17:55 +0100 Subject: initial --- sonics/instrument_gchord1.udo | 261 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100755 sonics/instrument_gchord1.udo (limited to 'sonics/instrument_gchord1.udo') diff --git a/sonics/instrument_gchord1.udo b/sonics/instrument_gchord1.udo new file mode 100755 index 0000000..314ea0a --- /dev/null +++ b/sonics/instrument_gchord1.udo @@ -0,0 +1,261 @@ +#ifndef UDO_FNMI_GCHORD1 +#define UDO_FNMI_GCHORD1 ## +/* + Portamento glitch-out textural chord player + Slim excerpt for Partial Emergence + + This file is part of the SONICS UDO collection by Richard Knight 2021 + License: GPL-2.0-or-later + http://1bpm.net +*/ +#include "sonics/wavetables.udo" +#include "sonics/sequencing_melodic_portamento.udo" +#include "sonics/sounddb.udo" +#include "sonics/frequency_tools.udo" +#include "sonics/uniqueid.udo" + +/* + sounddb glitchy chord player + aL, aR fnmi_gchord1 icollectionid, iattacktime, ireleasetime, icompressmode, kchangechance [, ipitchratio=1, ireadtype=0, ireloadtime=10] + aL, aR fnmi_gchord1 Scollection, iattacktime, ireleasetime, icompressmode, kchangechance [, ipitchratio=1, ireadtype=0, ireloadtime=10] + + aL, aR audio output + + icollectionid sounddb collection ID to use + Scollection sounddb collection name to use + iattacktime start fade in time + ireleasetime fade out time on host instrument note end + icompressmode 0 = none ; 1 = harshwall ; 2 = normal + kchangechance glitchy item change rate chance (1 = every quarter beat) + ipitchratio default pitch augmentation ratio + ireadtype 0 = sndwarp ; 1 = mincer + ireloadtime seconds between reloads of subinstruments to ensure variation in source sound +*/ + +opcode fnmi_gchord1, aa, iiiikpoj + icollectionid, iattacktime, ireleasetime, icompressmode, kchangechance, ipitchratio, ireadtype, ireloadtime xin + ilen = p3 + ireloadtime = (ireloadtime == -1) ? 10 : ireloadtime + instanceid = uniqueid() + + iusedinstruments[] uniqueinstrnums "_fnmi_gchord1_notehold", ftlen(gimel_freqs) + + ; set up notehold instruments + index = 0 + while (index < lenarray(iusedinstruments)) do + schedule iusedinstruments[index], 0, ilen, index, icollectionid, ireleasetime, instanceid, ipitchratio, ireadtype + index += 1 + od + + + ; reload random notehold instrument at periodic intervals (ie to change source sound) + klastchangetime init 0 + ktime timeinsts + if (ktime - klastchangetime > ireloadtime) then + kindex = round:k(random(0, lenarray(iusedinstruments)-1)) + kinstrument = iusedinstruments[kindex] + turnoff2 kinstrument, 4, 1 + schedulek kinstrument, ireleasetime*0.5, ilen-ktime, kindex, icollectionid, ireleasetime, instanceid, ipitchratio, ireadtype + klastchangetime = ktime + endif + + + ; if host instrument of opcode ends, turn off all notehold instances + kreleasing init 0 + if (release:k() == 1 && kreleasing == 0) then + kreleasing = 1 + kindex = 0 + while (kindex < lenarray(iusedinstruments)) do + turnoff2 iusedinstruments[kindex], 4, 1 + kindex += 1 + od + endif + + ; if at end of host instrument note length, add release time for relevant fade out + if (lastcycle:k() == 1) then + xtratim ireleasetime + endif + + + ; trigger for variations in individual notehold instruments + idivisions = 4 + as, aps syncphasor -(gkseq_beathz*idivisions), a(gkseq_beat) + ktrig trigger k(as), 0.1, 0 + chnset ktrig, sprintf("fnmi_gchord1_qtrig%d", instanceid) + + + ; 'global' change chance for the notehold instruments + kchangechance = 0.5 + chnset kchangechance, sprintf("fnmi_gchord1_changechance%d", instanceid) + + ; feed from the notehold instruments + aL, aR bus_read sprintf("fnmi_gchord1_out%d", instanceid) + + if (icompressmode == 1) then + acomp noise 0.2, 0.4 + aL balance aL, acomp + aR balance aL, acomp + elseif (icompressmode == 2) then + aL compress aL, aL, -5, 40, 40, 6, 0, 0.1, 0 + aR compress aR, aR, -5, 40, 40, 6, 0, 0.1, 0 + aL *= 30 + aR *= 30 + endif + + aL dcblock aL + aR dcblock aR + + + kamp linsegr 0, iattacktime, 1, ilen - iattacktime, 1, ireleasetime, 0 + + xout aL*kamp, aR*kamp +endop + +; overload for named collection +opcode fnmi_gchord1, aa, Siiikpoj + Scollection, iattacktime, ireleasetime, icompressmode, kchangechance, ipitchratio, ireadtype, ireloadtime xin + aL, aR fnmi_gchord1 sounddb_getcollectionid(Scollection), iattacktime, ireleasetime, icompressmode, kchangechance, ipitchratio, ireadtype, ireloadtime + xout aL, aR +endop + + + +/* + Used internally by fnmi_gchord1 for sound generation and return via channel +*/ +instr _fnmi_gchord1_notehold + index = p4 + icollectionid = p5 + ireleasetime = p6 + instanceid = p7 + iuserpitchratio = p8 + ireadtype = p9 + kamp table index, gimel_amps + + aL init 0 + aR init 0 + if (kamp > 0) then ; all processing + kamp *= 0.32 ;0.05 + kfreq table index, gimel_freqs + ibasenote random 30, 50 + ifileid, ipitchratio sounddb_mel_nearestnote icollectionid, ibasenote + ifn = gisounddb[ifileid][0] + + ipitchratio *= ((ireadtype == 0) ? (ftsr(ifn) / sr) : 1) * iuserpitchratio ; sr adjustment for sndwarp required + ilen = ftlen(ifn) / ftsr(ifn) + + ; pitch lfo + alfo oscil 2.5, 0.15, gifnSine + kfreq += k(alfo) + + kpitchratio = (kfreq / cpsmidinn(ibasenote)) * ipitchratio + + istart = random(0, 0.1) ;* ilen + iend = random(istart+0.1, 0.4) ; 0.9 + + kreadmode init 0 + + if (kreadmode == 0) then + atime = (abs(oscil(iend-istart, random(0.001, 0.1), gifnSine, random(0, 1)))) * ilen ; TODO: don't think + istart is required here + elseif (kreadmode == 1) then + atime = (istart * ilen) + ((phasor(random(2, 10)) * (ilen * (iend - istart)))) + else + atime = (istart * ilen) + ((phasor(-random(2, 10)) * (ilen * (iend - istart)))) + endif + + if (ireadtype == 0) then + aL, aR sndwarpst kamp, atime, interp(kpitchratio), ifn, istart, 441*random(1, 100), 44*random(1, 10), 8, gifnHalfSine, 1 + elseif (ireadtype == 1) then + aL, aR mincer atime, kamp, kpitchratio, ifn, 0 + endif + + kdo_crush init 0 + kdo_diff init 0 + kdo_delaytuner init 0 + kdo_ringmod init 0 + kdelmult init 8 + kcrushrange init 4 + kringmodmult init 2 + khpfreq init 150 + kpan init random(0, 1) + + if (kdo_crush == 1) then + kcrush = abs:k(oscil:k(kcrushrange, random(0.01, 0.3))) + kcrushrange + kcrushamount = abs:k(oscil:k(0.7, random(0.001, 0.2), gifnSaw, random(0, 1))) + aLbc, aRbc bitcrush aL, aR, kcrush + aL += aLbc * kcrushamount + aR += aRbc * kcrushamount + endif + + if (kdo_ringmod == 1) then + aL, aR ringmod1 aL, aR, kfreq*kringmodmult ;portk(kfreq*kringmodmult, 0.01) + endif + + if (kdo_delaytuner == 1) then + kdelaytuneramount = abs:k(oscil:k(0.5, random(0.001, 0.2), gifnSine, random(0, 1))) + aLdt, aRdt delaytuner aL, aR, max:k(1, kpitchratio)*kdelmult, 0.9 ; portk(kdelmult, 0.1) + aL += aLdt * kdelaytuneramount + aR += aRdt * kdelaytuneramount + endif + + aL butterhp aL, khpfreq + aR butterhp aR, khpfreq + + if (kdo_diff == 1) then + aL diff aL + endif + + ktrig = chnget:k(sprintf("fnmi_gchord1_qtrig%d", instanceid)) + kchangechance = chnget:k(sprintf("fnmi_gchord1_changechance%d", instanceid)) + + if (ktrig == 1 && random:k(0, 1) < kchangechance) then + if (random:k(0, 1) > 0.9) then + kreadmode = round:k(random:k(0, 2)) + endif + + if (random:k(0, 1) > 0.9) then + khpfreq = random:k(250, 2500) + endif + + if (random:k(0, 1) > 0.9) then + kdelmult = round:k(random:k(8, 16)) + endif + + if (random:k(0, 1) > 0.9) then + kcrushrange = round:k(random:k(2, 64)) + endif + + if (random:k(0, 1) > 0.95) then + kdo_crush = 1 - kdo_crush + endif + + if (random:k(0, 1) > 0.95) then + kdo_delaytuner = 1 - kdo_delaytuner + endif + + if (random:k(0, 1) > 0.95) then + kdo_ringmod = 1 - kdo_ringmod + endif + + if (random:k(0, 1) > 0.95) then + kringmodmult = pow:k(2, round:k(random:k(-1, 2))) ; 3 up to 8 + endif + + if (random:k(0, 1) > 0.9) then + kpan = random:k(0, 1) + endif + + if (random:k(0, 1) > 0.9) then + kdo_diff = 1 - kdo_diff + endif + endif + + aL *= kpan + aR *= (1-kpan) + endif ; if amp > 0 + + krelamp linsegr 1, p3, 1, ireleasetime, 0 + bus_mix(sprintf("fnmi_gchord1_out%d", instanceid), aL*krelamp, aR*krelamp) +endin + +#end -- cgit v1.2.3