diff options
Diffstat (limited to 'site/udo/sound_melsys.udo')
-rwxr-xr-x | site/udo/sound_melsys.udo | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/site/udo/sound_melsys.udo b/site/udo/sound_melsys.udo new file mode 100755 index 0000000..588f137 --- /dev/null +++ b/site/udo/sound_melsys.udo @@ -0,0 +1,215 @@ +#ifndef UDO_MELSYS
+#define UDO_MELSYS ##
+
+/*
+ Melodic sampler system
+
+ Typical external usage should only refer to
+ mel_playnote
+ mel_getcollection
+
+
+ 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 "host_tools.udo"
+#include "pvs_tools.udo"
+#include "bussing.udo"
+
+
+
+opcode _mel_loadobject, i[][], S[][]
+ Sres[][] xin
+ imelmap[][] init 128, 16
+ index = 0
+ while (index < lenarray(Sres)) do
+ ifileid strtod Sres[index][0]
+ ichannels strtod Sres[index][2]
+ iduration strtod Sres[index][3]
+ inote strtod Sres[index][4]
+
+ if (imelmap[inote][0] == 0) then
+ imelmap[inote][0] = 1
+ endif
+ imelmap[inote][imelmap[inote][0]] _rdb_loadsound ifileid, ichannels, iduration, Sres[index][1]
+ imelmap[inote][0] = imelmap[inote][0] + 1 ; first index keeps track of length
+
+ index += 1
+ od
+ xout imelmap
+endop
+
+
+
+
+/*
+ Get soundcollection with basic analysis information
+ isounds[][] getcollection ScollectionName
+
+ isounds[][] soundcollection object
+ ScollectionName the name of the filecollection in the database
+*/
+opcode mel_getcollection, i[][], S
+ Scollection xin
+ Sbase = {{select file_id, f_localpath(%d, path), channels, duration, note
+ from svw.analysis_basic_collectionnorm a
+ join filecollection fc on fc.id = a.filecollection_id
+ join filecollectiontype fct on fct.id = fc.type_id
+ where fc.name = '%s'
+ and fct.name = 'melsys'
+ }}
+ Squery sprintf Sbase, gihost_type, Scollection
+ Sres[][] dbarray gidb, Squery
+ idata[][] _mel_loadobject Sres
+ xout idata
+endop
+
+
+/*
+ Get all melodic soundcollection names
+ Scollections[] mel_listcollections
+
+ Scollections[] list of soundcollections
+*/
+opcode mel_listcollections, S[], 0
+ Sres[][] dbarray gidb, "select distinct fc.name from filecollection fc join filecollectiontype fct on fct.id = fc.type_id where fct.name = 'melsys'"
+ ilen = lenarray(Sres)
+ Scollections[] init ilen
+ index = 0
+ while (index < ilen) do
+ Scollections[index] = Sres[index][0]
+ index += 1
+ od
+ xout Scollections
+endop
+
+
+/*
+ Get nearest note and a ratio to alter to specific note
+*/
+opcode _mel_getnearestnote, ii, ii[][]
+ inote, imelmap[][] xin
+ iratio = 0
+ inearest = -1
+ idistance = 999
+ index = 0
+ while (index < 128) do
+ if (imelmap[index][0] > 0) then
+ if (inote > index) then
+ imeasure = inote - index
+ if (imeasure < idistance) then
+ idistance = imeasure
+ inearest = index
+ endif
+ elseif (inote < index ) then
+ imeasure = index - inote
+ if (imeasure < idistance) then
+ idistance = imeasure
+ inearest = index
+ endif
+ else
+ idistance = 0
+ inearest = inote
+ goto output
+ endif
+ endif
+ index += 1
+ od
+ iratio = cpsmidinn(inote) / cpsmidinn(inearest)
+output:
+ isoundindex = imelmap[inearest][int(random(1, imelmap[inearest][0]))]
+ xout isoundindex, iratio
+endop
+
+
+opcode mel_getrandnote, ii, ii[][]
+ inote, imelmap[][] xin
+ iout = -1
+ if (imelmap[inote][0] > 0) then
+ index = int(random(1, imelmap[inote][0]))
+ iout = imelmap[inote][index]
+ iratio = 1
+ else
+ iout, iratio _mel_getnearestnote inote, imelmap
+ endif
+ xout iout, iratio
+endop
+
+
+
+/*
+
+
+*/
+opcode _mel_playsound, 0, iSppooooo
+ index, Sbus, iamp, ipitchratio, iwhen, iusepvs, ikeepformant, ifadein, idurationoverride xin
+ Scoreline = sprintf("i\"mel_player_default\" %f 1 \"%s\" %f %f %f %d %d %d %f", iwhen, Sbus, index, iamp, ipitchratio, iusepvs, ikeepformant, ifadein, idurationoverride)
+ scoreline_i Scoreline
+endop
+
+
+opcode mel_playnote, 0, i[][]iSpooooo
+ imelmap[][], inote, Sbus, iamp, iwhen, idurationoverride, iusepvs, ikeepformant, ifadein xin
+ isoundindex, ipitchratio mel_getrandnote inote, imelmap
+ _mel_playsound isoundindex, Sbus, iamp, ipitchratio, iwhen, iusepvs, ikeepformant, ifadein, idurationoverride
+endop
+
+
+
+
+instr mel_player_default
+ Sbus = p4
+ isoundindex = p5
+ iamp = p6
+ ipitchratio = p7
+ iusepvs = p8
+ ikeepformant = p9
+ ifadein = p10
+ idurationoverride = p11
+ isound[] = get_sound(isoundindex)
+
+ if (idurationoverride == 0) then
+ p3 = isound[3] ; set duration
+ else
+ p3 = idurationoverride
+ endif
+
+
+ if (iusepvs == 1) then
+ iloscilratio = 1
+ else
+ iloscilratio = ipitchratio
+ endif
+
+ if (isound[2] == 1) then ; check channels
+ aL loscil iamp, iloscilratio, isound[0], 1
+ if (iusepvs == 1) then
+ aL pvscaler aL, ipitchratio, ikeepformant
+ endif
+ aR = aL
+ else
+ aL, aR loscil iamp, iloscilratio, isound[0], 1
+ if (iusepvs == 1) then
+ aL pvscaler aL, ipitchratio, ikeepformant
+ aR pvscaler aR, ipitchratio, ikeepformant
+ endif
+ endif
+
+ if (ifadein == 1) then
+ kenv linseg 0, p3*0.4, 1, p3*0.5, 1, p3*0.1, 0
+ else
+ kenv linseg 1, p3*0.9, 1, p3*0.1, 0
+ endif
+
+ bus_mix(Sbus, aL*kenv, aR*kenv)
+endin
+
+
+#end
|