diff --git a/src/net/torvald/terrarum/audio/AudioMixer.kt b/src/net/torvald/terrarum/audio/AudioMixer.kt index 1f38c3dd7..8a60fbd81 100644 --- a/src/net/torvald/terrarum/audio/AudioMixer.kt +++ b/src/net/torvald/terrarum/audio/AudioMixer.kt @@ -198,13 +198,15 @@ object AudioMixer: Disposable { masterTrack.filters[0] = SoftClp masterTrack.filters[1] = Buffer - masterTrack.filters[2] = Spectro() - masterTrack.filters[3] = Vecto(2f) + masterTrack.filters[2] = Vecto(1.4142f) + masterTrack.filters[3] = Spectro() musicTrack.filters[1] = Vecto() musicTrack.filters[2] = Spectro() ambientTrack.filters[1] = Vecto() ambientTrack.filters[2] = Spectro() + sfxSumBus.filters[1] = Vecto(0.7071f) + sfxSumBus.filters[2] = Spectro() listOf(sumBus, convolveBusOpen, convolveBusCave).forEach { it.addSidechainInput(musicTrack, 1.0) diff --git a/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt b/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt index 32c5d3fc2..3ccfd5571 100644 --- a/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt +++ b/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt @@ -67,6 +67,7 @@ class TerrarumAudioMixerTrack( var playStartedTime = 0L; private set inline fun getFilter() = filters.filterIsInstance().first()!! + inline fun getFilterOrNull() = filters.filterIsInstance().firstOrNull() internal val sidechainInputs = ArrayList>() internal fun getSidechains(): List = sidechainInputs.map { it.first } diff --git a/src/net/torvald/terrarum/audio/dsp/SoftClp.kt b/src/net/torvald/terrarum/audio/dsp/SoftClp.kt index 4ba8478ed..d17d3ac87 100644 --- a/src/net/torvald/terrarum/audio/dsp/SoftClp.kt +++ b/src/net/torvald/terrarum/audio/dsp/SoftClp.kt @@ -2,6 +2,8 @@ package net.torvald.terrarum.audio.dsp import com.badlogic.gdx.graphics.g2d.SpriteBatch import kotlin.math.absoluteValue +import kotlin.math.pow +import kotlin.math.sqrt import kotlin.math.tanh object SoftClp : TerrarumAudioFilter() { @@ -15,8 +17,8 @@ object SoftClp : TerrarumAudioFilter() { val out = outbuf[ch] for (i in inn.indices) { - val u = inn[i] * 0.95f - val v = tanh(u) + val u = inn[i] + val v = clipfun0(u / 2.0).toFloat() * 2f val diff = (v.absoluteValue / u.absoluteValue) out[i] = v @@ -27,6 +29,28 @@ object SoftClp : TerrarumAudioFilter() { } } + /** + * https://www.desmos.com/calculator/syqd1byzzl + * @param x0 -0.5..0.5 ish + * @return -0.5..0.5 + */ + private fun clipfun0(x0: Double): Double { + val p = 0.44444 // knee of around -6.02dB + val p1 = sqrt(1.0 - 2.0 * p) + + val x = x0 * (1.0 + p1) / 2.0 + + val t = 0.5 * p1 + val y0 = if (x < -t) + (1.0 / p) * (x + 0.5).pow(2) - 0.5 + else if (x > t) + -(1.0 / p) * (x - 0.5).pow(2) + 0.5 + else + x * 2.0 / (1.0 + p1) + + return y0 + } + override fun drawDebugView(batch: SpriteBatch, x: Int, y: Int) { } diff --git a/src/net/torvald/terrarum/audio/dsp/Spectro.kt b/src/net/torvald/terrarum/audio/dsp/Spectro.kt index 45bf54ddf..caf10c9b5 100644 --- a/src/net/torvald/terrarum/audio/dsp/Spectro.kt +++ b/src/net/torvald/terrarum/audio/dsp/Spectro.kt @@ -133,7 +133,7 @@ class Vecto(val gain: Float = 1f) : TerrarumAudioFilter() { private val halfStripW = STRIP_W / 2 - private val scopePlotCol = Color(0x61b3df_33) + private val scopePlotCol = Color(0xdf6fa0_33.toInt()) override fun drawDebugView(batch: SpriteBatch, x: Int, y: Int) { // vectorscope diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index 4d14191e7..8d4f9d2c2 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -537,6 +537,9 @@ class BasicDebugInfoWindow : UICanvas() { Toolkit.fillArea(batch, x, y, STRIP_W, stripFilterHeight * numberOfFilters) var filterBankYcursor = 0 + var filterBankYforVecto = 0 + + // draw filter banks. The filter view for Vecto will be drawn separately track.filters.forEachIndexed { i, filter -> if (filter !is NullFilter) { // draw filter title back batch.color = COL_FILTER_TITLE_SHADE @@ -547,7 +550,10 @@ class BasicDebugInfoWindow : UICanvas() { batch.color = if (filter.bypass) FILTER_BYPASSED else FILTER_NAME_ACTIVE App.fontSmallNumbers.draw(batch, filter.javaClass.simpleName, x + 3f, y + filterBankYcursor + 1f) - drawFilterParam(batch, x, y + filterBankYcursor + stripFilterHeight, filter, track) + if (filter !is Vecto) + drawFilterParam(batch, x, y + filterBankYcursor + stripFilterHeight, filter, track) + else + filterBankYforVecto = filterBankYcursor filterBankYcursor += stripFilterHeight + filter.debugViewHeight } } @@ -716,6 +722,11 @@ class BasicDebugInfoWindow : UICanvas() { Toolkit.fillArea(batch, x + 19 + channel*7, faderY + 16, 6, 2) } } + + // draw a view for Vecto + track.getFilterOrNull()?.let { + drawFilterParam(batch, x, y + filterBankYforVecto + stripFilterHeight, it, track) + } }