diff options
Diffstat (limited to 'site/udo/pvs_fsegproc.udo')
-rwxr-xr-x | site/udo/pvs_fsegproc.udo | 135 |
1 files changed, 135 insertions, 0 deletions
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
|