aboutsummaryrefslogtreecommitdiff
path: root/site/udo/fftconvolve.udo
diff options
context:
space:
mode:
Diffstat (limited to 'site/udo/fftconvolve.udo')
-rwxr-xr-xsite/udo/fftconvolve.udo116
1 files changed, 116 insertions, 0 deletions
diff --git a/site/udo/fftconvolve.udo b/site/udo/fftconvolve.udo
new file mode 100755
index 0000000..fe17319
--- /dev/null
+++ b/site/udo/fftconvolve.udo
@@ -0,0 +1,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