aboutsummaryrefslogtreecommitdiff
path: root/site/udo/chop.udo
diff options
context:
space:
mode:
authorRichard <q@1bpm.net>2025-04-13 18:48:02 +0100
committerRichard <q@1bpm.net>2025-04-13 18:48:02 +0100
commit9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 (patch)
tree291bd79ce340e67affa755a8a6b4f6a83cce93ea /site/udo/chop.udo
downloadapps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.tar.gz
apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.tar.bz2
apps.csound.1bpm.net-9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22.zip
initial
Diffstat (limited to 'site/udo/chop.udo')
-rwxr-xr-xsite/udo/chop.udo715
1 files changed, 715 insertions, 0 deletions
diff --git a/site/udo/chop.udo b/site/udo/chop.udo
new file mode 100755
index 0000000..cf8d2f3
--- /dev/null
+++ b/site/udo/chop.udo
@@ -0,0 +1,715 @@
+#ifndef UDO_CHOP
+#define UDO_CHOP ##
+/*
+ chop: init-time table editing
+
+ This file is part of the SONICS UDO collection by Richard Knight 2023, 2024
+ License: GPL-2.0-or-later
+ http://1bpm.net
+*/
+
+#include "/uniqueid.udo"
+
+opcode chop_mktemp, ii, ij
+ isize, imono xin
+ ifnL ftgen 0, 0, isize, 2, 0
+ if (imono < 1) then
+ ifnR ftgen 0, 0, isize, 2, 0
+ endif
+ xout ifnL, ifnR
+endop
+
+opcode chop_mktemp, i, i
+ isize xin
+ ifn ftgen 0, 0, -isize, -2, 0
+ xout ifn
+endop
+
+
+
+opcode chop_zerostartend, ii, i
+ ifn xin
+ ilen = ftlen(ifn)
+ istart = -1
+ iend = -1
+ iprevsample = tab_i(0, ifn)
+ index = 1
+ while (index < ilen) do
+ isample = tab_i(index, ifn)
+ if ((isample > 0 && iprevsample < 0) || (isample < 0 && iprevsample > 0)) then
+ istart = index
+ goto foundstart
+ endif
+ iprevsample = isample
+ index += 1
+ od
+
+foundstart:
+ index = ilen - 2
+ iprevsample = tab_i(ilen - 1, ifn)
+ while (index >= 0) do
+ isample = tab_i(index, ifn)
+ if ((isample > 0 && iprevsample < 0) || (isample < 0 && iprevsample > 0)) then
+ iend = index
+ goto foundend
+ endif
+ iprevsample = isample
+ index -= 1
+ od
+
+foundend:
+ xout istart, iend
+endop
+
+
+opcode _chop_assamples, iii, iii
+ ichopstart, ichoplen, iassamples xin
+ if (iassamples == 1) then
+ ichopstartsamp = ichopstart
+ ichopendsamp = ichopstart + ichoplen
+ ichoplensamp = ichoplen
+ else
+ ichopstartsamp = round(ichopstart * sr)
+ ichopendsamp = round((ichopstart + ichoplen) * sr)
+ ichoplensamp = round(ichoplen * sr)
+ endif
+ xout ichopstartsamp, ichopendsamp, ichoplensamp
+endop
+
+
+
+
+;ftslice better?
+opcode chop_cut, iiii, iiiij
+ ichopstart, ichoplen, ifnL, ifnR, iassamples xin
+ ichopstartsamp, ichopendsamp, ichoplensamp _chop_assamples ichopstart, ichoplen, iassamples
+
+ ilen = ftlen(ifnL)
+ inewlen = ilen - ichoplensamp
+ if (ifnR == -1) then
+ icutL chop_mktemp round(ichoplensamp)
+ ifntempL chop_mktemp round(inewlen)
+ else
+ icutL, icutR chop_mktemp round(ichoplensamp)
+ ifntempL, ifntempR chop_mktemp round(inewlen)
+ endif
+
+ ireadpos = 0
+ iwritepos = 0
+ ichopwritepos = 0
+ while (ireadpos + 1 < ilen) do
+ ivalL = tab_i(ireadpos, ifnL)
+ if (ifnR != -1) then
+ ivalR = tab_i(ireadpos, ifnR)
+ endif
+
+ if (ireadpos >= ichopstartsamp && ireadpos < ichopendsamp) then
+ tabw_i ivalL, ichopwritepos, icutL
+ if (ifnR != 1) then
+ tabw_i ivalR, ichopwritepos, icutR
+ endif
+ ichopwritepos += 1
+ else
+ tabw_i ivalL, iwritepos, ifntempL
+ if (ifnR != 1) then
+ tabw_i ivalR, iwritepos, ifntempR
+ endif
+ iwritepos += 1
+ endif
+ ireadpos += 1
+ od
+
+ ftfree ifnL, 0
+ if (ifnR != -1) then
+ ftfree ifnR, 0
+ endif
+
+ xout icutL, icutR, ifntempL, ifntempR
+endop
+
+
+opcode chop_cut, ii, iiij
+ ichopstart, ichoplen, ifn, iassamples xin
+ ifnCut, i_, ifnNew, i_ chop_cut ichopstart, ichoplen, ifn, -1, iassamples
+ xout ifnCut, ifnNew
+endop
+
+
+opcode _chop_copy, ii, iiiij
+ ichopstart, ichoplen, ifnL, ifnR, iassamples xin
+ ichopstartsamp, ichopendsamp, ichoplensamp _chop_assamples ichopstart, ichoplen, iassamples
+ if (ifnL > 0) then
+ ifntempL chop_mktemp round(ichoplensamp)
+ ftslicei ifnL, ifntempL, ichopstartsamp, ichopendsamp
+ endif
+ if (ifnR > 0) then
+ ifntempR chop_mktemp round(ichoplensamp)
+ ftslicei ifnR, ifntempR, ichopstartsamp, ichopendsamp
+ endif
+ xout ifntempL, ifntempR
+endop
+
+opcode chop_copy, i, iiij
+ ichopstart, ichoplen, ifn, iassamples xin
+ ifn, i_ _chop_copy ichopstart, ichoplen, ifn, -1, iassamples
+ xout ifn
+endop
+
+opcode chop_copy, ii, iiiij
+ ichopstart, ichoplen, ifnL, ifnR, iassamples xin
+ ifntempL, ifntempR _chop_copy ichopstart, ichoplen, ifnL, ifnR, iassamples
+ xout ifntempL, ifntempR
+endop
+
+
+
+opcode _chop_operation, 0, iiiiipoop ; should only be run in one k-cycle
+ ifnSource, ifnTarget, isourceStart, isourceEnd, itargetStart, iterations, itargetIncrement, imix, iteration xin
+ ilen = (isourceEnd - isourceStart)
+ ilens = ilen / sr
+ ikcycles = ilen / ksmps
+ kcount = 0
+ while (kcount < ikcycles) do
+ aposSource linseg isourceStart, ilens, isourceEnd
+ aposTarget linseg itargetStart, ilens, (itargetStart + ilen) - 1
+ asig table3 aposSource, ifnSource
+ if (imix == 1) then
+ asig += table3:a(aposTarget, ifnTarget)
+ endif
+ tablew asig, aposTarget, ifnTarget
+ kcount += 1
+ od
+ if (iteration < iterations) then
+ _chop_operation ifnSource, ifnTarget, isourceStart, isourceEnd, itargetStart + itargetIncrement, iterations, itargetIncrement, imix, iteration + 1
+ endif
+endop
+
+
+opcode chop_pastek, kiii, ijijipo
+ ifnSrcL, ifnSrcR, ifnDestL, ifnDestR, istart, inumber, imix xin
+ inumber = round(inumber)
+ kdone init 0
+ ifnanalysis = (ifnDestL != -1) ? ifnDestL : ifnDestR
+ idestlen = ftlen(ifnanalysis)
+ ipastelen = ftlen((ifnSrcL != -1) ? ifnSrcL : ifnSrcR)
+ itotalpastelen = ipastelen * inumber
+ iextended = 1
+ if (imix == 0) then
+ inewlen = round(idestlen + itotalpastelen)
+ else
+ if (itotalpastelen > idestlen - istart) then
+ inewlen = round(istart + itotalpastelen)
+ else
+ inewlen = idestlen
+ iextended = 0
+ endif
+ endif
+ ktimek timeinstk
+ if (ktimek == 1) then
+ if (ifnDestL != -1) then
+ if (iextended == 1) then
+ ifnNewL chop_mktemp inewlen
+ ftfree ifnDestL, 1
+ else
+ ifnNewL = ifnDestL
+ endif
+ if (imix == 0) then
+ _chop_operation ifnDestL, ifnNewL, 0, istart, 0
+ _chop_operation ifnSrcL, ifnNewL, 0, ipastelen, istart, inumber, ipastelen
+ _chop_operation ifnDestL, ifnNewL, istart + 1, idestlen, istart + itotalpastelen + 1
+ else
+ if (iextended == 1) then
+ _chop_operation ifnDestL, ifnNewL, 0, idestlen, 0
+ endif
+ _chop_operation ifnSrcL, ifnNewL, 0, ipastelen, istart, inumber, ipastelen, imix
+ endif
+ else
+ ifnNewL = -1
+ endif
+
+ if (ifnDestR != -1) then
+ if (iextended == 1) then
+ ifnNewR chop_mktemp inewlen
+ ftfree ifnDestR, 1
+ else
+ ifnNewR = ifnDestR
+ endif
+ if (imix == 0) then
+ _chop_operation ifnDestR, ifnNewR, 0, istart, 0
+ _chop_operation ifnSrcR, ifnNewR, 0, ipastelen, istart, inumber, ipastelen
+ _chop_operation ifnDestR, ifnNewR, istart + 1, idestlen, istart + itotalpastelen + 1
+ else
+ if (iextended == 1) then
+ _chop_operation ifnDestR, ifnNewR, 0, idestlen, 0
+ endif
+ _chop_operation ifnSrcR, ifnNewR, 0, ipastelen, istart, inumber, ipastelen, imix
+ endif
+ else
+ ifnNewR = -1
+ endif
+ else
+ kdone = 1
+ endif
+
+ xout kdone, ifnNewL, ifnNewR, itotalpastelen
+endop
+
+
+opcode chop_pastek, kiii, ijijip
+ ifnSrcL, ifnSrcR, ifnDestL, ifnDestR, istart, inumber xin
+ inumber = round(inumber)
+ kdone init 0
+ ifnanalysis = (ifnDestL != -1) ? ifnDestL : ifnDestR
+ ipastelen = ftlen((ifnSrcL != -1) ? ifnSrcL : ifnSrcR)
+ itotalpastelen = ipastelen * inumber
+ inewlen = round(ftlen(ifnanalysis) + itotalpastelen)
+ ktimek timeinstk
+ if (ktimek == 1) then
+ if (ifnDestL != -1) then
+ ifnNewL chop_mktemp inewlen
+ _chop_operation ifnDestL, ifnNewL, 0, istart, 0
+ _chop_operation ifnSrcL, ifnNewL, 0, ipastelen, istart, inumber, ipastelen
+ _chop_operation ifnDestL, ifnNewL, istart + 1, ftlen(ifnDestL), istart + itotalpastelen + 1
+ ftfree ifnDestL, 1
+ else
+ ifnNewL = -1
+ endif
+ if (ifnDestR != -1) then
+ ifnNewR chop_mktemp inewlen
+ _chop_operation ifnDestR, ifnNewR, 0, istart, 0
+ _chop_operation ifnSrcR, ifnNewR, 0, ipastelen, istart, inumber
+ _chop_operation ifnDestR, ifnNewR, istart + 1, ftlen(ifnDestR), istart + itotalpastelen + 1
+ ftfree ifnDestR, 1
+ else
+ ifnNewR = -1
+ endif
+ else
+ kdone = 1
+ endif
+
+ xout kdone, ifnNewL, ifnNewR, itotalpastelen
+endop
+
+
+opcode chop_setsilencek, k, iijjJ
+ istart, idellen, ifnL, ifnR, ktrig xin
+ kdone init 0
+ ktimek timeinstk
+
+ if (kdone == 0 && (ktrig == -1 && ktimek == 1 || ktrig == 1)) then
+ ilens = idellen / sr
+ ikcycles = idellen / ksmps
+ kcount = 0
+ while (kcount < ikcycles) do
+ apos linseg istart, ilens, istart + idellen
+ anull init 0
+ if (ifnL != -1) then
+ tablew dcblock(anull), apos, ifnL
+ endif
+ if (ifnR != -1) then
+ tablew dcblock(anull), apos, ifnR
+ endif
+ kcount += 1
+ od
+ kdone = 1
+ endif
+
+ xout kdone
+endop
+
+
+opcode chop_deletek, kii, iijj
+ istart, idellen, ifnL, ifnR xin
+ kdone init 0
+
+ ktimek timeinstk
+
+ if (ktimek == 1) then
+ if (ifnL != -1) then
+ ifnNewL chop_mktemp round(ftlen(ifnL) - idellen)
+ _chop_operation ifnL, ifnNewL, 0, istart, 0
+ _chop_operation ifnL, ifnNewL, istart + idellen, ftlen(ifnL), istart
+ ftfree ifnL, 1
+ else
+ ifnNewL = -1
+ ifnCutL = -1
+ endif
+ if (ifnR != -1) then
+ ifnNewR chop_mktemp round(ftlen(ifnR) - idellen)
+ _chop_operation ifnR, ifnNewR, 0, istart, 0
+ _chop_operation ifnR, ifnNewR, istart + idellen, ftlen(ifnR), istart
+ ftfree ifnR, 1
+ else
+ ifnNewR = -1
+ ifnCutR = -1
+ endif
+ else
+ kdone = 1
+ endif
+
+ xout kdone, ifnNewL, ifnNewR
+endop
+
+
+opcode chop_trimk, kii, iijj
+ istart, itrimlen, ifnL, ifnR xin
+ kdone init 0
+ ktimek timeinstk
+ if (ktimek == 1) then
+ if (ifnL != -1) then
+ ifnNewL chop_mktemp round(itrimlen)
+ _chop_operation ifnL, ifnNewL, istart, istart + itrimlen, 0
+ ftfree ifnL, 1
+ else
+ ifnNewL = -1
+ endif
+ if (ifnR != -1) then
+ ifnNewR chop_mktemp round(itrimlen)
+ _chop_operation ifnR, ifnNewR, istart, istart + itrimlen, 0
+ ftfree ifnR, 1
+ else
+ ifnNewR = -1
+ endif
+ else
+ kdone = 1
+ endif
+ xout kdone, ifnNewL, ifnNewR
+endop
+
+
+opcode chop_cutk, kiiii, iijj
+ istart, icutlen, ifnL, ifnR xin
+ kdone init 0
+
+ ktimek timeinstk
+
+ if (ktimek == 1) then
+ if (ifnL != -1) then
+ ifnNewL chop_mktemp round(ftlen(ifnL) - icutlen)
+ ifnCutL chop_mktemp round(icutlen)
+ _chop_operation ifnL, ifnNewL, 0, istart, 0
+ _chop_operation ifnL, ifnCutL, istart, istart + icutlen, 0
+ _chop_operation ifnL, ifnNewL, istart + icutlen, ftlen(ifnL), istart
+ ftfree ifnL, 1
+ else
+ ifnNewL = -1
+ ifnCutL = -1
+ endif
+ if (ifnR != -1) then
+ ifnNewR chop_mktemp round(ftlen(ifnR) - icutlen)
+ ifnCutR chop_mktemp round(icutlen)
+ _chop_operation ifnR, ifnNewR, 0, istart, 0
+ _chop_operation ifnR, ifnCutR, istart, istart + icutlen, 0
+ _chop_operation ifnR, ifnNewR, istart + icutlen, ftlen(ifnR), istart
+ ftfree ifnR, 1
+ else
+ ifnNewR = -1
+ ifnCutR = -1
+ endif
+ else
+ kdone = 1
+ endif
+
+ xout kdone, ifnCutL, ifnCutR, ifnNewL, ifnNewR
+endop
+
+
+
+opcode chop_copyk, kii, iiij
+ istart, ilen, ifnL, ifnR xin
+ kdone init 0
+
+ ktimek timeinstk
+
+ if (ktimek == 1) then
+ if (ifnL != -1) then
+ ifntempL chop_mktemp round(ilen)
+ _chop_operation ifnL, ifntempL, istart, istart + ilen, 0
+ else
+ ifntempL = -1
+ endif
+ if (ifnR != -1) then
+ ifntempR chop_mktemp round(ilen)
+ _chop_operation ifnR, ifntempR, istart, istart + ilen, 0
+ else
+ ifntempR = -1
+ endif
+ else
+ kdone = 1
+ endif
+ xout kdone, ifntempL, ifntempR
+endop
+
+
+
+
+opcode chop_move, ii, iiiii
+ ichopstart, ichoplen, ichopdest, ifnL, ifnR xin
+ ifnchopL, ifnchopR chop_copy ichopstart, ichoplen, ifnL, ifnR
+
+ ichopdestsamp = round(ichopdest * sr)
+ ichopendsamp = round((ichopdest + ichoplen) * sr)
+ ilen = ftlen(ifnL)
+ ifntempdestL, ifntempdestR chop_mktemp ilen
+
+ ilastvalL = 0
+ ilastvalR = 0
+ iwritemode = 0
+ ireadposmain = 0
+ ireadposchop = 0
+ iwritepos = 0
+ while (iwritepos < ilen) do
+ if (iwritepos >= ichopdestsamp && iwritepos + 1 < ichopendsamp) then
+ ivalL = tab_i(ireadposchop, ifnchopL)
+ ivalR = tab_i(ireadposchop, ifnchopR)
+ if (iwritemode == 0) then
+ if (ireadposchop + 1 <= ichopendsamp) then
+ ivalR = (ilastvalR + tab_i(ireadposchop + 1, ifnchopL)) * 0.5
+ ivalR = (ilastvalR + tab_i(ireadposchop + 1, ifnchopR)) * 0.5
+ endif
+ iwritemode = 1
+ endif
+ ireadposchop += 1
+ else
+ ivalL = tab_i(ireadposmain, ifnL)
+ ivalR = tab_i(ireadposmain, ifnR)
+ if (iwritemode == 1) then
+ if (ireadposmain + 1 <= ilen) then
+ ivalR = (ilastvalR + tab_i(ireadposmain + 1, ifnL)) * 0.5
+ ivalR = (ilastvalR + tab_i(ireadposmain + 1, ifnR)) * 0.5
+ endif
+ iwritemode = 0
+ endif
+ ireadposmain += 1
+ endif
+ ilastvalL = ivalL
+ ilastvalR = ivalR
+ tabw_i ivalL, iwritepos, ifntempdestL
+ tabw_i ivalR, iwritepos, ifntempdestR
+ iwritepos += 1
+ od
+
+ ftfree ifnchopL, 0
+ ftfree ifnchopR, 0
+ ftfree ifnL, 0
+ ftfree ifnR, 0
+ xout ifntempdestL, ifntempdestR
+endop
+
+
+
+
+opcode _chop_paste, iii, iiiiiii
+ ifnSrcL, ifnSrcR, ifnDestL, ifnDestR, istartsamp, inumber, itimevarratio xin
+ imonosrc = (ifnSrcR == -1) ? 1 : 0
+ imonodest = (ifnDestR == -1) ? 1 : 0
+
+ inumber = round(inumber)
+ ipastelen = ftlen(ifnSrcL) * inumber
+ inewlen = round(ftlen(ifnDestL) + ipastelen)
+ ifnNewL, ifnNewR chop_mktemp inewlen, imonodest
+
+ inum = 0
+ inputsamps = ftlen(ifnDestL)
+ ichoplensamps = ftlen(ifnSrcL)
+
+ if (itimevarratio != 0) then
+ itimevarratio = random(0.1, itimevarratio)
+ endif
+ ipastetime = istartsamp + (ichoplensamps * itimevarratio)
+ ipastepos = int(ipastetime)
+ ireadposorig = 0
+ iwritepos = 0
+ ireadchoppos = 0
+ idonepaste = 0
+print inumber
+ while (iwritepos < inewlen) do
+ if (idonepaste == 1 || iwritepos <= ipastepos) then
+ if (ireadposorig < inputsamps) then
+ ivalL = tab_i(ireadposorig, ifnDestL)
+ if (imonosrc == 0) then
+ ivalR = tab_i(ireadposorig, ifnDestR)
+ else
+ ivalL = ivalR
+ endif
+
+ if (imonodest == 1) then
+ tabw_i ivalL, iwritepos, ifnNewL
+ else
+ tabw_i ivalL, iwritepos, ifnNewL
+ tabw_i ivalR, iwritepos, ifnNewR
+ endif
+ endif
+ ireadposorig += 1
+ else
+ ivalL = tab_i(ireadchoppos, ifnSrcL)
+ if (imonosrc == 0) then
+ ivalR = tab_i(ireadchoppos, ifnSrcR)
+ else
+ ivalL = ivalR
+ endif
+
+ if (imonodest == 1) then
+ tabw_i ivalL, iwritepos, ifnNewL
+ else
+ tabw_i ivalL, iwritepos, ifnNewL
+ tabw_i ivalR, iwritepos, ifnNewR
+ endif
+
+ if (ireadchoppos + 1 >= ichoplensamps) then
+ ipastetime += (ichoplensamps * random(0, itimevarratio))
+ ipastepos = ipastetime
+print ipastepos
+ if (inum + 1 < inumber) then
+ inum += 1
+print inum
+ else
+ idonepaste = 1
+ endif
+ ireadchoppos = 0
+ else
+ ireadchoppos += 1
+ endif
+ endif
+
+ iwritepos += 1
+ od
+
+ ftfree ifnDestL, 0
+ ftfree ifnDestR, 0
+ xout ifnNewL, ifnNewR, ipastelen
+endop
+
+opcode chop_paste, ii, iiiii
+ ifnSrc, ifnDest, istartsamp, inumber, itimevarratio xin
+ ifnNew, i_, ipastelen _chop_paste ifnSrc, -1, ifnDest, -1, istartsamp, inumber, itimevarratio
+ xout ifnNew, ipastelen
+endop
+
+opcode chop_paste, iii, iiiiiii
+ ifnSrcL, ifnSrcR, ifnDestL, ifnDestR, istartsamp, inumber, itimevarratio xin
+ ifnNewL, ifnNewR, ipastelen _chop_paste ifnSrcL, ifnSrcR, ifnDestL, ifnDestR, istartsamp, inumber, itimevarratio
+ xout ifnNewL, ifnNewR, ipastelen
+endop
+
+
+
+
+/*
+opcode chop_pastek, kiii, ijijip
+ ifnSrcL, ifnSrcR, ifnDestL, ifnDestR, istart, inumber xin
+ inumber = round(inumber)
+ iktime = 1 / kr
+ if (ifnDestL != -1) then
+ ipastelen = ftlen(ifnSrcL) ;;;;;;;;;;;;;;;;;;;;;;;TODOTODOTODOTODO;TODO;;;;* inumber
+ inewlen = round(ftlen(ifnDestL) + ipastelen)
+ ifnNewL chop_mktemp inewlen
+
+ ; paste beginning from original
+ Schannel = sprintf("choppaste%d", uniqueid())
+ schedule("_chop_operation", 0, -1, ifnDestL, ifnNewL, 0, istart, 0, Schannel)
+ kdone1L chnget Schannel
+
+ ; paste buffer
+ Schannel = sprintf("choppaste%d", uniqueid())
+ schedule("_chop_operation", iktime, -1, ifnSrcL, ifnNewL, 0, ipastelen, istart, Schannel)
+ kdone2L chnget Schannel
+
+ ; paste remainder from original
+ Schannel = sprintf("choppaste%d", uniqueid())
+ ipasteend = istart + ipastelen
+ schedule("_chop_operation", iktime * 2, -1, ifnDestL, ifnNewL, istart + 1, ftlen(ifnDestL), istart + ipastelen + 1, Schannel)
+ kdone3L chnget Schannel
+
+ ftfree ifnDestL, 1
+ else
+ kdone1L init 1
+ kdone2L init 1
+ kdone3L init 1
+ ifnNewL = -1
+ endif
+
+ if (ifnDestR != -1) then
+ ipastelen = ftlen(ifnSrcR) ;;;;;;;;;;;;;;;;;;;;;;;TODOTODOTODOTODO;TODO;;;;* inumber
+ inewlen = round(ftlen(ifnDestR) + ipastelen)
+ ifnNewR chop_mktemp inewlen
+
+ Schannel = sprintf("choppaste%d", uniqueid())
+ schedule("_chop_operation", iktime * 3, -1, ifnDestR, ifnNewR, 0, istart, 0, Schannel)
+ kdone1R chnget Schannel
+
+ Schannel = sprintf("choppaste%d", uniqueid())
+ schedule("_chop_operation", iktime * 4, -1, ifnSrcR, ifnNewR, 0, ipastelen, istart, Schannel)
+ kdone2R chnget Schannel
+
+ Schannel = sprintf("choppaste%d", uniqueid())
+ schedule("_chop_operation", iktime * 5, -1, ifnDestR, ifnNewR, istart + 1, ftlen(ifnDestR), istart + ipastelen + 1, Schannel)
+ kdone3R chnget Schannel
+
+ ftfree ifnDestR, 1
+ else
+ kdone1R init 1
+ kdone2R init 1
+ kdone3R init 1
+ ifnNewR = -1
+ endif
+
+ xout (kdone1L & kdone2L & kdone3L & kdone1R & kdone2R & kdone3R), ifnNewL, ifnNewR, ipastelen
+endop
+*/
+
+opcode chop_copypaste, ii, iiiiii
+ ichopstart, ichoplen, inumber, itimevarratio, ifnL, ifnR xin
+ inumber = round(inumber)
+ ifnchopL, ifnchopR chop_copy ichopstart, ichoplen, ifnL, ifnR
+
+ inewlen = round(ftlen(ifnL) + (ichoplen * inumber * sr))
+ ifntempL, ifntempR chop_mktemp inewlen
+
+ inum = 0
+ inputsamps = ftlen(ifnL)
+ ichoplensamps = ftlen(ifnchopL)
+ ipastetime = ichopstart + (ichoplen * random(0, itimevarratio))
+ ipastepos = round(ipastetime * sr)
+ ireadposorig = 0
+ iwritepos = 0
+ ireadchoppos = 0
+ idonepaste = 0
+
+ while (iwritepos < inewlen) do
+ if (idonepaste == 1 || iwritepos <= ipastepos) then
+ if (ireadposorig < inputsamps) then
+ tabw_i tab_i(ireadposorig, ifnL), iwritepos, ifntempL
+ tabw_i tab_i(ireadposorig, ifnR), iwritepos, ifntempR
+ endif
+ ireadposorig += 1
+ else
+ tabw_i tab_i(ireadchoppos, ifnchopL), iwritepos, ifntempL
+ tabw_i tab_i(ireadchoppos, ifnchopR), iwritepos, ifntempR
+
+ if (ireadchoppos + 1 >= ichoplensamps) then
+ ipastetime += (ichoplen * random(0, itimevarratio))
+ ipastepos = round(ipastetime * sr)
+ if (inum + 1 < inumber) then
+ inum += 1
+ else
+ idonepaste = 1
+ endif
+ ireadchoppos = 0
+ else
+ ireadchoppos += 1
+ endif
+ endif
+
+ iwritepos += 1
+ od
+
+ ftfree ifnchopL, 0
+ ftfree ifnchopR, 0
+ ftfree ifnL, 0
+ ftfree ifnR, 0
+ xout ifntempL, ifntempR
+endop
+
+
+#end