From 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Apr 2025 18:48:02 +0100 Subject: initial --- site/udo/bsamp.udo | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100755 site/udo/bsamp.udo (limited to 'site/udo/bsamp.udo') diff --git a/site/udo/bsamp.udo b/site/udo/bsamp.udo new file mode 100755 index 0000000..a31cede --- /dev/null +++ b/site/udo/bsamp.udo @@ -0,0 +1,206 @@ +#ifndef UDO_BSAMP +#define UDO_BSAMP ## +/* + Live buffer sampling and glitch out playback + + This file is part of the SONICS UDO collection by Richard Knight 2023 + License: GPL-2.0-or-later + http://1bpm.net +*/ + + +#include "bussing.udo" +#include "tab2wav.udo" + +#ifndef BSAMP_BUFFERNUM +#define BSAMP_BUFFERNUM #8# +#end + +#ifndef BSAMP_CHANNELS +#define BSAMP_CHANNELS #1# +#end + +#ifndef BSAMP_BUFFERLENGTH +#define BSAMP_BUFFERLENGTH #8# +#end + +#ifndef BSAMP_IOPROCRATE +#define BSAMP_IOPROCRATE #10# +#end + +#ifndef BSAMP_IOBLOCKSIZE +#define BSAMP_IOBLOCKSIZE #2048# +#end + + +gibsamp_buffernum = $BSAMP_BUFFERNUM +gibsamp_channels = $BSAMP_CHANNELS +gibsamp_buffers[][] init gibsamp_buffernum, gibsamp_channels +gibsamp_bufferused[] init gibsamp_buffernum + + +isize = sr * $BSAMP_BUFFERLENGTH +index = 0 +while (index < gibsamp_buffernum) do + indexchan = 0 + while (indexchan < gibsamp_channels) do + gibsamp_buffers[index][indexchan] = ftgen(0, 0, isize, 2, 0) + gibsamp_bufferused[index] = isize + indexchan += 1 + od + index += 1 +od + +instr _bsamp_setbufferusedsize + ibufferindex = p4 + ilens = p5 + gibsamp_bufferused[ibufferindex] = round(ilens * sr) + turnoff +endin + + +opcode bsamp_save, k, iSjj + ibufferindex, Spath, iprocrate, iblocksize xin + + if (gibsamp_channels == 2) then + SpathL = sprintf("%s.L", Spath) + SpathR = sprintf("%s.R", Spath) + else + SpathL = Spath + SpathR = Spath + endif + + kdoneL tab2wav gibsamp_buffers[ibufferindex][0], SpathL, gibsamp_bufferused[ibufferindex], $BSAMP_IOPROCRATE, $BSAMP_IOBLOCKSIZE + if (gibsamp_channels == 2) then + kdoneR tab2wav gibsamp_buffers[ibufferindex][1], SpathR, gibsamp_bufferused[ibufferindex], $BSAMP_IOPROCRATE, $BSAMP_IOBLOCKSIZE + else + kdoneR init 1 + endif + + xout (kdoneL & kdoneR) +endop + + +opcode bsamp_load, k, iSjj + ibufferindex, Spath, iprocrate, iblocksize xin + SpathR = sprintf("%s.R", Spath) + if (filevalid(SpathR) == 1) then + SpathL = sprintf("%s.L", Spath) + else + SpathL = Spath + SpathR = Spath + endif + + gibsamp_bufferused[ibufferindex] = min(round(filelen(SpathL) * sr), ftlen(gibsamp_buffers[ibufferindex][0])) + + kdoneL wav2tab SpathL, gibsamp_buffers[ibufferindex][0], 0, $BSAMP_IOPROCRATE, $BSAMP_IOBLOCKSIZE + if (gibsamp_channels == 2) then + kdoneR wav2tab SpathR, gibsamp_buffers[ibufferindex][1], 1, $BSAMP_IOPROCRATE, $BSAMP_IOBLOCKSIZE + else + kdoneR init 1 + endif + + xout (kdoneL & kdoneR) +endop + + +instr bsamp_record + ibufferindex = p4 + Sbus = strget(p5) + + + ifnL = gibsamp_buffers[ibufferindex][0] + if (gibsamp_channels == 2) then + ifnR = gibsamp_buffers[ibufferindex][1] + else + ifnR = -1 + endif + + ilen = ftlen(ifnL) + apos lphasor 1 + + aL, aR bus_tap Sbus + + tablew aL, apos, ifnL, 0, 0, 1 + if (gibsamp_channels == 2) then + tablew aR, apos, ifnR, 0, 0, 1 + endif + + ktimes timeinsts + + kreleasing init 0 + if (release:k() == 1 && kreleasing == 0) then + kreleasing = 1 + if (ktimes > $BSAMP_BUFFERLENGTH) then + ktimes = ktimes % $BSAMP_BUFFERLENGTH + if (ktimes == 0) then + ktimes = $BSAMP_BUFFERLENGTH + endif + endif + schedulek("_bsamp_setbufferusedsize", 0, 1, ibufferindex, ktimes) + endif +endin + + +opcode bsamp_clear, 0, i + ibufferindex xin + gibsamp_bufferused[ibufferindex] = 0 + ftset gibsamp_buffers[ibufferindex][0], 0 + if (gibsamp_channels == 2) then + ftset gibsamp_buffers[ibufferindex][1], 0 + endif +endop + + +opcode bsamp_play, aa, ikkOo + ibufferindex, kreadstart, ktriglen, kreverse, iratiotimes xin + + ifnL = gibsamp_buffers[ibufferindex][0] + if (gibsamp_channels == 2) then + ifnR = gibsamp_buffers[ibufferindex][1] + else + ifnR = -1 + endif + + ilen = gibsamp_bufferused[ibufferindex] ; ftlen(ifn) + ilens = ilen / sr + + + areadstart = upsamp(kreadstart) + if (iratiotimes == 0) then + areadstart = areadstart / ilens + else + ktriglen *= ilens + endif + + klenchanger metro 1 / ktriglen + async upsamp klenchanger + + irate = (1 / ((ilen) / sr)) + apos, a_ syncphasor irate, async + + ;aamp triglinseg klenchanger, 0, 0.001, 1, 3600, 1 + ;kamp loopseg 0.01, klenchanger, 0, 0, 0.01, 1, 3600, 1 + ;aamp = upsamp(kamp) + aamp init 1 + + apos += areadstart + apos *= ilen + + if (kreverse == 1) then + apos = ilen - apos + endif + + aL tablei apos, ifnL, 0, 0, 1 + aL *= aamp + if (gibsamp_channels == 2) then + aR tablei apos, ifnR, 0, 0, 1 + aR *= aamp + else + aR = aL + endif + + xout aL, aR +endop + +#end -- cgit v1.2.3