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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
|
#ifndef UDO_TWIST_TRANSFORMAPI
#define UDO_TWIST_TRANSFORMAPI ##
#define TWST_TRANSFORM #i_ = p4#
opcode twst_param, k, S
Sname xin
Schannel = sprintf("%s_%s%d", nstrstr(p1), Sname, p4)
kvalue chnget Schannel
xout kvalue
endop
opcode twst_parami, i, S
Sname xin
Schannel = sprintf("%s_%s%d", nstrstr(p1), Sname, p4)
ivalue chnget Schannel
xout ivalue
endop
opcode twst_getinput, aaii, 0
aL chnget "twstfeedL"
aR chnget "twstfeedR"
xout aL, aR, gitwst_tf_state[0], gitwst_tf_state[1]
endop
opcode twst_setlatencysamples, 0, i
isamples xin
gitwst_tf_state[5] = isamples
endop
opcode twst_setlatencyseconds, 0, i
iseconds xin
twst_setlatencysamples iseconds * sr
endop
opcode twst_getlatencyseconds, i, 0
xout gitwst_tf_state[5] / sr
endop
opcode twst_tf_pitchscale_custom, k, S
SchanPrepend xin
if (twst_param(strcat(SchanPrepend, "pitchscalemode")) == 1) then
ksemitones = twst_param(strcat(SchanPrepend, "pitchsemitones"))
kscale = pow:k(2, ksemitones / 12)
else
kscale = twst_param(strcat(SchanPrepend, "pitchscale"))
endif
xout kscale
endop
opcode twst_tf_pitchscale, k, 0
xout twst_tf_pitchscale_custom("")
endop
opcode twst_tf_freq_custom, k, S
SchanPrepend xin
if (twst_param(strcat(SchanPrepend, "freqmode")) == 1) then
kfreq = cpsmidinn:k(twst_param(strcat(SchanPrepend, "note")))
else
kfreq = twst_param(strcat(SchanPrepend, "freq"))
endif
xout kfreq
endop
opcode twst_tf_freq, k, 0
xout twst_tf_freq_custom("")
endop
opcode twst_tf_freqi_custom, i, S
SchanPrepend xin
if (twst_parami(strcat(SchanPrepend, "freqmode")) == 1) then
ifreq = cpsmidinn:i(twst_parami(strcat(SchanPrepend,"note")))
else
ifreq = twst_parami(strcat(SchanPrepend,"freq"))
endif
xout ifreq
endop
opcode twst_tf_freqi, i, 0
xout twst_tf_freqi_custom("")
endop
opcode twst_tf_setplayposition, 0, k
kplayposratio xin
chnset kplayposratio, "twst_tfplayposratio"
endop
opcode twst_tf_getwintype, i, j
iwintype xin
if (iwintype == -1) then
iwintype = twst_parami("wintype")
endif
ifnWindow = gifnHanning
if (iwintype == 1) then
ifnWindow = gifnHamming
elseif (iwintype == 2) then
ifnWindow = gifnHalfSine
endif
xout ifnWindow
endop
opcode twst_tf_getwintypek, k, 0
kwintype = twst_param("wintype")
kfnWindow = gifnHanning
if (kwintype == 1) then
kfnWindow = gifnHamming
elseif (kwintype == 2) then
kfnWindow = gifnHalfSine
endif
xout kfnWindow
endop
opcode twst_tf_getwaveform, i, j
iwave xin
if (iwave == -1) then
iwave = twst_parami("wave")
endif
ifn = gifnSine
if (iwave == 1) then
ifn = gifnSquare
elseif (iwave == 2) then
ifn = gifnSaw
elseif (iwave == 3) then
ifn = gifnPulse
elseif (iwave == 4) then
ifn = gifnTriangle
endif
xout ifn
endop
opcode twst_tf_getwaveformk, k, J
kwave xin
kwave = (kwave == -1) ? twst_param("wave") : kwave
kfn = gifnSine
if (kwave == 1) then
kfn = gifnSquare
elseif (kwave == 2) then
kfn = gifnSaw
elseif (kwave == 3) then
kfn = gifnPulse
elseif (kwave == 4) then
kfn = gifnTriangle
endif
xout kfn
endop
opcode twst_getfinput, ffaaii, jJ
ifftsize, kpvslock xin
ifftsize = (ifftsize == -1) ? twst_parami("fftsize") : ifftsize
kpvslock = (kpvslock == -1) ? twst_param("pvslock") : kpvslock
iwintype = twst_parami("pvswintype")
idecimation = twst_parami("pvsdecimation")
iwinsizem = twst_parami("pvswinsizem")
iwinsize = ifftsize * iwinsizem
twst_setlatencysamples(iwinsize) ;idecimation)
aL, aR, ileft, iright twst_getinput
if (ileft == 0) then
fL pvsinit ifftsize
else
fLbase pvsanal aL, ifftsize, ifftsize / idecimation, iwinsize, 1
fL pvslock fLbase, kpvslock
endif
if (iright == 0) then
fR pvsinit ifftsize
else
fRbase pvsanal aR, ifftsize, ifftsize / idecimation, iwinsize, 1
fR pvslock fRbase, kpvslock
endif
xout fL, fR, aL, aR, ileft, iright
endop
/* TODO: LPC unstable with WASM
opcode twst_getfinput, ffaaii, jJ
ifftsize, kpvslock xin
ifftsize = (ifftsize == -1) ? twst_parami("fftsize") : ifftsize
kpvslock = (kpvslock == -1) ? twst_param:k("pvslock") : kpvslock
ipvstype = twst_parami("pvstype")
iwintype = twst_parami("pvswintype")
iwinlpcfn = twst_tf_getwintype(twst_parami("pvswintypelpc"))
idecimation = twst_parami("pvsdecimation")
iwinsizem = twst_parami("pvswinsizem")
iorderm = twst_parami("pvsorderm")
if (ipvstype == 1) then
ifftsize = min(ifftsize, 1024) ; crashes in WASM with high FFT size and LPC
endif
iorder = min(max(1, round(ifftsize * iorderm)), ifftsize)
iwinsize = ifftsize * iwinsizem
twst_setlatencysamples(iwinsize) ;idecimation)
aL, aR, ileft, iright twst_getinput
if (ileft == 0) then
fL pvsinit ifftsize
else
if (ipvstype == 0) then
fLbase pvsanal aL, ifftsize, ifftsize / idecimation, iwinsize, 1
else
fLbase pvslpc aL, ifftsize, ifftsize / idecimation, iorder, iwinlpcfn
endif
fL pvslock fLbase, kpvslock
endif
if (iright == 0) then
fR pvsinit ifftsize
else
if (ipvstype == 0) then
fRbase pvsanal aR, ifftsize, ifftsize / idecimation, iwinsize, 1
else
fRbase pvslpc aR, ifftsize, ifftsize / idecimation, iorder, iwinlpcfn
endif
fR pvslock fRbase, kpvslock
endif
xout fL, fR, aL, aR, ileft, iright
endop
*/
; ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate
opcode twst_tf_getstate, iiiiii, 0
ilengths = ((gitwst_tf_state[3] - gitwst_tf_state[2]) / sr)
xout gitwst_tf_state[0], gitwst_tf_state[1], gitwst_tf_state[2], gitwst_tf_state[3], gitwst_tf_state[4], ilengths
endop
opcode twst_tf_isoffline, i, 0
xout gitwst_tf_state[6]
endop
opcode twst_tfi_getfn, ii, jjjjjj
instanceindex, ileft, iright, istartsamp, iendsamp, idocut xin
instanceindex = (instanceindex == -1) ? gitwst_instanceindex : instanceindex
ileft = (ileft == -1) ? gitwst_tf_state[0] : ileft
iright = (iright == -1) ? gitwst_tf_state[1] : iright
istartsamp = (istartsamp == -1) ? gitwst_tf_state[2] : istartsamp
iendsamp = (iendsamp == -1) ? gitwst_tf_state[3] : iendsamp
idocut = (idocut == -1) ? gitwst_tf_state[4] : idocut
if (idocut == 1) then
itargetlen = iendsamp - istartsamp ;int(p3 * sr)
if (ileft == 1) then
ifnL ftgentmp 0, 0, -itargetlen, -2, 0
ftslicei gitwst_bufferL[instanceindex], ifnL, istartsamp, iendsamp, 1
else
ifnL = 0
endif
if (iright == 1) then
ifnR ftgentmp 0, 0, -itargetlen, -2, 0
ftslicei gitwst_bufferR[instanceindex], ifnR, istartsamp, iendsamp, 1
else
ifnR = 0
endif
else
ifnL = gitwst_bufferL[instanceindex]
ifnR = gitwst_bufferR[instanceindex]
endif
xout ifnL, ifnR
endop
opcode _twst_getcrossdata, iiiiiii, S
SchannelPrefix xin
if (strcmp(SchannelPrefix, "") == 0) then
ichannel = twst_parami("instchan")
instanceindex = twst_parami("instance")
istart = twst_parami("inststart")
iend = twst_parami("instend")
else
ichannel chnget strcat(SchannelPrefix, sprintf("instchan%d", p4))
instanceindex chnget strcat(SchannelPrefix, sprintf("instance%d", p4))
istart chnget strcat(SchannelPrefix, sprintf("inststart%d", p4))
iend chnget strcat(SchannelPrefix, sprintf("instend%d", p4))
endif
idoleft = 1
idoright = 1
if (ichannel == 0 || gitwst_channels[instanceindex] == 1) then
idoright = 0
elseif (ichannel == 1 && gitwst_channels[instanceindex] == 2) then
idoleft = 0
endif
if (istart == iend) then
istart = 0
iend = 1
endif
istart, ilen twst_getstartend istart, iend, instanceindex
ifnL = gitwst_bufferL[instanceindex]
ifnR = gitwst_bufferR[instanceindex]
xout idoleft, idoright, ifnL, ifnR, instanceindex, istart, ilen
endop
opcode _twst_getcrossdata, iiiiii, S
SchannelPrefix xin
ileft, iright, ifnL, ifnR, instanceindex, istart, iend _twst_getcrossdata SchannelPrefix
xout ifnL, ifnR, istart, iend - istart, ileft, iright
endop
opcode twst_getcrossdata, iiiiii, 0
ifnL, ifnR, istart, ilen, idoleft, idoright _twst_getcrossdata ""
xout ifnL, ifnR, istart, ilen, idoleft, idoright
endop
opcode twst_tfi_getcrossfn, ii, 0
ileft, iright, ifnL, ifnR, instanceindex, istart, ilen _twst_getcrossdata ""
idocut = (ftlen(ifnL) == ilen) ? 0 : 1
ifnLtemp, ifnRtemp twst_tfi_getfn instanceindex, ileft, iright, istart, istart + ilen, idocut
if (gitwst_channels[instanceindex] == 1) then
ifnRtemp = ifnLtemp
endif
xout ifnLtemp, ifnRtemp
endop
opcode _twst_getcrossinput, aaii, S
SchannelPrefix xin
ifnL, ifnR, istart, ilen, idoleft, idoright _twst_getcrossdata SchannelPrefix
if (strcmp(SchannelPrefix, "") == 0) then
ilooptype = twst_parami("otlooptype")
else
ichannel chnget strcat(SchannelPrefix, sprintf("looptype%d", p4))
endif
apos lphasor 1, 0, ilen, ilooptype
apos += istart
if (idoleft == 1) then
aL table3 apos, ifnL
endif
if (idoright == 1) then
aR table3 apos, ifnR
endif
if (idoright == 0) then
aR = aL
endif
if (idoleft == 0) then
aL = aR
endif
xout aL, aR, idoleft, idoright
endop
opcode twst_getcrossinput, aaii, 0
aL, aR, idoleft, idoright _twst_getcrossinput ""
xout aL, aR, idoleft, idoright
endop
opcode twst_getfcrossinput, ffii, 0
aL, aR, ileft, iright twst_getcrossinput
ifftsize = twst_parami("fftsize")
kpvslock = twst_param("pvslock")
idecimation = twst_parami("pvsdecimation")
iwinsizem = twst_parami("pvswinsizem")
iwinsize = ifftsize * iwinsizem
if (ileft == 0) then
fL pvsinit ifftsize
else
fLbase pvsanal aL, ifftsize, ifftsize / idecimation, iwinsize, 1
fL pvslock fLbase, kpvslock
endif
if (iright == 0) then
fR pvsinit ifftsize
else
fRbase pvsanal aR, ifftsize, ifftsize / idecimation, iwinsize, 1
fR pvslock fRbase, kpvslock
endif
xout fL, fR, ileft, iright
endop
opcode twst_tf_fresynth, a, f
fsig xin
imode = twst_parami("pvresmode")
if (imode == 0) then
aout pvsynth fsig
else
ifftsize = twst_parami("fftsize")
ioscnum = max(round((ifftsize * 0.5) * twst_parami("pvaoscnum")) - 1, 1)
kfmod = twst_param("pvafreqmod")
ibinoffset = round(ifftsize * 0.5 * twst_parami("pvabinoffset"))
ibinincr = twst_parami("pvabinincr")
ioscnum = ioscnum - ibinoffset
ioscnum = min(((ifftsize * 0.5) / ibinincr), ioscnum)
aout pvsadsyn fsig, ioscnum, kfmod, ibinoffset, ibinincr
endif
xout aout
endop
opcode twst_getrandombuffers, kk, k
kstereounique xin
kfnL = -1
kfnR = -1
if (kstereounique == 0) then
while (kfnL == -1) do
kindex = round:k(random:k(0, lenarray(gitwst_bufferL) - 1))
if (ftexists(gitwst_bufferL[kindex]) == 1) then
kfnL = gitwst_bufferL[kindex]
if (ftexists(gitwst_bufferR[kindex]) == 1) then
kfnR = gitwst_bufferR[kindex]
else
kfnR = kfnL
endif
endif
od
else
while (kfnL == -1) do
kfn = gitwst_bufferL[round:k(random:k(0, lenarray(gitwst_bufferL) - 1))]
if (ftexists(kfn) == 1) then
kfnL = kfn
endif
od
while (kfnR == -1) do
kfn = gitwst_bufferR[round:k(random:k(0, lenarray(gitwst_bufferR) - 1))]
if (ftexists(kfn) == 1) then
kfnR = kfn
endif
od
endif
xout kfnL, kfnR
endop
#end
|