mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
further convolving optimisaions
This commit is contained in:
@@ -49,6 +49,20 @@ private val IM1 = 0
|
||||
*/
|
||||
object FFT: Disposable {
|
||||
|
||||
private val ffts = hashMapOf(
|
||||
128 to FloatFFT_1D(128),
|
||||
256 to FloatFFT_1D(256),
|
||||
512 to FloatFFT_1D(512),
|
||||
1024 to FloatFFT_1D(1024),
|
||||
2048 to FloatFFT_1D(2048),
|
||||
4096 to FloatFFT_1D(4096),
|
||||
8192 to FloatFFT_1D(8192),
|
||||
16384 to FloatFFT_1D(16384),
|
||||
32768 to FloatFFT_1D(32768),
|
||||
65536 to FloatFFT_1D(65536),
|
||||
)
|
||||
|
||||
|
||||
init {
|
||||
// Loader.load(org.bytedeco.fftw.global.fftw3::class.java)
|
||||
|
||||
@@ -102,8 +116,7 @@ object FFT: Disposable {
|
||||
|
||||
// USING JTRANSFORMS //
|
||||
val signal = FloatArray(signal0.size * 2) { if (it % 2 == 0) signal0[it / 2] else 0f }
|
||||
val fft = FloatFFT_1D(signal0.size.toLong())
|
||||
fft.complexForward(signal)
|
||||
ffts[signal0.size]!!.complexForward(signal)
|
||||
return ComplexArray(signal)
|
||||
}
|
||||
|
||||
@@ -137,12 +150,17 @@ object FFT: Disposable {
|
||||
|
||||
|
||||
// USING JTRANSFORMS //
|
||||
val signal = signal0.reim
|
||||
val fft = FloatFFT_1D(signal0.size.toLong())
|
||||
fft.complexInverse(signal, true)
|
||||
ffts[signal0.size]!!.complexInverse(signal0.reim, true)
|
||||
return signal0.getReal()
|
||||
}
|
||||
|
||||
fun ifftAndGetReal(signal0: ComplexArray, output: FloatArray) {
|
||||
ffts[signal0.size]!!.complexInverse(signal0.reim, true)
|
||||
for (i in 0 until signal0.size) {
|
||||
output[i] = signal0.reim[i * 2]
|
||||
}
|
||||
}
|
||||
|
||||
// org.apache.commons.math3.transform.FastFouriesTransformer.java:214
|
||||
/**
|
||||
* Computes the standard transform of the specified complex data. The
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.audio.dsp
|
||||
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.App.measureDebugTime
|
||||
import net.torvald.terrarum.App.setDebugTime
|
||||
import net.torvald.terrarum.audio.*
|
||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.BUFFER_SIZE
|
||||
import java.io.File
|
||||
@@ -107,47 +108,26 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val targetY = ComplexArray(FloatArray(fftLen * 2))
|
||||
|
||||
private val realtime = (BLOCKSIZE / TerrarumAudioMixerTrack.SAMPLING_RATEF * 1000000000L)
|
||||
/**
|
||||
* https://thewolfsound.com/fast-convolution-fft-based-overlap-add-overlap-save-partitioned/
|
||||
*/
|
||||
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
||||
// println("Convolv thru")
|
||||
|
||||
val t1 = System.nanoTime()
|
||||
|
||||
|
||||
for (ch in outbuf.indices) {
|
||||
push(inbuf[ch].applyGain(gain), this.inbuf[ch])
|
||||
lateinit var u: FloatArray
|
||||
|
||||
|
||||
measureDebugTime("audio.convolve") {
|
||||
val inputFFT = FFT.fft(this.inbuf[ch])
|
||||
val Y = inputFFT * convFFT[ch]
|
||||
val y = FFT.ifftAndGetReal(Y)
|
||||
u = y.takeLast(BLOCKSIZE).toFloatArray()
|
||||
}
|
||||
|
||||
|
||||
// doesn't work AND slightly slower than the lines above
|
||||
/*measureDebugTime("audio.convolve") {
|
||||
// orthodox uneven-partitioning
|
||||
fillUnevenly(this.inbuf[ch], inputPartd[ch])
|
||||
val partY = inputPartd[ch].mapIndexed { i, inputSamples ->
|
||||
FFT.fft(inputSamples) * convFFTpartd[ch][i]
|
||||
}
|
||||
concatParts(partY, targetY)
|
||||
val y = FFT.ifftAndGetReal(targetY)
|
||||
u = y.takeLast(BLOCKSIZE).toFloatArray()
|
||||
}*/
|
||||
|
||||
|
||||
System.arraycopy(u, 0, outbuf[ch], 0, BLOCKSIZE)
|
||||
val inputFFT = FFT.fft(this.inbuf[ch])
|
||||
val Y = inputFFT * convFFT[ch]
|
||||
val y = FFT.ifftAndGetReal(Y)
|
||||
System.arraycopy(y, fftLen - BLOCKSIZE, outbuf[ch], 0, BLOCKSIZE)
|
||||
}
|
||||
val t2 = System.nanoTime()
|
||||
val ptime = (t2 - t1).toFloat()
|
||||
val realtime = BLOCKSIZE / TerrarumAudioMixerTrack.SAMPLING_RATEF * 1000000000L
|
||||
|
||||
|
||||
val ptime = System.nanoTime() - t1
|
||||
setDebugTime("audio.convolve", ptime)
|
||||
processingSpeed = realtime / ptime
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user