1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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
|