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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
#ifndef UDO_SOUNDSDB
#define UDO_SOUNDSDB ##
/*
SQL database interface to sound object management
This file is part of the SONICS UDO collection by Richard Knight 2021
License: GPL-2.0-or-later
http://1bpm.net
*/
#include "sound_db.udo"
#include "pgdb.udo"
#include "bussing.udo"
#include "host_tools.udo"
#include "pvs_tools.udo"
/*
soundcollection object structure: 2D array with first dimension as sound index and second as
0 runtime sound db index
1 rms normalised over all collections
2 average pitch hz
3 average centroid hz
4 match distance; optional depending on returning opcode
*/
;gisdb_data[][] init 99999, 4
/*
Internal: format a standard soundcollection database result as soundcollection object
isounds[][] _load_sdbobject Sresult[][], [ihasdistance]
isounds[][] soundcollection object
Sresult[][] the raw database result string array
ihasdistance whether to include the additional distance dimension
*/
opcode _sdb_loadobject, i[][], S[][]o
Sres[][], ihasdistance xin
iarraylength = lenarray(Sres)
idata[][] init iarraylength, 4 + ihasdistance
index = 0
while (index < lenarray(Sres)) do
ifileid strtod Sres[index][0]
ichannels strtod Sres[index][2]
iduration strtod Sres[index][3]
idata[index][0] _rdb_loadsound ifileid, ichannels, iduration, Sres[index][1]
idata[index][1] strtod Sres[index][4] ; rmsnormal
idata[index][2] strtod Sres[index][5] ; pitch
idata[index][3] strtod Sres[index][6] ; centroid
if (ihasdistance == 1) then
idata[index][4] strtod Sres[index][7]
endif
index += 1
od
xout idata
endop
/*
Get a string array of all current filecollections
Scollections[] sdb_listcollections
Scollections[] list of collections
*/
opcode sdb_listcollections, S[], 0
Sres[][] dbarray gidb, "select name from filecollection"
ilen = lenarray(Sres)
Scollections[] init ilen
index = 0
while (index < ilen) do
Scollections[index] = Sres[index][0]
index += 1
od
xout Scollections
endop
/*
Get soundcollection(s) with basic analysis information
isounds[][] sdb_getcollection ScollectionName
isounds[][] soundcollection object
ScollectionName the name of the filecollection in the database or comma separated list of collections
*/
opcode sdb_getcollection, i[][], S
Scollection xin
Sbase = {{select file_id, f_localpath(%d, path), channels, duration, rmsnormal, pitch, centroid
from svw.analysis_basic_collectionnorm a
join filecollection fc on fc.id = a.filecollection_id
where %s
}}
if (strindex(Scollection, ",") > 0) then
Sclause = "(1=2"
index = 1
Stemp = Scollection
while (index > 0) do
index strindex Stemp, ","
if (index > 0) then
Sclause strcat Sclause, sprintf(" or fc.name='%s'", strsub(Stemp, 0, index))
Stemp strsub Stemp, index+1
else
Sclause strcat Sclause, sprintf(" or fc.name='%s'", Stemp)
endif
od
Sclause strcat Sclause, ")"
else
Sclause = sprintf("fc.name = '%s'", Scollection)
endif
Squery sprintf Sbase, gihost_type, Sclause
Sres[][] dbarray gidb, Squery
idata[][] _sdb_loadobject Sres
xout idata
endop
/*
Bubble sort a soundcollection 'object' by a specified analysis element
iordered[][] orderby isounds[][], ielement, [isortorder=0]
iordered[][] the sorted soundcollection 'object'
isounds[][] the input soundcollection 'object'
ielement which analysis element to order by:
0 duration
1 rms
2 pitch
3 centroid
4 distance, if collection is provided from a matching opcode
isortorder optional sort order:
0 descending
1 ascending
*/
opcode sdb_orderby, i[][], i[][]io
idata[][], ielement, iordering xin
ilen = lenarray(idata)
index = 0
while (index < ilen) do
index2 = 0
while (index2 < ilen) do
; duration requires an obnoxious looking cross array reference
if (\
(ielement == 0 && ( \
(iordering == 0 && gisoundsdb[idata[index][0]][3] > gisoundsdb[idata[index2][0]][3]) \
|| (iordering == 1 && gisoundsdb[idata[index][0]][3] < gisoundsdb[idata[index2][0]][3]) \
)) || ( \
(iordering == 0 && idata[index][ielement] > idata[index2][ielement]) \
||(iordering == 1 && idata[index][ielement] < idata[index2][ielement]) \
) \
) then
iswap[] getrow idata, index
iswap2[] getrow idata, index2
idata setrow iswap2, index
idata setrow iswap, index2
endif
index2 += 1
od
index += 1
od
xout idata
endop
/*
Filter a soundcollection object with min and max parameters of basic analysis data applied
ifiltered[][], ivalid subselect isounds[][],
[iminduration, imaxdur, iminrms, imaxrms, iminpitch, imaxpitch, imincent, imaxcent]
ifiltered[][] the new soundcollection 'object' with sounds limited to scope specified
ivalid 1 if records returned, 0 if the returned array is effectively empty
isounds[][] the input soundcollection 'object' to be filtered
iminduration optional minimum duration
imaxduration optional maximum duration
iminrms optional minimum rms
imaxrms optional maximum rms
iminpitch optional minimum pitch
imaxpitch optional maximum pitch
imincent optional minimum centroid
imaxcent optional maximum centroid
*/
opcode sdb_subselect, i[][]i, i[][]iii
idata[][], ielement, imin, imax xin
indexes[] init lenarray(idata)
imaxindex = 0
index = 0
while (index < lenarray(idata)) do
if ( \
idata[index][ielement] >= imin && idata[index][ielement] <= imax \
) then
indexes[imaxindex] = index
imaxindex += 1
endif
index += 1
od
if (imaxindex == 0) then
ifiltered[][] init 1, 1
ivalid = 0
else
ifiltered[][] init imaxindex, 7
ivalid = 1
index = 0
while (index < imaxindex) do ; TODO setrow here?????
index2 = 0
while (index2 < 7) do
ifiltered[index][index2] = idata[indexes[index]][index2]
index2 += 1
od
index += 1
od
endif
xout ifiltered, ivalid
endop
opcode _sdb_playsound, 0, iSppoooo
index, Sbus, iamp, ihz, iwhen, iusepvs, ikeepformant, ifadein xin
Scoreline = sprintf("i\"sdb_player_default\" %f 1 \"%s\" %d %f %f %d %d %d", iwhen, Sbus, index, iamp, ihz, iusepvs, ikeepformant, ifadein)
scoreline_i Scoreline
endop
opcode sdb_playsound, 0, i[][]iSpooooo
isounds[][], index, Sbus, iamp, iwhen, ihz, iusepvs, ikeepformant, ifadein xin
_sdb_playsound isounds[index][0], Sbus, iamp, ihz, iwhen, iusepvs, ikeepformant, ifadein
endop
opcode sdb_playrandom, 0, i[][]Spooooo
isounds[][], Sbus, iamp, iwhen, ihz, iusepvs, ikeepformant, ifadein xin
index = round(random(0, lenarray(isounds)-1))
_sdb_playsound isounds[index][0], Sbus, iamp, ihz, iwhen, iusepvs, ikeepformant, ifadein
endop
instr sdb_player_default
Sbus = p4
isoundindex = p5
iamp = p6
ihz = p7
iusepvs = p8
ikeepformant = p9
ifadein = p10
isound[] = get_sound(isoundindex)
p3 = isound[3]
aL, aR loscil iamp, 1, isound[0], 1
kenv linseg 1, p3*0.9, 1, p3*0.1, 0
bus_mix(Sbus, aL*kenv, aR*kenv)
endin
#end
|