partitioned fft wip

This commit is contained in:
minjaesong
2023-11-25 23:31:54 +09:00
parent 1ed6f252db
commit 4d85d91478
2 changed files with 33 additions and 7 deletions

View File

@@ -5,10 +5,10 @@ import org.apache.commons.math3.transform.DftNormalization
import org.apache.commons.math3.transform.TransformType
import org.apache.commons.math3.util.FastMath
data class FComplex(var real: Float = 0f, var imaginary: Float = 0f) {
data class FComplex(var re: Float = 0f, var im: Float = 0f) {
operator fun times(other: FComplex) = FComplex(
this.real * other.real - this.imaginary * other.imaginary,
this.real * other.imaginary + this.imaginary * other.real
this.re * other.re - this.im * other.im,
this.re * other.im + this.im * other.re
)
}
@@ -34,8 +34,8 @@ object FFT {
fun ifftAndGetReal(y: Array<FComplex>): FloatArray {
val dataRI = Array<FloatArray>(2) { FloatArray(y.size) }
for (i in y.indices) {
dataRI[0][i] = y[i].real
dataRI[1][i] = y[i].imaginary
dataRI[0][i] = y[i].re
dataRI[1][i] = y[i].im
}
transformInPlace(dataRI, DftNormalization.STANDARD, TransformType.INVERSE)
@@ -112,8 +112,6 @@ object FFT {
bitReversalShuffle2(dataR, dataI)
// Do 4-term DFT.
// Do 4-term DFT.
if (type == TransformType.INVERSE) {
var i0 = 0

View File

@@ -315,12 +315,16 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() {
private val fftLen: Int
private val convFFT: Array<Array<FComplex>>
private val convFFTpartd: Array<Array<Array<FComplex>>> // index: Channel, partition, frequencies
private val inbuf: Array<FloatArray>
private val BLOCKSIZE = BUFFER_SIZE / 4
var processingSpeed = 1f; private set
private val partSizes: IntArray
private val partOffsets: IntArray
init {
if (!ir.exists()) {
throw IllegalArgumentException("Impulse Response file '${ir.path}' does not exist.")
@@ -358,6 +362,30 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() {
}
// println("convFFT Length = ${convFFT[0].size}")
if (fftLen < BUFFER_SIZE) // buffer size is always 4x the samples in the buffer
throw Error("FIR size is too small (minimum: $BUFFER_SIZE samples)")
val partitions = ArrayList<Int>()
var cnt = fftLen
while (cnt > BUFFER_SIZE / 4) {
cnt /= 2
partitions.add(cnt)
}
partitions.add(cnt)
partSizes = partitions.reversed().toIntArray()
partOffsets = partSizes.clone().also { it[0] = 0 }
// allocate arrays
convFFTpartd = Array(2) { ch ->
Array(partSizes.size) { partNo ->
Array(partSizes[partNo]) {
convFFT[ch][partOffsets[partNo] + it]
}
}
}
}
/**