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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
#ifndef UDO_TABLETOOLS
#define UDO_TABLETOOLS ##
/*
Table tools
This file is part of the SONICS UDO collection by Richard Knight 2022, 2024
License: GPL-2.0-or-later
http://1bpm.net
*/
/*
Normalise an audio ftable to to between -1 and 1
ftnormalise ifn
ifn ftable to analyse
*/
opcode ftnormalise, 0, ip
ifn, iscaling xin
imaxpos = -999
imaxneg = 999
iendpoint = 0
index = 0
while (index < ftlen(ifn)) do
ival table index, ifn
if (ival > 0 && ival > imaxpos) then
imaxpos = ival
elseif (ival < 0 && ival < imaxneg) then
imaxneg = ival
endif
index += 1
od
iscale = ((0.999/max(abs(imaxneg), abs(imaxpos)))) * iscaling
index = 0
while (index < ftlen(ifn)) do
ival table index, ifn
tablew ival * iscale, index, ifn
index += 1
od
endop
opcode tab_record, i, aj
ain, iduration xin
if (iduration == -1 || iduration > p3) then
iduration = p3
endif
ifn ftgen 0, 0, -(iduration * sr), -2, 0
apos lphasor 1
tablew ain, apos, ifn
xout ifn
endop
/*
Sample rate agnostic audio file loading
*/
opcode tab_loadaudio, iik, S
Sfile xin
kdone init 0
ilen = filelen(Sfile)
ilensamp = ilen * sr
ikcycles = ilen * kr
ichannels = filenchnls(Sfile)
ifnL ftgen 0, 0, ilensamp, 2, 0
if (ichannels == 2) then
ifnR ftgen 0, 0, ilensamp, 2, 0
else
ifnR = -1
endif
ktimek timeinstk
kcount init 0
if (ktimek == 1) then
while (kcount < ikcycles) do
apos linseg 0, ilen, ilensamp - 1
if (ichannels == 1) then
asig soundin Sfile
tablew asig, apos, ifnL
else
aL, aR soundin Sfile
tablew aL, apos, ifnL
tablew aR, apos, ifnR
endif
kcount += 1
od
else
kdone = 1
endif
xout ifnL, ifnR, kdone
endop
opcode tab_samplerateconvert, iik, ijpj
ifnL, ifnR, ifreeafter, isourcesr xin
isr = (isourcesr == -1) ? ftsr(ifnL) : isourcesr
kdone init 0
if (isr != sr) then
ilen = ftlen(ifnL)
ilens = ftlen(ifnL) / isr
inewlen = (sr / isr) * ilen
ifnnewL ftgen 0, 0, -inewlen, -2, 0
if (ifnR != -1) then
ifnnewR ftgen 0, 0, -inewlen, -2, 0
else
ifnnewR = -1
endif
ktimek timeinstk
ikcycles = ilens * kr
if (ktimek == 1) then
kcount = 0
while (kcount < ikcycles) do
aposw linseg 0, ilens, inewlen - 1
aposr linseg 0, ilens, ilen - 1
asig table3 aposr, ifnL
tablew asig, aposw, ifnnewL
if (ifnR != -1) then
asig table3 aposr, ifnR
tablew asig, aposw, ifnnewR
endif
kcount += 1
od
else
kdone = 1
endif
if (ifreeafter == 1) then
ftfree ifnL, 1
if (ifnR != -1) then
ftfree ifnR, 1
endif
endif
else
kdone init 1
ifnnewL = ifnL
ifnnewR = ifnR
endif
xout ifnnewL, ifnnewR, kdone
endop
opcode tab_samplerateconvert, ik, ipj
ifn, ifreeafter, isourcesr xin
ifnnew, i_, kdone tab_samplerateconvert ifn, -1, ifreeafter, isourcesr
xout ifnnew, kdone
endop
; table
opcode tab_serialise, S, i
ifn xin
ilen = ftlen(ifn)
index = 0
Sout = "["
while (index < ilen) do
if (index != 0) then
Sout = strcat(Sout, ",")
endif
ivalue = table:i(index, ifn)
SprintfChar = (frac(ivalue) == 0) ? "%d" : "%f"
Sout = strcat(Sout, sprintf(SprintfChar, ivalue))
index += 1
od
Sout = strcat(Sout, "]")
xout Sout
endop
opcode tab_unserialise, 0, Si
Sdata, ifn xin
ilen = strlen(Sdata)
ichar = 0
inarray = 0
ivalstart = -1
index = 0
while (ichar < ilen) do
Schar = strsub(Sdata, ichar, ichar + 1)
if (strcmp(Schar, "[") == 0) then
inarray = 1
ivalstart = ichar + 1
elseif (inarray == 1 && strcmp(Schar, "]") == 0) then
inarray = 0
elseif (inarray == 1 && strcmp(Schar, ",") == 0) then
tablew strtod(strsub(Sdata, ivalstart, ichar)), index, ifn
ivalstart = ichar + 1
index += 1
endif
ichar += 1
od
endop
opcode tab_bubblesort, 0, i
ifn xin
itemp = 0
ilen = ftlen(ifn)
index1 = 0
while (index1 < ilen - 1) do
index2 = 0
while (index2 < ilen - 1 - index1) do
ival1 = tab_i(index2, ifn)
ival2 = tab_i(index2 + 1, ifn)
if (ival1 > ival2) then
itemp = ival1
tabw_i ival2, index2, ifn
tabw_i itemp, index2 + 1, ifn
endif
index2 += 1
od
index1 += 1
od
endop
opcode tab_destroy, 0, i
ifn xin
if (ftexists(ifn) == 1) then
ftfree ifn, 0
endif
endop
/*
get condensed table eg for waveform view
*/
opcode tab_overview, i, io
ifn, isamples xin
isamples = (isamples == 0) ? 256 : isamples
ifnlen = ftlen(ifn)
istep = round(ifnlen / isamples)
ifndata ftgen 0, 0, -isamples, 7, 0
index = 0
indexwrite = 0
while (index < ifnlen) do
ival tab_i index, ifn
if (!(indexwrite > isamples - 1)) then
tabw_i ival, indexwrite, ifndata
endif
indexwrite += 1
index += istep
od
xout ifndata
endop
#end
|