diff options
Diffstat (limited to 'site/udo/sound_sdb.udo')
-rwxr-xr-x | site/udo/sound_sdb.udo | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/site/udo/sound_sdb.udo b/site/udo/sound_sdb.udo new file mode 100755 index 0000000..82fe009 --- /dev/null +++ b/site/udo/sound_sdb.udo @@ -0,0 +1,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
|