From 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Apr 2025 18:48:02 +0100 Subject: initial --- site/udo/scss/elasticlip.udo | 823 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 823 insertions(+) create mode 100755 site/udo/scss/elasticlip.udo (limited to 'site/udo/scss/elasticlip.udo') diff --git a/site/udo/scss/elasticlip.udo b/site/udo/scss/elasticlip.udo new file mode 100755 index 0000000..e5bd2ee --- /dev/null +++ b/site/udo/scss/elasticlip.udo @@ -0,0 +1,823 @@ +#ifndef UDO_SCSS_ELASTICLIP +#define UDO_SCSS_ELASTICLIP ## +/* + SCSS segemented timestretch record/playback loop engine + + This file is part of the SONICS UDO collection by Richard Knight 2024 + License: GPL-2.0-or-later + http://1bpm.net +*/ + +#include "/bussing.udo" +#include "/wavetables.udo" +#include "/interop.udo" +#include "/sequencing.udo" +#include "/sequencing_scheduled.udo" +#include "/table_tools.udo" +#include "/pvs_tools.udo" + +/* + Control Items + + 0 wave L + 1 wave R + 2 warp divisions per beat + 3 duration + 4 beats length + 5 utilised length + 6 warp mode ; 0 = repitch , 1 = texture , 2 = mincer , 2 = pvstab + 7 pitch, in semitones from original + 8 amp + 9 fft size + 10 texture window size + 11 texture random + 12 texture overlap + 13 loop switch + 14 warp switch + 15 texture window type ; 0 = hanning, 1 = hamming, 2 = half sine + 16 utilised start + 17 phase lock + 18 sample rate + 19 + = warp points +*/ +gSecp_clipnames[] init 9999 +giecp_fnclips[] init 9999 +giecp_clipindexmax = 0 + +giecp_controlitemnum = 19 + + +#ifndef ECP_NORECORDING +#ifndef ECP_RECORDBUFFERTIME +#define ECP_RECORDBUFFERTIME #10# +#end +giecp_recordbufferduration = $ECP_RECORDBUFFERTIME +giecp_recordbufferL ftgen 0, 0, -(giecp_recordbufferduration*sr), -7, 0 +giecp_recordbufferR ftgen 0, 0, -(giecp_recordbufferduration*sr), -7, 0 +#end + + +opcode ecp_set_warppoint, 0, iii + iclipindex, ipointindex, ivalue xin + ifndata = giecp_fnclips[iclipindex] + imax = tab_i(4, ifndata) * tab_i(2, ifndata) + if (ipointindex < imax) then + ipointindex += giecp_controlitemnum + tablew ivalue, ipointindex, ifndata + endif +endop + + + +opcode ecp_get_audiofn, ii, i + iclipindex xin + ifndata = giecp_fnclips[iclipindex] + ifnL tab_i 0, ifndata + ifnR tab_i 1, ifndata + xout ifnL, ifnR +endop + +opcode ecp_get_name, S, i + iclipindex xin + xout gSecp_clipnames[iclipindex] +endop + +opcode ecp_set_name, 0, iS + iclipindex, Sname xin + gSecp_clipnames[iclipindex] = Sname +endop + +opcode ecp_get_duration, i, i + iclipindex xin + xout tab_i(3, giecp_fnclips[iclipindex]) +endop + +opcode ecp_get_divisions, i, i + iclipindex xin + xout tab_i(2, giecp_fnclips[iclipindex]) +endop + +opcode ecp_set_pitch, 0, ii + iclipindex, ivalue xin + tabw_i ivalue, 7, giecp_fnclips[iclipindex] +endop + +opcode ecp_get_pitch, i, i + iclipindex xin + xout tab_i(7, giecp_fnclips[iclipindex]) +endop + +opcode ecp_get_warpmode, i, i + iclipindex xin + xout tab_i(6, giecp_fnclips[iclipindex]) +endop + +opcode ecp_set_warpmode, 0, ii + iclipindex, ivalue xin + tabw_i ivalue, 6, giecp_fnclips[iclipindex] +endop + +opcode ecp_set_texturesize, 0, ii + iclipindex, ivalue xin + tabw_i ivalue, 10, giecp_fnclips[iclipindex] +endop + +opcode ecp_get_texturesize, i, i + iclipindex xin + xout tab_i(10, giecp_fnclips[iclipindex]) +endop + +opcode ecp_set_texturerandom, 0, ii + iclipindex, ivalue xin + tabw_i ivalue, 11, giecp_fnclips[iclipindex] +endop + +opcode ecp_get_texturerandom, i, i + iclipindex xin + xout tab_i(11, giecp_fnclips[iclipindex]) +endop + +opcode ecp_set_textureoverlap, 0, ii + iclipindex, ivalue xin + tabw_i ivalue, 12, giecp_fnclips[iclipindex] +endop + +opcode ecp_get_textureoverlap, i, i + iclipindex xin + xout tab_i(12, giecp_fnclips[iclipindex]) +endop + +opcode ecp_set_loop, 0, ii + iclipindex, ivalue xin + tabw_i ivalue, 13, giecp_fnclips[iclipindex] +endop + +opcode ecp_get_loop, i, i + iclipindex xin + xout tab_i(13, giecp_fnclips[iclipindex]) +endop + +opcode ecp_set_warp, 0, ii + iclipindex, ivalue xin + tabw_i ivalue, 14, giecp_fnclips[iclipindex] +endop + +opcode ecp_get_warp, i, i + iclipindex xin + xout tab_i(14, giecp_fnclips[iclipindex]) +endop + +opcode ecp_set_texturewindow, 0, ii + iclipindex, ivalue xin + tabw_i ivalue, 15, giecp_fnclips[iclipindex] +endop + +opcode ecp_get_texturewindow, i, i + iclipindex xin + xout tab_i(15, giecp_fnclips[iclipindex]) +endop + + +opcode ecp_randomise_warppoints, 0, io + iclipindex, imode xin + ipoints = ecp_get_duration(iclipindex) * ecp_get_divisions(iclipindex) + iduration = ecp_get_duration(iclipindex) + iaveragedivision = iduration / ipoints + ilasttime = (imode == -1) ? iduration : 0 + index = 0 + while (index < ipoints) do + if (imode == 0) then + ecp_set_warppoint iclipindex, index, random(0, iduration) + else + itime = (imode == 1) ? min(random(ilasttime, ilasttime + iaveragedivision), iduration) : max(random(ilasttime - iaveragedivision, ilasttime), 0) + ecp_set_warppoint iclipindex, index, itime + ilasttime = itime + endif + index += 1 + od +endop + + +opcode ecp_replacetables, 0, iiop + iclipindex, ifnL, ifnR, ireplaceall xin + ifndata = giecp_fnclips[iclipindex] + + ifnLoriginal tab_i 0, ifndata + ifnRoriginal tab_i 1, ifndata + if (ifnL == ifnLoriginal) then + goto complete + endif + ioriginallen table 3, ifndata + ilen = ftlen(ifnL) / ftsr(ifnL) + + if (ireplaceall == 1) then + index = 0 + while (index < lenarray(giecp_fnclips)) do + if (index != iclipindex && giecp_fnclips[index] > 0) then + itfnL tab_i 0, giecp_fnclips[index] ; assuming ifnR will do as well + if (itfnL == ifnLoriginal) then + tablew ifnL, 0, giecp_fnclips[index] + tablew ifnR, 1, giecp_fnclips[index] + endif + endif + index += 1 + od + + if (ftexists(ifnLoriginal) == 1) then + ftfree ifnLoriginal, 0 + endif + if (ifnRoriginal != 0 && ftexists(ifnRoriginal) == 1) then + ftfree ifnRoriginal, 0 + endif + else + tablew ifnL, 0, ifndata + tablew ifnR, 1, ifndata + + endif + + + ; needs to be done for all if ireplaceall is set + if (ioriginallen != ilen) then + tablew ilen, 3, ifndata + ibeats table 4, ifndata + idivisionsperbeat table 2, ifndata + itotalpoints = ibeats * idivisionsperbeat + iparttime = ilen / itotalpoints + index = giecp_controlitemnum + itime = 0 + while (index < ftlen(ifndata)) do + tablew itime, index, ifndata + itime += iparttime + index += 1 + od + endif +complete: +endop + + +opcode ecp_removeclip, 0, i + iclipindex xin + ifndata = giecp_fnclips[iclipindex] + ifnL tab_i 0, ifndata + ifnR tab_i 1, ifndata + + iremovefn = 1 + index = 0 + while (index < lenarray(giecp_fnclips)) do + if (index != iclipindex && giecp_fnclips[index] > 0) then + itfnL tab_i 0, giecp_fnclips[index] ; assuming ifnR will do as well + if (itfnL == ifnL) then + iremovefn = 0 + goto complete + endif + endif + index += 1 + od +complete: + if (iremovefn == 1) then + ftfree ifnL, 0 + if (ifnR > 0) then + ftfree ifnR, 0 + endif + endif + ftfree ifndata, 0 + giecp_fnclips[iclipindex] = 0 +endop + +opcode ecp_importclip, i, i + ifndata xin + iclipindex = giecp_clipindexmax + giecp_clipindexmax += 1 + gSecp_clipnames[iclipindex] = "Imported" ; defunct really: TODO remove + giecp_fnclips[iclipindex] = ifndata + xout iclipindex +endop + +/* + Add clip to runtime engine + + iclipindex ecp_addclip Sname, ifnL, ifnR, ibeats [, idivisionsperbeat = 4] + + iclipindex index of the clip for recall + Sname name of the clip, can be passed blank to default + ifnL left ftable of audio + ifnR right ftable of audio, can be passed as 0 if mono + ibeats the length of the clip in beats + idivisionsperbeat resolution of markers per beat, default is 4 + +*/ +opcode ecp_addclip, i, Siiij + Sname, ifnL, ifnR, ibeats, idivisionsperbeat xin + idivisionsperbeat = (idivisionsperbeat == -1) ? 4 : idivisionsperbeat + iclipindex = giecp_clipindexmax + giecp_clipindexmax += 1 + + if (strcmp(Sname, "") == 0) then + Sname = sprintf("clip %d", iclipindex + 1) + endif + ilen = ftlen(ifnL) / ftsr(ifnL) + itotalpoints = ibeats * idivisionsperbeat + iparttime = ilen / itotalpoints + ifndata ftgen 0, 0, -(itotalpoints+giecp_controlitemnum), -2, 0 + + tablew ifnL, 0, ifndata + tablew ifnR, 1, ifndata + tablew idivisionsperbeat, 2, ifndata + tablew ilen, 3, ifndata ; seconds length + tablew ibeats, 4, ifndata ; beats length + tablew ilen, 5, ifndata ; seconds utilised length + tablew 0, 6, ifndata ; warp mode + tablew 0, 7, ifndata ; pitch + tablew 1, 8, ifndata ; amp + tablew 512, 9, ifndata ; fft size + tablew 4410, 10, ifndata ; texture window size + tablew 441, 11, ifndata ; texture random + tablew 2, 12, ifndata ; texture overlap + tablew 0, 13, ifndata ; whether to loop or one shot + tablew 0, 14, ifndata ; whether to warp or straight playback + tablew 0, 15, ifndata ; texture mode window shape, corresponds to hanning, hamming, half sine + tablew 0, 16, ifndata ; utilised start + tablew 1, 17, ifndata ; phase lock + tablew ftsr(ifnL), 18, ifndata ; samplerate + + index = giecp_controlitemnum + itime = 0 + while (index < ftlen(ifndata)) do + tablew itime, index, ifndata + itime += iparttime + index += 1 + od + + gSecp_clipnames[iclipindex] = Sname + giecp_fnclips[iclipindex] = ifndata + xout iclipindex +endop + + +opcode ecp_loadsound, i, Sio + Spath, ibeats, iforcemono xin + ichnls = (iforcemono == 1) ? 1 : filenchnls(Spath) + ifnL ftgen 0, 0, 0, 1, Spath, 0, 0, 1 + if (ichnls == 2) then + ifnR ftgen 0, 0, 0, 1, Spath, 0, 0, 2 + else + ifnR = 0 + endif + iclipindex = ecp_addclip(Spath, ifnL, ifnR, ibeats, 4) + xout iclipindex +endop + + +opcode ecp_setaudiounique, 0, i + iclipindex xin + ifndata = giecp_fnclips[iclipindex] + ifnL tab_i 0, ifndata + ifnR tab_i 1, ifndata + + irequired = 0 + index = 0 + while (index < lenarray(giecp_fnclips)) do + if (index != iclipindex && giecp_fnclips[index] > 0) then + itfnL tab_i 0, giecp_fnclips[index] ; assuming ifnR will do as well + if (itfnL == ifnL) then + irequired = 1 + goto complete + endif + endif + index += 1 + od +complete: + if (irequired == 1) then + isize = ftlen(ifnL) + ifnLnew ftgen 0, 0, -isize, -2, 0 + tableicopy ifnLnew, ifnL + tabw_i ifnLnew, 0, ifndata + if (ifnR > 0) then + ifnRnew ftgen 0, 0, -isize, -2, 0 + tableicopy ifnRnew, ifnR + tabw_i ifnRnew, 1, ifndata + endif + endif +endop + + +opcode ecp_cloneclip, i, i + iclipindexfrom xin + iclipindexto = giecp_clipindexmax + giecp_clipindexmax += 1 + + ifndatafrom = giecp_fnclips[iclipindexfrom] + ifndatato ftgen 0, 0, -ftlen(ifndatafrom), -2, 0 + + gSecp_clipnames[iclipindexto] = gSecp_clipnames[iclipindexfrom] + tableicopy ifndatato, ifndatafrom + + giecp_fnclips[iclipindexto] = ifndatato + xout iclipindexto +endop + + +instr ecp_stop + icbid = p4 + turnoff2 nstrnum("ecp_playback") + (icbid / 1000000), 4, 1 + turnoff +endin + + +opcode ecp_getwaveform, i, io + iclipindex, isamples xin + ifnL table 0, giecp_fnclips[iclipindex] + ifndata tab_overview ifnL, isamples + xout ifndata +endop + + +instr ecp_stopaudition + icbid = p4 + turnoff2 nstrnum("ecp_playaudition") + (icbid / 1000000), 4, 1 + turnoff +endin + +instr ecp_playaudition_complete + icbid = p4 + io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":0}", icbid)) + turnoff +endin + +instr ecp_playaudition + icbid = p4 + iclipindex = p5 + iduration = p6 + ichannel = p7 + p1 += (icbid / 1000000) + io_sendstring("callback", sprintf("{\"cbid\": %d, \"status\": 1}", icbid)) + aL, aR subinstr "ecp_playback_tst", icbid, iclipindex, iduration + outs aL, aR ; channels?? + + kreleasing init 0 + if (lastcycle:k() == 1 || (kreleasing == 0 && release:k() == 1)) then + kreleasing = 1 + schedulek("ecp_playaudition_complete", 0, 1, icbid) + endif +endin + + +instr ecp_playback_tst + icbid = p4 + iclipindex = p5 + iduration = p6 + istartoffset = p7 + + ifndata = giecp_fnclips[iclipindex] + ifnL tab_i 0, ifndata + ifnR tab_i 1, ifndata + idivisions tab_i 2, ifndata + itotalduration tab_i 3, ifndata + + iutilisedlength tab_i 5, ifndata + iwarpmode tab_i 6, ifndata ; 0 = repitch, 1 = texture, 2 = mincer, 3 = pvstab + kpitch = pow:k(2, (tab:k(7, ifndata) / 12)) + kamp tab 8, ifndata + ifftsize tab_i 9, ifndata + iwindowsize tab_i 10, ifndata + irandwin tab_i 11, ifndata + ioverlap tab_i 12, ifndata + iloop tab_i 13, ifndata + iwarp tab_i 14, ifndata + iwindowtype tab_i 15, ifndata + istart = tab_i(16, ifndata) + istartoffset + kphaselock tab 17, ifndata + isr tab_i 18, ifndata + + if (iwindowtype == 0) then + iwindow = gifnHanning + elseif (iwindowtype == 1) then + iwindow = gifnHamming + else + iwindow = gifnHalfSine + endif + + if (iwarp == 1) then + atime linseg istart, iduration, iutilisedlength + else + atime = (phasor(1 / itotalduration) * (iutilisedlength - istart)) + istart + endif + + + ; repitch + if (iwarp == 0) then + aptime = atime * ftsr(ifnL) * kpitch + aoutL table3 aptime, ifnL, 0 + if (ifnR != 0) then + aoutR table3 aptime, ifnR, 0 + else + aoutR = aoutL + endif + + ; texture + elseif (iwarpmode == 1) then + isradjust = isr / sr + aoutL sndwarp 1, atime, a(kpitch) * isradjust, ifnL, 0, iwindowsize, irandwin, ioverlap, iwindow, 1 + if (ifnR != 0) then + aoutR sndwarp 1, atime, a(kpitch) * isradjust, ifnR, 0, iwindowsize, irandwin, ioverlap, iwindow, 1 + else + aoutR = aoutL + endif + + ; mincer + elseif (iwarpmode == 2) then + aoutL mincer atime, 1, kpitch, ifnL, kphaselock, ifftsize, 4 + if (ifnR != 0) then + aoutR mincer atime, 1, kpitch, ifnR, kphaselock, ifftsize, 4 + else + aoutR = aoutL + endif + + ; pvs + elseif (iwarpmode == 3) then ; contentious benefit + ipvsbufL pvs_ifn2buffer ifnL, ifftsize, ifftsize / 4, ifftsize, 2 + ffoutL pvsbufread k(atime), ipvsbufL + if (kpitch != 1) then + fscaleL pvscale ffoutL, kpitch + aoutL pvsynth fscaleL + else + aoutL pvsynth ffoutL + endif + + if (ifnR != 0) then + ipvsbufR pvs_ifn2buffer ifnR, ifftsize, ifftsize / 4, ifftsize, 2 + ffoutR pvsbufread k(atime), ipvsbufR + if (kpitch != 1) then + fscaleR pvscale ffoutR, kpitch + aoutR pvsynth fscaleR + else + aoutR pvsynth ffoutR + endif + else + ifnR = ifnL + endif + endif + + aamp linseg 1, iduration * 0.9999, 1, iduration * 0.0001, 0 + + aoutL *= aamp * kamp + aoutR *= aamp * kamp + outs aoutL, aoutR +endin + + +instr ecp_playback + icbid = p4 + iclipindex = p5 + + if (icbid > 0) then + p1 += icbid / 1000000 + io_sendstring("callback", sprintf("{\"cbid\": %d, \"status\": 3}", icbid)) + endif + + Sbus = strget(p6) + if (strcmp(Sbus, "") == 0) then + Sbus = "main" + endif + + kmincelock init 1 + + ifndata = giecp_fnclips[iclipindex] + ifnL table 0, ifndata + ifnR table 1, ifndata + idivisions table 2, ifndata + itotalduration table 3, ifndata + + iwarpmode table 6, ifndata ; 0 = repitch, 1 = texture, 2 = pvs, 3 = mincer + kpitch = pow:k(2, (tab:k(7, ifndata) / 12)) + kamp table 8, ifndata + ifftsize table 9, ifndata + iwindowsize table 10, ifndata + irandwin table 11, ifndata + ioverlap table 12, ifndata + iloop table 13, ifndata + iwarp table 14, ifndata + iwindowtype table 15, ifndata + + if (iwindowtype == 0) then + iwindow = gifnHanning + elseif (iwindowtype == 1) then + iwindow = gifnHamming + else + iwindow = gifnHalfSine + endif + + + if (iloop == 0 && iwarp == 0) then + p3 = itotalduration + if (iwarpmode == 0) then + p3 /= tab_i(7, ifndata) + endif + endif + + if (iwarp == 1) then + if (iloop == 1) then + iduration = itotalduration + else + iduration = p3 + endif + + kdiv = gkseq_beattime / idivisions + as, aps syncphasor -(gkseq_beathz*idivisions), a(gkseq_beat) + ;ithresh = ((1 / sr) * ksmps) * 16 + kt trigger k(as), 0.1, 0 ; was 0.005.. works? + + ktime init 0 + kpoint init giecp_controlitemnum + kcps init 1 / iduration + kpointend init table:i(giecp_controlitemnum+1, ifndata) + + if (kt == 1) then + ktime = table:k(kpoint, ifndata) + + if (kpoint + 1 < ftlen(ifndata)) then + kpointend = table:k(kpoint + 1, ifndata) + kpoint += 1 + else + kpointend = iduration + kpoint = giecp_controlitemnum + endif + kcps = (kpointend - ktime) / kdiv + endif + atime, a_ syncphasor kcps, a(kt) ;a(gkseq_beat) ;aps + + else + ktime init 0 + atime phasor 1 / itotalduration + atime *= itotalduration + endif + + ; repitch + if (iwarpmode == 0) then + if (iwarp == 1) then + aptime = (atime + ktime) * ftsr(ifnL) + else + aptime = atime * ftsr(ifnL) * kpitch ; * 0.5 ; why is 0.5 required here? + endif + + aoutL table3 aptime, ifnL, 0 + if (ifnR != 0) then + aoutR tablekt aptime, ifnR, 0 + else + aoutR = aoutL + endif + + ; texture + elseif (iwarpmode == 1) then + isradjust = ftsr(ifnL) / sr + aoutL sndwarp 1, (atime + ktime), a(kpitch) * isradjust, ifnL, 0, iwindowsize, irandwin, ioverlap, iwindow, 1 + if (ifnR != 0) then + aoutR sndwarp 1, (atime + ktime), a(kpitch) * isradjust, ifnR, 0, iwindowsize, irandwin, ioverlap, iwindow, 1 + else + aoutR = aoutL + endif + + ; mincer + elseif (iwarpmode == 2) then + aoutL mincer atime + ktime, 1, kpitch, ifnL, kmincelock, ifftsize, 4 + if (ifnR != 0) then + aoutR mincer atime + ktime, 1, kpitch, ifnR, kmincelock, ifftsize, 4 + else + aoutR = aoutL + endif + + ; pvs + elseif (iwarpmode == 3) then ; contentious benefit + ipvsbufL pvs_ifn2buffer ifnL, ifftsize, ifftsize/4, ifftsize, 2 + ffoutL pvsbufread k(atime) + ktime, ipvsbufL + if (kpitch != 1) then + fscaleL pvscale ffoutL, kpitch + aoutL pvsynth fscaleL + else + aoutL pvsynth ffoutL + endif + + if (ifnR != 0) then + ipvsbufR pvs_ifn2buffer ifnR, ifftsize, ifftsize/4, ifftsize, 2 + ffoutR pvsbufread k(atime) + ktime, ipvsbufR + if (kpitch != 1) then + fscaleR pvscale ffoutR, kpitch + aoutR pvsynth fscaleR + else + aoutR pvsynth ffoutR + endif + else + ifnR = ifnL + endif + endif + + aamp linseg 1, p3 * 0.9999, 1, p3 * 0.0001, 0 + + aoutL *= aamp * kamp + aoutR *= aamp * kamp + bus_mix(Sbus, aoutL, aoutR) + if (icbid > 0) then + kreleasing init 0 + if (release:k() == 1 && kreleasing == 0) then + kreleasing = 1 + schedulek("ecp_stopped", 0, 1, icbid) + endif + endif +endin + + +instr ecp_stopped + icbid = p4 + io_sendstring("callback", sprintf("{\"cbid\": %d, \"status\": 0}", icbid)) + turnoff +endin + + +#ifndef ECP_NORECORDING +instr ecp_record_stop + icbid = p4 + turnoff2 nstrnum("ecp_record") + (icbid / 1000000), 4, 1 + turnoff +endin + + +instr ecp_record + icbid = p4 + istereo = p5 + + p1 += icbid / 1000000 + io_sendstring("callback", sprintf("{\"cbid\": %d, \"status\": 1}", icbid)) + + kbeats init 0 + if (gkseq_beat == 1) then + kbeats += 1 + endif + + awritepos lphasor 1 + ainL inch 1 + tabw ainL, awritepos, giecp_recordbufferL + if (istereo == 1) then + ainR inch 2 + tabw ainR, awritepos, giecp_recordbufferR + endif + + kreleasing init 0 + if (release:k() == 1 && kreleasing == 0) then + kreleasing = 1 + schedulek "ecp_record_post", 0, 10, icbid, istereo, kbeats + endif +endin + + +instr ecp_record_scheduled_cancel + icbid = p4 + turnoff2 nstrnum("ecp_record_scheduled") + (icbid / 1000000), 4, 1 + turnoff +endin + +instr ecp_record_scheduled + icbid = p4 + istereo = p5 + imode = p6 ; -1 = now, 0 = beat, 1 = bar , 2 = bargroup + + p1 += icbid / 1000000 + io_sendstring("callback", sprintf("{\"cbid\": %d, \"status\": 4}", icbid)) + + if ((imode == -1) || (imode == 0 && gkseq_beat == 1) || (imode == 1 && gkseq_bar_trig == 1) || (imode == 2 && gkseq_bargroup_trig == 1)) then + schedulek("ecp_record", 0, giecp_recordbufferduration, icbid, istereo) + turnoff + endif +endin + + +instr ecp_record_post + icbid = p4 + istereo = p5 + ibeats = p6 + + io_sendstring("callback", sprintf("{\"cbid\": %d, \"status\": 2}", icbid)) + + istart = 0 ;ksmps * 8 + iduration = i(gkseq_beattime) * ibeats + ilen = iduration * sr + ifnL ftgen 0, 0, -ilen, -7, 0 + ftslicei giecp_recordbufferL, ifnL, istart, ilen + if (istereo == 1) then + ifnR ftgen 0, 0, -ilen, -7, 0 + ftslicei giecp_recordbufferR, ifnR, istart, ilen + endif + iclipindex = ecp_addclip("", ifnL, ifnR, ibeats, 4) + + io_sendstring("callback", sprintf("{\"cbid\": %d, \"status\": 0}", icbid)) + + ; testing + if (gkseq_bar_trig == 1) then + schedulek "ecp_playback", 0, 100, iclipindex, "mxchan0" + turnoff + endif + + ; turnoff +endin +#end + +#end -- cgit v1.2.3