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
|
#ifndef UDO_FFTCONVOLVE
#define UDO_FFTCONVOLVE ##
/*
Block based FFT convolution
This file is part of the SONICS UDO collection by Richard Knight 2021
License: GPL-2.0-or-later
http://1bpm.net
*/
/*
Per FFT block convolution
aout blockconvolve ain1, ain2, [ifftsize, ihopsize]
aout convolved output
ain1 input 1
ain2 input 2
ifftsize FFT size DEFAULT(256)
ihopsize FFT hop size DEFAULT(256)
*/
opcode blockconvolve, a, aajj
idopow = 0 ; use pow on mags
ain1, ain2, ifftsize, ihopsize xin
if (ihopsize == -1) then
ihopsize = 256
endif
if (ifftsize == -1) then
ifftsize = 256
endif
setksmps 1
iolaps = ifftsize / ihopsize
ibw = sr / ifftsize
kcnt init 0
krow init 0
kOla1[] init ifftsize
kOla2[] init ifftsize
kIn1[] init ifftsize
kIn2[] init ifftsize
kOut[][] init iolaps, ifftsize ; output buffers
if (kcnt == ihopsize) then
kWin1[] window kIn1, krow * ihopsize
kWin2[] window kIn2, krow * ihopsize
kSpec1[] rfft kWin1
kSpec2[] rfft kWin2
kmags1[] mags kSpec1
kmags2[] mags kSpec2
kmagMult[] = kmags1 * kmags2
kphs1[] phs kSpec1
kphs2[] phs kSpec2
kphsMult[] = kphs1 * kphs2
; pow thing doesn't sound that good
if (idopow == 1) then
kindex = 0
kpows[] init lenarray(kmagMult)
while (kindex < lenarray(kmagMult)) do
kpows[kindex] pow kmagMult[kindex], 0.5
kindex += 1
od
else
kpows[] = kmagMult
endif
kSpec1 pol2rect kpows, kphsMult
; IFFT + window
kRow[] rifft kSpec1
kWin1 window kRow, krow * ihopsize
; place it on out buffer
kOut setrow kWin1, krow
; zero the ola buffer
kOla1 = 0
; overlap add
ki = 0
until (ki == iolaps) do
kRow getrow kOut, ki
kOla1 = kOla1 + kRow
ki += 1
od
; update counters
krow = (krow + 1) % iolaps
kcnt = 0
endif
; shift audio in/out of buffers
kIn1 shiftin ain1
kIn2 shiftin ain2
aout shiftout kOla1
xout aout / iolaps
; increment counter
kcnt += ksmps
endop
#end
|