diff options
Diffstat (limited to 'site/udo/twist')
-rwxr-xr-x | site/udo/twist/automation.udo | 241 | ||||
-rwxr-xr-x | site/udo/twist/checkpointing.udo | 127 | ||||
-rwxr-xr-x | site/udo/twist/checkpointing_hold.udo | 196 | ||||
-rwxr-xr-x | site/udo/twist/transform_api.udo | 421 | ||||
-rwxr-xr-x | site/udo/twist/transforms.udo | 25 | ||||
-rwxr-xr-x | site/udo/twist/transforms/amplitude.udo | 179 | ||||
-rwxr-xr-x | site/udo/twist/transforms/cross_processing.udo | 176 | ||||
-rwxr-xr-x | site/udo/twist/transforms/delay.udo | 72 | ||||
-rwxr-xr-x | site/udo/twist/transforms/filter.udo | 172 | ||||
-rwxr-xr-x | site/udo/twist/transforms/frequency.udo | 65 | ||||
-rwxr-xr-x | site/udo/twist/transforms/general.udo | 28 | ||||
-rwxr-xr-x | site/udo/twist/transforms/generate.udo | 363 | ||||
-rwxr-xr-x | site/udo/twist/transforms/granular.udo | 138 | ||||
-rwxr-xr-x | site/udo/twist/transforms/harmonic.udo | 142 | ||||
-rwxr-xr-x | site/udo/twist/transforms/reverb.udo | 80 | ||||
-rwxr-xr-x | site/udo/twist/transforms/spectral.udo | 642 | ||||
-rwxr-xr-x | site/udo/twist/transforms/warping.udo | 210 | ||||
-rwxr-xr-x | site/udo/twist/twist.udo | 1304 |
18 files changed, 4581 insertions, 0 deletions
diff --git a/site/udo/twist/automation.udo b/site/udo/twist/automation.udo new file mode 100755 index 0000000..39585fb --- /dev/null +++ b/site/udo/twist/automation.udo @@ -0,0 +1,241 @@ +#ifndef TWST_AUTOMATION
+#define TWST_AUTOMATION ##
+/*
+ Twist waveform editor and transformer
+ Automation and modulation
+
+ This file is part of the SONICS UDO collection by Richard Knight 2024
+ License: GPL-2.0-or-later
+ http://1bpm.net
+*/
+
+
+opcode twst_xa_rms, 0, S
+ Schannel xin
+ kscale chnget strcat(Schannel, "xrmsscale")
+ kporttime chnget strcat(Schannel, "porttime")
+
+ aL, aR, ileft, iright _twst_getcrossinput "xrms"
+ if (ileft == 1 && iright == 1) then
+ kvalue rms (aL + aR) / 2
+ elseif (ileft == 1) then
+ kvalue rms aL
+ else
+ kvalue rms aR
+ endif
+
+ kvalue *= kscale
+ if (kporttime > 0) then
+ kresultvalue portk kvalue, kporttime
+ else
+ kresultvalue = kvalue
+ endif
+ chnset kresultvalue, Schannel
+endop
+
+opcode twst_xa_pitchamdf, 0, S
+ Schannel xin
+ kscale chnget strcat(Schannel, "xpitchscale")
+ ipitchmin chnget strcat(Schannel, "xpitchmin")
+ ipitchmax chnget strcat(Schannel, "xpitchmax")
+ kporttime chnget strcat(Schannel, "porttime")
+ aL, aR, ileft, iright _twst_getcrossinput "xpitch"
+
+ if (ileft == 1 && iright == 1) then
+ kcps, krms pitchamdf (aL + aR) / 2, ipitchmin, ipitchmax
+ elseif (ileft == 1) then
+ kcps, krms pitchamdf aL, ipitchmin, ipitchmax
+ else
+ kcps, krms pitchamdf aR, ipitchmin, ipitchmax
+ endif
+
+ kvalue = ((ipitchmin + max:k(0, kcps)) / (ipitchmax - ipitchmin)) * kscale
+ if (kporttime > 0) then
+ kresultvalue portk kvalue, kporttime
+ else
+ kresultvalue = kvalue
+ endif
+ chnset kresultvalue, Schannel
+endop
+
+opcode twst_xa_pitch1, 0, S
+ Schannel xin
+ kscale chnget strcat(Schannel, "xpitchscale")
+ ihopsize chnget strcat(Schannel, "xpitchhopsize")
+ kporttime chnget strcat(Schannel, "porttime")
+
+ ipitchmin = 20
+ ipitchmax = sr / 2
+ ihopsize = pow(2, ihopsize)
+
+ aL, aR, ileft, iright _twst_getcrossinput "xpitch"
+ if (ileft == 1 && iright == 1) then
+ kcps, kamp ptrack (aL + aR) / 2, ihopsize
+ elseif (ileft == 1) then
+ kcps, kamp ptrack aL, ihopsize
+ else
+ kcps, kamp ptrack aR, ihopsize
+ endif
+
+ kvalue = ((ipitchmin + max:k(0, kcps)) / (ipitchmax - ipitchmin)) * kscale
+ if (kporttime > 0) then
+ kresultvalue portk kvalue, kporttime
+ else
+ kresultvalue = kvalue
+ endif
+ chnset kresultvalue, Schannel
+endop
+
+opcode twst_xa_pitch2, 0, S
+ Schannel xin
+ kscale chnget strcat(Schannel, "xpitchscale")
+ iperiod chnget strcat(Schannel, "xpitchperiod")
+ ipitchmin = octcps(chnget:i(strcat(Schannel, "xpitchmin")))
+ ipitchmax = octcps(chnget:i(strcat(Schannel, "xpitchmax")))
+ iampthresh chnget strcat(Schannel, "xpitchampthresh")
+ kporttime chnget strcat(Schannel, "porttime")
+
+ aL, aR, ileft, iright _twst_getcrossinput "xpitch"
+ if (ileft == 1 && iright == 1) then
+ koct, kamp pitch (aL + aR) / 2, iperiod, ipitchmin, ipitchmax, iampthresh
+ elseif (ileft == 1) then
+ koct, kamp pitch aL, iperiod, ipitchmin, ipitchmax, iampthresh
+ else
+ koct, kamp pitch aR, iperiod, ipitchmin, ipitchmax, iampthresh
+ endif
+
+ kcps cpsoct koct
+ kvalue = ((ipitchmin + max:k(0, kcps)) / (ipitchmax - ipitchmin)) * kscale
+ if (kporttime > 0) then
+ kresultvalue portk kvalue, kporttime
+ else
+ kresultvalue = kvalue
+ endif
+ chnset kresultvalue, Schannel
+endop
+
+opcode twst_xa_centroid, 0, S
+ Schannel xin
+ kscale chnget strcat(Schannel, "xcentroidscale")
+ ifftsize chnget strcat(Schannel, "xcentroidfftsize")
+ kperiod chnget strcat(Schannel, "xcentroidperiod")
+ kporttime chnget strcat(Schannel, "porttime")
+ ipitchmin = 20
+ ipitchmax = sr / 2
+ ktrig metro 1 / kperiod
+
+ aL, aR, ileft, iright _twst_getcrossinput "xcentroid"
+ if (ileft == 1 && iright == 1) then
+ kcent centroid (aL + aR) / 2, ktrig, ifftsize
+ elseif (ileft == 1) then
+ kcent centroid aL, ktrig, ifftsize
+ else
+ kcent centroid aL, ktrig, ifftsize
+ endif
+
+ kvalue = ((ipitchmin + max:k(0, kcent)) / (ipitchmax - ipitchmin)) * kscale
+ if (kporttime > 0) then
+ kresultvalue portk kvalue, kporttime
+ else
+ kresultvalue = kvalue
+ endif
+ chnset kresultvalue, Schannel
+endop
+
+opcode twst_mod_jitter, 0, S
+ Schannel xin
+ kbase chnget strcat(Schannel, "base")
+ kamp chnget strcat(Schannel, "amp")
+ kfreqmin chnget strcat(Schannel, "freqmin")
+ kfreqmax chnget strcat(Schannel, "freqmax")
+ imin chnget strcat(Schannel, "min")
+ imax chnget strcat(Schannel, "max")
+ kval jitter kamp, kfreqmin, kfreqmax
+ kval = kbase + (kval * (imax - imin))
+ kval = min:k(max:k(kval, imin), imax)
+ chnset kval, Schannel
+endop
+
+opcode twst_mod_jitter2, 0, S
+ Schannel xin
+ kbase chnget strcat(Schannel, "base")
+ ktotalamp chnget strcat(Schannel, "totalamp")
+ kamp1 chnget strcat(Schannel, "amp1")
+ kfreq1 chnget strcat(Schannel, "freq1")
+ kamp2 chnget strcat(Schannel, "amp2")
+ kfreq2 chnget strcat(Schannel, "freq2")
+ kamp3 chnget strcat(Schannel, "amp3")
+ kfreq3 chnget strcat(Schannel, "freq3")
+ imin chnget strcat(Schannel, "min")
+ imax chnget strcat(Schannel, "max")
+ kval jitter2 ktotalamp, kamp1, kfreq1, kamp2, kfreq2, kamp3, kfreq3, 1
+ kval = kbase + (kval * (imax - imin))
+ kval = min:k(max:k(kval, imin), imax)
+ chnset kval, Schannel
+endop
+
+opcode twst_mod_lfo, 0, S
+ Schannel xin
+ krate chnget strcat(Schannel, "rate")
+ kbase chnget strcat(Schannel, "base")
+ kgain chnget strcat(Schannel, "gain")
+ imin chnget strcat(Schannel, "min")
+ imax chnget strcat(Schannel, "max")
+ kfn twst_tf_getwaveformk chnget:k(strcat(Schannel, "wave"))
+ kval = kbase + (oscilikt:k(kgain, krate, kfn) * (imax - imin))
+ kval = min:k(max:k(kval, imin), imax)
+ chnset kval, Schannel
+endop
+
+opcode twst_mod_line, 0, S
+ Schannel xin
+ ilatency twst_getlatencyseconds
+ ifirst chnget strcat(Schannel, "first")
+ ilast chnget strcat(Schannel, "last")
+ if (ilatency > 0) then
+ ksig linseg ifirst, ilatency, ifirst, p3, ilast
+ else
+ ksig linseg ifirst, p3, ilast
+ endif
+
+ chnset ksig, Schannel
+endop
+
+opcode twst_mod_random, 0, S
+ Schannel xin
+ krate chnget strcat(Schannel, "rate")
+ kmin chnget strcat(Schannel, "min")
+ kmax chnget strcat(Schannel, "max")
+ kporttime chnget strcat(Schannel, "porttime")
+
+ imin chnget strcat(Schannel, "min")
+ imax chnget strcat(Schannel, "max")
+ initval random imin, imax
+
+ kval init initval
+ ktrig metro krate
+ if (ktrig == 1) then
+ kval = random:k(kmin, kmax)
+ endif
+ kportval portk kval, kporttime
+ chnset kportval, Schannel
+endop
+
+
+instr twst_automationprepare
+ icbid = p4
+ itemnum = pcount()
+ index = 5
+ Sinstr = "instr twst_automaterun\n"
+ while (index < itemnum + 1) do
+
+ Sinstr = strcat(strcat(Sinstr, strget(p(index))), "\n")
+ index += 1
+ od
+ Sinstr = strcat(Sinstr, "a_ init 0\nout a_\nendin\n")
+ ires compilestr Sinstr
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":%d}", icbid, (ires == 0) ? 1 : 0))
+endin
+
+
+#end
\ No newline at end of file diff --git a/site/udo/twist/checkpointing.udo b/site/udo/twist/checkpointing.udo new file mode 100755 index 0000000..39c45e8 --- /dev/null +++ b/site/udo/twist/checkpointing.udo @@ -0,0 +1,127 @@ +#ifndef UDO_TWIST_CHECKPOINTING
+#define UDO_TWIST_CHECKPOINTING ##
+
+gitwst_maxundolevels = 32
+gitwst_checkpoints[][] init imaxinstances, gitwst_maxundolevels
+gitwst_checkpointstate[] init imaxinstances
+gitwst_checkpointencodemult = 10000
+
+
+opcode twst_checkpoint_encode, i, ii
+ ifnL, ifnR xin
+ iencoded = (ifnL * gitwst_checkpointencodemult) + (ifnR / gitwst_checkpointencodemult)
+ xout iencoded
+endop
+
+opcode twst_checkpoint_decode, ii, i
+ iencoded xin
+ ifnL = int(iencoded) / gitwst_checkpointencodemult
+ ifnR = frac(iencoded) * gitwst_checkpointencodemult
+ xout ifnL, ifnR
+endop
+
+opcode twst_checkpoint_clear, 0, j
+ instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ icheckpointnumber = gitwst_checkpointstate[instanceindex]
+ while (icheckpointnumber >= 0) do
+ ifnL, ifnR twst_checkpoint_decode gitwst_checkpoints[instanceindex][icheckpointnumber]
+ if (ifnL > 0 && ftexists(ifnL) == 1) then
+ ftfree ifnL, 0
+ endif
+ if (ifnR > 0 && ftexists(ifnR) == 1) then
+ ftfree ifnR, 0
+ endif
+ icheckpointnumber -= 1
+ od
+ gitwst_checkpointstate[instanceindex] = 0
+endop
+
+opcode twst_checkpoint, 0, j
+ instanceindex xin
+ imaxundo chnget "twst_maxundo"
+ imaxundo = (imaxundo == -1) ? gitwst_maxundolevels : imaxundo
+ if (imaxundo == 0 || imaxundo > gitwst_maxundolevels) then
+ goto complete
+ endif
+
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ icheckpointnumber = gitwst_checkpointstate[instanceindex]
+ if (icheckpointnumber >= imaxundo) then
+ ifnL, ifnR twst_checkpoint_decode gitwst_checkpoints[instanceindex][0]
+ if (ifnL > 0 && ftexists(ifnL) == 1) then
+ ftfree ifnL, 0
+ endif
+ if (ifnR > 0 && ftexists(ifnR) == 1) then
+ ftfree ifnR, 0
+ endif
+ index = 1
+ itemp[] getrow gitwst_checkpoints, instanceindex
+ while (index <= imaxundo) do
+ gitwst_checkpoints[instanceindex][index - 1] = itemp[index]
+ index += 1
+ od
+ gitwst_checkpointstate[instanceindex] = icheckpointnumber ;- 1
+ else
+ gitwst_checkpointstate[instanceindex] = icheckpointnumber + 1
+ endif
+
+ ifnL = gitwst_bufferL[instanceindex]
+ ifnR = gitwst_bufferR[instanceindex]
+ ilen = ftlen(ifnL)
+
+ ifnCheckpointL ftgen 0, 0, ilen, 2, 0
+ tableicopy ifnCheckpointL, ifnL
+ if (ifnR > 0) then
+ ifnCheckpointR ftgen 0, 0, ilen, 2, 0
+ tableicopy ifnCheckpointR, ifnR
+ else
+ ifnCheckpointR = 0
+ endif
+
+ iencoded twst_checkpoint_encode ifnCheckpointL, ifnCheckpointR
+ gitwst_checkpoints[instanceindex][icheckpointnumber] = iencoded
+
+complete:
+endop
+
+opcode twst_undo, i, jp
+ instanceindex, iapplyundo xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+
+ icheckpointnumber = gitwst_checkpointstate[instanceindex]
+
+ icheckpointnumber -= 1
+ if (icheckpointnumber < 0) then
+ istatus = -1
+ goto complete
+ endif
+
+ gitwst_checkpointstate[instanceindex] = icheckpointnumber
+ ifnL, ifnR twst_checkpoint_decode gitwst_checkpoints[instanceindex][icheckpointnumber]
+
+ if (iapplyundo == 1) then ; apply or just step back and forget
+ if (ifnL > 0 && ftexists(ifnL) = 1) then
+ ftfree gitwst_bufferL[instanceindex], 0
+ gitwst_bufferL[instanceindex] = ifnL
+ endif
+ if (ifnR > 0 && ftexists(ifnR) == 1) then
+ ftfree gitwst_bufferR[instanceindex], 0
+ gitwst_bufferR[instanceindex] = ifnR
+ endif
+ else
+ if (ifnL > 0 && ftexists(ifnL) = 1) then
+ ftfree ifnL, 0
+ endif
+ if (ifnL > 0 && ftexists(ifnR) = 1) then
+ ftfree ifnR, 0
+ endif
+ endif
+
+ istatus = 1
+
+complete:
+ xout istatus
+endop
+
+#end
diff --git a/site/udo/twist/checkpointing_hold.udo b/site/udo/twist/checkpointing_hold.udo new file mode 100755 index 0000000..523d423 --- /dev/null +++ b/site/udo/twist/checkpointing_hold.udo @@ -0,0 +1,196 @@ +#ifndef UDO_TWIST_CHECKPOINTING
+#define UDO_TWIST_CHECKPOINTING ##
+
+; file checkpointing broken due to WASM FS issue, but keep in memory maybe better anyway
+
+#ifdef TWIST_FTCHECKPOINTING
+
+gitwst_checkpoints[][] init imaxinstances, gitwst_maxundolevels
+gitwst_checkpointstate[] init imaxinstances
+gitwst_checkpointencodemult = 10000
+
+opcode twst_checkpoint, 0, j
+ instanceindex xin
+ imaxundo chnget "maxundo"
+ imaxundo = (imaxundo == -1) ? gitwst_maxundolevels : imaxundo
+ if (imaxundo == 0 || imaxundo > gitwst_maxundolevels) then
+ goto complete
+ endif
+
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ icheckpointnumber = gitwst_checkpointstate[instanceindex]
+
+ if (icheckpointnumber >= imaxundo) then
+ ftfree gitwst_checkpoints[instanceindex][0], 0
+ index = 1
+ while (index < gitwst_maxundolevels) do
+ gitwst_checkpoints[instanceindex][index - 1] = gitwst_checkpoints[instanceindex][index]
+ index += 1
+ od
+ else
+ gitwst_checkpointstate[instanceindex] = icheckpointnumber + 1
+ endif
+
+ ifnL = gitwst_bufferL[instanceindex]
+ ifnR = gitwst_bufferR[instanceindex]
+ ilen = ftlen(ifnL)
+
+ ifnCheckpointL ftgen 0, 0, ilen, 2, 0
+ tableicopy ifnCheckpointL, ifnL
+ ifnEncodedL = ifnCheckpointL * gitwst_checkpointencodemult
+ if (ifnR > 0) then
+ ifnCheckpointR ftgen 0, 0, ilen, 2, 0
+ tableicopy ifnCheckpointR, ifnR
+ ifnEncodedR = ifnCheckpointR / gitwst_checkpointencodemult
+ else
+ ifnEncodedR = 0
+ endif
+
+ iencoded = ifnEncodedL + ifnEncodedR
+ gitwst_checkpoints[instanceindex][icheckpointnumber] = iencoded
+
+complete:
+endop
+
+opcode twst_undo, i, j
+ instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ Sloaded = ""
+
+ icheckpointnumber = gitwst_checkpointstate[instanceindex]
+
+ icheckpointnumber -= 1
+ if (icheckpointnumber < 0) then
+ istatus = -1
+ goto complete
+ endif
+
+ icheckpointEncoded = gitwst_checkpoints[instanceindex][icheckpointnumber]
+ ifnCheckpointL = icheckpointEncoded / gitwst_checkpointencodemult
+ ifnCheckpointR = icheckpointEncoded * gitwst_checkpointencodemult
+
+ ftfree gitwst_bufferL[instanceindex], 0
+ gitwst_bufferL[instanceindex] = ifnCheckpointL
+
+ if (ifnCheckpointR > 0) then
+ ftfree gitwst_bufferR[instanceindex], 0
+ gitwst_bufferR[instanceindex] = ifnCheckpointR
+ endif
+
+ istatus = 1
+
+complete:
+ xout istatus
+endop
+
+#else
+
+gitwst_checkpoint[][] init imaxinstances, 2
+gitwst_checkpointlengths[][] init imaxinstances, gitwst_maxundolevels
+opcode twst_checkpointfilename, S, jj
+ instanceindex, icheckpointnumber xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ icheckpointnumber = (icheckpointnumber == -1) ? gitwst_checkpoint[instanceindex][0] : icheckpointnumber
+ Sfile = sprintf("checkpoint-%d-%d", instanceindex, icheckpointnumber)
+ Sfile = strcat(host_tempdir(), strcat("/", Sfile))
+ xout Sfile
+endop
+
+opcode twst_checkpoint, 0, j
+ instanceindex xin
+ imaxundo chnget "maxundo"
+ if (imaxundo == 0 || imaxundo > gitwst_maxundolevels) then
+ goto complete
+ endif
+
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ icheckpointnumber = gitwst_checkpoint[instanceindex][0]
+ icheckpointoffset = gitwst_checkpoint[instanceindex][1]
+
+ if (icheckpointoffset + icheckpointnumber >= imaxundo) then
+ Sdelete = twst_checkpointfilename(icheckpointoffset)
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"delete\": [\"%s\", \"%s.len\"]}", giwst_globalcbid, Sdelete, Sdelete))
+ icheckpointoffset += 1
+ gitwst_checkpoint[instanceindex][1] = icheckpointoffset
+ endif
+
+ Sfile = twst_checkpointfilename(instanceindex)
+
+ gitwst_checkpointlengths[instanceindex][icheckpointnumber - icheckpointoffset] = ftlen(gitwst_bufferL[instanceindex])
+ /* can't use this as WASM not writing/closing files properly
+ ilen = ftlen(gitwst_bufferL[instanceindex])
+ ihf fiopen strcat(Sfile, ".len"), 0
+ fouti ihf, 0, 0, ilen
+ ficlose ihf*
+ ; nor this ;fprints strcat(Sfile, ".len"), "%d\n", ftlen(gitwst_bufferL[instanceindex])
+ */
+
+ if (gitwst_channels[instanceindex] == 1) then
+ ftsave Sfile, 0, gitwst_bufferL[instanceindex]
+ else
+ ftsave Sfile, 0, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex]
+ endif
+ gitwst_checkpoint[instanceindex][0] = icheckpointnumber + 1
+complete:
+endop
+
+opcode twst_undo, iS, j
+ instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ Sloaded = ""
+
+ icheckpointnumber = gitwst_checkpoint[instanceindex][0]
+ icheckpointoffset = gitwst_checkpoint[instanceindex][1]
+
+ if (icheckpointnumber - icheckpointoffset <= 0) then
+ istatus = -1
+ goto complete
+ endif
+
+ icheckpointnumber -= 1
+ gitwst_checkpoint[instanceindex][0] = icheckpointnumber
+ Sfile = twst_checkpointfilename(instanceindex)
+
+ ilen = gitwst_checkpointlengths[instanceindex][icheckpointnumber - icheckpointoffset]
+ /* can't use this as WASM not writing/closing files properly thus checkpoint step doesn't write
+ SlenFile = strcat(Sfile, ".len")
+ if (filevalid(Sfile) != 1 || filevalid(SlenFile) != 1) then
+ istatus = -2
+ goto complete
+ endif
+
+ ilen init 0
+ ihf fiopen SlenFile, 1
+ fini ihf, 0, 1, ilen
+ ficlose ihf
+ */
+
+ if (ilen == 0) then
+ istatus = -3
+ goto complete
+ endif
+
+ if (ilen != ftlen(gitwst_bufferL[instanceindex])) then
+ twst_clearbuffers gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex]
+ gitwst_bufferL[instanceindex] ftgen 0, 0, -ilen, -2, 0
+ if (gitwst_channels[instanceindex] == 2) then
+ gitwst_bufferR[instanceindex] ftgen 0, 0, -ilen, -2, 0
+ else
+ gitwst_bufferR[instanceindex] = 0
+ endif
+ endif
+
+ if (gitwst_channels[instanceindex] == 1) then
+ ftload Sfile, 0, gitwst_bufferL[instanceindex]
+ else
+ ftload Sfile, 0, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex]
+ endif
+ Sloaded = Sfile
+ istatus = 1
+
+complete:
+ xout istatus, Sloaded
+endop
+#end
+
+#end
\ No newline at end of file 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
diff --git a/site/udo/twist/transforms.udo b/site/udo/twist/transforms.udo new file mode 100755 index 0000000..2587d18 --- /dev/null +++ b/site/udo/twist/transforms.udo @@ -0,0 +1,25 @@ +#ifndef TWST_TRANSFORMS
+#define TWST_TRANSFORMS ##
+/*
+ Twist waveform editor and transformer
+ Transforms
+
+ This file is part of the SONICS UDO collection by Richard Knight 2024
+ License: GPL-2.0-or-later
+ http://1bpm.net
+*/
+
+#include "/twist/transforms/amplitude.udo"
+#include "/twist/transforms/cross_processing.udo"
+#include "/twist/transforms/delay.udo"
+#include "/twist/transforms/filter.udo"
+#include "/twist/transforms/frequency.udo"
+#include "/twist/transforms/general.udo"
+#include "/twist/transforms/generate.udo"
+#include "/twist/transforms/granular.udo"
+#include "/twist/transforms/harmonic.udo"
+#include "/twist/transforms/reverb.udo"
+#include "/twist/transforms/spectral.udo"
+#include "/twist/transforms/warping.udo"
+
+#end
\ No newline at end of file diff --git a/site/udo/twist/transforms/amplitude.udo b/site/udo/twist/transforms/amplitude.udo new file mode 100755 index 0000000..d477b4f --- /dev/null +++ b/site/udo/twist/transforms/amplitude.udo @@ -0,0 +1,179 @@ +#include "/twist/transform_api.udo"
+#include "/frequency_tools.udo"
+
+opcode _twst_tf_normalise_analyse, i, iii
+ ifn, istartsamp, iendsamp xin
+ iscale = 0
+ imaxpos = 0
+ imaxneg = 0
+ while (istartsamp < iendsamp) do
+ ival table istartsamp, ifn
+ if (ival > 0 && ival > imaxpos) then
+ imaxpos = ival
+ elseif (ival < 0 && ival < imaxneg) then
+ imaxneg = ival
+ endif
+ istartsamp += 1
+ od
+ iscale = ((1 / max(abs(imaxneg), abs(imaxpos))))
+ xout iscale
+endop
+
+instr twst_tf_normalise
+ $TWST_TRANSFORM
+ i_, i_, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ aL, aR, ileft, iright twst_getinput
+ istereoequal = twst_parami("equal")
+ kuserscale = twst_param:k("scale")
+
+ if (ileft == 1) then
+ iscalingL _twst_tf_normalise_analyse gitwst_bufferL[gitwst_instanceindex], istartsamp, iendsamp
+ endif
+ if (iright == 1) then
+ iscalingR _twst_tf_normalise_analyse gitwst_bufferR[gitwst_instanceindex], istartsamp, iendsamp
+ endif
+
+ if (istereoequal == 1 && ileft == 1 && iright == 1) then
+ iscaling = min(iscalingL, iscalingR)
+ aL *= iscaling * kuserscale
+ aR *= iscaling * kuserscale
+ elseif (ileft == 1) then
+ aL *= iscalingL * kuserscale
+ elseif (iright == 1) then
+ aR *= iscalingR * kuserscale
+ endif
+
+ outs aL, aR
+endin
+
+instr twst_tf_amplitude
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kgain = twst_param:k("gain")
+ kbalance = twst_param:k("balance")
+ if (ileft == 1) then
+ kb = max:k(1, (1 - kbalance) * 2)
+ aL *= kgain * kb
+ endif
+ if (iright == 1) then
+ kb = max:k(1, kbalance * 2)
+ aR *= kgain * kb
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_strobe
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ krate = twst_param:k("rate")
+ kholdtime = twst_param:k("holdtime")
+ kwindowed = twst_param:k("windowed")
+
+ ktrig metro krate
+ ktrig trighold ktrig, kholdtime
+ kamp = 1 - ktrig
+
+ if (kwindowed == 1) then
+ kenv portk kamp, kholdtime * 0.5
+ else
+ kenv = kamp
+ endif
+
+ if (ileft == 1) then
+ aL *= kenv
+ endif
+ if (iright == 1) then
+ aR *= kenv
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_bitcrush
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kcrush = twst_param:k("crush")
+ if (ileft == 1) then
+ aL bitcrush aL, kcrush
+ elseif (iright == 1) then
+ aR bitcrush aR, kcrush
+ endif
+ outs aL, aR
+endin
+
+
+instr twst_tf_suppress
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kmode = twst_param:k("mode")
+ kthreshold = twst_param:k("threshold")
+
+ if (ileft == 1) then
+ if (kmode == 0) then
+ aL limit aL, -kthreshold, kthreshold
+ elseif (kmode == 1) then
+ aL wrap aL, -kthreshold, kthreshold
+ elseif (kmode == 2) then
+ aL mirror aL, -kthreshold, kthreshold
+ endif
+ endif
+ if (iright == 1) then
+ if (kmode == 0) then
+ aR limit aR, -kthreshold, kthreshold
+ elseif (kmode == 1) then
+ aR wrap aR, -kthreshold, kthreshold
+ elseif (kmode == 2) then
+ aR mirror aR, -kthreshold, kthreshold
+ endif
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_pdclip
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kwidth = twst_param:k("width")
+ kcentre = twst_param:k("centre")
+ ibipolar = twst_parami("bipolar")
+ ifullscale = twst_parami("fullscale")
+
+ if (ileft == 1) then
+ aL pdclip aL, kwidth, kcentre, ibipolar, ifullscale
+ endif
+ if (iright == 1) then
+ aR pdclip aR, kwidth, kcentre, ibipolar, ifullscale
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_distort
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamount = twst_param:k("amount")
+ ihp = twst_parami("halfpower")
+ ifn twst_tf_getwaveform
+
+ if (ileft == 1) then
+ aL distort aL, kamount, ifn, ihp
+ endif
+ if (iright == 1) then
+ aL distort aR, kamount, ifn, ihp
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_distort1
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kpregain = twst_param:k("pregain")
+ kpostgain = twst_param:k("postgain")
+ kshape1 = twst_param:k("shape1")
+ kshape2 = twst_param:k("shape2")
+
+ if (ileft == 1) then
+ aL distort1 aL, kpregain, kpostgain, kshape1, kshape2, 1
+ endif
+ if (iright == 1) then
+ aL distort1 aR, kpregain, kpostgain, kshape1, kshape2, 1
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/cross_processing.udo b/site/udo/twist/transforms/cross_processing.udo new file mode 100755 index 0000000..203c393 --- /dev/null +++ b/site/udo/twist/transforms/cross_processing.udo @@ -0,0 +1,176 @@ +#include "/twist/transform_api.udo"
+#include "/mfcc_match.udo"
+#include "/fftconvolve.udo"
+#include "/chop.udo"
+
+
+instr twst_tf_crossrearrange
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kminsamples = twst_param:k("minsamples")
+ kmaxsamples = twst_param:k("maxsamples")
+ kstereounique = twst_param:k("stereounique")
+ krate = twst_param:k("rate")
+
+ ktrig metro krate
+ async init 0
+
+ if (ktrig == 1) then
+ kfnLo, kfnRo twst_getrandombuffers kstereounique
+ ktablen = tableng:k(kfnLo)
+ klen = min:k(random:k(kminsamples, kmaxsamples), ktablen)
+ kstart = random:k(0, ktablen - klen)
+ async = 1
+ else
+ async = 0
+ endif
+
+ apos, a_ syncphasor 1 / (klen / sr), async
+ areadpos = (apos * klen) + kstart
+
+ if (ileft == 1) then
+ aL tablekt areadpos, kfnLo
+ endif
+ if (iright == 1) then
+ aR tablekt areadpos, kfnRo
+ endif
+
+ outs aL, aR
+endin
+
+instr twst_tf_directconvolve
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ifnLo, ifnRo twst_tfi_getcrossfn
+ kamp = twst_parami("amp")
+ isizeratio = twst_parami("sizeratio")
+ if (ileft == 1) then
+ aL dconv aL * kamp, isizeratio * ftlen(ifnLo), ifnLo
+ endif
+ if (iright == 1) then
+ aR dconv aR * kamp, isizeratio * ftlen(ifnRo), ifnRo
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_blockconvolve
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ aLo, aRo, ilefto, irighto twst_getcrossinput
+ ifftsize = twst_parami("fftsize")
+ ioverlap = twst_parami("overlap")
+ ihopsize = ifftsize / ioverlap
+
+ if (ileft == 1 && ilefto == 1) then
+ aL blockconvolve aL, aLo, ifftsize, ihopsize
+ endif
+ if (iright == 1 && irighto == 1) then
+ aR blockconvolve aR, aRo, ifftsize, ihopsize
+ endif
+ outs aL, aR
+endin
+
+/* not in WASM at current
+instr twst_tf_tvconv
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ aLo, aRo, ilefto, irighto twst_getcrossinput
+ kapply1 = twst_param:k("apply1")
+ kapply2 = twst_param:k("apply2")
+ imode = twst_parami("mode")
+ iparts = twst_parami("parts")
+ idftfiltersize = twst_parami("dftfiltersize")
+ ifirfiltersize = twst_parami("firfiltersize")
+
+ if (imode == 1) then
+ iparts = 1
+ ifiltersize = ifirfiltersize
+ else
+ ifiltersize = idftfiltersize
+ endif
+
+ if (ileft == 1 && ilefto == 1) then
+ aL tvconv aL, aLo, kapply1, kapply2, iparts, ifiltersize
+ endif
+
+ if (iright == 1 && irighto == 1) then
+ aR tvconv aR, aRo, kapply1, kapply2, iparts, ifiltersize
+ endif
+ outs aL, aR
+endin
+*/
+
+instr twst_tf_crosssynth
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ fLo, fRo, ilefto, irighto twst_getfcrossinput
+ kamp1 = twst_param:k("amp1")
+ kamp2 = twst_param:k("amp2")
+
+ if (ileft == 1 && ilefto == 1) then
+ foutL pvscross fL, fLo, kamp1, kamp2
+ aL twst_tf_fresynth foutL
+ endif
+
+ if (iright == 1 && irighto == 1) then
+ foutR pvscross fR, fRo, kamp1, kamp2
+ aR twst_tf_fresynth foutR
+ endif
+ outs aL, aR
+endin
+
+
+instr twst_tf_morph
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ fLo, fRo, ilefto, irighto twst_getfcrossinput
+ kamp = twst_param:k("amp")
+ kfreq = twst_param:k("freq")
+
+ if (ileft == 1 && ilefto == 1) then
+ foutL pvsmorph fL, fLo, kamp, kfreq
+ aL twst_tf_fresynth foutL
+ endif
+
+ if (iright == 1 && irighto == 1) then
+ foutR pvsmorph fR, fRo, kamp, kfreq
+ aR twst_tf_fresynth foutR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_mfccmatch
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ifnoL, ifnoR twst_tfi_getcrossfn
+ ifftsize = twst_parami("fftsize")
+ ifreqmin = twst_parami("freqmin")
+ ifreqmax = twst_parami("freqmax")
+ ibands = twst_parami("bands")
+ kstretch = twst_param:k("stretch")
+ kauditionreadyL init 0
+ kauditionreadyR init 0
+ ktimek timeinstk
+
+ if (ileft == 1) then
+ kdone, ifnAnalysisL mfm_analysecorpus ktimek, ifnoL, ifreqmin, ifreqmax, ifftsize, ibands, -1, 1
+ if (kdone == 1) then
+ kauditionreadyL = 1
+ aoutL mfm_matchplay aL, ifnoL, ifnAnalysisL, kstretch, ifreqmin, ifreqmax, ifftsize, ibands
+ endif
+ else
+ kauditionreadyL = 1
+ endif
+ if (iright == 1) then
+ kdone, ifnAnalysisR mfm_analysecorpus ktimek, ifnoR, ifreqmin, ifreqmax, ifftsize, ibands, -1, 1
+ if (kdone == 1) then
+ kauditionreadyR = 1
+ aoutR mfm_matchplay aR, ifnoR, ifnAnalysisR, kstretch, ifreqmin, ifreqmax, ifftsize, ibands
+ endif
+ else
+ kauditionreadyR = 1
+ endif
+
+ chnset (kauditionreadyL & kauditionreadyR), "auditionready"
+ outs aoutL, aoutR
+endin
diff --git a/site/udo/twist/transforms/delay.udo b/site/udo/twist/transforms/delay.udo new file mode 100755 index 0000000..5d59612 --- /dev/null +++ b/site/udo/twist/transforms/delay.udo @@ -0,0 +1,72 @@ +#include "/twist/transform_api.udo"
+
+instr twst_tf_vdelay
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kdelay = twst_param:k("delay") * 1000
+ kfeedback = twst_param:k("feedback")
+ adelay = a(kdelay)
+
+ if (ileft == 1) then
+ afbkL init 0
+ aLd vdelay3 aL + afbkL, adelay, 1000
+ afbkL = aLd * kfeedback
+ aL = aLd
+ endif
+ if (iright == 1) then
+ afbkR init 0
+ aRd vdelay3 aR + afbkR, adelay, 1000
+ afbkR = aRd * kfeedback
+ aR = aRd
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_flanger
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kdelay = twst_param:k("delay")
+ kfeedback = twst_param:k("feedback")
+
+ adelay = a(kdelay)
+ if (ileft == 1) then
+ aL flanger aL, adelay, kfeedback
+ endif
+ if (iright == 1) then
+ aR flanger aR, adelay, kfeedback
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_phaser1
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("freq")
+ iord = twst_parami("order")
+ kfeedback = twst_param:k("feedback")
+ if (ileft == 1) then
+ aL phaser1 aL, kfreq, iord, kfeedback
+ endif
+ if (iright == 1) then
+ aR phaser1 aR, kfreq, iord, kfeedback
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_phaser2
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("freq")
+ kq = twst_param:k("q")
+ iord = twst_parami("order")
+ imode = twst_parami("mode")
+ ksep = twst_param:k("sep")
+ kfeedback = twst_param:k("feedback")
+ if (ileft == 1) then
+ aL phaser2 aL, kfreq, kq, iord, imode, ksep, kfeedback
+ endif
+ if (iright == 1) then
+ aR phaser2 aR, kfreq, kq, iord, imode, ksep, kfeedback
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/filter.udo b/site/udo/twist/transforms/filter.udo new file mode 100755 index 0000000..38fad69 --- /dev/null +++ b/site/udo/twist/transforms/filter.udo @@ -0,0 +1,172 @@ +#include "/twist/transform_api.udo"
+
+instr twst_tf_lpf
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("frequency")
+ if (ileft == 1) then
+ aL butterlp aL, kfreq
+ endif
+ if (iright == 1) then
+ aR butterlp aR, kfreq
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_hpf
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("frequency")
+ if (ileft == 1) then
+ aL butterhp aL, kfreq
+ endif
+ if (iright == 1) then
+ aR butterhp aR, kfreq
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_bpf
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("frequency")
+ kbw = twst_param:k("bandwidth")
+ if (ileft == 1) then
+ aL butterbp aL, kfreq, kbw
+ endif
+ if (iright == 1) then
+ aR butterbp aR, kfreq, kbw
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_pareq
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("frequency")
+ kgain = twst_param:k("gain")
+ kq = twst_param:k("q")
+ if (ileft == 1) then
+ aL pareq aL, kfreq, kgain, kq
+ endif
+ if (iright == 1) then
+ aR pareq aR, kfreq, kgain, kq
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_dcblock
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ if (ileft == 1) then
+ aL dcblock2 aL
+ endif
+ if (iright = 1) then
+ aR dcblock2 aR
+ endif
+ outs aL, aR
+endin
+
+/* not in WASM
+{
+ name: "Non-linear filter",
+ instr: "twst_tf_nlfilter",
+ parameters: [
+ {name: "Parameter a", channel: "pa", min: 0, max: 1, dfault: 0.3},
+ {name: "Parameter b", channel: "pb", min: -1, max: 1, dfault: 0.1},
+ {name: "Parameter d", channel: "pd", min: 0, max: 1, dfault: 0.7},
+ {name: "Parameter C", channel: "pC", min: 0, max: 1, dfault: 0.12},
+ {name: "Parameter L", channel: "pL", min: 1, max: 220, dfault: 20},
+ {preset: "applymode"}
+ ]
+},
+
+instr twst_tf_nlfilter
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kpa = twst_param:k("pa")
+ kpb = twst_param:k("pb")
+ kpd = twst_param:k("pd")
+ kpC = twst_param:k("pC")
+ kpL = twst_param:k("pL")
+ nfilt
+ if (ileft == 1) then
+ aL nfilt2 aL, kpa, kpb, kpd, kpC, kpL
+ endif
+ if (iright == 1) then
+ aR nfilt2 aR, kpa, kpb, kpd, kpC, kpL
+ endif
+ outs aL, aR
+endin
+*/
+
+instr twst_tf_mooghpf
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("freq")
+ if (ileft == 1) then
+ aL mvchpf aL, kfreq
+ endif
+ if (iright == 1) then
+ aR mvchpf aR, kfreq
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_mooglpf
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("freq")
+ kres = twst_param:k("resonance")
+ kmode = twst_param:k("mode")
+ if (ileft == 1) then
+ if (kmode == 0) then
+ aL mvclpf1 aL, kfreq, kres
+ elseif (kmode == 1) then
+ aL mvclpf2 aL, kfreq, kres
+ elseif (kmode == 2) then
+ aL mvclpf3 aL, kfreq, kres
+ endif
+ endif
+ if (iright == 1) then
+ if (kmode == 0) then
+ aR mvclpf1 aR, kfreq, kres
+ elseif (kmode == 1) then
+ aR mvclpf2 aR, kfreq, kres
+ elseif (kmode == 2) then
+ aR mvclpf3 aR, kfreq, kres
+ endif
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_waveguide1
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("freq")
+ kcutoff = twst_param:k("cutoff")
+ kfeedback = twst_param:k("feedback")
+ if (ileft == 1) then
+ aL wguide1 aL, kfreq, kcutoff, kfeedback
+ endif
+ if (iright == 1) then
+ aR wguide1 aR, kfreq, kcutoff, kfeedback
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_tbvcf
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("freq")
+ kres = twst_param:k("resonance")
+ kdist = twst_param:k("dist")
+ kasym = twst_param:k("asym")
+ if (ileft == 1) then
+ aL tbvcf aL, kfreq, kres, kdist, kasym
+ endif
+ if (iright == 1) then
+ aR tbvcf aR, kfreq, kres, kdist, kasym
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/frequency.udo b/site/udo/twist/transforms/frequency.udo new file mode 100755 index 0000000..a56b808 --- /dev/null +++ b/site/udo/twist/transforms/frequency.udo @@ -0,0 +1,65 @@ +#include "/twist/transform_api.udo"
+#include "/frequency_tools.udo"
+
+instr twst_tf_freqshift1
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kshift = twst_param:k("shift")
+ if (ileft == 1 && iright == 1) then
+ aL, aR freqshift1 aL, aR, kshift
+ elseif (ileft == 1) then
+ aL freqshift1 aL, kshift
+ elseif (iright == 1) then
+ aR freqshift1 aR, kshift
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_freqshift2
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kshift = twst_param:k("shift")
+ if (ileft == 1 && iright == 1) then
+ aL, aR freqshift2 aL, aR, kshift
+ elseif (ileft == 1) then
+ aL freqshift2 aL, kshift
+ elseif (iright == 1) then
+ aR freqshift2 aR, kshift
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_ringmod
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("frequency")
+ if (ileft == 1 && iright == 1) then
+ aL, aR ringmod1 aL, aR, kfreq
+ elseif (ileft == 1) then
+ aL ringmod1 aL, kfreq
+ elseif (iright == 1) then
+ aR ringmod1 aR, kfreq
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_exciter
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreqlow = twst_tf_freq_custom("low")
+ kfreqhigh = twst_tf_freq_custom("high")
+ kharmonics = twst_param:k("harmonics")
+ kblend = twst_param:k("blend")
+
+ if (kfreqhigh < kfreqlow) then
+ kfreqhigh = kfreqlow
+ endif
+
+ if (ileft == 1) then
+ aL exciter aL, kfreqlow, kfreqhigh, kharmonics, kblend
+ endif
+ if (iright == 1) then
+ aR exciter aR, kfreqlow, kfreqhigh, kharmonics, kblend
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/general.udo b/site/udo/twist/transforms/general.udo new file mode 100755 index 0000000..b46f570 --- /dev/null +++ b/site/udo/twist/transforms/general.udo @@ -0,0 +1,28 @@ +#include "/twist/transform_api.udo"
+
+instr twst_tfi_reverse
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ ifnL, ifnR twst_tfi_getfn
+ ioffline twst_tf_isoffline
+ apos linseg (iendsamp - istartsamp) - 1, ilength, 0
+ if (ileft == 1) then
+ if (ioffline == 1) then
+ ifntempL ftgentmp 0, 0, -ftlen(ifnL), -2, 0
+ tableicopy ifntempL, ifnL
+ aL table3 apos, ifntempL
+ else
+ aL table3 apos, ifnL
+ endif
+ endif
+ if (iright == 1) then
+ if (ioffline == 1) then
+ ifntempR ftgentmp 0, 0, -ftlen(ifnR), -2, 0
+ tableicopy ifntempR, ifnR
+ aR table3 apos, ifntempR
+ else
+ aR table3 apos, ifnR
+ endif
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/generate.udo b/site/udo/twist/transforms/generate.udo new file mode 100755 index 0000000..e7355a8 --- /dev/null +++ b/site/udo/twist/transforms/generate.udo @@ -0,0 +1,363 @@ +#include "/addsub.udo"
+
+instr twst_tf_gensilence
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ a0 init 0
+ if (ileft == 1) then
+ aL = a0
+ endif
+ if (iright == 1) then
+ aR = a0
+ endif
+ outs aL, aR
+endin
+
+
+instr twst_tf_genadditive
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ifreq = twst_parami("minfreq")
+ ifreqmax = twst_parami("maxfreq")
+ ifreqstepmult = twst_parami("step")
+ ifreqstepmultrand = twst_parami("steprand")
+ iamp = twst_parami("amp")
+ iampmult = twst_parami("ampmult")
+
+ if (ileft == 1) then
+ aL as_additive ifreq, ifreqmax, ifreqstepmult, ifreqstepmultrand, iamp, iampmult
+ endif
+ if (iright == 1) then
+ aR as_additive ifreq, ifreqmax, ifreqstepmult, ifreqstepmultrand, iamp, iampmult
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_gentone
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamp = twst_param:k("amp")
+ kfreq twst_tf_freq
+ kfn twst_tf_getwaveformk
+
+ aosc oscilikt kamp, kfreq, kfn
+ if (ileft == 1) then
+ aL = aosc
+ endif
+ if (iright == 1) then
+ aR = aosc
+ endif
+ outs aL, aR
+endin
+
+
+opcode twst_tf_gensimpleadditive, a, kkkkkio
+ kamp, kmultiplier, kfreq, kstepmult, kampprofile, iharmonics, index xin
+ if (kampprofile == 0) then
+ kgain = 1
+ else
+ kgain = (1 - (index / iharmonics))
+ endif
+ aosc oscili (1 / iharmonics) * kgain, (kfreq * kmultiplier)
+ if (index < iharmonics) then
+ arec twst_tf_gensimpleadditive, min:k(kfreq * kstepmult, sr / 2), kstepmult, kampprofile, iharmonics, index + 1
+ aosc += arec
+ endif
+ xout aosc * kamp
+endop
+
+instr twst_tf_gensimpleadditive
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamp = twst_param:k("amp")
+ kfreq twst_tf_freq
+ kmultiplier = twst_param:k("multiplier")
+ kstepmult = twst_param:k("stepmultiplier")
+ kampprofile = twst_param:k("ampprofile")
+ iharmonics = twst_parami("harmonics")
+
+ if (ileft == 1) then
+ aL twst_tf_gensimpleadditive kamp, kmultiplier, kfreq, kstepmult, kampprofile, iharmonics
+ endif
+ if (iright == 1) then
+ aR twst_tf_gensimpleadditive kamp, kmultiplier, kfreq, kstepmult, kampprofile, iharmonics
+ endif
+ outs aL, aR
+endin
+
+opcode twst_tf_genfeedback, a, kkkk
+ kfeedback, kfreq, kpostgain, kbw xin
+ asig init 0
+ asig += noise(0.00001, 0)
+ adel delay asig, 0.0001
+ asig += (adel * kfeedback)
+ asig butterbp asig, kfreq, kbw
+ asig butterbp asig, kfreq, kbw
+ asig tanh ain
+ asig *= kpostgain
+ xout asig
+endop
+
+instr twst_tf_genfeedback
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamp = twst_param:k("amp")
+ kfeedback = twst_param:k("feedback")
+ kfreq twst_tf_freq
+ kpostgain = twst_param:k("postgain")
+ kbw = twst_param:k("bandwidth")
+ if (ileft == 1) then
+ aL twst_tf_genfeedback kfeedback, kfreq, kpostgain
+ aL *= kamp
+ endif
+ if (iright == 1) then
+ aR twst_tf_genfeedback kfeedback, kfreq, kpostgain
+ aR *= kamp
+ endif
+ outs aL, aR
+endin
+
+
+instr twst_tf_genfm
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq twst_tf_freq
+ kamp = twst_param:k("amp")
+ kcarrier = twst_param:k("carrier")
+ kmod = twst_param:k("modulator")
+ kindex = twst_param:k("index")
+ kstereo = twst_param:k("stereovar")
+ ifn twst_tf_getwaveform
+
+ if (ileft == 0 || iright == 0) then
+ kstereo = 1
+ endif
+
+ if (ileft == 1) then
+ aL foscili kamp, kfreq, kcarrier * kstereo, kmod * kstereo, kindex * kstereo, ifn
+ endif
+ if (iright == 1) then
+ kstereo = 1 - (kstereo - 1)
+ aR foscili kamp, kfreq, kcarrier * kstereo, kmod * kstereo, kindex * kstereo, ifn
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_genfmmodel
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq twst_tf_freq
+ ifmtype = twst_parami("fmtype")
+ kamp = twst_param:k("amp")
+ kc1 = twst_param:k("control1")
+ kc2 = twst_param:k("control2")
+ kvibdepth = twst_param:k("vibdepth")
+ kvibrate = twst_param:k("vibrate")
+ ifn1 twst_tf_getwaveform twst_parami("wave1")
+ ifn2 twst_tf_getwaveform twst_parami("wave2")
+ ifn3 twst_tf_getwaveform twst_parami("wave3")
+ ifn4 twst_tf_getwaveform twst_parami("wave4")
+ ifnv twst_tf_getwaveform twst_parami("vibwave")
+ kstereo = twst_param:k("stereovar")
+
+ if (ileft == 0 || iright == 0) then
+ kstereo = 1
+ endif
+
+ if (ileft == 1) then
+ ifmtypei = (ifmtype == 5) ? round(random(0, 4)) : ifmtype
+ if (ifmtypei == 0) then
+ aL fmb3 kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ elseif (ifmtypei == 1) then
+ aL fmbell kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ elseif (ifmtypei == 2) then
+ aL fmpercfl kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ elseif (ifmtypei == 3) then
+ aL fmrhode kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ elseif (ifmtypei == 4) then
+ aL fmwurlie kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ endif
+ endif
+ if (iright == 1) then
+ kstereo = 1 - (kstereo - 1)
+ ifmtypei = (ifmtype == 5) ? round(random(0, 4)) : ifmtype
+
+ if (ifmtypei == 0) then
+ aR fmb3 kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ elseif (ifmtypei == 1) then
+ aR fmbell kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ elseif (ifmtypei == 2) then
+ aR fmpercfl kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ elseif (ifmtypei == 3) then
+ aR fmrhode kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ elseif (ifmtypei == 4) then
+ aR fmwurlie kamp, kfreq, kc1 * kstereo, kc2 * kstereo, kvibdepth * kstereo, kvibrate * kstereo, ifn1, ifn2, ifn3, ifn4, ifnv
+ endif
+ endif
+ outs aL, aR
+endin
+
+
+opcode _twst_tf_genrepluck, a, kkiiikkkkk
+ kamp, kfn, ipluckpoint, ifreq, ipickuppoint, krefl, kexcitemode, kexcitefn, kexcitefreq, kexciteamp xin
+
+ if (kexcitemode == 0) then
+ aexcite noise kexciteamp, 0.5
+ else
+ aexcite oscilikt kexciteamp, kexcitefreq, kexcitefn
+ endif
+ aout repluck ipluckpoint, kamp, ifreq, ipickuppoint, krefl, aexcite
+ aout dcblock2 aout
+ xout aout
+endop
+
+instr twst_tf_genrepluck
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamp = twst_param:k("amp")
+ kfn twst_tf_getwaveformk
+ ipluckpoint = twst_parami("pluckpoint")
+ ifreq twst_tf_freqi
+ ipickuppoint = twst_parami("pickpoint")
+ krefl = twst_param:k("reflection")
+ kexciteamp = twst_param:k("exciteamp")
+ kexcitemode = twst_param:k("excitemode")
+ kexcitefn twst_tf_getwaveformk twst_param:k("excitewave")
+ kexcitefreq = twst_tf_freq_custom("excite")
+
+ if (ileft == 1) then
+ aL _twst_tf_genrepluck kamp, kfn, ipluckpoint, ifreq, ipickuppoint, krefl, kexcitemode, kexcitefn, kexcitefreq, kexciteamp
+ endif
+ if (iright == 1) then
+ aR _twst_tf_genrepluck kamp, kfn, ipluckpoint, ifreq, ipickuppoint, krefl, kexcitemode, kexcitefn, kexcitefreq, kexciteamp
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_genwgbow
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamp = twst_param:k("amp")
+ kfreq twst_tf_freq
+ kpres = twst_param:k("pressure")
+ kpos = twst_param:k("position")
+ kvibf = twst_param:k("vibfreq")
+ kvamp = twst_param:k("vibamp")
+ ifn twst_tf_getwaveform
+
+ if (ileft == 1) then
+ aL wgbow kamp, kfreq, kpres, kpos, kvibf, kvamp, ifn, 20
+ endif
+ if (iright == 1) then
+ aR wgbow kamp, kfreq, kpres, kpos, kvibf, kvamp, ifn, 20
+ endif
+ outs aL, aR
+endin
+
+/* not quite right, doesn't create sound as expected
+instr twst_tf_genwgbowedbar
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamp = twst_param:k("amp")
+ kfreq twst_tf_freq
+ kpres = twst_param:k("pressure")
+ kpos = twst_param:k("position")
+ kgain = twst_param:k("filtergain")
+
+ if (ileft == 1) then
+ aL wgbowedbar kamp, kfreq, kpos, kpres, kgain
+ endif
+ if (iright == 1) then
+ aR wgbowedbar kamp, kfreq, kpos, kpres, kgain
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_genwgbrass
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamp = twst_param:k("amp")
+ kfreq twst_tf_freq
+ ktension = twst_param:k("tension")
+ iattack = twst_parami("attack")
+ kvibf = twst_param:k("vibfreq")
+ kvamp = twst_param:k("vibamp")
+ ifn twst_tf_getwaveform
+
+ if (ileft == 1) then
+ aL wgbrass kamp, kfreq, ktension, iattack, kvibf, kvamp, ifn, 100
+ endif
+ if (iright == 1) then
+ aR wgbrass kamp, kfreq, ktension, iattack, kvibf, kvamp, ifn, 100
+ endif
+ outs aL, aR
+endin
+*/
+
+instr twst_tf_gennoise
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ktype = twst_param:k("type")
+ kamp = twst_param:k("amp")
+ kbeta = twst_param:k("beta")
+
+ if (ileft == 1) then
+ if (ktype == 0) then
+ aL unirand 2
+ aL = aL - 1
+ elseif (ktype == 1) then
+ aL pinker
+ endif
+ aL *= kamp
+ endif
+ if (iright == 1) then
+ if (ktype == 0) then
+ aR unirand 2
+ aR = aR - 1
+ elseif (ktype == 1) then
+ aR pinker
+ endif
+ aR *= kamp
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_genbamboo
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kamp = twst_param:k("amp")
+ inum = twst_parami("number")
+ ifreq1 = twst_parami("r1freq")
+ ifreq2 = twst_parami("r2freq")
+ ifreq3 = twst_parami("r3freq")
+
+ if (ileft == 1) then
+ aL bamboo kamp, 0, inum, 0, 0, ifreq1, ifreq2, ifreq3
+ endif
+ if (iright == 1) then
+ aR bamboo kamp, 0, inum, 0, 0, ifreq1, ifreq2, ifreq3
+ endif
+ outs aL, aR
+endin
+
+/* opcode unavailable in WASM
+{name: "Fractal noise", instr: "twst_tf_genfractalnoise", parameters: [
+ {name: "Type", options: ["White", "Pink", "Brown"], automatable: true, description: "Type of noise"},
+ {preset: "amp"},
+ {preset: "applymode"}
+]}
+
+instr twst_tf_genfractalnoise
+ aL, aR, ileft, iright twst_getinput
+ ktype = twst_param:k("type")
+ kamp = twst_param:k("amp")
+
+ if (ileft == 1) then
+ aL fractalnoise kamp, ktype
+ endif
+ if (iright == 1) then
+ aR fractalnoise kamp, ktype
+ endif
+ outs aL, aR
+endin
+*/
diff --git a/site/udo/twist/transforms/granular.udo b/site/udo/twist/transforms/granular.udo new file mode 100755 index 0000000..c25a517 --- /dev/null +++ b/site/udo/twist/transforms/granular.udo @@ -0,0 +1,138 @@ +#include "/twist/transform_api.udo"
+#include "/fx_autoglitch.udo"
+#include "/sample_level.udo"
+
+instr twst_tfi_rearrange
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ istereounique = twst_parami("stereounique")
+ ichops = twst_parami("chopnumber")
+ ichopmin = twst_parami("chopmin")
+ ichopmax = twst_parami("chopmax")
+ ifnL, ifnR twst_tfi_getfn
+ if (ileft == 1 && iright == 1) then
+ if (istereounique == 1) then
+ aL smp_rearrange ichops, ichopmin, ichopmax, ifnL
+ aR smp_rearrange ichops, ichopmin, ichopmax, ifnR
+ else
+ aL, aR smp_rearrange ichops, ichopmin, ichopmax, ifnL, ifnR
+ endif
+ elseif (ileft == 1) then
+ aL smp_rearrange ichops, ichopmin, ichopmax, ifnL
+ elseif (iright == 1) then
+ aR smp_rearrange ichops, ichopmin, ichopmax, ifnR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tfi_grain
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ kamp = twst_param:k("amp")
+ kpitch = twst_tf_pitchscale()
+ kdensity = twst_param:k("density")
+ kgrainsize = twst_param:k("grainsize")
+ kampvar = twst_param:k("ampvar")
+ kpitchvar = twst_param:k("pitchvar")
+ irandom = twst_parami("randomread")
+ ifnWindow = twst_tf_getwintype()
+
+ ifnL, ifnR twst_tfi_getfn
+
+ kpitch *= (sr / ftlen(ifnL))
+
+ if (ileft == 1) then
+ aL grain kamp, kpitch, kdensity, kampvar, kpitchvar, kgrainsize, ifnL, ifnWindow, 0.5, irandom
+ endif
+ if (iright == 1) then
+ aR grain kamp, kpitch, kdensity, kampvar, kpitchvar, kgrainsize, ifnR, ifnWindow, 0.5, irandom
+ endif
+ outs aL, aR
+endin
+
+instr twst_tfi_syncgrain
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ kamp = twst_param:k("amp")
+ kfreq = twst_param:k("frequency")
+ kpitch = twst_tf_pitchscale()
+ kgrsize = twst_param:k("grainsize")
+ ioverlaps = twst_parami("overlaps")
+ itimescale = twst_parami("timescale")
+ ifnWindow = twst_tf_getwintype()
+
+ iprate = (1 / ioverlaps) * itimescale
+ p3 = ilength * itimescale
+
+ ifnL, ifnR twst_tfi_getfn
+
+ if (ileft == 1) then
+ aL syncgrain kamp, kfreq, kpitch, kgrsize, iprate, ifnL, ifnWindow, ioverlaps
+ endif
+ if (iright == 1) then
+ aR syncgrain kamp, kfreq, kpitch, kgrsize, iprate, ifnR, ifnWindow, ioverlaps
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_autoglitch
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kminratio = twst_param:k("minratio")
+ kchangerate = twst_param:k("changerate")
+ kchangechance = twst_param:k("changechance")
+ kporttime = twst_param:k("porttime")
+ kdo_distortion = twst_param:k("distortion")
+ kdo_ampchange = twst_param:k("ampchange")
+ ibuflens = twst_parami("buflens")
+ kreadmode = twst_param:k("readmode")
+ istereounique = twst_parami("stereounique")
+
+ twst_setlatencyseconds ibuflens
+
+ if (ileft == 1 && iright == 1) then
+ aL, aR fx_autoglitch aL, aR, kminratio, kchangerate, kchangechance, kporttime, kdo_distortion, kdo_ampchange, ibuflens, istereounique, kreadmode
+ elseif (ileft == 1) then
+ aL fx_autoglitch aL, kminratio, kchangerate, kchangechance, kporttime, kdo_distortion, kdo_ampchange, ibuflens, kreadmode
+ elseif (iright == 1) then
+ aR fx_autoglitch aR, kminratio, kchangerate, kchangechance, kporttime, kdo_distortion, kdo_ampchange, ibuflens, kreadmode
+ endif
+ outs aL, aR
+endin
+
+instr twst_tfi_retriglitch
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ ktriglen = twst_param:k("triglen")
+ kpitchscale = twst_tf_pitchscale()
+ kapplywindowing = twst_param:k("applywindowing")
+ ireadmode = twst_parami("readmode")
+ kwintype twst_tf_getwintypek
+
+ p3 = ilength
+ if (ireadmode == 0) then
+ atime linseg 0, p3, ilength
+ elseif (ireadmode == 1) then
+ ktime = twst_param:k("readtime")
+ twst_tf_setplayposition ktime
+ atime = a(ktime * ilength)
+ elseif (ireadmode == 2) then
+ itimescale = twst_parami("timescale")
+ p3 = ilength * itimescale
+ atime linseg 0, p3, ilength
+ elseif (ireadmode == 3) then
+ atime linseg ilength, p3, 0
+ elseif (ireadmode == 4) then
+ atime init -1
+ endif
+
+ ifnL, ifnR twst_tfi_getfn
+
+ if (ileft == 1) then
+ aL fx_retrigglitch ifnL, ktriglen, atime, kpitchscale, kapplywindowing, kwintype
+ endif
+ if (iright == 1) then
+ aR fx_retrigglitch ifnR, ktriglen, atime, kpitchscale, kapplywindowing, kwintype
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/harmonic.udo b/site/udo/twist/transforms/harmonic.udo new file mode 100755 index 0000000..717de44 --- /dev/null +++ b/site/udo/twist/transforms/harmonic.udo @@ -0,0 +1,142 @@ +#include "/twist/transform_api.udo"
+
+instr twst_tf_resony
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq twst_tf_freq
+ kbw = twst_param:k("bandwidth")
+ inum = twst_parami("num")
+ ksep = twst_param:k("separation")
+ isepmode = twst_parami("sepmode")
+ ibalance = twst_parami("balance")
+
+ if (ileft == 1) then
+ aLr resony aL, kfreq, kbw, inum, ksep, isepmode
+ if (ibalance == 1) then
+ aL balance aLr, aL
+ else
+ aL = aLr
+ endif
+ endif
+ if (iright == 1) then
+ aRr resony aR, kfreq, kbw, inum, ksep, isepmode
+ if (ibalance == 1) then
+ aR balance aRr, aR
+ else
+ aR = aRr
+ endif
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_resonx
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq twst_tf_freq
+ kbw = twst_param:k("bandwidth")
+ inum = twst_parami("num")
+ ibalance = twst_parami("balance")
+
+ if (ileft == 1) then
+ aLr resonx aL, kfreq, kbw, inum
+ if (ibalance == 1) then
+ aL balance aLr, aL
+ else
+ aL = aLr
+ endif
+ endif
+ if (iright == 1) then
+ aRr resonx aR, kfreq, kbw, inum
+ if (ibalance == 1) then
+ aR balance aRr, aR
+ else
+ aR = aRr
+ endif
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_streson
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq twst_tf_freq
+ kfeedback = twst_param:k("feedback")
+ if (ileft == 1) then
+ aL streson aL, kfreq, kfeedback
+ endif
+ if (iright == 1) then
+ aR streson aR, kfreq, kfeedback
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_mvmfilter
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfreq = twst_param:k("freq")
+ kdecay = twst_param:k("decay")
+ kbalance = twst_param:k("balance")
+ if (ileft == 1) then
+ aLf mvmfilter aL, kfreq, kdecay
+ if (kbalance == 1) then
+ aL balance aLf, aL
+ else
+ aL = aLf
+ endif
+ endif
+ if (iright == 1) then
+ aRf mvmfilter aR, kfreq, kdecay
+ if (kbalance == 1) then
+ aL balance aRf, aR
+ else
+ aR = aRf
+ endif
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_harmon
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kestfreq = twst_param:k("estfreq")
+ kmaxvar = twst_param:k("maxvar")
+ kgenfreq1 = twst_param:k("genfreq1")
+ kgenfreq2 = twst_param:k("genfreq2")
+ iminfreq = twst_parami("minfreq")
+ ianalysistime = twst_parami("analysistime")
+ if (ileft == 1) then
+ aL harmon aL, kestfreq, kmaxvar, kgenfreq1, kgenfreq2, 0, iminfreq, ianalysistime
+ endif
+ if (iright == 1) then
+ aR harmon aR, kestfreq, kmaxvar, kgenfreq1, kgenfreq2, 0, iminfreq, ianalysistime
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_formantharmon
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kgenfreq1 = twst_param:k("genfreq1")
+ kgenfreq2 = twst_param:k("genfreq2")
+ kgenfreq3 = twst_param:k("genfreq3")
+ kgenfreq4 = twst_param:k("genfreq4")
+ iminfreq = octcps:i(twst_parami("minfreq"))
+ ipolarity = twst_parami("polarity")
+
+ ipupdate = twst_parami("pupdate")
+ iplow = octcps:i(twst_parami("plowfreq"))
+ iphigh = octcps:i(twst_parami("phighfreq"))
+ ipthresh = dbamp:i(twst_parami("pthresh"))
+ ipfrqs = twst_parami("pfrqs")
+ ipconfirm = twst_parami("pconfirms")
+
+ if (ileft == 1) then
+ koct, kamp pitch aL, ipupdate, iplow, iphigh, ipthresh, ipfrqs, ipconfirm
+ aL harmon4 aL, koct, kgenfreq1, kgenfreq2, kgenfreq3, kgenfreq4, 0, iminfreq, ipolarity
+ endif
+ if (iright == 1) then
+ koct, kamp pitch aR, ipupdate, iplow, iphigh, ipthresh, ipfrqs, ipconfirm
+ aR harmon4 aR, koct, kgenfreq1, kgenfreq2, kgenfreq3, kgenfreq4, 0, iminfreq, ipolarity
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/reverb.udo b/site/udo/twist/transforms/reverb.udo new file mode 100755 index 0000000..e6f66ec --- /dev/null +++ b/site/udo/twist/transforms/reverb.udo @@ -0,0 +1,80 @@ +#include "/twist/transform_api.udo"
+
+instr twst_tf_reverb1
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ktime = twst_param:k("time")
+ if (ileft == 1) then
+ aL reverb aL, ktime
+ endif
+ if (iright == 1) then
+ aR reverb aR, ktime
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_reverb2
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ktime = twst_param:k("time")
+ khfdamp = twst_param:k("hfdamp")
+ if (ileft == 1) then
+ aL nreverb aL, ktime, khfdamp
+ endif
+ if (iright == 1) then
+ aR nreverb aR, ktime, khfdamp
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_reverb3
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kroomsize = twst_param:k("roomsize")
+ khfdamp = twst_param:k("hfdamp")
+ if (ileft != 1) then
+ aL noise 0.001, 0.5
+ endif
+ if (iright != 1) then
+ aR noise 0.001, 0.5
+ endif
+ aL, aR freeverb aL, aR, kroomsize, khfdamp
+ outs aL, aR
+endin
+
+instr twst_tf_reverb4
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kfeedback = twst_param:k("feedback")
+ khfdamp = twst_param:k("hfdamp") * (sr / 2)
+ ipitchmod = twst_parami("pitchmod")
+ if (ileft != 1) then
+ aL noise 0.001, 0.5
+ endif
+ if (iright != 1) then
+ aR noise 0.001, 0.5
+ endif
+ aL, aR reverbsc aL, aR, kfeedback, khfdamp, sr, ipitchmod
+ outs aL, aR
+endin
+
+
+instr twst_tf_reverb5
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ iwidth = twst_parami("width")
+ idepth = twst_parami("depth")
+ iheight = twst_parami("height")
+ kposx = twst_param:k("posx") * iwidth
+ kposy = twst_param:k("posy") * idepth
+ kposz = twst_param:k("posz") * iheight
+ if (ileft == 1 && iright == 1) then
+ ainput = (aL + aR) * 0.5
+ elseif (ileft != 1) then
+ ainput = aR
+ else
+ ainput = aL
+ endif
+ aL, aR babo ainput, kposx, kposy, kposz, iwidth, idepth, iheight
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/spectral.udo b/site/udo/twist/transforms/spectral.udo new file mode 100755 index 0000000..b5f2fab --- /dev/null +++ b/site/udo/twist/transforms/spectral.udo @@ -0,0 +1,642 @@ +#include "/twist/transform_api.udo"
+#include "/pvs_tabproc.udo"
+#include "/spectral_transforms.udo"
+#include "/fx_autoglitch.udo"
+#include "/host_platform.udo"
+#include "/addsub.udo"
+
+instr twst_tf_tpvinvert
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kinvertamp = twst_param:k("invertamp")
+ kinvertfreq = twst_param:k("invertfreq")
+
+ if (ileft == 1) then
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_invert kreadyL, itpvdataL, kinvertamp, kinvertfreq
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_invert kreadyR, itpvdataR, kinvertamp, kinvertfreq
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+
+instr twst_tf_tpvbubble
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kchance = twst_param:k("chance")
+ kstereounique = twst_param:k("stereounique")
+
+ if (ileft == 1) then
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_bubble kreadyL, itpvdataL, kchance, kstereounique
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_bubble kreadyR, itpvdataR, kchance, kstereounique
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_tpvsmear
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ imaxframes = twst_parami("maxframes")
+ kframes = twst_param:k("frames")
+ kavgfreqs = twst_param:k("avgfreqs")
+ kincludeoriginal = twst_param:k("includeoriginal")
+
+ if (ileft == 1) then
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_smear kreadyL, itpvdataL, imaxframes, kframes, kavgfreqs, kincludeoriginal
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_smear kreadyR, itpvdataR, imaxframes, kframes, kavgfreqs, kincludeoriginal
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+
+instr twst_tf_tpvscramble
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kstep = twst_param:k("step")
+ kdoamp = twst_param:k("scrambleamp")
+ kdofreq = twst_param:k("scramblefreq")
+
+ if (ileft == 1) then
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_scramble kreadyL, itpvdataL, kstep, kdoamp, kdofreq
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_scramble kreadyR, itpvdataR, kstep, kdoamp, kdofreq
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_tpvthreshold
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kthreshold = twst_param:k("threshold")
+ kdirection = twst_param:k("direction")
+
+ if (ileft == 1) then
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_threshold kreadyL, itpvdataL, kthreshold, kdirection
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_threshold kreadyR, itpvdataR, kthreshold, kdirection
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_tpvfreeze
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kfreeze = twst_param:k("freeze")
+ kfreezeamp = twst_param:k("freezeamp")
+ kfreezefreq = twst_param:k("freezefreq")
+ kcrossfade = twst_param:k("crossfade")
+
+ if (ileft == 1) then
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_freeze1 kreadyL, itpvdataL, kfreeze, kfreezeamp, kfreezefreq, kcrossfade
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_freeze1 kreadyR, itpvdataR, kfreeze, kfreezeamp, kfreezefreq, kcrossfade
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_tpvwrap
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kwrapampbin = twst_param:k("wrapampbin")
+ kwrapfreqbin = twst_param:k("wrapfreqbin")
+
+ if (ileft == 1) then
+ i_, inumbins, i_, i_ pvsinfo fL
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_wrap kreadyL, itpvdataL, kwrapampbin * inumbins, kwrapfreqbin * inumbins
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ i_, inumbins, i_, i_ pvsinfo fR
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_wrap kreadyR, itpvdataR, kwrapampbin * inumbins, kwrapfreqbin * inumbins
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_tpvswap
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kampStart = twst_param:k("ampstart")
+ kampLength = twst_param:k("amplength")
+ kampTarget = twst_param:k("amptarget")
+ kfreqStart = twst_param:k("freqstart")
+ kfreqLength = twst_param:k("freqlength")
+ kfreqTarget = twst_param:k("freqtarget")
+ kwrapmode = twst_param:k("wrapmode")
+
+ if (ileft == 1) then
+ i_, inumbins, i_, i_ pvsinfo fL
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_swap kreadyL, itpvdataL, kampStart * inumbins, kampLength * inumbins, kampTarget * inumbins, kfreqStart * inumbins, kfreqLength * inumbins, kfreqTarget * inumbins, kwrapmode
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ i_, inumbins, i_, i_ pvsinfo fR
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_swap kreadyR, itpvdataR, kampStart * inumbins, kampLength * inumbins, kampTarget * inumbins, kfreqStart * inumbins, kfreqLength * inumbins, kfreqTarget * inumbins, kwrapmode
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_tpvaverage
+ $TWST_TRANSFORM
+ setksmps(64)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kmax = twst_param:k("maxframes")
+ kavgamp = twst_param:k("avgamp")
+ kavgfreq = twst_param:k("avgfreq")
+ krate = twst_param:k("rate")
+
+ ktrig metro krate
+
+ if (ileft == 1) then
+ kreadyL, itpvdataL tpv_anal fL
+ tpv_average kreadyL, itpvdataL, kmax, kavgamp, kavgfreq, ktrig
+ fL tpv_resynth itpvdataL, fL
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ kreadyR, itpvdataR tpv_anal fR
+ tpv_average kreadyR, itpvdataR, kmax, kavgamp, kavgfreq, ktrig
+ fR tpv_resynth itpvdataR, fR
+ aR twst_tf_fresynth fR
+ endif
+ outs aL, aR
+endin
+
+
+/*
+instr twst_tf_stencil
+ $TWST_TRANSFORM
+ Spvx = strcat(host_tempdir(), "twist_stencil.pvx")
+ ifftsize = twst_parami("fftsize")
+ kran init 0
+ ktimek timeinstk
+ if (ktimek == 1) then
+ ifnL, ifnR, istart, ilen, ileft, iright twst_getcrossdata
+ ikcycles = round(ilen / kr)
+ kcount = 1
+ while (kcount < ikcycles) do
+ aLo, aRo, ileft, iright twst_getcrossinput
+ if (ileft == 1 && iright == 1) then
+ ain = (aLo + aRo) * 0.5
+ elseif (ileft == 1) then
+ ain = aLo
+ elseif (iright == 1) then
+ ain = aRo
+ endif
+ f1 pvsanal ain, ifftsize, ifftsize/4, ifftsize, 1
+ pvsfwrite f1, Spvx
+ kcount += 1
+ od
+
+ elseif (ktimek == 1) then
+ schedulek("_twst_tf_stencilplayback", 0, p3, p4, Spvx) ; TODO : won't work offline
+ endif
+
+ aL, aR bus_read "stencilplayback"
+ kreleasing init 0
+ if (kreleasing == 0 && release:k() == 1) then
+ turnoff2 "_twst_tf_stencilplayback", 0, 1
+ kreleasing = 1
+ endif
+
+ outs aL, aR
+endin
+
+instr _twst_tf_stencilplayback
+ $TWST_TRANSFORM
+ Spvx = strget(p5)
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ ifftsize = twst_parami("fftsize")
+ kgain = twst_param:k("gain")
+ klevel = twst_param:k("level")
+
+ ifn ftgentmp 0, 0, (ifftsize * 2) + 1, 43, Spvx, 1
+
+ if (ileft == 1) then
+ fpsL pvstencil fL, kgain, klevel, ifn
+ aL twst_tf_fresynth fpsL
+ endif
+ if (iright == 1) then
+ fpsR pvstencil fR, kgain, klevel, ifn
+ aR twst_tf_fresynth fpsR
+ endif
+ bus_mix("stencilplayback", aL, aR)
+endin
+*/
+
+instr twst_tf_spectralshift
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kfreqincr = twst_param:k("freqincr")
+ kporttime = twst_param:k("porttime")
+ kfreqscale = twst_tf_pitchscale()
+ istart = twst_parami("start")
+ iend = twst_parami("end")
+ ifn = twst_tf_getwaveform()
+
+ if (ileft == 1) then
+ aL spc_shift fL, kfreqincr, istart, iend, kfreqscale, kporttime, ifn
+ endif
+ if (iright == 1) then
+ aR spc_shift fR, kfreqincr, istart, iend, kfreqscale, kporttime, ifn
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_spectraldelay
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kdeltime = twst_param:k("time")
+ kdeladd = twst_param:k("add")
+ kporttime = twst_param:k("porttime")
+ kfreqscale = twst_tf_pitchscale()
+ istart = twst_parami("start")
+ iend = twst_parami("end")
+ ifn = twst_tf_getwaveform()
+
+ if (ileft == 1) then
+ aL spc_delay fL, kdeltime, kdeladd, istart, iend, kfreqscale, kporttime, ifn
+ endif
+ if (iright == 1) then
+ aR spc_delay fR, kdeltime, kdeladd, istart, iend, kfreqscale, kporttime, ifn
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_spectralgate
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kthresh = twst_param:k("threshold")
+ khold = twst_param:k("hold")
+ kporttime = twst_param:k("porttime")
+ kfreqscale = twst_tf_pitchscale()
+ istart = twst_parami("start")
+ iend = twst_parami("end")
+ ifn = twst_tf_getwaveform()
+
+ if (ileft == 1) then
+ aL spc_gate fL, kthresh, khold, istart, iend, kfreqscale, kporttime, ifn
+ endif
+ if (iright == 1) then
+ aR spc_gate fR, kthresh, khold, istart, iend, kfreqscale, kporttime, ifn
+ endif
+ outs aL, aR
+endin
+
+instr twst_tfi_spectralgrain1
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ ifnL, ifnR twst_tfi_getfn
+
+ ireadmode = twst_parami("readmode")
+ if (ireadmode == 0) then
+ ktime linseg 0, p3, ilength
+ elseif (ireadmode == 1) then
+ ktime = twst_param:k("readtime")
+ twst_tf_setplayposition ktime
+ ktime *= ilength
+ elseif (ireadmode == 2) then
+ itimescale = twst_parami("timescale")
+ p3 = ilength * itimescale
+ ktime linseg 0, p3, ilength
+ elseif (ireadmode == 3) then
+ ktime linseg ilength, p3, 0
+ endif
+
+ kgraindur = twst_param:k("graindur")
+ ifftsize = twst_parami("fftsize")
+ ilayers = twst_parami("layers")
+ kporttime = twst_param:k("porttime")
+ kfreqscale = twst_tf_pitchscale()
+ kfreqrand = twst_param:k("freqrand")
+ kdurrand = twst_param:k("durrand")
+ kpitchrand = twst_param:k("pitchrand")
+ istart = twst_parami("start")
+ iend = twst_parami("end")
+ ifn = twst_tf_getwaveform()
+ twst_setlatencysamples(ifftsize)
+
+ if (ileft == 1) then
+ aL spc_grain1 ifnL, ktime, kgraindur, ifftsize, ilayers, istart, iend, kfreqscale, kfreqrand, kdurrand, kpitchrand, kporttime, ifn
+ endif
+ if (iright == 1) then
+ aR spc_grain1 ifnR, ktime, kgraindur, ifftsize, ilayers, istart, iend, kfreqscale, kfreqrand, kdurrand, kpitchrand, kporttime, ifn
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_spectralread
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ ifftsize = twst_parami("fftsize")
+ ktime = twst_param:k("readtime") * ilength
+ twst_tf_setplayposition ktime
+ twst_setlatencysamples(ifftsize)
+
+ ktimek timeinstk
+ ilensamps = iendsamp - istartsamp
+ ikcycles = ilength * kr
+ kcount init 0
+ if (ktimek == 1) then
+ while (kcount < ikcycles) do
+ apos linseg 0, ilength, iendsamp
+ if (ileft == 1 && iright == 1) then
+ aL table3 apos, gitwst_bufferL[gitwst_instanceindex]
+ aR table3 apos, gitwst_bufferR[gitwst_instanceindex]
+ asig = (aL + aR) * 0.5
+ elseif (ileft == 1) then
+ asig table3 apos, gitwst_bufferL[gitwst_instanceindex]
+ elseif (iright == 1) then
+ asig table3 apos, gitwst_bufferR[gitwst_instanceindex]
+ endif
+ fsig pvsanal asig, ifftsize, ifftsize/4, ifftsize, 1
+ ipbuf, k_ pvsbuffer fsig, ilength
+ kcount += 1
+ od
+ else
+ if (ileft == 1) then
+ fL pvsbufread ktime, ipbuf
+ aL twst_tf_fresynth fL
+ endif
+ if (iright == 1) then
+ fR pvsbufread ktime, ipbuf
+ aR twst_tf_fresynth fR
+ endif
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_centroidoscillator
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kporttime = twst_param:k("porttime")
+ kfreqscale = twst_tf_pitchscale()
+ kfn twst_tf_getwaveformk
+
+ if (ileft == 1) then
+ kcent pvscent fL
+ kfreq portk kcent * kfreqscale, kporttime
+ aL oscilikt 1, kfreq, kfn
+ endif
+ if (iright == 1) then
+ kcent pvscent fR
+ kfreq portk kcent * kfreqscale, kporttime
+ aR oscilikt 1, kfreq, kfn
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_binoscillator
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kporttime = twst_param:k("porttime")
+ kbin = twst_param:k("bin")
+ kfreqscale = twst_tf_pitchscale()
+ kfn twst_tf_getwaveformk
+
+ if (ileft == 1) then
+ i_, inumbins, i_, i_ pvsinfo fL
+ kamp, kfreqbase pvsbin fL, round:k(kbin * inumbins)
+ kfreq portk kfreqbase * kfreqscale, kporttime
+ aL oscilikt 1, kfreq, kfn
+ endif
+ if (iright == 1) then
+ i_, inumbins, i_, i_ pvsinfo fR
+ kamp, kfreqbase pvsbin fL, round:k(kbin * inumbins)
+ kfreq portk kfreqbase * kfreqscale, kporttime
+ aR oscilikt 1, kfreq, kfn
+ endif
+ outs aL, aR
+endin
+
+opcode _twst_tf_partialreconstruction, a, aikkkikkki
+ ain, ifftsize, kthresh, kminpoints, kmaxgap, imaxtracks, kampscale, kfreqscale, kmaxtracks, ifn xin
+ ffreq, fphase pvsifd ain, ifftsize, ifftsize/4, 1
+ ftrks partials ffreq, fphase, kthresh, kminpoints, kmaxgap, imaxtracks
+ aout resyn ftrks, kampscale, kfreqscale, kmaxtracks, ifn
+ aout dcblock aout
+ xout aout
+endop
+
+instr twst_tf_partialreconstruction
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ifftsize = twst_parami("fftsize")
+ kthresh = twst_param:k("threshold")
+ kminpoints = twst_param:k("minpoints")
+ kmaxgap = twst_param:k("maxgap")
+ imaxtracks = round(twst_parami("anlmaxtracks") * ifftsize * 0.5)
+ kampscale = twst_param:k("ampscale")
+ kfreqscale = twst_tf_pitchscale()
+ kmaxtracks = round:k(twst_param:k("resmaxtracks") * ifftsize * 0.5)
+ ifn = twst_tf_getwaveform()
+ twst_setlatencysamples(ifftsize)
+
+ if (ileft == 1) then
+ aL _twst_tf_partialreconstruction aL, ifftsize, kthresh, kminpoints, kmaxgap, imaxtracks, kampscale, kfreqscale, kmaxtracks, ifn
+ endif
+ if (iright == 1) then
+ aR _twst_tf_partialreconstruction aR, ifftsize, kthresh, kminpoints, kmaxgap, imaxtracks, kampscale, kfreqscale, kmaxtracks, ifn
+ endif
+ outs aL, aR
+endin
+
+opcode _twst_tf_residual, a, aii
+ ain, ifftsize, ihsize xin
+ ffr, fphs pvsifd ain, ifftsize, ihsize, 1
+ ftrk partials ffr, fphs, 0, 1, 3, 500
+ aout sinsyn ftrk, 2, 500, gifnSine
+ asd delayr ifftsize / sr
+ asig deltapn ifftsize - ihsize
+ delayw ain
+ xout asig - aout
+endop
+
+instr twst_tf_residual
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ifftsize = twst_parami("fftsize")
+ twst_setlatencysamples(ifftsize)
+ ihsize = ifftsize / 4
+ if (ileft == 1) then
+ aL _twst_tf_residual aL, ifftsize, ihsize
+ endif
+ if (iright == 1) then
+ aR _twst_tf_residual aR, ifftsize, ihsize
+ endif
+ outs aL, aR
+endin
+
+/* not in WASM
+instr twst_tf_trace
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ inumbins = twst_parami("fftsize") / 2
+ kbins = twst_param("bins") * inumbins
+
+ if (ileft == 1) then
+ foutL pvstrace fL, kbins
+ aL twst_tf_fresynth foutL
+ endif
+ if (iright == 1) then
+ foutR pvstrace fR, kbins
+ aR twst_tf_fresynth foutR
+ endif
+ outs aL, aR
+endin
+*/
+
+instr twst_tf_isolator
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kbin = twst_param("bin")
+ kattenuation = twst_param("attenuation")
+ kgain = twst_param("accentuation")
+
+ if (ileft == 1) then
+ foutL pvsarp fL, kbin, kattenuation, kgain
+ aL twst_tf_fresynth foutL
+ endif
+ if (iright == 1) then
+ foutR pvsarp fR, kbin, kattenuation, kgain
+ aR twst_tf_fresynth foutR
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_blur
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ ktime = twst_param:k("time")
+ if (ileft == 1) then
+ fL1 pvsblur fL, ktime, 3
+ aL twst_tf_fresynth fL1
+ endif
+ if (iright == 1) then
+ fR1 pvsblur fR, ktime, 3
+ aR twst_tf_fresynth fR1
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_spectralautoglitch
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kchangerate = twst_param:k("changerate")
+ kchangechance = twst_param:k("changechance")
+ kporttime = twst_param:k("porttime")
+ kdo_pitchalter = twst_param:k("pitchalter")
+ ifftsize = twst_parami("fftsize")
+
+ twst_setlatencysamples ifftsize
+
+ if (ileft == 1) then
+ aL fx_spectralautoglitch aL, kchangerate, kchangechance, kdo_pitchalter, kporttime, ifftsize
+ endif
+ if (iright == 1) then
+ aR fx_spectralautoglitch aR, kchangerate, kchangechance, kdo_pitchalter, kporttime, ifftsize
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_subtractive
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ifreq = twst_parami("minfreq")
+ ifreqmax = twst_parami("maxfreq")
+ ifreqstepmult = twst_parami("step")
+ ifreqstepmultrand = twst_parami("steprand")
+ iamp = twst_parami("amp")
+ iampmult = twst_parami("ampmult")
+
+ if (ileft == 1) then
+ aL as_subtractive aL, ifreq, ifreqmax, ifreqstepmult, ifreqstepmultrand, iamp, iampmult
+ endif
+ if (iright == 1) then
+ aR as_subtractive aR, ifreq, ifreqmax, ifreqstepmult, ifreqstepmultrand, iamp, iampmult
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_phasemash
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ifftsize = twst_parami("fftsize")
+ kphasemode = twst_param:k("phasereplace")
+ kphasevalue = twst_param:k("phasevalue")
+
+ if (kphasemode == 0) then
+ kphasevalue *= 7
+ else
+ kphasevalue = ((kphasevalue * 2) - 1) * 3.141
+ endif
+
+ if (ileft == 1) then
+ aL spc_phasemash aL, kphasemode, kphasevalue, ifftsize
+ endif
+ if (iright == 1) then
+ aR spc_phasemash aR, kphasemode, kphasevalue, ifftsize
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/transforms/warping.udo b/site/udo/twist/transforms/warping.udo new file mode 100755 index 0000000..3eb4e6e --- /dev/null +++ b/site/udo/twist/transforms/warping.udo @@ -0,0 +1,210 @@ +#include "/twist/transform_api.udo"
+#include "/sample_level.udo"
+
+instr twst_tf_smphold
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kratio = twst_param:k("ratio")
+ if (ileft == 1) then
+ aL smp_hold aL, kratio
+ endif
+ if (iright == 1) then
+ aR smp_hold aR, kratio
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_fftpitchscale
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kscale = twst_tf_pitchscale()
+ kformant = twst_param:k("formants")
+ kcoefs = twst_param:k("formantcoefs")
+
+ if (ileft == 1) then
+ fL1 pvscale fL, kscale, kformant, 1, kcoefs
+ aL twst_tf_fresynth fL1
+ endif
+ if (iright == 1) then
+ fR1 pvscale fR, kscale, kformant, 1, kcoefs
+ aR twst_tf_fresynth fR1
+ endif
+ outs aL, aR
+endin
+
+opcode _twst_tf_autotune, f, fkkk
+ fsig, kthreshold, kformant, kcoefs xin
+ kfreq, kamp pvspitch fsig, kthreshold
+ if (kfreq > 20) then
+ knote ftom kfreq
+ kscale = cpsmidinn:k(int:k(knote)) / kfreq
+ fsigo pvscale fsig, kscale, kformant, 1, kcoefs
+ else
+ fsigo = fsig
+ endif
+ xout fsigo
+endop
+
+
+instr twst_tf_autotune
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kthreshold = twst_param:k("threshold")
+ kformant = twst_param:k("formants")
+ kcoefs = twst_param:k("formantcoefs")
+
+ if (ileft == 1) then
+ fL1 _twst_tf_autotune fL, kthreshold, kformant, kcoefs
+ aL twst_tf_fresynth fL1
+ endif
+ if (iright == 1) then
+ fR1 _twst_tf_autotune fR, kthreshold, kformant, kcoefs
+ aR twst_tf_fresynth fR1
+ endif
+ outs aL, aR
+endin
+
+
+instr twst_tf_hilbertpitchscale
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ ifftsize = twst_parami("fftsize")
+ kscale = twst_tf_pitchscale()
+ twst_setlatencysamples(ifftsize)
+
+ if (ileft == 1) then
+ ahL1, ahL2 hilbert2 aL, ifftsize, ifftsize / 4
+ amL, afmL fmanal ahL1, ahL2
+ aL oscil amL, afmL * kscale
+ endif
+ if (iright == 1) then
+ ahR1, ahR2 hilbert2 aR, ifftsize, ifftsize / 4
+ amR, afmR fmanal ahR1, ahR2
+ aR oscil amR, afmR * kscale
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_waveset
+ $TWST_TRANSFORM
+ aL, aR, ileft, iright twst_getinput
+ kreps = twst_param:k("reps")
+ if (ileft == 1) then
+ aL waveset aL, kreps
+ endif
+ if (iright == 1) then
+ aR waveset aR, kreps
+ endif
+ outs aL, aR
+endin
+
+instr twst_tf_freeze
+ $TWST_TRANSFORM
+ fL, fR, aL, aR, ileft, iright twst_getfinput
+ kfreezeamp = twst_param:k("freezeamp")
+ kfreezefreq = twst_param:k("freezefreq")
+ if (ileft == 1) then
+ fL1 pvsfreeze fL, kfreezeamp, kfreezefreq
+ aL twst_tf_fresynth fL1
+ endif
+ if (iright == 1) then
+ fR1 pvsfreeze fR, kfreezeamp, kfreezefreq
+ aR twst_tf_fresynth fR1
+ endif
+ outs aL, aR
+endin
+
+instr twst_tfi_sndwarp
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ ireadmode = twst_parami("readmode")
+ kpitchscale = twst_tf_pitchscale()
+ iwinsize = twst_parami("winsize")
+ irandwin = twst_parami("randwin")
+ ioverlap = twst_parami("overlap")
+ ifnWindow = twst_tf_getwintype()
+
+ p3 = ilength
+ if (ireadmode == 0) then
+ atime linseg 0, p3, ilength
+ elseif (ireadmode == 1) then
+ ktime = twst_param:k("readtime")
+ twst_tf_setplayposition ktime
+ atime = a(ktime * ilength)
+ elseif (ireadmode == 2) then
+ itimescale = twst_parami("timescale")
+ p3 = ilength * itimescale
+ atime linseg 0, p3, ilength
+ elseif (ireadmode == 3) then
+ atime linseg ilength, p3, 0
+ endif
+
+ ifnL, ifnR twst_tfi_getfn
+
+ kpitchscale *= ftsr(ifnL) / sr
+ apitchscale = a(kpitchscale)
+ if (ileft == 1) then
+ aL sndwarp 1, atime, apitchscale, ifnL, 0, iwinsize, irandwin, ioverlap, ifnWindow, 1
+ endif
+ if (iright == 1) then
+ aR sndwarp 1, atime, apitchscale, ifnR, 0, iwinsize, irandwin, ioverlap, ifnWindow, 1
+ endif
+ outs aL, aR
+endin
+
+instr twst_tfi_mincer
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+ ifftsize = twst_parami("fftsize")
+ kpitchscale = twst_tf_pitchscale()
+ klock = twst_param:k("phaselock")
+ ireadmode = twst_parami("readmode")
+ idecimation = twst_parami("decimation")
+
+ p3 = ilength
+ if (ireadmode == 0) then
+ atime linseg 0, p3, ilength
+ elseif (ireadmode == 1) then
+ ktime = twst_param:k("readtime")
+ twst_tf_setplayposition ktime
+ atime = a(ktime * ilength)
+ elseif (ireadmode == 2) then
+ itimescale = twst_parami("timescale")
+ p3 = ilength * itimescale
+ atime linseg 0, p3, ilength
+ elseif (ireadmode == 3) then
+ atime linseg ilength, p3, 0
+ endif
+
+ twst_setlatencysamples(ifftsize)
+ ifnL, ifnR twst_tfi_getfn
+ if (ileft == 1) then
+ aL mincer atime, 1, kpitchscale, ifnL, klock, ifftsize, idecimation
+ endif
+ if (iright == 1) then
+ aR mincer atime, 1, kpitchscale, ifnR, klock, ifftsize, idecimation
+ endif
+ outs aL, aR
+endin
+
+instr twst_tfi_paulstretch
+ $TWST_TRANSFORM
+ ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
+
+ istretch = twst_parami("stretch")
+ iwinsize = twst_parami("winsize")
+ iduration = ilength * istretch
+ p3 = iduration
+
+ twst_setlatencyseconds iwinsize
+
+ ifnL, ifnR twst_tfi_getfn
+
+ if (ileft == 1) then
+ aL paulstretch istretch, iwinsize, ifnL
+ endif
+ if (iright == 1) then
+ aR paulstretch istretch, iwinsize, ifnR
+ endif
+ outs aL, aR
+endin
diff --git a/site/udo/twist/twist.udo b/site/udo/twist/twist.udo new file mode 100755 index 0000000..34fa7cb --- /dev/null +++ b/site/udo/twist/twist.udo @@ -0,0 +1,1304 @@ +#ifndef UDO_TWIST
+#define UDO_TWIST ##
+/*
+ Twist
+ Waveform editor and transformer
+
+ This file is part of the SONICS UDO collection by Richard Knight 2024
+ License: GPL-2.0-or-later
+ http://1bpm.net
+*/
+
+
+#include "/table_tools.udo"
+#include "/host_platform.udo"
+#include "/wavetables.udo"
+#include "/interop.udo"
+#include "/bussing.udo"
+#include "/chop.udo"
+#include "/transient_detect.udo"
+
+#ifdef TWST_FAILONLAG
+#include "/lagdetect.udo"
+#end
+
+gitwst_userstopped = 0
+imaxinstances = 16
+gitwst_instanceindex = 0
+gitwst_channels[] init imaxinstances
+gitwst_duration[] init imaxinstances
+gitwst_bufferL[] init imaxinstances
+gitwst_bufferR[] init imaxinstances
+
+gitwst_copyBufferL = 0
+gitwst_copyBufferR = 0
+
+gitwst_tf_state[] init 7
+
+#include "/twist/checkpointing.udo"
+
+opcode twst_clearbuffers, 0, jj
+ ibufferL, ibufferR xin
+ ibufferL = (ibufferL == -1) ? gitwst_bufferL[gitwst_instanceindex] : ibufferL
+ ibufferR = (ibufferR == -1) ? gitwst_bufferR[gitwst_instanceindex] : ibufferR
+
+ if (ibufferL > 0 && ftexists(ibufferL) == 1) then
+ ftfree ibufferL, 1
+ endif
+ if (ibufferR > 0 && ftexists(ibufferR) == 1) then
+ ftfree ibufferR, 1
+ endif
+endop
+
+opcode twst_samplestoratio, ii, iij
+ istart, iend, instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ itotallen = ftlen(gitwst_bufferL[instanceindex])
+ if (istart > 1 && iend > 1) then
+ istart /= itotallen
+ iend /= itotallen
+ endif
+ xout istart, iend
+endop
+
+opcode twst_getstartend, iii, iij
+ istart, iend, instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ itotallen = ftlen(gitwst_bufferL[instanceindex])
+ if (istart <= 1 && iend <= 1) then
+ istart *= itotallen
+ iend *= itotallen
+ ilen = int(iend - istart)
+ istart = int(istart)
+ iend = int(iend)
+ else
+ istart = max(0, istart)
+ iend = min(itotallen, iend)
+ ilen = iend - istart
+ endif
+ xout istart, ilen, iend
+endop
+
+opcode twst_getstartend, ii, iij
+ istart, iend, instanceindex xin
+ istart, ilen, iend twst_getstartend istart, iend, instanceindex
+ xout istart, ilen
+endop
+
+#include "/twist/transform_api.udo"
+
+opcode twst_createoverviewsextra, S, iSjjjp
+ icbid, Sextra, iselstart, iselend, instanceindex, istatus xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+
+ iduration = ftlen(gitwst_bufferL[instanceindex]) / ftsr(gitwst_bufferL[instanceindex])
+ if (qnan(iduration) == 1) then
+ iduration = 1
+ endif
+ gitwst_duration[instanceindex] = iduration
+ Sresponse = sprintf("{\"cbid\":%d,\"status\":%d,\"waveL\":%d,\"duration\":%f,\"undolevel\":%d", icbid, istatus, gitwst_bufferL[instanceindex], iduration, gitwst_checkpointstate[instanceindex])
+ if (gitwst_channels[instanceindex] == 2) then
+ Sresponse = strcat(Sresponse, sprintf(",\"waveR\":%d", gitwst_bufferR[instanceindex]))
+ endif
+
+ if (iselstart != -1 && iselend != -1) then
+ iselstart, iselend twst_samplestoratio iselstart, iselend, instanceindex
+ Sresponse = strcat(Sresponse, sprintf(",\"selstart\":%f,\"selend\":%f", iselstart, iselend))
+ endif
+
+ if (strcmp(Sextra, "") != 0) then
+ Sresponse = strcat(Sresponse, strcat(",", Sextra))
+ endif
+
+ xout strcat(Sresponse, "}")
+endop
+
+opcode twst_createoverviews, S, ijjp
+ icbid, iselstart, iselend, istatus xin
+ Sresponse twst_createoverviewsextra icbid, "", iselstart, iselend, -1, istatus
+ xout Sresponse
+endop
+
+
+opcode twst_failresponse, S, ij
+ icbid, istatus xin
+ xout sprintf("{\"cbid\":%d,\"status\":%d}", icbid, istatus)
+endop
+
+instr twst_successresponse
+ icbid = p4
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1}", icbid))
+ turnoff
+endin
+
+instr twst_checkalive
+ icbid = p4
+ io_sendstring("callback", sprintf("{\"cbid\": %d}", icbid))
+ turnoff
+endin
+
+opcode twst_setapplymode, aa, iaaaa
+ iuniqueid, aLorig, aRorig, aLnew, aRnew xin
+ kapplymode chnget sprintf("applymode%d", iuniqueid)
+ kdry chnget sprintf("applymodedry%d", iuniqueid)
+ kwet chnget sprintf("applymodewet%d", iuniqueid)
+ khpf chnget sprintf("applymodehpf%d", iuniqueid)
+ klpf chnget sprintf("applymodelpf%d", iuniqueid)
+
+ ; applymode 0 is replace
+ if (kapplymode == 1) then ; mix
+ aLnew = (aLorig * kdry) + (aLnew * kwet)
+ aRnew = (aRorig * kdry) + (aRnew * kwet)
+ elseif (kapplymode == 2) then ; modulate
+ aLnew = aLorig * aLnew
+ aRnew = aRorig * aRnew
+ elseif (kapplymode == 3) then ; demodulate
+ aLnew = tanh(aLorig / aLnew)
+ aRnew = tanh(aRorig / aRnew)
+ elseif (kapplymode == 4) then ; filter mix
+ kbw = klpf - khpf
+ kfreq = khpf + (kbw / 2)
+ aLbp butterbp aLnew, kfreq, kbw
+ aLbr butterbr aLorig, kfreq, kbw
+ aRbp butterbp aRnew, kfreq, kbw
+ aRbr butterbr aRorig, kfreq, kbw
+ aLnew = aLbp + aLbr
+ aRnew = aRbp + aRbr
+ endif
+ xout aLnew, aRnew
+endop
+
+
+opcode twst_playback, iaaiiiii, iiiSiioooOPo
+ istart, iend, ichannel, Stransform, ioffline, iautomating, icrossfadein, icrossfadeout, iuniqueid xin
+ itransforming = strcmp(Stransform, "")
+ if (istart == iend) then
+ istart = istart
+ iend = 1
+ endif
+
+ istatus = 1
+ itfi = (strcmp(strsub(Stransform, 5, 8), "tfi") == 0) ? 1 : 0
+ ibuflen = ftlen(gitwst_bufferL[gitwst_instanceindex])
+ istartsamp = ibuflen * istart
+ iendsamp = ibuflen * iend
+ iendsampw = iendsamp
+ ilensamp = iendsamp - istartsamp
+ iextracycles = 0
+ idurations = ilensamp / ftsr(gitwst_bufferL[gitwst_instanceindex])
+ p3 = idurations
+ icrossfadeins = idurations * icrossfadein
+ icrossfadeouts = idurations * icrossfadeout
+
+ ileft = 1
+ iright = 1
+ if (ichannel == 0 || gitwst_channels[gitwst_instanceindex] == 1) then
+ iright = 0
+ elseif (ichannel == 1 && gitwst_channels[gitwst_instanceindex] == 2) then
+ ileft = 0
+ endif
+
+ if (ioffline == 1) then
+ idelaysamples = gitwst_tf_state[5]
+ if (idelaysamples > 0) then
+ idelays = idelaysamples / sr
+ iextracycles = round(kr * idelays)
+ else
+ idelays = 0
+ endif
+ else
+ idelaysamples = 0
+ iextracycles = 0
+ idelays = 0
+ endif
+
+ gitwst_tf_state[0] = ileft
+ gitwst_tf_state[1] = iright
+ gitwst_tf_state[2] = istartsamp
+ gitwst_tf_state[3] = iendsamp
+ gitwst_tf_state[5] = 0 ; latency for fft processing etc
+ gitwst_tf_state[6] = ioffline
+
+ aL init 0
+ aR init 0
+ ifnL = gitwst_bufferL[gitwst_instanceindex]
+ ifnR = gitwst_bufferR[gitwst_instanceindex]
+ ifnTargetL = gitwst_bufferL[gitwst_instanceindex]
+ ifnTargetR = gitwst_bufferR[gitwst_instanceindex]
+
+ if (itfi == 1) then
+ idocut = 0
+ if (istart != 0 && iend != 1) then
+ idocut = 1
+ endif
+
+ ; only 4 pfields in subinstr allowed
+ gitwst_tf_state[4] = idocut
+ aoutL, aoutR subinstr Stransform, iuniqueid
+ ; aoutL, aoutR twst_setapplymode iuniqueid, aL, aR, aoutL, aoutR ; no applymode for tfi
+ if (iautomating == 1) then
+ a_ subinstr "twst_automaterun"
+ endif
+
+ if (ioffline == 1) then
+ itargetlen = int(p3 * sr)
+ iextracycles += (p3 * kr)
+ iendsampw = istartsamp + itargetlen
+
+ if (p3 != idurations) then
+ inewlen = (ftlen(gitwst_bufferL[gitwst_instanceindex]) - ilensamp) + itargetlen
+ if (inewlen >= gihost_max32bitftlen) then ; limitation with WASM Csound build at the moment
+ istatus = -2
+ goto complete
+ endif
+
+ ifnTargetL ftgen 0, 0, -inewlen, -2, 0
+ ifnTargetR ftgen 0, 0, -inewlen, -2, 0
+
+ if (istartsamp != 0) then ; copy part before commit
+ indexr = 0
+ indexw = 0
+ while (indexw < istartsamp - 1) do
+ if (ileft == 1) then
+ tabw_i tab_i(indexr, gitwst_bufferL[gitwst_instanceindex]), indexw, ifnTargetL
+ endif
+ if (iright == 1) then
+ tabw_i tab_i(indexr, gitwst_bufferR[gitwst_instanceindex]), indexw, ifnTargetR
+ endif
+ indexr += 1
+ indexw += 1
+ od
+
+/* aliasing from ftslice???
+ if (ileft == 1) then
+ ftslicei gitwst_bufferL[gitwst_instanceindex], ifnTargetL, 0, istartsamp, 1
+ endif
+ if (iright == 1) then
+ ftslicei gitwst_bufferR[gitwst_instanceindex], ifnTargetR, 0, istartsamp, 1
+ endif
+*/
+ endif
+
+ if (iendsampw < ftlen(ifnTargetL)) then ; copy part after commit
+ indexr = iendsamp + 1
+ indexw = iendsampw + 1
+ while (indexw < inewlen - 1) do
+ if (ileft == 1) then
+ tabw_i tab_i(indexr, gitwst_bufferL[gitwst_instanceindex]), indexw, ifnTargetL
+ endif
+ if (iright == 1) then
+ tabw_i tab_i(indexr, gitwst_bufferR[gitwst_instanceindex]), indexw, ifnTargetR
+ endif
+ indexr += 1
+ indexw += 1
+ od
+ endif
+ else
+ inewlen = ibuflen
+ endif
+ endif
+ idurations = p3
+
+ else ; is not tfi
+ inewlen = ibuflen ;ilensamp
+ aposr linseg istartsamp, idurations, iendsampw ;iendsamp
+
+ if (ileft == 1) then
+ aL table3 aposr, ifnL
+ endif
+ if (iright == 1) then
+ aR table3 aposr, ifnR
+ endif
+
+ if (itransforming == 1) then
+ if (iautomating == 1) then
+ a_ subinstr "twst_automaterun"
+ endif
+ chnset aL, "twstfeedL"
+ chnset aR, "twstfeedR"
+ aoutL, aoutR subinstr Stransform, iuniqueid
+ aoutL, aoutR twst_setapplymode iuniqueid, aL, aR, aoutL, aoutR
+ else
+ aoutL = aL
+ aoutR = aR
+ endif
+ endif ; end not tfi
+
+ if (ioffline == 0) then
+ chnset -1, "twst_tfplayposratio"
+ kplayposratio chnget "twst_tfplayposratio"
+ if (kplayposratio >= 0) then
+ chnset (kplayposratio * (iend - istart)) + istart, "twst_playposratio"
+ else
+ ktimeenv linseg istart, p3, iend
+ chnset ktimeenv, "twst_playposratio"
+ endif
+ endif
+
+
+ if ((icrossfadein != 0 || icrossfadeout != 0) && (icrossfadein + icrossfadeout) < 1) then
+ icrossfadeins = max(0.0000001, icrossfadeins) ; god damn times can't seem to be 0 in linseg
+ icrossfademids = idurations - (icrossfadeins + icrossfadeouts)
+ icrossfademids = max(0.0000001, icrossfademids)
+ icrossfadeouts = max(0.0000001, icrossfadeouts)
+
+ if (itfi == 1) then
+ imidsamp1 = istartsamp + (icrossfadeins * sr)
+ imidsamp2 = iendsamp - (icrossfadeouts * sr)
+ if (idelays != 0) then
+ aposr linseg istartsamp, idelays, istartsamp, icrossfadeins, imidsamp1, icrossfademids, imidsamp2, icrossfadeouts, iendsamp
+ else
+ aposr linseg istartsamp, icrossfadeins, imidsamp1, icrossfademids, imidsamp2, icrossfadeouts, iendsamp
+ endif
+ if (ileft == 1) then
+ aL table3 aposr, ifnL
+ endif
+ if (iright = 1) then
+ aR table3 aposr, ifnR
+ endif
+
+ endif
+
+ if (idelays != 0) then
+ acrossfade linseg 0, idelays, 0, icrossfadeins, 1, icrossfademids, 1, icrossfadeouts, 0
+ else
+ acrossfade linseg 0, icrossfadeins, 1, icrossfademids, 1, icrossfadeouts, 0
+ endif
+
+ if (ileft == 1) then
+ aoutL = (aL * (1 - acrossfade)) + (aoutL * acrossfade)
+ endif
+ if (iright == 1) then
+ aoutR = (aR * (1 - acrossfade)) + (aoutR * acrossfade)
+ endif
+ endif
+
+ if (chnget:i("twst_dcblockoutputs") == 1) then
+ aoutL dcblock2 aoutL
+ aoutR dcblock2 aoutR
+ endif
+
+ if (chnget:i("twst_tanhoutputs") == 1) then
+ aoutL tanh aoutL
+ aoutR tanh aoutR
+ endif
+
+ anull init 0
+ if (ioffline == 1) then
+ if (itfi == 1) then
+ iendsampw = (idurations * sr) + istartsamp
+ endif
+
+ if (idelays != 0) then
+ aposw linseg istartsamp, idelays, istartsamp, idurations, iendsampw
+ else
+ aposw linseg istartsamp, idurations, iendsampw
+ endif
+
+ if (ileft == 1) then
+ tablew aoutL, aposw, ifnTargetL
+ endif
+ if (iright == 1) then
+ tablew aoutR, aposw, ifnTargetR
+ endif
+ amonitorL = anull
+ amonitorR = anull
+ else
+ amonitorL = aoutL
+ if (gitwst_channels[gitwst_instanceindex] == 1) then
+ amonitorR = amonitorL
+ else
+ amonitorR = aoutR
+ endif
+ endif
+
+ inewlen = ftlen((ifnTargetL > 0) ? ifnTargetL : ifnTargetR)
+
+complete:
+ xout istatus, amonitorL, amonitorR, ifnTargetL, ifnTargetR, iextracycles, istartsamp / inewlen, iendsampw / inewlen
+endop
+
+
+
+instr twst_setinstance
+ icbid = p4
+ gitwst_instanceindex = p5
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1}", icbid))
+ turnoff
+endin
+
+opcode twst_copy, k, opjj
+ istart, iend, ichannel, instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+
+ istart, ilen, iend twst_getstartend istart, iend
+
+ twst_clearbuffers(gitwst_copyBufferL, gitwst_copyBufferR)
+ gitwst_copyBufferL = -1
+ gitwst_copyBufferR = -1
+
+ if (gitwst_channels[instanceindex] == 2 && ichannel == -1) then
+ kdone, gitwst_copyBufferL, gitwst_copyBufferR chop_copyk istart, ilen, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex]
+ elseif (ichannel == 1) then
+ kdone, gitwst_copyBufferR, i_ chop_copyk istart, ilen, gitwst_bufferR[instanceindex]
+ else
+ kdone, gitwst_copyBufferL, i_ chop_copyk istart, ilen, gitwst_bufferL[instanceindex]
+ endif
+ xout kdone
+endop
+
+instr twst_copy
+ icbid = p4
+ istart = p5
+ iend = p6
+ ichannel = p7
+ inocheckpoint = p8
+
+ kdone twst_copy istart, iend, ichannel
+ if (kdone == 1) then
+ schedulek("twst_successresponse", 0, 1, icbid)
+ turnoff
+ endif
+endin
+
+
+opcode twst_trim, k, opjj
+ istart, iend, ichannel, instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ istart, ilen, iend twst_getstartend istart, iend
+
+ kdone init 0
+ kdone, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex] chop_trimk istart, ilen, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex]
+ xout kdone
+endop
+
+instr twst_trim
+ icbid = p4
+ istart = p5
+ iend = p6
+ ichannel = p7
+ inocheckpoint = p8
+
+ if (inocheckpoint == 0) then
+ twst_checkpoint()
+ endif
+
+ kdone twst_trim istart, iend, ichannel
+ if (kdone == 1) then
+ schedulek("twst_overviews_response", 0, 1, icbid, 0, 1)
+ turnoff
+ endif
+endin
+
+
+opcode twst_cut, ki, opjj
+ istart, iend, ichannel, instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ istart, ilen, iend twst_getstartend istart, iend
+
+ twst_clearbuffers(gitwst_copyBufferL, gitwst_copyBufferR)
+ gitwst_copyBufferL = -1
+ gitwst_copyBufferR = -1
+ kdone init 0
+
+ if (gitwst_channels[instanceindex] == 2) then
+ if (ichannel == -1) then
+ kdone, gitwst_copyBufferL, gitwst_copyBufferR, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex] chop_cutk istart, ilen, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex]
+ elseif (ichannel == 0) then
+ kdone1, gitwst_copyBufferL, i_ chop_copyk istart, ilen, gitwst_bufferL[instanceindex]
+ kdone chop_setsilencek istart, ilen, gitwst_bufferL[instanceindex], -1, kdone1
+ elseif (ichannel == 1) then
+ kdone1, gitwst_copyBufferR, i_ chop_copyk istart, ilen, gitwst_bufferR[instanceindex]
+ kdone chop_setsilencek istart, ilen, gitwst_bufferR[instanceindex], -1, kdone1
+ endif
+ else
+ kdone, gitwst_copyBufferL, i_, gitwst_bufferL[instanceindex], i_ chop_cutk istart, ilen, gitwst_bufferL[instanceindex]
+ endif
+
+ inewlen = ftlen(gitwst_bufferL[instanceindex])
+ xout kdone, istart / inewlen
+endop
+
+
+
+instr twst_overviews_response
+ icbid = p4
+ iselstart = p5
+ iselend = p6
+ io_sendstring("callback", twst_createoverviews(icbid, iselstart, iselend))
+ turnoff
+endin
+
+instr twst_cut
+ icbid = p4
+ istart = p5
+ iend = p6
+ ichannel = p7
+ inocheckpoint = p8
+
+ if (inocheckpoint == 0) then
+ twst_checkpoint()
+ endif
+
+ kdone, istart twst_cut istart, iend, ichannel
+ if (kdone == 1) then
+ schedulek("twst_overviews_response", 0, 1, icbid, istart, istart)
+ turnoff
+ endif
+endin
+
+
+opcode twst_delete, ki, opjj
+ istart, iend, ichannel, instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ istart, ilen, iend twst_getstartend istart, iend
+ kdone init 0
+
+ if (gitwst_channels[instanceindex] == 2) then
+ if (ichannel == -1) then
+ kdone, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex] chop_deletek istart, ilen, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex]
+ elseif (ichannel == 0) then
+ kdone chop_setsilencek istart, ilen, gitwst_bufferL[instanceindex]
+ elseif (ichannel == 1) then
+ kdone chop_setsilencek istart, ilen, gitwst_bufferR[instanceindex]
+ endif
+ else
+ kdone, gitwst_bufferL[instanceindex], i_ chop_deletek istart, ilen, gitwst_bufferL[instanceindex]
+ endif
+
+ inewlen = ftlen(gitwst_bufferL[instanceindex])
+ xout kdone, istart / inewlen
+endop
+
+
+instr twst_delete
+ icbid = p4
+ istart = p5
+ iend = p6
+ ichannel = p7
+ inocheckpoint = p8
+
+ if (inocheckpoint == 0) then
+ twst_checkpoint()
+ endif
+
+ kdone, istart twst_delete istart, iend, ichannel
+ if (kdone == 1) then
+ schedulek("twst_overviews_response", 0, 1, icbid, istart, istart)
+ turnoff
+ endif
+endin
+
+opcode twst_trypaste, ikii, ojjpo
+ istart, ichannel, instanceindex, inumber, imix xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ istart, ilen, iend twst_getstartend istart, 1
+ inewlen = ftlen(gitwst_bufferL[instanceindex]) + (ftlen(gitwst_copyBufferL) * inumber)
+
+ if (inewlen >= gihost_max32bitftlen) then ; limitation with WASM Csound build at the moment
+ iresponse = -2
+ goto complete
+ elseif (gitwst_copyBufferL < 1 && gitwst_copyBufferR < 1) then
+ iresponse = -1
+ goto complete
+ endif
+
+ kdone init 0
+ if (gitwst_channels[instanceindex] == 1) then
+ kdone, gitwst_bufferL[instanceindex], i_, ipastelen chop_pastek gitwst_copyBufferL, -1, gitwst_bufferL[instanceindex], -1, istart, inumber, imix
+ elseif (gitwst_copyBufferR > 0 && ichannel == -1) then
+ kdone, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex], ipastelen chop_pastek gitwst_copyBufferL, gitwst_copyBufferR, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex], istart, inumber, imix
+ elseif (ichannel == 0) then
+ isrc = (gitwst_copyBufferL > 0) ? gitwst_copyBufferL : gitwst_copyBufferR
+ kdone1, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex], ipastelen chop_pastek isrc, isrc, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex], istart, inumber, imix
+ kdone chop_setsilencek istart, ilen, gitwst_bufferR[instanceindex], -1, kdone1
+ elseif (ichannel == 1) then
+ isrc = (gitwst_copyBufferR > 0) ? gitwst_copyBufferR : gitwst_copyBufferL
+ kdone1, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex], ipastelen chop_pastek isrc, isrc, gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex], istart, inumber, imix
+ kdone chop_setsilencek istart, ilen, gitwst_bufferL[instanceindex], -1, kdone1
+ endif
+ iresponse = 1
+ inewlen = ftlen(gitwst_bufferL[instanceindex])
+
+complete:
+ xout iresponse, kdone, istart, (istart + ipastelen)
+endop
+
+opcode twst_paste, k, ojjp
+ istart, ichannel, instanceindex, inumber xin
+ istatus, kdone, istart, iend twst_trypaste istart, ichannel, instanceindex, inumber
+ xout kdone
+endop
+
+
+instr twst_paste
+ icbid = p4
+ istart = p5
+ iend = p6
+ ichannel = p7
+ inocheckpoint = p8
+
+ if (inocheckpoint == 0) then
+ twst_checkpoint()
+ endif
+
+ istatus, kdone, istart, iend twst_trypaste istart, ichannel
+ if (istatus < 0) then
+ io_sendstring("callback", twst_failresponse(icbid, istatus))
+ turnoff
+ else
+ if (kdone == 1) then
+ schedulek("twst_overviews_response", 0, 1, icbid, istart, iend)
+ turnoff
+ endif
+ endif
+endin
+
+
+
+instr twst_pastespecial
+ icbid = p4
+ istart = p5
+ iend = p6
+ ichannel = p7
+ inocheckpoint = p8
+
+ if (inocheckpoint == 0) then
+ twst_checkpoint()
+ endif
+
+ inumber = chnget:i(sprintf("%s_repetitions0", nstrstr(p1)))
+ inumber = (inumber < 1) ? 1 : inumber
+ imix = chnget:i(sprintf("%s_mixpaste0", nstrstr(p1)))
+ istatus, kdone, istart, iend twst_trypaste istart, ichannel, -1, inumber, imix
+ if (istatus < 0) then
+ io_sendstring("callback", twst_failresponse(icbid, istatus))
+ turnoff
+ else
+ if (kdone == 1) then
+ schedulek("twst_overviews_response", 0, 1, icbid, istart, iend)
+ turnoff
+ endif
+ endif
+endin
+
+
+instr twst_nexttransientresponse
+ icbid = p4
+ iselstart = p5
+ iselend = p6
+ if (iselstart == -1 && iselend == -1) then
+ io_sendstring("callback", sprintf("{\"cbid\":%d}", icbid))
+ else
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"selstart\":%f,\"selend\":%f}", icbid, iselstart, iselend))
+ endif
+ turnoff
+endin
+
+instr twst_nexttransient
+ icbid = p4
+ istart = p5
+ iend = p6
+ ichannel = p7
+ p3 = 60
+
+ instanceindex = gitwst_instanceindex
+ isamps = ftlen(gitwst_bufferL[instanceindex])
+
+ istartsamp = iend * isamps
+ idurationsamp = isamps - istartsamp
+ idurations = idurationsamp / sr
+
+ ileft = 1
+ iright = 1
+ if (ichannel == 0 || gitwst_channels[gitwst_instanceindex] == 1) then
+ iright = 0
+ elseif (ichannel == 1 && gitwst_channels[gitwst_instanceindex] == 2) then
+ ileft = 0
+ endif
+
+ ktimek timeinstk
+ ikcycles = idurationsamp / ksmps
+ if (ktimek == 1) then
+ kcount init 0
+ while (kcount < ikcycles) do
+ apos linseg istartsamp, idurations, isamps
+ if (ileft == 1 && iright == 1) then
+ asig = (table3:a(apos, gitwst_bufferL[instanceindex]) + table3:a(apos, gitwst_bufferR[instanceindex])) * 0.5
+ elseif (iright == 1) then
+ asig = table3:a(apos, gitwst_bufferR[instanceindex])
+ else
+ asig = table3:a(apos, gitwst_bufferL[instanceindex])
+ endif
+ ktrig transientdetect asig
+ if (ktrig == 1 && kcount != 0) then
+ kselend = ((kcount * ksmps) + istartsamp) / isamps
+ kselstart = (istart == iend) ? kselend : istart
+ schedulek("twst_nexttransientresponse", 0, 1, icbid, kselstart, kselend)
+ turnoff
+ endif
+ kcount += 1
+ od
+ else
+ schedulek("twst_nexttransientresponse", 0, 1, icbid, -1, -1)
+ turnoff
+ endif
+endin
+
+
+instr twst_undo
+ icbid = p4
+ istatus twst_undo
+ if (istatus < 0) then
+ Sresponse = twst_failresponse(icbid)
+ else
+ Sresponse = twst_createoverviews(icbid)
+ endif
+
+ io_sendstring("callback", Sresponse)
+ turnoff
+endin
+
+
+instr twst_destroytables
+ ifnL = p4
+ ifnR = p5
+ twst_clearbuffers(ifnL, ifnR)
+ turnoff
+endin
+
+
+opcode twst_loadfile, ik, Sj
+ Spath, instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ kdone init 0
+ if (filevalid(Spath) != 1) then
+ iresponse = -1
+ goto complete
+ endif
+
+ ifilesr = filesr(Spath)
+ ifilechannels = filenchnls(Spath)
+ ilens = filelen(Spath)
+ ilen = round(ilens * ifilesr)
+
+ if (ilen >= gihost_max32bitftlen || ilens * sr >= gihost_max32bitftlen) then ; limitation with WASM Csound build at the moment
+ iresponse = -2
+ goto complete
+ endif
+
+ twst_checkpoint_clear(instanceindex)
+
+ twst_clearbuffers(gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex])
+ gitwst_channels[instanceindex] = ifilechannels
+
+ gitwst_bufferL[instanceindex] = ftgen(0, 0, -ilen, 1, Spath, 0, 0, 1)
+ if (gitwst_channels[instanceindex] == 2) then
+ gitwst_bufferR[instanceindex] = ftgen(0, 0, -ilen, 1, Spath, 0, 0, 2)
+ gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex], kdone tab_samplerateconvert gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex]
+ imono = 0
+ else
+ gitwst_bufferL[instanceindex], kdone tab_samplerateconvert gitwst_bufferL[instanceindex]
+ imono = 1
+ endif
+
+
+ iresponse = 1
+complete:
+ xout iresponse, kdone
+endop
+
+
+/*
+opcode twst_loadfile, ik, Sj
+ Spath, instanceindex xin
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ kdone init 0
+ if (filevalid(Spath) != 1) then
+ iresponse = -1
+ goto complete
+ endif
+
+ ifilesr = filesr(Spath)
+ ifilechannels = filenchnls(Spath)
+ ilens = filelen(Spath)
+ ilen = round(ilens * ifilesr)
+
+ if (ilen >= gihost_max32bitftlen || ilens * sr >= gihost_max32bitftlen) then ; limitation with WASM Csound build at the moment
+ iresponse = -2
+ goto complete
+ endif
+
+ twst_checkpoint_clear(instanceindex)
+
+ gitwst_channels[instanceindex] = ifilechannels
+ twst_clearbuffers(gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex])
+
+ gitwst_bufferL[instanceindex] = ftgen(0, 0, -ilen, 1, Spath, 0, 0, 1)
+ if (gitwst_channels[instanceindex] == 2) then
+ gitwst_bufferR[instanceindex] = ftgen(0, 0, -ilen, 1, Spath, 0, 0, 2)
+ imono = 0
+ else
+ imono = 1
+ endif
+
+ if (sr != ifilesr) then ; different sr causes issues in table reading opcodes, convert..
+ inewlen = ilens * sr
+ ifnnewL ftgen 0, 0, -inewlen, -2, 0
+ if (imono == 0) then
+ ifnnewR ftgen 0, 0, -inewlen, -2, 0
+ endif
+ ktimek timeinstk
+ ikcycles = ilens * kr
+ if (ktimek == 1) then
+ kcount = 0
+ while (kcount < ikcycles) do
+ aposw linseg 0, ilens, inewlen - 1
+ aposr linseg 0, ilens, ilen - 1
+ asig table3 aposr, gitwst_bufferL[instanceindex]
+ tablew asig, aposw, ifnnewL
+ if (imono == 0) then
+ asig table3 aposr, gitwst_bufferR[instanceindex]
+ tablew asig, aposw, ifnnewR
+ endif
+ kcount += 1
+ od
+ else
+ kdone = 1
+ endif
+
+ ftfree gitwst_bufferL[instanceindex], 1
+ gitwst_bufferL[instanceindex] = ifnnewL
+ if (imono == 0) then
+ ftfree gitwst_bufferR[instanceindex], 1
+ gitwst_bufferR[instanceindex] = ifnnewR
+ endif
+ else
+ kdone = 1
+ endif
+
+ iresponse = 1
+complete:
+ xout iresponse, kdone
+endop
+*/
+
+instr twst_loadclipboard
+ icbid = p4
+ p3 = 60
+
+ instanceindex = gitwst_instanceindex
+ twst_clearbuffers(gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex])
+
+ ilen = ftlen(gitwst_copyBufferL)
+ ifnL ftgen 0, 0, -ilen, -2, 0
+ tableicopy ifnL, gitwst_copyBufferL
+ gitwst_bufferL[instanceindex] = ifnL
+ if (gitwst_copyBufferR > 0 && ftexists(gitwst_copyBufferR) == 1) then
+ ifnR ftgen 0, 0, -ilen, -2, 0
+ tableicopy ifnR, gitwst_copyBufferR
+ gitwst_bufferR[instanceindex] = ifnR
+ gitwst_channels[instanceindex] = 2
+ else
+ gitwst_channels[instanceindex] = 1
+ gitwst_bufferR[instanceindex] = 0
+ endif
+ schedule("twst_overviews_response", 0, 1, icbid, 0, 0)
+ turnoff
+endin
+
+instr twst_loadftable
+ icbid = p4
+ ifnL = p5
+ ifnR = p6
+ iclearbuffers = p7
+ p3 = 60
+ instanceindex = gitwst_instanceindex
+
+ if (ifnL <= 0 || ftexists(ifnL) == 0 || (ifnR > 0 && ftexists(ifnR) == 0)) then
+ io_sendstring("callback", twst_failresponse(icbid, -1))
+ turnoff
+ endif
+
+ twst_checkpoint_clear(instanceindex)
+
+ if (iclearbuffers == 1) then
+ twst_clearbuffers(gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex])
+ endif
+
+ gitwst_bufferL[instanceindex] = ifnL
+ if (ifnR > 0) then
+ gitwst_bufferR[instanceindex] = ifnR
+ gitwst_channels[instanceindex] = 2
+ else
+ gitwst_channels[instanceindex] = 1
+ endif
+
+ schedule("twst_overviews_response", 0, 1, icbid, 0, 0)
+ turnoff
+endin
+
+instr twst_getbuffers
+ icbid = p4
+ instanceindex = gitwst_instanceindex
+ if (gitwst_channels[instanceindex] == 2) then
+ Stables = sprintf("[%d,%d]", gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex])
+ else
+ Stables = sprintf("[%d]", gitwst_bufferL[instanceindex])
+ endif
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1,\"tables\":%s}", icbid, Stables))
+ turnoff
+endin
+
+
+instr twst_loadfile
+ icbid = p4
+ p3 = 120
+ Spath = strget(p5)
+ istatus, kdone twst_loadfile Spath, -1, 1
+ if (istatus < 0) then
+ Sresponse = twst_failresponse(icbid, istatus)
+ io_sendstring("callback", Sresponse)
+ turnoff
+ else
+ if (kdone == 1) then
+ schedulek("twst_overviews_response", 0, 1, icbid, 0, 0)
+ turnoff
+ endif
+ endif
+endin
+
+
+
+/*
+instr twst_loadfile
+ icbid = p4
+ Spath = strget(p5)
+ if (filevalid(Spath) != 1) then
+ Sresponse = twst_failresponse(icbid)
+ else
+ twst_clearbuffers()
+ gitwst_channels[gitwst_instanceindex] = filenchnls(Spath)
+ gitwst_bufferL[gitwst_instanceindex] = ftgen(0, 0, 0, 1, Spath, 0, 0, 1)
+ if (gitwst_channels[gitwst_instanceindex] == 2) then
+ gitwst_bufferR[gitwst_instanceindex] = ftgen(0, 0, 0, 1, Spath, 0, 0, 2)
+ endif
+ Sresponse = twst_createoverviews(icbid)
+ endif
+ io_sendstring("callback", Sresponse)
+ turnoff
+endin
+*/
+
+
+
+opcode twst_createempty, i, ijj
+ iduration, ichannels, instanceindex xin
+ ichannels = (ichannels == -1) ? 2 : ichannels
+ instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
+ twst_clearbuffers(gitwst_bufferL[instanceindex], gitwst_bufferR[instanceindex])
+ idurationsamps = iduration * sr
+
+ if (idurationsamps >= gihost_max32bitftlen) then ; limitation with WASM Csound build at the moment
+ iresponse = -2
+ goto complete
+ endif
+
+ twst_checkpoint_clear(instanceindex)
+
+ gitwst_bufferL[instanceindex] ftgen 0, 0, -idurationsamps, -2, 0
+ if (ichannels == 2) then
+ gitwst_channels[instanceindex] = 2
+ gitwst_bufferR[instanceindex] ftgen 0, 0, -idurationsamps, -2, 0
+ else
+ gitwst_channels[instanceindex] = 1
+ endif
+ iresponse = 1
+complete:
+ xout iresponse
+endop
+
+
+instr twst_createempty
+ icbid = p4
+ iduration = p5
+ ichannels = p6
+ p3 = 60
+ istatus twst_createempty iduration, ichannels
+ if (istatus < 0) then
+ io_sendstring("callback", twst_failresponse(icbid, istatus))
+ else
+ schedule("twst_overviews_response", 0, 1, icbid, 0, 0)
+ endif
+ turnoff
+endin
+
+
+instr twst_savefile_response
+ icbid = p4
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1}", icbid))
+ turnoff
+endin
+
+
+instr twst_savefile
+ icbid = p4
+ p3 = 60
+ Spath = strget(p5)
+ ktimek timeinstk
+ idurations = ftlen(gitwst_bufferL[gitwst_instanceindex]) / ftsr(gitwst_bufferL[gitwst_instanceindex])
+ ikcycles = idurations * kr
+ if (ktimek == 1) then
+ kcount init 0
+ while (kcount < ikcycles) do
+ apos lphasor 1
+ aL table apos, gitwst_bufferL[gitwst_instanceindex]
+ if (gitwst_channels[gitwst_instanceindex] == 1) then
+ fout Spath, 14, aL
+ else
+ aR table3 apos, gitwst_bufferR[gitwst_instanceindex]
+ fout Spath, 14, aL, aR
+ endif
+ kcount += 1
+ od
+ else
+ schedulek("twst_savefile_response", 0, 1, icbid)
+ turnoff
+ endif
+endin
+
+
+
+instr twst_auditioncomplete_response
+ icbid = p4
+ istatus = 0
+ if (gitwst_userstopped == 1) then
+ istatus = 3
+ endif
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":%d}", icbid, istatus))
+ turnoff
+endin
+
+instr twst_stop
+ gitwst_userstopped = 1
+ turnoff2 "twst_audition", 0, 1
+ turnoff2 "twst_record", 0, 1
+ turnoff
+endin
+
+#ifdef TWST_FAILONLAG
+instr twst_auditionlag_response
+ icbid = p4
+ turnoff2 "twst_audition", 0, 0
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":-1}", icbid))
+ turnoff
+endin
+#end
+
+instr twst_play
+ schedule("twst_audition", 0, p3, p4, p5, p6, p7, "", 0)
+ turnoff
+endin
+
+instr twst_audition
+ icbid = p4
+ gitwst_userstopped = 0
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1}", icbid))
+ istart = p5
+ iend = p6
+ if (istart == iend) then
+ iend = 1
+ endif
+ ichannel = p7
+ Stransform = strget(p8)
+ iautomating = p9
+ icrossfadein = p10
+ icrossfadeout = p11
+ iuniqueid = p12
+ iapplymode chnget sprintf("applymode%d", iuniqueid)
+ kapplymodedry chnget sprintf("applymodedry%d", iuniqueid)
+ kapplymodewet chnget sprintf("applymodewet%d", iuniqueid)
+
+ i_, aL, aR, i_, i_, iextracycles, i_, i_ twst_playback istart, iend, ichannel, Stransform, 0, iautomating, icrossfadein, icrossfadeout, iuniqueid
+
+ gitwst_currentplayduration = p3
+
+#ifdef TWST_FAILONLAG
+ if (strcmp(Stransform, "") != 0) then
+ klagging lagdetect 0.8
+ if (klagging == 1) then
+ schedulek("twst_auditionlag_response", 0, 1, icbid)
+ endif
+ endif
+#end
+
+ kreleasing init 0
+ ktimek timeinstk
+ iduration = (p3 * kr) + (iextracycles / sr)
+ krelease release
+ if (kreleasing == 0 && (krelease == 1 || ktimek >= iduration)) then
+ kreleasing = 1
+ schedulek("twst_auditioncomplete_response", 0, 1, icbid)
+ turnoff
+ endif
+
+ outs aL, aR
+endin
+
+
+instr twst_recordcomplete_response
+ icbid = p4
+ iselstart = p5
+ iselend = p6
+ io_sendstring("callback", twst_createoverviews(icbid, iselstart, iselend, 2))
+endin
+
+instr twst_record
+ icbid = p4
+ gitwst_userstopped = 0
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1}", icbid))
+ istart = p5
+ iend = p6
+ if (istart == iend) then
+ iend = 1
+ endif
+ ichannel = p7
+ ibuflen = ftlen(gitwst_bufferL[gitwst_instanceindex])
+ istartsamp, ilensamp, iendsamp twst_getstartend istart, iend, gitwst_instanceindex
+ ilens = ilensamp / sr
+ p3 = ilens
+
+ twst_checkpoint()
+
+ apos linseg istartsamp, ilens, iendsamp
+ aL init 0
+ aR init 0
+
+ if (gitwst_channels[gitwst_instanceindex] == 1) then
+ if (ichannel == 1) then
+ aL inch 2
+ else
+ aL inch 1
+ endif
+ tablew aL, apos, gitwst_bufferL[gitwst_instanceindex]
+ else
+ if (ichannel == -1 || ichannel == 0) then
+ aL inch 1
+ tablew aL, apos, gitwst_bufferL[gitwst_instanceindex]
+ endif
+ if (ichannel == -1 || ichannel == 1) then
+ aR inch 2
+ tablew aR, apos, gitwst_bufferR[gitwst_instanceindex]
+ endif
+ endif
+
+ chnset k(aL), "recordmonitorL"
+ chnset k(aR), "recordmonitorR"
+
+ ktimeenv linseg istart, p3, iend
+ chnset ktimeenv, "twst_playposratio"
+ kreleasing init 0
+ ktimek timeinstk
+ iduration = p3 * kr
+ if (kreleasing == 0 && (release:k() == 1 || ktimek >= iduration)) then
+ kreleasing = 1
+ klastwritten = k(apos)
+ schedulek("twst_recordcomplete_response", 0, 1, icbid, istart, klastwritten / ibuflen)
+ turnoff
+ endif
+endin
+
+
+
+instr twst_commit_response
+ icbid = p4
+ ifnL = p5
+ ifnR = p6
+ iselstart = p7
+ iselend = p8
+ if (ifnL > 0 && ifnL != gitwst_bufferL[gitwst_instanceindex]) then
+ if (gitwst_bufferL[gitwst_instanceindex] > 0 && ftexists(gitwst_bufferL[gitwst_instanceindex]) == 1) then
+ ftfree gitwst_bufferL[gitwst_instanceindex], 0
+ endif
+ gitwst_bufferL[gitwst_instanceindex] = ifnL
+ endif
+ if (ifnR > 0 && ifnR != gitwst_bufferR[gitwst_instanceindex]) then
+ if (gitwst_bufferR[gitwst_instanceindex] > 0 && gitwst_bufferR[gitwst_instanceindex] == 1) then
+ ftfree gitwst_bufferR[gitwst_instanceindex], 0
+ endif
+ gitwst_bufferR[gitwst_instanceindex] = ifnR
+ endif
+
+ io_sendstring("callback", twst_createoverviews(icbid, iselstart, iselend))
+ turnoff
+endin
+
+instr twst_commit
+ icbid = p4
+ istart = p5
+ iend = p6
+ if (istart == iend) then
+ istart = 0
+ iend = 1
+ endif
+ ichannel = p7
+ Stransform = strget(p8)
+ iautomating = p9
+ icrossfadein = p10
+ icrossfadeout = p11
+ inoCheckpoint = p12
+ iuniqueid = p13
+
+ ibuflen = ftlen(gitwst_bufferL[gitwst_instanceindex])
+ istartsamp = ibuflen * istart
+ iendsamp = ibuflen * iend
+ idurations = (iendsamp - istartsamp) / ftsr(gitwst_bufferL[gitwst_instanceindex])
+
+ if (inoCheckpoint == 0) then
+ twst_checkpoint()
+ endif
+
+ iblocks = 100
+ ikcycles = round(idurations * kr)
+ if (ikcycles < iblocks) then
+ ikcyclesperblock = ikcycles
+ else
+ ikcyclesperblock = round(ikcycles / iblocks)
+ endif
+ ktotalcount init 0
+ klastpercent init 100
+
+ kreleasing init 0
+ ifnL = 0
+ ifnR = 0
+
+ if (ktotalcount < ikcycles) then
+ kcount = 0
+ while (kcount < ikcyclesperblock) do
+ istatus, a_, a_, ifnL, ifnR, iextracycles, iselstart, iselend twst_playback istart, iend, ichannel, Stransform, 1, iautomating, icrossfadein, icrossfadeout, iuniqueid
+ if (istatus <= 0) then
+ io_sendstring("callback", twst_failresponse(icbid, istatus))
+ turnoff
+ endif
+ ikcycles += iextracycles ; weird in loop but it's a k loop, so i is set here...
+
+ kcount += 1
+ ktotalcount += 1
+ od
+ kpercent = round((100 / ikcycles) * ktotalcount)
+ if (kpercent != klastpercent) then
+ io_send "percent", kpercent
+ klastpercent = kpercent
+ endif
+ else
+ schedulek("twst_commit_response", 0, 1, icbid, ifnL, ifnR, iselstart, iselend)
+ turnoff
+ endif
+endin
+
+
+#include "/twist/automation.udo"
+#include "/twist/transforms.udo"
+
+
+#end
|