aboutsummaryrefslogtreecommitdiff
path: root/site/udo/fftconvolve.udo
blob: fe17319a54db9361d7342ad1bdfb0860ece02fa2 (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
#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