#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