mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 03:24:06 +09:00
fix: fade state may get inconsistent on rapid ui open-close; correct logscale impl
This commit is contained in:
@@ -11,9 +11,7 @@ import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RAT
|
|||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF
|
||||||
import net.torvald.terrarum.modulebasegame.MusicContainer
|
import net.torvald.terrarum.modulebasegame.MusicContainer
|
||||||
import net.torvald.terrarum.tryDispose
|
import net.torvald.terrarum.tryDispose
|
||||||
import kotlin.math.log
|
import kotlin.math.*
|
||||||
import kotlin.math.log10
|
|
||||||
import kotlin.math.pow
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any audio reference fed into this manager will get lost; you must manually store and dispose of them on your own.
|
* Any audio reference fed into this manager will get lost; you must manually store and dispose of them on your own.
|
||||||
@@ -79,6 +77,8 @@ object AudioMixer: Disposable {
|
|||||||
private var lpLength = 0.4
|
private var lpLength = 0.4
|
||||||
private var lpOutFired = false
|
private var lpOutFired = false
|
||||||
private var lpInFired = false
|
private var lpInFired = false
|
||||||
|
private var lpStart = SAMPLING_RATED / 2.0
|
||||||
|
private var lpTarget = SAMPLING_RATED / 2.0
|
||||||
|
|
||||||
// TODO make sidechaining work
|
// TODO make sidechaining work
|
||||||
// TODO master volume controls the master track
|
// TODO master volume controls the master track
|
||||||
@@ -122,28 +122,30 @@ object AudioMixer: Disposable {
|
|||||||
|
|
||||||
if (lpOutFired) {
|
if (lpOutFired) {
|
||||||
lpAkku += delta
|
lpAkku += delta
|
||||||
val x = lpAkku / lpLength
|
// https://www.desmos.com/calculator/dmhve2awxm
|
||||||
val q = 400.0
|
val t = (lpAkku / lpLength).coerceIn(0.0, 1.0)
|
||||||
val step = (q.pow(x) - 1) / (q - 1) // https://www.desmos.com/calculator/sttaq2qhzm
|
val b = ln(lpStart / lpTarget) / -1.0
|
||||||
val cutoff = FastMath.interpolateLinear(step, SAMPLING_RATED / 100.0, SAMPLING_RATED)
|
val a = lpStart
|
||||||
|
val cutoff = a * exp(b * t)
|
||||||
faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(cutoff) }
|
faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(cutoff) }
|
||||||
|
|
||||||
|
|
||||||
if (lpAkku >= lpLength) {
|
if (lpAkku >= lpLength) {
|
||||||
lpOutFired = false
|
lpOutFired = false
|
||||||
faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(SAMPLING_RATEF) }
|
faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(lpTarget) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lpInFired) {
|
else if (lpInFired) {
|
||||||
lpAkku += delta
|
lpAkku += delta
|
||||||
val x = lpAkku / lpLength
|
// https://www.desmos.com/calculator/dmhve2awxm
|
||||||
val q = 400.0
|
val t = (lpAkku / lpLength).coerceIn(0.0, 1.0)
|
||||||
val step = log((q-1) * x + 1.0, q) // https://www.desmos.com/calculator/sttaq2qhzm
|
val b = ln(lpStart / lpTarget) / -1.0
|
||||||
val cutoff = FastMath.interpolateLinear(step, SAMPLING_RATED, SAMPLING_RATED / 100.0)
|
val a = lpStart
|
||||||
|
val cutoff = a * exp(b * t)
|
||||||
faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(cutoff) }
|
faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(cutoff) }
|
||||||
|
|
||||||
if (lpAkku >= lpLength) {
|
if (lpAkku >= lpLength) {
|
||||||
faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(SAMPLING_RATEF / 100.0) }
|
faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(lpTarget) }
|
||||||
lpInFired = false
|
lpInFired = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,6 +196,8 @@ object AudioMixer: Disposable {
|
|||||||
lpLength = length.coerceAtLeast(1.0/1024.0)
|
lpLength = length.coerceAtLeast(1.0/1024.0)
|
||||||
lpAkku = 0.0
|
lpAkku = 0.0
|
||||||
lpOutFired = true
|
lpOutFired = true
|
||||||
|
lpStart = (musicTrack.filters[0] as Lowpass).cutoff
|
||||||
|
lpTarget = SAMPLING_RATED / 2.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +206,8 @@ object AudioMixer: Disposable {
|
|||||||
lpLength = length.coerceAtLeast(1.0/1024.0)
|
lpLength = length.coerceAtLeast(1.0/1024.0)
|
||||||
lpAkku = 0.0
|
lpAkku = 0.0
|
||||||
lpInFired = true
|
lpInFired = true
|
||||||
|
lpStart = (musicTrack.filters[0] as Lowpass).cutoff
|
||||||
|
lpTarget = SAMPLING_RATED / 100.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
override fun show() {
|
override fun show() {
|
||||||
Gdx.input.inputProcessor = BuildingMakerController(this)
|
Gdx.input.inputProcessor = BuildingMakerController(this)
|
||||||
(AudioMixer.musicTrack.filters[0] as Lowpass).setCutoff(TerrarumAudioMixerTrack.SAMPLING_RATEF)
|
(AudioMixer.musicTrack.filters[0] as Lowpass).setCutoff(TerrarumAudioMixerTrack.SAMPLING_RATEF / 2)
|
||||||
super.show()
|
super.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
IngameRenderer.setRenderedWorld(world)
|
IngameRenderer.setRenderedWorld(world)
|
||||||
blockMarkingActor.isVisible = true
|
blockMarkingActor.isVisible = true
|
||||||
|
|
||||||
AudioMixer.faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(SAMPLING_RATEF) }
|
AudioMixer.faderTrack.forEach { (it.filters[0] as Lowpass).setCutoff(SAMPLING_RATEF / 2) }
|
||||||
|
|
||||||
|
|
||||||
super.show() // this function sets gameInitialised = true
|
super.show() // this function sets gameInitialised = true
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
UILoadGovernor.reset()
|
UILoadGovernor.reset()
|
||||||
|
|
||||||
|
|
||||||
(AudioMixer.musicTrack.filters[0] as Lowpass).setCutoff(TerrarumAudioMixerTrack.SAMPLING_RATEF)
|
(AudioMixer.musicTrack.filters[0] as Lowpass).setCutoff(TerrarumAudioMixerTrack.SAMPLING_RATEF / 2)
|
||||||
|
|
||||||
|
|
||||||
loadThingsWhileIntroIsVisible()
|
loadThingsWhileIntroIsVisible()
|
||||||
|
|||||||
@@ -365,8 +365,8 @@ class UIInventoryFull(
|
|||||||
INGAME.pause()
|
INGAME.pause()
|
||||||
INGAME.setTooltipMessage(null)
|
INGAME.setTooltipMessage(null)
|
||||||
|
|
||||||
AudioMixer.requestLowpassIn(0.4)
|
AudioMixer.requestLowpassIn(0.3)
|
||||||
AudioMixer.requestFadeOut(0.4, 0.5)
|
AudioMixer.requestFadeOut(0.3, 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doClosing(delta: Float) {
|
override fun doClosing(delta: Float) {
|
||||||
@@ -375,8 +375,8 @@ class UIInventoryFull(
|
|||||||
INGAME.resume()
|
INGAME.resume()
|
||||||
INGAME.setTooltipMessage(null)
|
INGAME.setTooltipMessage(null)
|
||||||
|
|
||||||
AudioMixer.requestLowpassOut(0.4)
|
AudioMixer.requestLowpassOut(0.3)
|
||||||
AudioMixer.requestFadeIn(0.4, 1.0)
|
AudioMixer.requestFadeIn(0.3, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun endOpening(delta: Float) {
|
override fun endOpening(delta: Float) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
|||||||
import net.torvald.terrarum.audio.*
|
import net.torvald.terrarum.audio.*
|
||||||
import net.torvald.terrarum.audio.MixerTrackProcessor.Companion.BACK_BUF_COUNT
|
import net.torvald.terrarum.audio.MixerTrackProcessor.Companion.BACK_BUF_COUNT
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.BUFFER_SIZE
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.BUFFER_SIZE
|
||||||
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED
|
||||||
import net.torvald.terrarum.controller.TerrarumController
|
import net.torvald.terrarum.controller.TerrarumController
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
@@ -27,9 +28,7 @@ import net.torvald.terrarum.weather.WeatherStateBox
|
|||||||
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
import net.torvald.terrarum.worlddrawer.LightmapRenderer
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.*
|
||||||
import kotlin.math.max
|
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-03-14.
|
* Created by minjaesong on 2016-03-14.
|
||||||
@@ -499,6 +498,16 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
private fun drawFilterParam(batch: SpriteBatch, x: Int, y: Int, filter: TerrarumAudioFilter, track: TerrarumAudioMixerTrack) {
|
private fun drawFilterParam(batch: SpriteBatch, x: Int, y: Int, filter: TerrarumAudioFilter, track: TerrarumAudioMixerTrack) {
|
||||||
when (filter) {
|
when (filter) {
|
||||||
is Lowpass -> {
|
is Lowpass -> {
|
||||||
|
// https://www.desmos.com/calculator/dmhve2awxm
|
||||||
|
val f = filter.cutoff
|
||||||
|
val b = ln(24 / 24000.0) / -1.0
|
||||||
|
val a = 24.0
|
||||||
|
val perc = (ln(f / a) / b).toFloat()
|
||||||
|
batch.color = COL_METER_GRAD2
|
||||||
|
Toolkit.fillArea(batch, x.toFloat(), y.toFloat(), stripW * perc, 14f)
|
||||||
|
batch.color = COL_METER_GRAD
|
||||||
|
Toolkit.fillArea(batch, x.toFloat(), y+14f, stripW * perc, 2f)
|
||||||
|
|
||||||
batch.color = FILTER_NAME_ACTIVE
|
batch.color = FILTER_NAME_ACTIVE
|
||||||
App.fontSmallNumbers.draw(batch, "F:${filter.cutoff.toInt()}", x+3f, y+1f)
|
App.fontSmallNumbers.draw(batch, "F:${filter.cutoff.toInt()}", x+3f, y+1f)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ abstract class UICanvas(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val OPENCLOSE_GENERIC = 0.0666f
|
const val OPENCLOSE_GENERIC = 0.1f
|
||||||
|
|
||||||
fun doOpeningFade(ui: UICanvas, openCloseTime: Second) {
|
fun doOpeningFade(ui: UICanvas, openCloseTime: Second) {
|
||||||
ui.handler.opacity = max(0f, ui.handler.openCloseCounter - 0.02f) / openCloseTime // fade start 1/50 sec late, it's intended
|
ui.handler.opacity = max(0f, ui.handler.openCloseCounter - 0.02f) / openCloseTime // fade start 1/50 sec late, it's intended
|
||||||
|
|||||||
Reference in New Issue
Block a user