aboutsummaryrefslogtreecommitdiff
path: root/site/udo/sound_db.udo
blob: c9862fc1928417afb04088ac2f55065495ded915 (plain)
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
#ifndef UDO_RUNTIMEDB
#define UDO_RUNTIMEDB ##
/*
	Runtime sound database manager

	This file is part of the SONICS UDO collection by Richard Knight 2021
		License: GPL-2.0-or-later
		http://1bpm.net
*/

#include "string_tools.udo"

/*
	Runtime sound database array structure:
		0	ftable number
		1	file id
		2	number of channels
		3	duration
*/
gisoundsdb[][] init 99999, 4
gisoundsdbmax init 0


/*
	Load a sound to the runtime sounds db array, or return the index if already loaded (by file id tracking)
	For pgdb usage
	index loadsound ifileid, ichannels, iduration, Spath

	index		sound database index

	ifileid		database file id, for tracking
	ichannels	number of channels in file
	iduration	duration of file
	Spath		path to the file
*/
opcode _rdb_loadsound, i, iiiS
	ifileid, ichannels, iduration, Spath xin
	index = 0
	ifn = -1
				;goto loadrequired	; HACK, 32bit fail on hash
	while (index < gisoundsdbmax) do
		if (gisoundsdb[index][0] == 0) then ; nothing loaded at all
			igoto loadrequired ; give up now, don't go through all of array
		endif

		if (gisoundsdb[index][1] == ifileid) then
			igoto complete
		endif
		index += 1
	od

loadrequired:
	if (ifn == -1) then
		isize = filelen(Spath) * filesr(Spath) * filenchnls(Spath); HACK: grain cannot use deferred time: TODO: pass in samplerate and length to opcode (TODO: database needs samplerate)
		ifn = ftgen(0, 0, isize, 1, Spath, 0, 0, 0)
		index = gisoundsdbmax
		gisoundsdb[index][0] = ifn
		gisoundsdb[index][1] = ifileid
		gisoundsdb[index][2] = ichannels
		gisoundsdb[index][3] = iduration
		gisoundsdbmax += 1
	endif

complete:
	xout index
endop


/*
	Load a sound to the runtime sounds db array, or return the index if already loaded (by file id tracking)
	For direct FS usage
	index loadsound Spath

	index		sound database index

	Spath		path to the file

*/
opcode rdb_loadsound, i, S
	Spath xin
	ifileid str_hash Spath
	ichannels = filenchnls(Spath)
	iduration = filelen(Spath)
print iduration
	xout _rdb_loadsound(ifileid, ichannels, iduration, Spath)
endop



/*
	Load a directory of sounds with suffix .wav and return an array of the runtime db indexes
	indexes[] rdb_loaddir Spath

	indexes[]	sound database indexes

	Spath		directory path
*/
opcode rdb_loaddir, i[], S
	Spath xin
	Sfiles[] directory Spath, ".wav"
	isounds[] init lenarray(Sfiles)
	index = 0
	while (index < lenarray(Sfiles)) do
		isounds[index] rdb_loadsound Sfiles[index]
		index += 1
	od
	xout isounds
endop



/*
	Get sound array from sound database
	isound[] get_sound index

	isound[]	the runtime sound database entry

	index		sound index as provided by load_sound	
*/
opcode get_sound, i[], i
	index xin
	;xout getrow(gisoundsdb, index) ; 32bit fail!

	ilen lenarray gisoundsdb, 2
	idata[] init ilen
	index2 = 0
	while (index2 < ilen) do
		idata[index2] = gisoundsdb[index][index2]
		index2 += 1
	od
	xout idata
endop


/*
	Get sound array from sound database
	ifn, ifileid, inchnls, idur get_sound index

	ifn			ftable of sound
	ifileid		file id
	inchnls		number of channels
	idur		duration in seconds

	index		sound index as provided by load_sound	
*/
opcode get_sound, iiii, i
	index xin
	xout gisoundsdb[index][0], gisoundsdb[index][1], gisoundsdb[index][2], gisoundsdb[index][3]
endop


#end