#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