mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
partitioned fft wip
This commit is contained in:
@@ -5,10 +5,10 @@ import org.apache.commons.math3.transform.DftNormalization
|
|||||||
import org.apache.commons.math3.transform.TransformType
|
import org.apache.commons.math3.transform.TransformType
|
||||||
import org.apache.commons.math3.util.FastMath
|
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(
|
operator fun times(other: FComplex) = FComplex(
|
||||||
this.real * other.real - this.imaginary * other.imaginary,
|
this.re * other.re - this.im * other.im,
|
||||||
this.real * other.imaginary + this.imaginary * other.real
|
this.re * other.im + this.im * other.re
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,8 +34,8 @@ object FFT {
|
|||||||
fun ifftAndGetReal(y: Array<FComplex>): FloatArray {
|
fun ifftAndGetReal(y: Array<FComplex>): FloatArray {
|
||||||
val dataRI = Array<FloatArray>(2) { FloatArray(y.size) }
|
val dataRI = Array<FloatArray>(2) { FloatArray(y.size) }
|
||||||
for (i in y.indices) {
|
for (i in y.indices) {
|
||||||
dataRI[0][i] = y[i].real
|
dataRI[0][i] = y[i].re
|
||||||
dataRI[1][i] = y[i].imaginary
|
dataRI[1][i] = y[i].im
|
||||||
}
|
}
|
||||||
|
|
||||||
transformInPlace(dataRI, DftNormalization.STANDARD, TransformType.INVERSE)
|
transformInPlace(dataRI, DftNormalization.STANDARD, TransformType.INVERSE)
|
||||||
@@ -112,8 +112,6 @@ object FFT {
|
|||||||
|
|
||||||
bitReversalShuffle2(dataR, dataI)
|
bitReversalShuffle2(dataR, dataI)
|
||||||
|
|
||||||
// Do 4-term DFT.
|
|
||||||
|
|
||||||
// Do 4-term DFT.
|
// Do 4-term DFT.
|
||||||
if (type == TransformType.INVERSE) {
|
if (type == TransformType.INVERSE) {
|
||||||
var i0 = 0
|
var i0 = 0
|
||||||
|
|||||||
@@ -315,12 +315,16 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() {
|
|||||||
|
|
||||||
private val fftLen: Int
|
private val fftLen: Int
|
||||||
private val convFFT: Array<Array<FComplex>>
|
private val convFFT: Array<Array<FComplex>>
|
||||||
|
private val convFFTpartd: Array<Array<Array<FComplex>>> // index: Channel, partition, frequencies
|
||||||
private val inbuf: Array<FloatArray>
|
private val inbuf: Array<FloatArray>
|
||||||
|
|
||||||
private val BLOCKSIZE = BUFFER_SIZE / 4
|
private val BLOCKSIZE = BUFFER_SIZE / 4
|
||||||
|
|
||||||
var processingSpeed = 1f; private set
|
var processingSpeed = 1f; private set
|
||||||
|
|
||||||
|
private val partSizes: IntArray
|
||||||
|
private val partOffsets: IntArray
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (!ir.exists()) {
|
if (!ir.exists()) {
|
||||||
throw IllegalArgumentException("Impulse Response file '${ir.path}' does not exist.")
|
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}")
|
// 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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user