aboutsummaryrefslogtreecommitdiff
path: root/site/udo/table_tools.udo
blob: 50f5997aec715db843157211273e414d4d45e0d3 (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
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