From 9fbf91db06a6d4f4b5cd8bb45389a731bb86bf22 Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 13 Apr 2025 18:48:02 +0100 Subject: initial --- site/udo/pvs_fsegproc.udo | 135 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100755 site/udo/pvs_fsegproc.udo (limited to 'site/udo/pvs_fsegproc.udo') diff --git a/site/udo/pvs_fsegproc.udo b/site/udo/pvs_fsegproc.udo new file mode 100755 index 0000000..984be86 --- /dev/null +++ b/site/udo/pvs_fsegproc.udo @@ -0,0 +1,135 @@ +#ifndef UDO_PVSFSEGPROC +#define UDO_PVSFSEGPROC ## +/* + Segmented multiband frequency processing + + Instruments passed to fsegproc should begin with $FSEGPROCINPUT which will + provide the segment audio as aL and aR, and the segment group as igroupindex + + + This file is part of the SONICS UDO collection by Richard Knight 2025 + License: GPL-2.0-or-later + http://1bpm.net +*/ + +#include "bussing.udo" + +gifsegproc_maxsessionindex = 0 + +opcode _fsegproc_channels, SS, ii + isessionindex, igroupindex xin + Ssend = sprintf("bp%d_%d_%d", isessionindex, igroupindex, 1) + Sreturn = sprintf("bp%d_%d_%d", isessionindex, igroupindex, 0) + xout Ssend, Sreturn +endop + +opcode _fsegproc_send, 0, ffiio + fL, fR, isessionindex, ifnsegbins, isegindex xin + ifnmap = tab_i(isegindex, ifnsegbins) + fmL pvsmaska fL, ifnmap, 1 + fmR pvsmaska fR, ifnmap, 1 + + aL pvsynth fmL + aR pvsynth fmR + bus_mix sprintf("bp%d_%d", isessionindex, isegindex), aL, aR + + if (isegindex + 1 < ftlen(ifnsegbins)) then + _fsegproc_send fL, fR, isessionindex, ifnsegbins, isegindex + 1 + endif +endop + + +opcode _fsegproc_receive, aa, iiS[]o + isegments, isessionindex, Sinstrs[], igroupindex xin + ilen = lenarray(Sinstrs) + if (ilen == 1) then + Sinstr = Sinstrs[0] + elseif (ilen == isegments) then + Sinstr = Sinstrs[igroupindex] + else + index = min(round((ilen / isegments) * igroupindex), isegments - 1) + Sinstr = Sinstrs[index] + endif + aL, aR subinstr Sinstr, igroupindex, sprintf("bp%d_%d", isessionindex, igroupindex) + if (igroupindex + 1 < isegments) then + arL, arR _fsegproc_receive isegments, isessionindex, Sinstrs, igroupindex + 1 + aL += arL + aR += arR + endif + xout aL, aR +endop + + +opcode _fsegproc_inner, aa, ffS[]jpj + fL, fR, Sinstrs[], isegments, imode, ifnmap xin + if (isegments == -1) then + isegments = lenarray(Sinstrs) + endif + isessionindex = gifsegproc_maxsessionindex + gifsegproc_maxsessionindex += 1 + aL, aR _fsegproc_receive isegments, isessionindex, Sinstrs + + i_, ibins, i_, i_ pvsinfo fL + isegmentsize = 0 + icursegment = 0 + if (imode == 0) then + isegmentsize = round(ibins / isegments) + endif + if (ifnmap == -1) then + ifnmap ftgentmp 0, 0, ibins, 2, 0 + index = 0 + indexsegment = 0 + while (index < ftlen(ifnmap)) do + if (imode == 0) then + isegment = icursegment + if (indexsegment + 1 >= isegmentsize && icursegment + 1 < isegments) then + icursegment += 1 + indexsegment = 0 + else + indexsegment += 1 + endif + else + isegment = round(random(0, isegments - 1)) + endif + tabw_i isegment, index, ifnmap + index += 1 + od + endif + ifnsegbins ftgentmp 0, 0, -isegments, -2, 0 + index = 0 + while (index < isegments) do + tabw_i ftgentmp(0, 0, -ibins, -2, 0), index, ifnsegbins + index += 1 + od + index = 0 + while (index < ftlen(ifnmap)) do + tabw_i 1, index, tab_i(tab_i(index, ifnmap), ifnsegbins) + index += 1 + od + _fsegproc_send fL, fR, isessionindex, ifnsegbins + xout aL, aR +endop + +/* + mode 0 = sequential, 1 = randomised +*/ +opcode fsegproc, aa, ffS[]jpj + fL, fR, Sinstrs[], isegments, imode, ifnmap xin + aL, aR _fsegproc_inner fL, fR, Sinstrs, isegments, imode, ifnmap + xout aL, aR +endop + +opcode fsegproc, aa, ffSjpj + fL, fR, Sinstr, isegments, imode, ifnmap xin + Sinstrs[] fillarray Sinstr + aL, aR _fsegproc_inner fL, fR, Sinstrs, isegments, imode, ifnmap + xout aL, aR +endop + +#define FSEGPROCINPUT # +igroupindex = p4 +Sbus = p5 +aL, aR bus_read Sbus +# + +#end -- cgit v1.2.3