diff --git a/src/net/torvald/terrarum/audio/FFT.kt b/src/net/torvald/terrarum/audio/FFT.kt index 6ced155c3..0524d4496 100644 --- a/src/net/torvald/terrarum/audio/FFT.kt +++ b/src/net/torvald/terrarum/audio/FFT.kt @@ -146,6 +146,11 @@ object FFT: Disposable { ffts[signal0.size]!!.complexForward(signal0.reim) } + fun fftInto(signal0: ComplexArray, out: ComplexArray) { + System.arraycopy(signal0.reim, 0, out.reim, 0, signal0.reim.size) + ffts[signal0.size]!!.complexForward(out.reim) + } + // org.apache.commons.math3.transform.FastFouriesTransformer.java:404 fun ifftAndGetReal(signal0: ComplexArray): FloatArray { // val re = FloatArray(signal0.size) { signal0.reim[it * 2] } diff --git a/src/net/torvald/terrarum/audio/dsp/Convolv.kt b/src/net/torvald/terrarum/audio/dsp/Convolv.kt index a85618561..7bd38a843 100644 --- a/src/net/torvald/terrarum/audio/dsp/Convolv.kt +++ b/src/net/torvald/terrarum/audio/dsp/Convolv.kt @@ -11,9 +11,7 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() { val fftLen: Int private val convFFT: Array - private val convFFTpartd: Array> // index: Channel, partition, frequencies - private val inputPartd: Array> // index: Channel, partition, frequencies - private val inbuf: Array + private val inbuf: Array private val BLOCKSIZE = TerrarumAudioMixerTrack.BUFFER_SIZE / 4 @@ -33,7 +31,7 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() { println("IR '${ir.path}' Sample Count = $sampleCount; FFT Length = $fftLen") val conv = Array(2) { FloatArray(fftLen) } - inbuf = Array(2) { FloatArray(fftLen) } + inbuf = Array(2) { ComplexArray(FloatArray(fftLen * 2)) } ir.inputStream().let { for (i in 0 until sampleCount) { @@ -70,42 +68,6 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() { } partSizes = master0.toIntArray() partOffsets = master0.toIntArray().also { it[0] = 0 } - - - convFFTpartd = Array(2) { - Array(partSizes.size) { - ComplexArray(FloatArray(2*partSizes[it])) - } - } - inputPartd = Array(2) { - Array(partSizes.size) { - FloatArray(partSizes[it]) - } - } - fillUnevenly(convFFT[0], convFFTpartd[0]) - fillUnevenly(convFFT[1], convFFTpartd[1]) - } - - private fun fillUnevenly(source: ComplexArray, dest: Array) { - for (i in partSizes.indices) { - val len = 2*partSizes[i] - val offset = 2*partOffsets[i] - System.arraycopy(source.reim, offset, dest[i].reim, 0, len) - } - } - private fun fillUnevenly(source: FloatArray, dest: Array) { - for (i in partSizes.indices) { - val len = partSizes[i] - val offset = partOffsets[i] - System.arraycopy(source, offset, dest[i], 0, len) - } - } - private fun concatParts(source: List, dest: ComplexArray) { - for (i in partSizes.indices) { - val len = 2*partSizes[i] - val offset = 2*partOffsets[i] - System.arraycopy(source[i].reim, 0, dest.reim, offset, len) - } } private val realtime = (BLOCKSIZE / TerrarumAudioMixerTrack.SAMPLING_RATEF * 1000000000L) @@ -122,14 +84,9 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() { for (ch in outbuf.indices) { - push(inbuf[ch].applyGain(gain), this.inbuf[ch]) + push(gain, inbuf[ch], this.inbuf[ch]) - for (i in 0 until fftLen) { - fftIn.reim[i * 2] = this.inbuf[ch][i] - fftIn.reim[i * 2 + 1] = 0f - } - - FFT.fft(fftIn) + FFT.fftInto(this.inbuf[ch], fftIn) fftIn.mult(convFFT[ch], fftMult) FFT.ifftAndGetReal(fftMult, fftOut) System.arraycopy(fftOut, fftLen - BLOCKSIZE, outbuf[ch], 0, BLOCKSIZE) @@ -141,4 +98,14 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() { processingSpeed = realtime / ptime } + + fun push(gain: Float, samples: FloatArray, buf: ComplexArray) { + System.arraycopy(buf.reim, samples.size * 2, buf.reim, 0, buf.reim.size - samples.size * 2) + val baseI = buf.reim.size - samples.size * 2 + samples.forEachIndexed { index, fl -> + buf.reim[baseI + index * 2 + 0] = fl * gain + buf.reim[baseI + index * 2 + 1] = 0f + } + } + } \ No newline at end of file