From 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Apr 2025 18:48:02 +0100 Subject: initial --- site/udo/twist/transform_api.udo | 421 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100755 site/udo/twist/transform_api.udo (limited to 'site/udo/twist/transform_api.udo') diff --git a/site/udo/twist/transform_api.udo b/site/udo/twist/transform_api.udo new file mode 100755 index 0000000..9b916e3 --- /dev/null +++ b/site/udo/twist/transform_api.udo @@ -0,0 +1,421 @@ +#ifndef UDO_TWIST_TRANSFORMAPI +#define UDO_TWIST_TRANSFORMAPI ## + +#define TWST_TRANSFORM #i_ = p4# + +opcode twst_param, k, S + Sname xin + Schannel = sprintf("%s_%s%d", nstrstr(p1), Sname, p4) + kvalue chnget Schannel + xout kvalue +endop + +opcode twst_parami, i, S + Sname xin + Schannel = sprintf("%s_%s%d", nstrstr(p1), Sname, p4) + ivalue chnget Schannel + xout ivalue +endop + +opcode twst_getinput, aaii, 0 + aL chnget "twstfeedL" + aR chnget "twstfeedR" + xout aL, aR, gitwst_tf_state[0], gitwst_tf_state[1] +endop + +opcode twst_setlatencysamples, 0, i + isamples xin + gitwst_tf_state[5] = isamples +endop + +opcode twst_setlatencyseconds, 0, i + iseconds xin + twst_setlatencysamples iseconds * sr +endop + +opcode twst_getlatencyseconds, i, 0 + xout gitwst_tf_state[5] / sr +endop + +opcode twst_tf_pitchscale_custom, k, S + SchanPrepend xin + if (twst_param:k(strcat(SchanPrepend, "pitchscalemode")) == 1) then + ksemitones = twst_param:k(strcat(SchanPrepend, "pitchsemitones")) + kscale = pow:k(2, ksemitones / 12) + else + kscale = twst_param:k(strcat(SchanPrepend, "pitchscale")) + endif + xout kscale +endop + +opcode twst_tf_pitchscale, k, 0 + xout twst_tf_pitchscale_custom("") +endop + +opcode twst_tf_freq_custom, k, S + SchanPrepend xin + if (twst_param:k(strcat(SchanPrepend, "freqmode")) == 1) then + kfreq = cpsmidinn:k(twst_param:k(strcat(SchanPrepend, "note"))) + else + kfreq = twst_param:k(strcat(SchanPrepend, "freq")) + endif + xout kfreq +endop + +opcode twst_tf_freq, k, 0 + xout twst_tf_freq_custom("") +endop + +opcode twst_tf_freqi_custom, i, S + SchanPrepend xin + if (twst_parami(strcat(SchanPrepend, "freqmode")) == 1) then + ifreq = cpsmidinn:i(twst_parami(strcat(SchanPrepend,"note"))) + else + ifreq = twst_parami(strcat(SchanPrepend,"freq")) + endif + xout ifreq +endop + +opcode twst_tf_freqi, i, 0 + xout twst_tf_freqi_custom("") +endop + +opcode twst_tf_setplayposition, 0, k + kplayposratio xin + chnset kplayposratio, "twst_tfplayposratio" +endop + +opcode twst_tf_getwintype, i, j + iwintype xin + if (iwintype == -1) then + iwintype = twst_parami("wintype") + endif + ifnWindow = gifnHanning + if (iwintype == 1) then + ifnWindow = gifnHamming + elseif (iwintype == 2) then + ifnWindow = gifnHalfSine + endif + xout ifnWindow +endop + +opcode twst_tf_getwintypek, k, 0 + kwintype = twst_param:k("wintype") + kfnWindow = gifnHanning + if (kwintype == 1) then + kfnWindow = gifnHamming + elseif (kwintype == 2) then + kfnWindow = gifnHalfSine + endif + xout kfnWindow +endop + +opcode twst_tf_getwaveform, i, j + iwave xin + if (iwave == -1) then + iwave = twst_parami("wave") + endif + ifn = gifnSine + if (iwave == 1) then + ifn = gifnSquare + elseif (iwave == 2) then + ifn = gifnSaw + elseif (iwave == 3) then + ifn = gifnPulse + elseif (iwave == 4) then + ifn = gifnTriangle + endif + xout ifn +endop + +opcode twst_tf_getwaveformk, k, J + kwave xin + kwave = (kwave == -1) ? twst_param:k("wave") : kwave + kfn = gifnSine + if (kwave == 1) then + kfn = gifnSquare + elseif (kwave == 2) then + kfn = gifnSaw + elseif (kwave == 3) then + kfn = gifnPulse + elseif (kwave == 4) then + kfn = gifnTriangle + endif + xout kfn +endop + +opcode twst_getfinput, ffaaii, jJ + ifftsize, kpvslock xin + ifftsize = (ifftsize == -1) ? twst_parami("fftsize") : ifftsize + kpvslock = (kpvslock == -1) ? twst_param:k("pvslock") : kpvslock + iwintype = twst_parami("pvswintype") + idecimation = twst_parami("pvsdecimation") + iwinsizem = twst_parami("pvswinsizem") + + iwinsize = ifftsize * iwinsizem + twst_setlatencysamples(iwinsize) ;idecimation) + aL, aR, ileft, iright twst_getinput + + if (ileft == 0) then + fL pvsinit ifftsize + else + fLbase pvsanal aL, ifftsize, ifftsize / idecimation, iwinsize, 1 + fL pvslock fLbase, kpvslock + endif + + if (iright == 0) then + fR pvsinit ifftsize + else + fRbase pvsanal aR, ifftsize, ifftsize / idecimation, iwinsize, 1 + fR pvslock fRbase, kpvslock + endif + xout fL, fR, aL, aR, ileft, iright +endop + +/* TODO: LPC unstable with WASM +opcode twst_getfinput, ffaaii, jJ + ifftsize, kpvslock xin + ifftsize = (ifftsize == -1) ? twst_parami("fftsize") : ifftsize + kpvslock = (kpvslock == -1) ? twst_param:k("pvslock") : kpvslock + ipvstype = twst_parami("pvstype") + iwintype = twst_parami("pvswintype") + iwinlpcfn = twst_tf_getwintype(twst_parami("pvswintypelpc")) + idecimation = twst_parami("pvsdecimation") + iwinsizem = twst_parami("pvswinsizem") + iorderm = twst_parami("pvsorderm") + + if (ipvstype == 1) then + ifftsize = min(ifftsize, 1024) ; crashes in WASM with high FFT size and LPC + endif + + iorder = min(max(1, round(ifftsize * iorderm)), ifftsize) + iwinsize = ifftsize * iwinsizem + twst_setlatencysamples(iwinsize) ;idecimation) + aL, aR, ileft, iright twst_getinput + + if (ileft == 0) then + fL pvsinit ifftsize + else + if (ipvstype == 0) then + fLbase pvsanal aL, ifftsize, ifftsize / idecimation, iwinsize, 1 + else + fLbase pvslpc aL, ifftsize, ifftsize / idecimation, iorder, iwinlpcfn + endif + fL pvslock fLbase, kpvslock + endif + + if (iright == 0) then + fR pvsinit ifftsize + else + if (ipvstype == 0) then + fRbase pvsanal aR, ifftsize, ifftsize / idecimation, iwinsize, 1 + else + fRbase pvslpc aR, ifftsize, ifftsize / idecimation, iorder, iwinlpcfn + endif + fR pvslock fRbase, kpvslock + endif + xout fL, fR, aL, aR, ileft, iright +endop +*/ + + +; ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate +opcode twst_tf_getstate, iiiiii, 0 + ilengths = ((gitwst_tf_state[3] - gitwst_tf_state[2]) / sr) + xout gitwst_tf_state[0], gitwst_tf_state[1], gitwst_tf_state[2], gitwst_tf_state[3], gitwst_tf_state[4], ilengths +endop + +opcode twst_tf_isoffline, i, 0 + xout gitwst_tf_state[6] +endop + +opcode twst_tfi_getfn, ii, jjjjjj + instanceindex, ileft, iright, istartsamp, iendsamp, idocut xin + instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex + ileft = (ileft == -1) ? gitwst_tf_state[0] : ileft + iright = (iright == -1) ? gitwst_tf_state[1] : iright + istartsamp = (istartsamp == -1) ? gitwst_tf_state[2] : istartsamp + iendsamp = (iendsamp == -1) ? gitwst_tf_state[3] : iendsamp + idocut = (idocut == -1) ? gitwst_tf_state[4] : idocut + if (idocut == 1) then + itargetlen = iendsamp - istartsamp ;int(p3 * sr) + if (ileft == 1) then + ifnL ftgentmp 0, 0, -itargetlen, -2, 0 + ftslicei gitwst_bufferL[instanceindex], ifnL, istartsamp, iendsamp, 1 + else + ifnL = 0 + endif + if (iright == 1) then + ifnR ftgentmp 0, 0, -itargetlen, -2, 0 + ftslicei gitwst_bufferR[instanceindex], ifnR, istartsamp, iendsamp, 1 + else + ifnR = 0 + endif + else + ifnL = gitwst_bufferL[instanceindex] + ifnR = gitwst_bufferR[instanceindex] + endif + xout ifnL, ifnR +endop + +opcode _twst_getcrossdata, iiiiiii, S + SchannelPrefix xin + if (strcmp(SchannelPrefix, "") == 0) then + ichannel = twst_parami("instchan") + instanceindex = twst_parami("instance") + istart = twst_parami("inststart") + iend = twst_parami("instend") + else + ichannel chnget strcat(SchannelPrefix, sprintf("instchan%d", p4)) + instanceindex chnget strcat(SchannelPrefix, sprintf("instance%d", p4)) + istart chnget strcat(SchannelPrefix, sprintf("inststart%d", p4)) + iend chnget strcat(SchannelPrefix, sprintf("instend%d", p4)) + endif + idoleft = 1 + idoright = 1 + if (ichannel == 0 || gitwst_channels[instanceindex] == 1) then + idoright = 0 + elseif (ichannel == 1 && gitwst_channels[instanceindex] == 2) then + idoleft = 0 + endif + if (istart == iend) then + istart = 0 + iend = 1 + endif + istart, ilen twst_getstartend istart, iend, instanceindex + ifnL = gitwst_bufferL[instanceindex] + ifnR = gitwst_bufferR[instanceindex] + + xout idoleft, idoright, ifnL, ifnR, instanceindex, istart, ilen +endop + +opcode _twst_getcrossdata, iiiiii, S + SchannelPrefix xin + ileft, iright, ifnL, ifnR, instanceindex, istart, iend _twst_getcrossdata SchannelPrefix + xout ifnL, ifnR, istart, iend - istart, ileft, iright +endop + +opcode twst_getcrossdata, iiiiii, 0 + ifnL, ifnR, istart, ilen, idoleft, idoright _twst_getcrossdata "" + xout ifnL, ifnR, istart, ilen, idoleft, idoright +endop + +opcode twst_tfi_getcrossfn, ii, 0 + ileft, iright, ifnL, ifnR, instanceindex, istart, ilen _twst_getcrossdata "" + idocut = (ftlen(ifnL) == ilen) ? 0 : 1 + ifnLtemp, ifnRtemp twst_tfi_getfn instanceindex, ileft, iright, istart, istart + ilen, idocut + if (gitwst_channels[instanceindex] == 1) then + ifnRtemp = ifnLtemp + endif + xout ifnLtemp, ifnRtemp +endop + +opcode _twst_getcrossinput, aaii, S + SchannelPrefix xin + ifnL, ifnR, istart, ilen, idoleft, idoright _twst_getcrossdata SchannelPrefix + if (strcmp(SchannelPrefix, "") == 0) then + ilooptype = twst_parami("otlooptype") + else + ichannel chnget strcat(SchannelPrefix, sprintf("looptype%d", p4)) + endif + apos lphasor 1, 0, ilen, ilooptype + apos += istart + + if (idoleft == 1) then + aL table3 apos, ifnL + endif + if (idoright == 1) then + aR table3 apos, ifnR + endif + + if (idoright == 0) then + aR = aL + endif + if (idoleft == 0) then + aL = aR + endif + xout aL, aR, idoleft, idoright +endop + +opcode twst_getcrossinput, aaii, 0 + aL, aR, idoleft, idoright _twst_getcrossinput "" + xout aL, aR, idoleft, idoright +endop + +opcode twst_getfcrossinput, ffii, 0 + aL, aR, ileft, iright twst_getcrossinput + ifftsize = twst_parami("fftsize") + kpvslock = twst_param:k("pvslock") + idecimation = twst_parami("pvsdecimation") + iwinsizem = twst_parami("pvswinsizem") + iwinsize = ifftsize * iwinsizem + + if (ileft == 0) then + fL pvsinit ifftsize + else + fLbase pvsanal aL, ifftsize, ifftsize / idecimation, iwinsize, 1 + fL pvslock fLbase, kpvslock + endif + + if (iright == 0) then + fR pvsinit ifftsize + else + fRbase pvsanal aR, ifftsize, ifftsize / idecimation, iwinsize, 1 + fR pvslock fRbase, kpvslock + endif + xout fL, fR, ileft, iright +endop + +opcode twst_tf_fresynth, a, f + fsig xin + imode = twst_parami("pvresmode") + if (imode == 0) then + aout pvsynth fsig + else + ifftsize = twst_parami("fftsize") + ioscnum = max(round((ifftsize * 0.5) * twst_parami("pvaoscnum")) - 1, 1) + kfmod = twst_param:k("pvafreqmod") + ibinoffset = round(ifftsize * 0.5 * twst_parami("pvabinoffset")) + ibinincr = twst_parami("pvabinincr") + ioscnum = ioscnum - ibinoffset + ioscnum = min(((ifftsize * 0.5) / ibinincr), ioscnum) + aout pvsadsyn fsig, ioscnum, kfmod, ibinoffset, ibinincr + endif + xout aout +endop + +opcode twst_getrandombuffers, kk, k + kstereounique xin + kfnL = -1 + kfnR = -1 + + if (kstereounique == 0) then + while (kfnL == -1) do + kindex = round:k(random:k(0, lenarray(gitwst_bufferL) - 1)) + if (ftexists:k(gitwst_bufferL[kindex]) == 1) then + kfnL = gitwst_bufferL[kindex] + if (ftexists:k(gitwst_bufferR[kindex]) == 1) then + kfnR = gitwst_bufferR[kindex] + else + kfnR = kfnL + endif + endif + od + else + while (kfnL == -1) do + kfn = gitwst_bufferL[round:k(random:k(0, lenarray(gitwst_bufferL) - 1))] + if (ftexists:k(kfn) == 1) then + kfnL = kfn + endif + od + while (kfnR == -1) do + kfn = gitwst_bufferR[round:k(random:k(0, lenarray(gitwst_bufferR) - 1))] + if (ftexists:k(kfn) == 1) then + kfnR = kfn + endif + od + endif + xout kfnL, kfnR +endop + +#end -- cgit v1.2.3