From 402b0a8414183f666622a7cb5498465354601dee Mon Sep 17 00:00:00 2001 From: minjaesong Date: Thu, 23 Nov 2023 23:34:05 +0900 Subject: [PATCH] cheap reverb filter --- src/net/torvald/terrarum/audio/AudioMixer.kt | 3 +- .../terrarum/audio/TerrarumAudioFilter.kt | 55 ++++++++++++++++--- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/net/torvald/terrarum/audio/AudioMixer.kt b/src/net/torvald/terrarum/audio/AudioMixer.kt index 0d929b670..eb2756682 100644 --- a/src/net/torvald/terrarum/audio/AudioMixer.kt +++ b/src/net/torvald/terrarum/audio/AudioMixer.kt @@ -102,6 +102,7 @@ object AudioMixer: Disposable { init { // musicTrack.filters[0] = BinoPan((Math.random() * 2.0 - 1.0).toFloat()) +// musicTrack.filters[1] = Reverb(25f, 1f, 1000f) masterTrack.filters[0] = SoftClp masterTrack.filters[1] = Buffer @@ -110,7 +111,7 @@ object AudioMixer: Disposable { fadeBus.addSidechainInput(musicTrack, 1.0) fadeBus.addSidechainInput(ambientTrack, 1.0) fadeBus.addSidechainInput(sfxMixTrack, 1.0) - fadeBus.filters[0] = Lowpass(SAMPLING_RATE / 2f, SAMPLING_RATE) + fadeBus.filters[0] = Lowpass(SAMPLING_RATE / 2f) masterTrack.addSidechainInput(fadeBus, 1.0) masterTrack.addSidechainInput(guiTrack, 1.0) diff --git a/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt b/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt index d474aca7b..90acbd1dc 100644 --- a/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt +++ b/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt @@ -42,7 +42,7 @@ object SoftClp : TerrarumAudioFilter() { val out = outbuf1[ch] for (i in inn.indices) { - val u = inn[i] + val u = inn[i] * 0.95f val v = tanh(u) val diff = (v.absoluteValue / u.absoluteValue) out[i] = v @@ -90,7 +90,7 @@ class Scope : TerrarumAudioFilter() { } -class Lowpass(cutoff0: Float, val rate: Int): TerrarumAudioFilter() { +class Lowpass(cutoff0: Float): TerrarumAudioFilter() { var cutoff = cutoff0.toDouble(); private set private var alpha: Float = 0f @@ -100,9 +100,8 @@ class Lowpass(cutoff0: Float, val rate: Int): TerrarumAudioFilter() { } fun setCutoff(cutoff: Float) { -// println("LP Cutoff: $cutoff") val RC: Float = 1f / (cutoff * FastMath.TWO_PI) - val dt: Float = 1f / rate + val dt: Float = 1f / SAMPLING_RATEF alpha = dt / (RC + dt) this.cutoff = cutoff.toDouble() } @@ -110,7 +109,7 @@ class Lowpass(cutoff0: Float, val rate: Int): TerrarumAudioFilter() { fun setCutoff(cutoff: Double) { // println("LP Cutoff: $cutoff") val RC: Double = 1.0 / (cutoff * Math.PI * 2.0) - val dt: Double = 1.0 / rate + val dt: Double = 1.0 / SAMPLING_RATEF alpha = (dt / (RC + dt)).toFloat() this.cutoff = cutoff } @@ -131,7 +130,7 @@ class Lowpass(cutoff0: Float, val rate: Int): TerrarumAudioFilter() { } -class Highpass(cutoff0: Float, val rate: Int): TerrarumAudioFilter() { +class Highpass(cutoff0: Float): TerrarumAudioFilter() { var cutoff = cutoff0.toDouble(); private set private var alpha: Float = 0f @@ -143,7 +142,7 @@ class Highpass(cutoff0: Float, val rate: Int): TerrarumAudioFilter() { fun setCutoff(cutoff: Float) { // println("LP Cutoff: $cutoff") val RC: Float = 1f / (cutoff * FastMath.TWO_PI) - val dt: Float = 1f / rate + val dt: Float = 1f / SAMPLING_RATEF alpha = dt / (RC + dt) this.cutoff = cutoff.toDouble() } @@ -151,7 +150,7 @@ class Highpass(cutoff0: Float, val rate: Int): TerrarumAudioFilter() { fun setCutoff(cutoff: Double) { // println("LP Cutoff: $cutoff") val RC: Double = 1.0 / (cutoff * Math.PI * 2.0) - val dt: Double = 1.0 / rate + val dt: Double = 1.0 / SAMPLING_RATEF alpha = (RC / (RC + dt)).toFloat() this.cutoff = cutoff } @@ -248,4 +247,42 @@ class Bitcrush(var steps: Int, var inputGain: Float = 1f): TerrarumAudioFilter() } } } -} \ No newline at end of file +} + +class Reverb(val delayMS: Float, var decay: Float, var lowpass: Float): TerrarumAudioFilter() { + + private var delay = (SAMPLING_RATEF * delayMS / 1000f).roundToInt() + + private val buf = Array(2) { FloatArray(delay) } + + private fun unshift(sample: Float, buf: FloatArray) { + for (i in delay - 1 downTo 1) { + buf[i] = buf[i - 1] + } + buf[0] = sample + } + + override fun thru(inbuf0: List, inbuf1: List, outbuf0: List, outbuf1: List) { + val RC: Float = 1f / (lowpass * FastMath.TWO_PI) + val dt: Float = 1f / SAMPLING_RATEF + val alpha = dt / (RC + dt) + + for (ch in 0 until outbuf1.size) { + for (i in 0 until BUFFER_SIZE / 4) { + val in1 = inbuf1[ch][i] + + val in2 = buf[ch][delay - 2] + val in3 = buf[ch][delay - 1] + + val dek1 = 1f / (1f + decay) + val dek2 = decay / (1f + decay) + + val out = in1 * dek1 + (in2 + alpha * (in3 - in2)) * dek2 + + unshift(out, buf[ch]) + + outbuf1[ch][i] = out + } + } + } +}