#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