From 755ced9ea442646f8b1652d6f84f01ff7a6743c4 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Tue, 16 Jan 2024 02:50:47 +0900 Subject: [PATCH] sound engine is no longer a singleton --- .../terrarum/musicplayer/gui/MusicPlayer.kt | 36 +++++----- src/net/torvald/terrarum/App.java | 21 +++++- .../torvald/terrarum/AudioManagerRunnable.kt | 4 +- src/net/torvald/terrarum/Terrarum.kt | 2 +- src/net/torvald/terrarum/audio/AudioMixer.kt | 71 +++++++++++++------ .../torvald/terrarum/audio/AudioProcessBuf.kt | 27 +++---- .../terrarum/audio/MixerTrackProcessor.kt | 35 ++++++--- .../terrarum/audio/TerrarumAudioMixerTrack.kt | 19 +++-- src/net/torvald/terrarum/audio/dsp/BinoPan.kt | 18 +++-- .../torvald/terrarum/audio/dsp/Bitcrush.kt | 6 +- src/net/torvald/terrarum/audio/dsp/Buffer.kt | 6 +- src/net/torvald/terrarum/audio/dsp/Convolv.kt | 21 +++--- src/net/torvald/terrarum/audio/dsp/Gain.kt | 7 +- .../torvald/terrarum/audio/dsp/Highpass.kt | 4 ++ src/net/torvald/terrarum/audio/dsp/Lowpass.kt | 5 ++ .../torvald/terrarum/audio/dsp/NullFilter.kt | 3 + src/net/torvald/terrarum/audio/dsp/Reverb.kt | 7 +- src/net/torvald/terrarum/audio/dsp/SoftClp.kt | 3 + src/net/torvald/terrarum/audio/dsp/Spectro.kt | 28 +++++--- .../terrarum/audio/dsp/TerrarumAudioFilter.kt | 1 + src/net/torvald/terrarum/audio/dsp/XYtoMS.kt | 12 +++- src/net/torvald/terrarum/gameactors/Actor.kt | 10 +-- .../terrarum/modulebasegame/BuildingMaker.kt | 5 +- .../terrarum/modulebasegame/TerrarumIngame.kt | 14 ++-- .../modulebasegame/TerrarumMusicGovernor.kt | 15 ++-- .../terrarum/modulebasegame/TitleScreen.kt | 5 +- .../gameactors/FixtureJukebox.kt | 5 +- .../modulebasegame/ui/UIInventoryFull.kt | 9 ++- .../modulebasegame/ui/UISoundControlPanel.kt | 19 +++-- .../terrarum/ui/BasicDebugInfoWindow.kt | 16 ++--- 30 files changed, 275 insertions(+), 159 deletions(-) diff --git a/MusicPlayer/src/net/torvald/terrarum/musicplayer/gui/MusicPlayer.kt b/MusicPlayer/src/net/torvald/terrarum/musicplayer/gui/MusicPlayer.kt index a5d42f6cb..4f5f097bd 100644 --- a/MusicPlayer/src/net/torvald/terrarum/musicplayer/gui/MusicPlayer.kt +++ b/MusicPlayer/src/net/torvald/terrarum/musicplayer/gui/MusicPlayer.kt @@ -335,7 +335,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { } else { if (!transitionOngoing) - transitionRequest = AudioMixer.musicTrack.isPlaying.toInt() * MODE_MOUSE_UP + transitionRequest = App.audioMixer.musicTrack.isPlaying.toInt() * MODE_MOUSE_UP } } @@ -343,7 +343,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { // prev song if (mode < MODE_SHOW_LIST) { getPrevSongFromPlaylist()?.let { ingame.musicGovernor.unshiftPlaylist(it) } - AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) { + App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) { ingame.musicGovernor.startMusic() // required for "intermittent" mode } } @@ -362,10 +362,10 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { 2 -> { // stop if (mode < MODE_SHOW_LIST) { // disable stop button entirely on MODE_SHOW_LIST - if (AudioMixer.musicTrack.isPlaying) { - val thisMusic = AudioMixer.musicTrack.currentTrack - AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) - AudioMixer.musicTrack.nextTrack = null + if (App.audioMixer.musicTrack.isPlaying) { + val thisMusic = App.audioMixer.musicTrack.currentTrack + App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) + App.audioMixer.musicTrack.nextTrack = null ingame.musicGovernor.stopMusic() thisMusic?.let { ingame.musicGovernor.queueMusicToPlayNext(it) } } @@ -378,7 +378,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { 3 -> { // next // next song if (mode < MODE_SHOW_LIST) { - AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) { + App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) { ingame.musicGovernor.startMusic() // required for "intermittent" mode, does seemingly nothing on "continuous" mode } } @@ -410,7 +410,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { } else { if (!transitionOngoing) - transitionRequest = AudioMixer.musicTrack.isPlaying.toInt() * MODE_MOUSE_UP + transitionRequest = App.audioMixer.musicTrack.isPlaying.toInt() * MODE_MOUSE_UP } } } @@ -421,12 +421,12 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { val list = songsInGovernor if (index < list.size) { // if selected song != currently playing - if (AudioMixer.musicTrack.currentTrack == null || list[index] != AudioMixer.musicTrack.currentTrack) { + if (App.audioMixer.musicTrack.currentTrack == null || list[index] != App.audioMixer.musicTrack.currentTrack) { // rebuild playlist ingame.musicGovernor.queueIndexFromPlaylist(index) // fade out - AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) { + App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) { ingame.musicGovernor.startMusic() // required for "intermittent" mode } } @@ -442,10 +442,10 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { // (navigating into the selected album involves too much complication :p) if (ingame.musicGovernor.playlistSource != albumsList[index].canonicalPath) { // fade out - AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) { + App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) { loadNewAlbum(albumsList[index]) ingame.musicGovernor.startMusic() // required for "intermittent" mode - resetPlaylistScroll(AudioMixer.musicTrack.nextTrack) + resetPlaylistScroll(App.audioMixer.musicTrack.nextTrack) } } } @@ -471,7 +471,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { } private fun resetPlaylistScroll(song: MusicContainer? = null) { - val currentlyPlaying = songsInGovernor.indexOf(song ?: AudioMixer.musicTrack.currentTrack) + val currentlyPlaying = songsInGovernor.indexOf(song ?: App.audioMixer.musicTrack.currentTrack) if (currentlyPlaying >= 0) { playlistScroll = (currentlyPlaying / PLAYLIST_LINES) * PLAYLIST_LINES } @@ -482,7 +482,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { private fun getPrevSongFromPlaylist(): MusicContainer? { val list = songsInGovernor.slice(songsInGovernor.indices) // make copy of the list - val nowPlaying = AudioMixer.musicTrack.currentTrack ?: return null + val nowPlaying = App.audioMixer.musicTrack.currentTrack ?: return null // find current index val currentIndex = list.indexOfFirst { it == nowPlaying } @@ -796,7 +796,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { val pnum = i + playlistScroll val m1 = songsInGovernor.getOrNull(pnum) - val m2 = AudioMixer.musicTrack.currentTrack + val m2 = App.audioMixer.musicTrack.currentTrack val currentlyPlaying = if (m1 == null || m2 == null) false else (m1 == m2) // print number @@ -988,7 +988,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { // stop button else if (i == 2) { // get correct stop/play button - val iconY = if (!AudioMixer.musicTrack.isPlaying) 1 else 0 + val iconY = if (!App.audioMixer.musicTrack.isPlaying) 1 else 0 // fade if avaliable batch.color = Color(1f, 1f, 1f, alphaBase * (1f - buttonFadePerc)) batch.draw(controlButtons.get(i, iconY), btnX, btnY) @@ -1077,7 +1077,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { private val fftBarHeights = FloatArray(5) private fun updateMeter() { - val inbuf = AudioMixer.musicTrack.extortField("processor")!!.extortField>("fout1")!! + val inbuf = App.audioMixer.musicTrack.extortField("processor")!!.extortField>("fout1")!! push(inbuf[0], inBuf[0]) push(inbuf[1], inBuf[1]) for (i in 0 until FFTSIZE) { @@ -1235,7 +1235,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() { private fun loadNewAlbum(albumDir: File) { val albumProp = albumPropCache[albumDir] - AudioMixer.musicTrack.let { track -> + App.audioMixer.musicTrack.let { track -> track.doGaplessPlayback = (albumProp.diskJockeyingMode == "continuous") if (track.doGaplessPlayback) { track.pullNextTrack = { diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index ed1fa83da..887bcd8c2 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -927,7 +927,7 @@ public class App implements ApplicationListener { } if (audioMixerInitialised) { - AudioMixer.INSTANCE.dispose(); + audioMixer.dispose(); } if (currentScreen != null) { @@ -1052,6 +1052,9 @@ public class App implements ApplicationListener { private static Boolean audioMixerInitialised = false; + public static AudioMixer audioMixer; + public static int audioBufferSize; + /** * Init stuffs which needs GL context */ @@ -1203,9 +1206,10 @@ public class App implements ApplicationListener { } - AudioMixer.INSTANCE.getMasterVolume(); + audioBufferSize = getConfigInt("audio_buffer_size"); + audioMixer = new AudioMixer(audioBufferSize); audioMixerInitialised = true; - audioManagerThread = new Thread(new AudioManagerRunnable(), "TerrarumAudioManager"); + audioManagerThread = new Thread(new AudioManagerRunnable(audioMixer), "TerrarumAudioManager"); audioManagerThread.setPriority(MAX_PRIORITY); // higher = more predictable; audio delay is very noticeable so it gets high priority audioManagerThread.start(); @@ -1230,6 +1234,17 @@ public class App implements ApplicationListener { printdbg(this, "PostInit done; took "+tms+" seconds"); } + public static void renewAudioProcessor(int bufferSize) { + audioManagerThread.interrupt(); + audioMixer.dispose(); + + audioBufferSize = bufferSize; + audioMixer = new AudioMixer(audioBufferSize); + audioManagerThread = new Thread(new AudioManagerRunnable(audioMixer), "TerrarumAudioManager"); + audioManagerThread.setPriority(MAX_PRIORITY); // higher = more predictable; audio delay is very noticeable so it gets high priority + audioManagerThread.start(); + } + private void setCameraPosition(float newX, float newY) { camera.position.set((-newX + scr.getWidth() / 2), (-newY + scr.getHeight() / 2), 0f); // deliberate integer division diff --git a/src/net/torvald/terrarum/AudioManagerRunnable.kt b/src/net/torvald/terrarum/AudioManagerRunnable.kt index 9999fae82..029109857 100644 --- a/src/net/torvald/terrarum/AudioManagerRunnable.kt +++ b/src/net/torvald/terrarum/AudioManagerRunnable.kt @@ -5,7 +5,7 @@ import net.torvald.terrarum.audio.AudioMixer /** * Created by minjaesong on 2023-11-08. */ -class AudioManagerRunnable : Runnable { +class AudioManagerRunnable(val audioMixer: AudioMixer) : Runnable { var oldT = System.nanoTime() var dT = 0f @@ -16,7 +16,7 @@ class AudioManagerRunnable : Runnable { val T = System.nanoTime() dT = (T - oldT) / 1000000000f oldT = T; - AudioMixer.update(dT) + audioMixer.update(dT) // println("AudioManagerRunnable dT = ${dT * 1000f} ms") Thread.sleep(1L) } diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 77481998d..7a8cb174c 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -17,6 +17,7 @@ import net.torvald.terrarum.App.* import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED import net.torvald.terrarum.audio.AudioCodex +import net.torvald.terrarum.audio.AudioMixer import net.torvald.terrarum.blockproperties.BlockCodex import net.torvald.terrarum.blockproperties.FluidCodex import net.torvald.terrarum.blockproperties.OreCodex @@ -70,7 +71,6 @@ object Terrarum : Disposable { shapeRender.end() }*/ - var blockCodex = BlockCodex(); internal set /** The actual contents of the ItemCodex is sum of Player's Codex and the World's Codex */ var itemCodex = ItemCodex(); internal set diff --git a/src/net/torvald/terrarum/audio/AudioMixer.kt b/src/net/torvald/terrarum/audio/AudioMixer.kt index 8a60fbd81..f634a10fe 100644 --- a/src/net/torvald/terrarum/audio/AudioMixer.kt +++ b/src/net/torvald/terrarum/audio/AudioMixer.kt @@ -7,20 +7,15 @@ import com.badlogic.gdx.utils.Disposable import com.jme3.math.FastMath import net.torvald.spriteanimation.AssembledSpriteAnimation import net.torvald.terrarum.* -import net.torvald.terrarum.App.THREAD_COUNT -import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED import net.torvald.terrarum.audio.dsp.* import net.torvald.terrarum.concurrent.ThreadExecutor -import net.torvald.terrarum.concurrent.sliceEvenly import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.modulebasegame.BuildingMaker import net.torvald.terrarum.modulebasegame.MusicContainer import java.lang.Thread.MAX_PRIORITY import java.util.* -import java.util.concurrent.Callable -import java.util.concurrent.atomic.AtomicReference import kotlin.math.* /** @@ -28,13 +23,16 @@ import kotlin.math.* * * Created by minjaesong on 2023-11-07. */ -object AudioMixer: Disposable { - var SPEED_OF_SOUND = 340f +class AudioMixer(val bufferSize: Int): Disposable { - const val SPEED_OF_SOUND_AIR = 340f - const val SPEED_OF_SOUND_WATER = 1480f + companion object { + const val SPEED_OF_SOUND_AIR = 340f + const val SPEED_OF_SOUND_WATER = 1480f + const val SPEED_OF_SOUND = 340f + + const val DEFAULT_FADEOUT_LEN = 1.8 + } - const val DEFAULT_FADEOUT_LEN = 1.8 val masterVolume: Double get() = App.getConfigDouble("mastervolume") @@ -99,7 +97,7 @@ object AudioMixer: Disposable { val fadeBus: TerrarumAudioMixerTrack get() = tracks[7] - var processing = true + var processing = false var actorNowPlaying = Terrarum.ingame?.actorNowPlaying; private set @@ -128,8 +126,7 @@ object AudioMixer: Disposable { return (headSize0 ?: 0f).times(scale).coerceAtLeast(BinoPan.EARDIST_DEFAULT) } - private val processingExecutor = ThreadExecutor() - val processingThread = Thread { + fun createProcessingThread(): Thread = Thread { // serial precessing while (processing) { actorNowPlaying = Terrarum.ingame?.actorNowPlaying @@ -184,8 +181,13 @@ object AudioMixer: Disposable { masterTrack.adev!!.writeSamples(masterTrack.pcmQueue.removeFirst()) // it blocks until the queue is consumed } }*/ + }.also { + it.priority = MAX_PRIORITY // higher = more predictable; audio delay is very noticeable so it gets high priority } + private val processingExecutor = ThreadExecutor() + lateinit var processingThread: Thread + // val parallelProcessingSchedule: Array> @@ -246,8 +248,8 @@ object AudioMixer: Disposable { arrayOf(fadeBus) + arrayOf(masterTrack)*/ - - processingThread.priority = MAX_PRIORITY // higher = more predictable; audio delay is very noticeable so it gets high priority + processingThread = createProcessingThread() + processing = true processingThread.start() // feedingThread.priority = MAX_PRIORITY // feedingThread.start() @@ -306,7 +308,7 @@ object AudioMixer: Disposable { if (Gdx.input.isKeyPressed(Input.Keys.NUM_3)) testAudioMixRatio = 1.0 if (!muteLatched && Gdx.input.isKeyPressed(Input.Keys.NUM_4)) { - AudioMixer.sumBus.volume = 1.0 - AudioMixer.sumBus.volume + sumBus.volume = 1.0 - sumBus.volume muteLatched = true } else if (!Gdx.input.isKeyPressed(Input.Keys.NUM_4)) @@ -316,13 +318,13 @@ object AudioMixer: Disposable { if (testAudioMixRatio >= 0.0) { val ratio1 = testAudioMixRatio.coerceIn(0.0, 1.0) - AudioMixer.convolveBusCave.volume = ratio1 - AudioMixer.convolveBusOpen.volume = 1.0 - ratio1 + convolveBusCave.volume = ratio1 + convolveBusOpen.volume = 1.0 - ratio1 } else { val ratio1 = (testAudioMixRatio / MaterialCodex["AIIR"].sondrefl).absoluteValue.coerceIn(0.0, 1.0) - AudioMixer.convolveBusOpen.volume = (1.0 - ratio1).pow(0.75) - AudioMixer.convolveBusCave.volume = 0.0 + convolveBusOpen.volume = (1.0 - ratio1).pow(0.75) + convolveBusCave.volume = 0.0 } } @@ -496,6 +498,35 @@ object AudioMixer: Disposable { }, 500L) } + fun updateBufferSizeChange() { + processing = false + processingThread.interrupt() + + + + dynamicTracks.forEach { it.stop() } + tracks.filter { it.trackType == TrackType.STATIC_SOURCE }.forEach { it.stop() } + masterTrack.volume = 0.0 + + dynamicTracks.forEach { it.updateBufferSizeChange() } + tracks.forEach { it.updateBufferSizeChange() } + masterTrack.updateBufferSizeChange() + + + + processingThread = createProcessingThread() + processing = true + processingThread.start() + + + // give some time for the cave bus to decay before ramping the volume up + Timer().schedule(object : TimerTask() { + override fun run() { + masterTrack.volume = 1.0 + } + }, 500L) + } + override fun dispose() { processingExecutor.killAll() // processingSubthreads.forEach { it.interrupt() } diff --git a/src/net/torvald/terrarum/audio/AudioProcessBuf.kt b/src/net/torvald/terrarum/audio/AudioProcessBuf.kt index 9c2e6f6b0..02103457f 100644 --- a/src/net/torvald/terrarum/audio/AudioProcessBuf.kt +++ b/src/net/torvald/terrarum/audio/AudioProcessBuf.kt @@ -1,7 +1,7 @@ package net.torvald.terrarum.audio -import com.jme3.math.FastMath -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE +import net.torvald.terrarum.App +import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE import net.torvald.terrarum.ceilToInt import net.torvald.terrarum.floorToInt @@ -54,7 +54,6 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray) } } - private val BS = AUDIO_BUFFER_SIZE private val MP3_CHUNK_SIZE = 1152 // 1152 for 32k-48k, 576 for 16k-24k, 384 for 8k-12k @@ -76,13 +75,13 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray) } } - private fun getOptimalBufferSize(rate: Int) = bufLut[BS to rate]!! + private fun getOptimalBufferSize(rate: Int) = bufLut[App.audioBufferSize to rate]!! } private val q get() = internalSamplingRate.toDouble() / SAMPLING_RATE // <= 1.0 - private val fetchSize = (BS.toFloat() / MP3_CHUNK_SIZE).ceilToInt() * MP3_CHUNK_SIZE // fetchSize is always multiple of MP3_CHUNK_SIZE, even if the audio is NOT MP3 + private val fetchSize = (App.audioBufferSize.toFloat() / MP3_CHUNK_SIZE).ceilToInt() * MP3_CHUNK_SIZE // fetchSize is always multiple of MP3_CHUNK_SIZE, even if the audio is NOT MP3 private val internalBufferSize = getOptimalBufferSize(inputSamplingRate)// fetchSize * 3 private val PADSIZE = TAPS + 1 @@ -120,13 +119,17 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray) private val foutR = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4 private val readBuf = ByteArray(fetchSize * 4) + init { + printdbg(this, "App.audioMixerBufferSize=${App.audioBufferSize}") + } + private fun shift(array: FloatArray, size: Int) { System.arraycopy(array, size, array, 0, array.size - size) for (i in array.size - size until array.size) { array[i] = 0f } } fun fetchBytes() { - val readCount = if (validSamplesInBuf < BS) fetchSize else 0 + val readCount = if (validSamplesInBuf < App.audioBufferSize) fetchSize else 0 val writeCount = (readCount / q).roundToInt() fun getFromReadBuf(i: Int, bytesRead: Int) = if (i < bytesRead) readBuf[i].toUint() else 0 @@ -187,17 +190,17 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray) fun getLR(volume: Double): Pair { // copy into the out - val outL = FloatArray(BS) { (foutL[it] * volume).toFloat() } - val outR = FloatArray(BS) { (foutR[it] * volume).toFloat() } + val outL = FloatArray(App.audioBufferSize) { (foutL[it] * volume).toFloat() } + val outR = FloatArray(App.audioBufferSize) { (foutR[it] * volume).toFloat() } // shift bytes in the fout - System.arraycopy(foutL, BS, foutL, 0, validSamplesInBuf - BS) - System.arraycopy(foutR, BS, foutR, 0, validSamplesInBuf - BS) - for (i in validSamplesInBuf until BS) { + System.arraycopy(foutL, App.audioBufferSize, foutL, 0, validSamplesInBuf - App.audioBufferSize) + System.arraycopy(foutR, App.audioBufferSize, foutR, 0, validSamplesInBuf - App.audioBufferSize) + for (i in validSamplesInBuf until App.audioBufferSize) { foutL[i] = 0f foutR[i] = 0f } // decrement necessary variables - validSamplesInBuf -= BS + validSamplesInBuf -= App.audioBufferSize return outL to outR } diff --git a/src/net/torvald/terrarum/audio/MixerTrackProcessor.kt b/src/net/torvald/terrarum/audio/MixerTrackProcessor.kt index 6112df578..838eef4cb 100644 --- a/src/net/torvald/terrarum/audio/MixerTrackProcessor.kt +++ b/src/net/torvald/terrarum/audio/MixerTrackProcessor.kt @@ -1,9 +1,7 @@ package net.torvald.terrarum.audio import com.badlogic.gdx.utils.Queue -import com.jme3.math.FastMath import net.torvald.reflection.forceInvoke -import net.torvald.spriteanimation.AssembledSpriteAnimation import net.torvald.terrarum.App import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED @@ -19,7 +17,18 @@ import kotlin.math.* /** * Created by minjaesong on 2023-11-17. */ -class MixerTrackProcessor(val buffertaille: Int, val rate: Int, val track: TerrarumAudioMixerTrack): Runnable { +class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAudioMixerTrack): Runnable { + + private var buffertaille = bufferSize + + fun reset(newBufferSize: Int) { + buffertaille = newBufferSize +// printdbg("new buffertaille = $buffertaille") + emptyBuf = FloatArray(buffertaille) + fout1 = listOf(emptyBuf, emptyBuf) + purgeStreamBuf() + } + companion object { } @@ -29,7 +38,7 @@ class MixerTrackProcessor(val buffertaille: Int, val rate: Int, val track: Terra private val pauseLock = java.lang.Object() - private val emptyBuf = FloatArray(buffertaille) + private var emptyBuf = FloatArray(buffertaille) internal var streamBuf: AudioProcessBuf? = null @@ -117,18 +126,18 @@ class MixerTrackProcessor(val buffertaille: Int, val rate: Int, val track: Terra // update panning and shits if (track.trackType == TrackType.DYNAMIC_SOURCE && track.isPlaying) { - (track.filters[0] as BinoPan).earDist = AudioMixer.listenerHeadSize + (track.filters[0] as BinoPan).earDist = App.audioMixer.listenerHeadSize - if (AudioMixer.actorNowPlaying != null) { - if (track.trackingTarget == null || track.trackingTarget == AudioMixer.actorNowPlaying) { + if (App.audioMixer.actorNowPlaying != null) { + if (track.trackingTarget == null || track.trackingTarget == App.audioMixer.actorNowPlaying) { // "reset" the track track.volume = track.maxVolume (track.filters[0] as BinoPan).pan = 0f (track.filters[1] as Lowpass).setCutoff(SAMPLING_RATE / 2f) } else if (track.trackingTarget is ActorWithBody) { - val relativeXpos = relativeXposition(AudioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody) - val distFromActor = distBetweenActors(AudioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody) + val relativeXpos = relativeXposition(App.audioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody) + val distFromActor = distBetweenActors(App.audioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody) val vol = track.maxVolume * getVolFun(distFromActor / distFalloff).coerceAtLeast(0.0) track.volume = vol (track.filters[0] as BinoPan).pan = (1.3f * relativeXpos / distFalloff).toFloat() @@ -169,7 +178,13 @@ class MixerTrackProcessor(val buffertaille: Int, val rate: Int, val track: Terra // add all up sidechains.forEach { (side, mix) -> for (i in samplesL1.indices) { - samplesL1[i] += side.processor.fout1[0][i] * (mix * track.volume).toFloat() +// try { + samplesL1[i] += side.processor.fout1[0][i] * (mix * track.volume).toFloat() +// } +// catch (e: ArrayIndexOutOfBoundsException) { +// printdbg("buffertaille = $buffertaille, samplesL1 size = ${samplesL1.size}, side.processor.fout1[0] size = ${side.processor.fout1[0].size}") +// throw e +// } samplesR1[i] += side.processor.fout1[1][i] * (mix * track.volume).toFloat() } } diff --git a/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt b/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt index 3ccfd5571..58738ef6c 100644 --- a/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt +++ b/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt @@ -1,11 +1,9 @@ package net.torvald.terrarum.audio import com.badlogic.gdx.Gdx -import com.badlogic.gdx.audio.Sound import com.badlogic.gdx.backends.lwjgl3.audio.OpenALLwjgl3Audio import com.badlogic.gdx.utils.Disposable import com.badlogic.gdx.utils.Queue -import net.torvald.reflection.forceInvoke import net.torvald.terrarum.App import net.torvald.terrarum.audio.dsp.NullFilter import net.torvald.terrarum.audio.dsp.TerrarumAudioFilter @@ -35,7 +33,6 @@ class TerrarumAudioMixerTrack( const val SAMPLING_RATE = 48000 const val SAMPLING_RATEF = 48000f const val SAMPLING_RATED = 48000.0 - val AUDIO_BUFFER_SIZE = App.getConfigInt("audio_buffer_size") // n ms -> 384 * n } val hash = getHashStr() @@ -168,7 +165,7 @@ class TerrarumAudioMixerTrack( // 1st ring of the hell: the THREADING HELL // - internal var processor = MixerTrackProcessor(AUDIO_BUFFER_SIZE, SAMPLING_RATE, this) + internal var processor = MixerTrackProcessor(App.audioBufferSize, SAMPLING_RATE, this) /*private val processorThread = Thread(processor).also { // uncomment to multithread it.priority = MAX_PRIORITY // higher = more predictable; audio delay is very noticeable so it gets high priority it.start() @@ -178,8 +175,8 @@ class TerrarumAudioMixerTrack( private lateinit var queueDispatcherThread: Thread init { - pcmQueue.addLast(listOf(FloatArray(AUDIO_BUFFER_SIZE), FloatArray(AUDIO_BUFFER_SIZE))) - pcmQueue.addLast(listOf(FloatArray(AUDIO_BUFFER_SIZE), FloatArray(AUDIO_BUFFER_SIZE))) + pcmQueue.addLast(listOf(FloatArray(App.audioBufferSize), FloatArray(App.audioBufferSize))) + pcmQueue.addLast(listOf(FloatArray(App.audioBufferSize), FloatArray(App.audioBufferSize))) /*if (isMaster) { // uncomment to multithread queueDispatcher = FeedSamplesToAdev(BUFFER_SIZE, SAMPLING_RATE, this) @@ -190,6 +187,16 @@ class TerrarumAudioMixerTrack( }*/ } + fun updateBufferSizeChange() { +// printdbg(this, "new buffer size: $App.audioMixerBufferSize") + pcmQueue.clear() + pcmQueue.addLast(listOf(FloatArray(App.audioBufferSize), FloatArray(App.audioBufferSize))) + pcmQueue.addLast(listOf(FloatArray(App.audioBufferSize), FloatArray(App.audioBufferSize))) + processor.reset(App.audioBufferSize) + filters.forEach { it.reset() } + } + + override fun hashCode() = hashCode0 } diff --git a/src/net/torvald/terrarum/audio/dsp/BinoPan.kt b/src/net/torvald/terrarum/audio/dsp/BinoPan.kt index 91da8e645..ea47ed616 100644 --- a/src/net/torvald/terrarum/audio/dsp/BinoPan.kt +++ b/src/net/torvald/terrarum/audio/dsp/BinoPan.kt @@ -3,10 +3,7 @@ package net.torvald.terrarum.audio.dsp import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.jme3.math.FastMath import net.torvald.terrarum.App -import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.audio.AudioMixer -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF import net.torvald.terrarum.audio.decibelsToFullscale import net.torvald.terrarum.ceilToInt @@ -43,8 +40,8 @@ class BinoPan(var pan: Float, var earDist: Float = EARDIST_DEFAULT): TerrarumAud private val delays = arrayOf(0f, 0f) private val mults = arrayOf(1f, 1f) - private val outLs = Array(2) { FloatArray(AUDIO_BUFFER_SIZE) } - private val outRs = Array(2) { FloatArray(AUDIO_BUFFER_SIZE) } + private var outLs = Array(2) { FloatArray(App.audioBufferSize) } + private var outRs = Array(2) { FloatArray(App.audioBufferSize) } companion object { @@ -58,6 +55,13 @@ class BinoPan(var pan: Float, var earDist: Float = EARDIST_DEFAULT): TerrarumAud private val HALF_PI = (Math.PI / 2.0).toFloat() } + override fun reset() { + outLs = Array(2) { FloatArray(App.audioBufferSize) } + outRs = Array(2) { FloatArray(App.audioBufferSize) } + delayLineL.fill(0f) + delayLineR.fill(0f) + } + /** * @param intensity -inf to +inf */ @@ -104,7 +108,7 @@ class BinoPan(var pan: Float, var earDist: Float = EARDIST_DEFAULT): TerrarumAud mults[R] = volMultFsOther } - for (i in 0 until AUDIO_BUFFER_SIZE) { + for (i in 0 until App.audioBufferSize) { sumbuf[L][i] = mults[L] * getFrom(i - delays[L], delayLine, inbuf) sumbuf[R][i] = mults[R] * getFrom(i - delays[R], delayLine, inbuf) } @@ -115,7 +119,7 @@ class BinoPan(var pan: Float, var earDist: Float = EARDIST_DEFAULT): TerrarumAud thru("L", -50f, inbuf[L], outLs, delayLineL) // 50 will become 59.036 on panningFieldMap thru("R", +50f, inbuf[R], outRs, delayLineR) - for (i in 0 until AUDIO_BUFFER_SIZE) { + for (i in 0 until App.audioBufferSize) { val outL = (outLs[L][i] + outRs[L][i]) / 2f val outR = (outLs[R][i] + outRs[R][i]) / 2f outbuf[L][i] = outL diff --git a/src/net/torvald/terrarum/audio/dsp/Bitcrush.kt b/src/net/torvald/terrarum/audio/dsp/Bitcrush.kt index 8b7a669da..913aaa620 100644 --- a/src/net/torvald/terrarum/audio/dsp/Bitcrush.kt +++ b/src/net/torvald/terrarum/audio/dsp/Bitcrush.kt @@ -3,7 +3,6 @@ package net.torvald.terrarum.audio.dsp import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.jme3.math.FastMath import net.torvald.terrarum.App -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack import net.torvald.terrarum.audio.linToLogPerc import net.torvald.terrarum.roundToFloat import net.torvald.terrarum.ui.BasicDebugInfoWindow @@ -13,7 +12,7 @@ import net.torvald.terrarum.ui.Toolkit class Bitcrush(var steps: Int, var inputGain: Float = 1f): TerrarumAudioFilter() { override fun thru(inbuf: List, outbuf: List) { for (ch in outbuf.indices) { - for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) { + for (i in 0 until App.audioBufferSize) { val inn = ((inbuf[ch][i] * inputGain).coerceIn(-1f, 1f) + 1f) / 2f // 0f..1f val stepped = (inn * (steps - 1)).roundToFloat() / (steps - 1) val out = (stepped * 2f) - 1f // -1f..1f @@ -35,5 +34,8 @@ class Bitcrush(var steps: Int, var inputGain: Float = 1f): TerrarumAudioFilter() App.fontSmallNumbers.draw(batch, "B:$bits", x+3f, y+1f) } + override fun reset() { + } + override val debugViewHeight = 16 } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/dsp/Buffer.kt b/src/net/torvald/terrarum/audio/dsp/Buffer.kt index 2a65f4a08..79592d654 100644 --- a/src/net/torvald/terrarum/audio/dsp/Buffer.kt +++ b/src/net/torvald/terrarum/audio/dsp/Buffer.kt @@ -2,7 +2,6 @@ package net.torvald.terrarum.audio.dsp import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.terrarum.App -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.FILTER_NAME_ACTIVE object Buffer : TerrarumAudioFilter() { @@ -16,7 +15,10 @@ object Buffer : TerrarumAudioFilter() { override fun drawDebugView(batch: SpriteBatch, x: Int, y: Int) { batch.color = FILTER_NAME_ACTIVE - App.fontSmallNumbers.draw(batch, "Bs:${AUDIO_BUFFER_SIZE}", x+3f, y+1f) + App.fontSmallNumbers.draw(batch, "Bs:${App.audioBufferSize}", x+3f, y+1f) + } + + override fun reset() { } override val debugViewHeight = 16 diff --git a/src/net/torvald/terrarum/audio/dsp/Convolv.kt b/src/net/torvald/terrarum/audio/dsp/Convolv.kt index bfb5a1da6..e089f2c4f 100644 --- a/src/net/torvald/terrarum/audio/dsp/Convolv.kt +++ b/src/net/torvald/terrarum/audio/dsp/Convolv.kt @@ -5,8 +5,6 @@ import com.jme3.math.FastMath import net.torvald.terrarum.App import net.torvald.terrarum.App.setDebugTime import net.torvald.terrarum.audio.* -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE -import net.torvald.terrarum.ui.BasicDebugInfoWindow import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.COL_METER_GRAD import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.COL_METER_GRAD2 import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.COL_METER_GRAD2_RED @@ -25,14 +23,13 @@ import kotlin.math.roundToInt * @param gain output gain. Fullscale (0.0 - 1.0) */ class Convolv(ir: File, val crossfeed: Float, gain: Float = 1f / 256f): TerrarumAudioFilter() { + private val gain: Float = gain / (1f + crossfeed) val fftLen: Int private val convFFT: Array private val sumbuf: Array - private val BLOCKSIZE = TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE - var processingSpeed = 1f; private set init { @@ -71,12 +68,18 @@ class Convolv(ir: File, val crossfeed: Float, gain: Float = 1f / 256f): Terrarum } } - private val realtime = (BLOCKSIZE / TerrarumAudioMixerTrack.SAMPLING_RATEF * 1000000000L) + private var realtime = (App.audioBufferSize / TerrarumAudioMixerTrack.SAMPLING_RATEF * 1000000000L) private val fftIn = ComplexArray(FloatArray(fftLen * 2)) private val fftMult = ComplexArray(FloatArray(fftLen * 2)) private val fftOutL = FloatArray(fftLen) private val fftOutR = FloatArray(fftLen) + override fun reset() { + realtime = (App.audioBufferSize / TerrarumAudioMixerTrack.SAMPLING_RATEF * 1000000000L) + processingSpeed = 1f + sumbuf.forEach { it.reim.fill(0f) } + } + private fun convolve(x: ComplexArray, h: ComplexArray, output: FloatArray) { FFT.fftInto(x, fftIn) fftIn.mult(h, fftMult) @@ -96,9 +99,9 @@ class Convolv(ir: File, val crossfeed: Float, gain: Float = 1f / 256f): Terrarum convolve(sumbuf[0], convFFT[0], fftOutL) convolve(sumbuf[1], convFFT[1], fftOutR) - for (i in 0 until BLOCKSIZE) { - outbuf[0][i] = fftOutL[fftLen - BLOCKSIZE + i] - outbuf[1][i] = fftOutR[fftLen - BLOCKSIZE + i] + for (i in 0 until App.audioBufferSize) { + outbuf[0][i] = fftOutL[fftLen - App.audioBufferSize + i] + outbuf[1][i] = fftOutR[fftLen - App.audioBufferSize + i] } @@ -144,7 +147,7 @@ class Convolv(ir: File, val crossfeed: Float, gain: Float = 1f / 256f): Terrarum Toolkit.fillArea(batch, x.toFloat(), y+14f, STRIP_W * perc, 2f) // filter length bar - val g = FastMath.intLog2(AUDIO_BUFFER_SIZE) + val g = FastMath.intLog2(App.audioBufferSize) val perc2 = (FastMath.intLog2(fftLen).minus(g).toFloat() / (16f - g)).coerceIn(0f, 1f) batch.color = COL_METER_GRAD2 Toolkit.fillArea(batch, x.toFloat(), y + 16f, STRIP_W * perc2, 14f) diff --git a/src/net/torvald/terrarum/audio/dsp/Gain.kt b/src/net/torvald/terrarum/audio/dsp/Gain.kt index 9e0b2a51b..c04c0e47f 100644 --- a/src/net/torvald/terrarum/audio/dsp/Gain.kt +++ b/src/net/torvald/terrarum/audio/dsp/Gain.kt @@ -2,14 +2,13 @@ package net.torvald.terrarum.audio.dsp import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.terrarum.App -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack import net.torvald.terrarum.audio.fullscaleToDecibels import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.FILTER_NAME_ACTIVE import kotlin.math.roundToInt class Gain(var gain: Float): TerrarumAudioFilter() { override fun thru(inbuf: List, outbuf: List) { - for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) { + for (i in 0 until App.audioBufferSize) { outbuf[0][i] = inbuf[0][i] * gain outbuf[1][i] = inbuf[1][i] * gain } @@ -20,5 +19,9 @@ class Gain(var gain: Float): TerrarumAudioFilter() { App.fontSmallNumbers.draw(batch, "G:${fullscaleToDecibels(gain.toDouble()).times(100).roundToInt().div(100f)}", x+3f, y+1f) } + + override fun reset() { + } + override val debugViewHeight = 16 } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/dsp/Highpass.kt b/src/net/torvald/terrarum/audio/dsp/Highpass.kt index 6c816414d..58452781b 100644 --- a/src/net/torvald/terrarum/audio/dsp/Highpass.kt +++ b/src/net/torvald/terrarum/audio/dsp/Highpass.kt @@ -68,4 +68,8 @@ class Highpass(cutoff0: Float): TerrarumAudioFilter() { override val debugViewHeight = 16 + override fun reset() { + in0.fill(0f) + out0.fill(0f) + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/dsp/Lowpass.kt b/src/net/torvald/terrarum/audio/dsp/Lowpass.kt index b34cb25c1..842133f89 100644 --- a/src/net/torvald/terrarum/audio/dsp/Lowpass.kt +++ b/src/net/torvald/terrarum/audio/dsp/Lowpass.kt @@ -67,4 +67,9 @@ class Lowpass(cutoff0: Float): TerrarumAudioFilter() { } override val debugViewHeight = 16 + + override fun reset() { + in0.fill(0f) + out0.fill(0f) + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/dsp/NullFilter.kt b/src/net/torvald/terrarum/audio/dsp/NullFilter.kt index 37b19a511..0ae0b8359 100644 --- a/src/net/torvald/terrarum/audio/dsp/NullFilter.kt +++ b/src/net/torvald/terrarum/audio/dsp/NullFilter.kt @@ -13,4 +13,7 @@ object NullFilter : TerrarumAudioFilter() { } override val debugViewHeight = 0 + + override fun reset() { + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/dsp/Reverb.kt b/src/net/torvald/terrarum/audio/dsp/Reverb.kt index 092cefa89..75b5fd98f 100644 --- a/src/net/torvald/terrarum/audio/dsp/Reverb.kt +++ b/src/net/torvald/terrarum/audio/dsp/Reverb.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.audio.dsp import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.jme3.math.FastMath +import net.torvald.terrarum.App import net.torvald.terrarum.audio.TerrarumAudioMixerTrack import kotlin.math.roundToInt @@ -31,7 +32,7 @@ class Reverb(val delayMS: Float = 36f, var feedback: Float = 0.92f, var lowpass: val alphaHi = RCHi / (RCHi + dt) for (ch in outbuf.indices) { - for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) { + for (i in 0 until App.audioBufferSize) { val inn = inbuf[ch][i] // reverb @@ -52,4 +53,8 @@ class Reverb(val delayMS: Float = 36f, var feedback: Float = 0.92f, var lowpass: } override val debugViewHeight = 0 + + override fun reset() { + buf.forEach { it.fill(0f) } + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/dsp/SoftClp.kt b/src/net/torvald/terrarum/audio/dsp/SoftClp.kt index ff6b96293..e4da89b11 100644 --- a/src/net/torvald/terrarum/audio/dsp/SoftClp.kt +++ b/src/net/torvald/terrarum/audio/dsp/SoftClp.kt @@ -56,4 +56,7 @@ object SoftClp : TerrarumAudioFilter() { } override val debugViewHeight = 0 + + override fun reset() { + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/dsp/Spectro.kt b/src/net/torvald/terrarum/audio/dsp/Spectro.kt index caf10c9b5..d87c338e1 100644 --- a/src/net/torvald/terrarum/audio/dsp/Spectro.kt +++ b/src/net/torvald/terrarum/audio/dsp/Spectro.kt @@ -3,8 +3,8 @@ package net.torvald.terrarum.audio.dsp import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.jme3.math.FastMath +import net.torvald.terrarum.App import net.torvald.terrarum.audio.* -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED import net.torvald.terrarum.ui.BasicDebugInfoWindow import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.STRIP_W @@ -91,15 +91,18 @@ class Spectro(val gain: Float = 1f) : TerrarumAudioFilter() { } override val debugViewHeight = STRIP_W + + override fun reset() { + } } class Vecto(val gain: Float = 1f) : TerrarumAudioFilter() { - val backbufL = Array((6144f / AUDIO_BUFFER_SIZE).roundToInt().coerceAtLeast(1)) { - FloatArray(AUDIO_BUFFER_SIZE) + var backbufL = Array((6144f / App.audioBufferSize).roundToInt().coerceAtLeast(1)) { + FloatArray(App.audioBufferSize) } - val backbufR = Array((6144f / AUDIO_BUFFER_SIZE).roundToInt().coerceAtLeast(1)) { - FloatArray(AUDIO_BUFFER_SIZE) + var backbufR = Array((6144f / App.audioBufferSize).roundToInt().coerceAtLeast(1)) { + FloatArray(App.audioBufferSize) } private val sqrt2p = 0.7071067811865475 @@ -110,11 +113,11 @@ class Vecto(val gain: Float = 1f) : TerrarumAudioFilter() { backbufL[i] = backbufL[i - 1] backbufR[i] = backbufR[i - 1] } - backbufL[0] = FloatArray(TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) - backbufR[0] = FloatArray(TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) + backbufL[0] = FloatArray(App.audioBufferSize) + backbufR[0] = FloatArray(App.audioBufferSize) // plot dots - for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) { + for (i in 0 until App.audioBufferSize) { val y0 = +inbuf[0][i] * gain val x0 = -inbuf[1][i] * gain// rotate the domain by -90 deg @@ -154,4 +157,13 @@ class Vecto(val gain: Float = 1f) : TerrarumAudioFilter() { } override val debugViewHeight = STRIP_W + + override fun reset() { + backbufL = Array((6144f / App.audioBufferSize).roundToInt().coerceAtLeast(1)) { + FloatArray(App.audioBufferSize) + } + backbufR = Array((6144f / App.audioBufferSize).roundToInt().coerceAtLeast(1)) { + FloatArray(App.audioBufferSize) + } + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/audio/dsp/TerrarumAudioFilter.kt b/src/net/torvald/terrarum/audio/dsp/TerrarumAudioFilter.kt index 097ec6800..8d44b0b58 100644 --- a/src/net/torvald/terrarum/audio/dsp/TerrarumAudioFilter.kt +++ b/src/net/torvald/terrarum/audio/dsp/TerrarumAudioFilter.kt @@ -13,6 +13,7 @@ abstract class TerrarumAudioFilter { } else thru(inbuf, outbuf) } + abstract fun reset() abstract fun drawDebugView(batch: SpriteBatch, x: Int, y: Int) abstract val debugViewHeight: Int } diff --git a/src/net/torvald/terrarum/audio/dsp/XYtoMS.kt b/src/net/torvald/terrarum/audio/dsp/XYtoMS.kt index f11542ffc..ed33fbb57 100644 --- a/src/net/torvald/terrarum/audio/dsp/XYtoMS.kt +++ b/src/net/torvald/terrarum/audio/dsp/XYtoMS.kt @@ -1,11 +1,11 @@ package net.torvald.terrarum.audio.dsp import com.badlogic.gdx.graphics.g2d.SpriteBatch -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack +import net.torvald.terrarum.App object XYtoMS: TerrarumAudioFilter() { override fun thru(inbuf: List, outbuf: List) { - for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) { + for (i in 0 until App.audioBufferSize) { val X = inbuf[0][i] val Y = inbuf[1][i] val M = (X + Y) / 2f @@ -19,11 +19,14 @@ object XYtoMS: TerrarumAudioFilter() { } override val debugViewHeight = 0 + + override fun reset() { + } } object MStoXY: TerrarumAudioFilter() { override fun thru(inbuf: List, outbuf: List) { - for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) { + for (i in 0 until App.audioBufferSize) { val M = inbuf[0][i] val S = inbuf[1][i] val X = M + S @@ -37,4 +40,7 @@ object MStoXY: TerrarumAudioFilter() { } override val debugViewHeight = 0 + + override fun reset() { + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/Actor.kt b/src/net/torvald/terrarum/gameactors/Actor.kt index b1a8229d4..93c1188b1 100644 --- a/src/net/torvald/terrarum/gameactors/Actor.kt +++ b/src/net/torvald/terrarum/gameactors/Actor.kt @@ -1,13 +1,9 @@ package net.torvald.terrarum.gameactors -import com.badlogic.gdx.audio.Music -import com.badlogic.gdx.audio.Sound import net.torvald.random.HQRNG -import net.torvald.terrarum.App.printdbg +import net.torvald.terrarum.App import net.torvald.terrarum.INGAME -import net.torvald.terrarum.ReferencingRanges import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.audio.AudioMixer import net.torvald.terrarum.audio.TerrarumAudioMixerTrack import net.torvald.terrarum.audio.TrackVolume import net.torvald.terrarum.modulebasegame.MusicContainer @@ -113,9 +109,9 @@ abstract class Actor : Comparable, Runnable { // if there is no existing track, try to get one if (track == null) { track = if (this == Terrarum.ingame?.actorNowPlaying) - AudioMixer.getFreeTrackNoMatterWhat() + App.audioMixer.getFreeTrackNoMatterWhat() else - AudioMixer.getFreeTrack() + App.audioMixer.getFreeTrack() // if the request was successful, put it into the hashmap if (track != null) { musicTracks[music] = track diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index 84c3920dd..01d34d517 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -7,9 +7,6 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion import net.torvald.terrarum.* import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE -import net.torvald.terrarum.audio.AudioMixer -import net.torvald.terrarum.audio.dsp.Lowpass -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.BlockPropUtil import net.torvald.terrarum.gameactors.* @@ -300,7 +297,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { override fun show() { Gdx.input.inputProcessor = BuildingMakerController(this) - AudioMixer.reset() + App.audioMixer.reset() super.show() } diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index ddd8d5510..ae87692ee 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -8,14 +8,10 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import net.torvald.terrarum.* import net.torvald.terrarum.App.* -import net.torvald.terrarum.Terrarum.audioCodex import net.torvald.terrarum.Terrarum.getPlayerSaveFiledesc import net.torvald.terrarum.Terrarum.getWorldSaveFiledesc import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED -import net.torvald.terrarum.audio.AudioMixer -import net.torvald.terrarum.audio.dsp.Lowpass -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF import net.torvald.terrarum.blockproperties.BlockPropUtil import net.torvald.terrarum.blockstats.MinimapComposer import net.torvald.terrarum.blockstats.TileSurvey @@ -298,7 +294,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { IngameRenderer.setRenderedWorld(world) blockMarkingActor.isVisible = true - AudioMixer.reset() + App.audioMixer.reset() super.show() // this function sets gameInitialised = true @@ -893,13 +889,13 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { val ratio = (TileSurvey.getRatio("basegame.Ingame.audioReflection") ?: 0.0) if (ratio >= 0.0) { val ratio1 = ratio.coerceIn(0.0, 1.0) - AudioMixer.convolveBusCave.volume = ratio1 - AudioMixer.convolveBusOpen.volume = 1.0 - ratio1 + App.audioMixer.convolveBusCave.volume = ratio1 + App.audioMixer.convolveBusOpen.volume = 1.0 - ratio1 } else { val ratio1 = (ratio / MaterialCodex["AIIR"].sondrefl).absoluteValue.coerceIn(0.0, 1.0) - AudioMixer.convolveBusOpen.volume = (1.0 - ratio1).pow(0.75) - AudioMixer.convolveBusCave.volume = 0.0 + App.audioMixer.convolveBusOpen.volume = (1.0 - ratio1).pow(0.75) + App.audioMixer.convolveBusCave.volume = 0.0 } diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumMusicGovernor.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumMusicGovernor.kt index f2330d65d..24b420443 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumMusicGovernor.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumMusicGovernor.kt @@ -16,7 +16,6 @@ import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.audio.AudioMixer import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE -import net.torvald.terrarum.gameworld.fmod import java.io.File import java.io.FileInputStream import javax.sound.sampled.AudioSystem @@ -203,8 +202,8 @@ class TerrarumMusicGovernor : MusicGovernor() { */ fun queueDirectory(musicDir: String, shuffled: Boolean, diskJockeyingMode: String, fileToName: ((String) -> String)? = null) { if (musicState != STATE_INIT && musicState != STATE_INTERMISSION) { - AudioMixer.requestFadeOut(AudioMixer.fadeBus, AudioMixer.DEFAULT_FADEOUT_LEN) // explicit call for fade-out when the game instance quits - stopMusic(AudioMixer.musicTrack.currentTrack) + App.audioMixer.requestFadeOut(App.audioMixer.fadeBus, AudioMixer.DEFAULT_FADEOUT_LEN) // explicit call for fade-out when the game instance quits + stopMusic(App.audioMixer.musicTrack.currentTrack) } songs.forEach { it.gdxMusic.tryDispose() } @@ -337,7 +336,7 @@ class TerrarumMusicGovernor : MusicGovernor() { } fun stopMusic(callStopMusicHook: Boolean = true, pauseLen: Float = Float.POSITIVE_INFINITY) { - stopMusic(AudioMixer.musicTrack.currentTrack, callStopMusicHook) + stopMusic(App.audioMixer.musicTrack.currentTrack, callStopMusicHook) intermissionLength = pauseLen // printdbg(this, "StopMusic Intermission2: $intermissionLength seconds") } @@ -347,7 +346,7 @@ class TerrarumMusicGovernor : MusicGovernor() { } private fun startMusic(song: MusicContainer) { - AudioMixer.startMusic(song) + App.audioMixer.startMusic(song) printdbg(this, "startMusic Now playing: ${song.name}") // INGAME.sendNotification("Now Playing $EMDASH ${song.name}") if (musicStartHooks.isNotEmpty()) musicStartHooks.forEach { it(song) } @@ -386,7 +385,7 @@ class TerrarumMusicGovernor : MusicGovernor() { } private fun startAmbient(song: MusicContainer) { - AudioMixer.startAmb(song) + App.audioMixer.startAmb(song) printdbg(this, "startAmbient Now playing: $song") // INGAME.sendNotification("Now Playing $EMDASH ${song.name}") ambState = STATE_PLAYING @@ -438,8 +437,8 @@ class TerrarumMusicGovernor : MusicGovernor() { } override fun dispose() { - AudioMixer.requestFadeOut(AudioMixer.fadeBus, AudioMixer.DEFAULT_FADEOUT_LEN) // explicit call for fade-out when the game instance quits - stopMusic(AudioMixer.musicTrack.currentTrack) + App.audioMixer.requestFadeOut(App.audioMixer.fadeBus, AudioMixer.DEFAULT_FADEOUT_LEN) // explicit call for fade-out when the game instance quits + stopMusic(App.audioMixer.musicTrack.currentTrack) stopAmbient() } } diff --git a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt index b486afc51..043532593 100644 --- a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt +++ b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt @@ -17,9 +17,6 @@ import net.torvald.terrarum.App.printdbgerr import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF -import net.torvald.terrarum.audio.AudioMixer -import net.torvald.terrarum.audio.dsp.Lowpass -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack import net.torvald.terrarum.clut.Skybox import net.torvald.terrarum.console.CommandDict import net.torvald.terrarum.gameactors.* @@ -269,7 +266,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) { App.bogoflops = maxOf(App.bogoflops, bogoflops) - AudioMixer.reset() + App.audioMixer.reset() } diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt index 28e1010df..940643526 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt @@ -9,8 +9,7 @@ import net.torvald.spriteanimation.SheetSpriteAnimation import net.torvald.terrarum.* import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE -import net.torvald.terrarum.audio.AudioMixer -import net.torvald.terrarum.audio.AudioMixer.DEFAULT_FADEOUT_LEN +import net.torvald.terrarum.audio.AudioMixer.Companion.DEFAULT_FADEOUT_LEN import net.torvald.terrarum.audio.dsp.Convolv import net.torvald.terrarum.audio.dsp.NullFilter import net.torvald.terrarum.gameactors.AVKey @@ -110,7 +109,7 @@ class FixtureJukebox : Electric { discCurrentlyPlaying = index - AudioMixer.requestFadeOut(AudioMixer.musicTrack, DEFAULT_FADEOUT_LEN / 2f) { + App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, DEFAULT_FADEOUT_LEN / 2f) { startAudio(musicNowPlaying!!) { it.filters[2] = Convolv( ModMgr.getFile( diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt index fee0b171c..309b3eca2 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryFull.kt @@ -6,7 +6,6 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.jme3.math.FastMath import net.torvald.terrarum.* import net.torvald.terrarum.App.* -import net.torvald.terrarum.audio.AudioMixer import net.torvald.terrarum.audio.decibelsToFullscale import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.langpack.Lang @@ -388,8 +387,8 @@ class UIInventoryFull( INGAME.pause() INGAME.setTooltipMessage(null) - AudioMixer.requestLowpassIn(0.25) - AudioMixer.requestFadeOut(AudioMixer.fadeBus, 0.25, decibelsToFullscale(-3.0)) + App.audioMixer.requestLowpassIn(0.25) + App.audioMixer.requestFadeOut(App.audioMixer.fadeBus, 0.25, decibelsToFullscale(-3.0)) } override fun doClosing(delta: Float) { @@ -398,8 +397,8 @@ class UIInventoryFull( INGAME.resume() INGAME.setTooltipMessage(null) - AudioMixer.requestLowpassOut(0.25) - AudioMixer.requestFadeIn(AudioMixer.fadeBus, 0.25, 1.0) + App.audioMixer.requestLowpassOut(0.25) + App.audioMixer.requestFadeIn(App.audioMixer.fadeBus, 0.25, 1.0) } override fun endOpening(delta: Float) { diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UISoundControlPanel.kt b/src/net/torvald/terrarum/modulebasegame/ui/UISoundControlPanel.kt index 1dba86cb2..384dffe6b 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UISoundControlPanel.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UISoundControlPanel.kt @@ -1,8 +1,9 @@ package net.torvald.terrarum.modulebasegame.ui -import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.App +import net.torvald.terrarum.audio.AudioMixer import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.ui.UICanvas @@ -28,10 +29,10 @@ class UISoundControlPanel(remoCon: UIRemoCon?) : UICanvas() { arrayOf("", { "" }, "pp"), arrayOf("guivolume", { Lang["MENU_LABEL_INTERFACE"] }, "sliderd,0,1"), arrayOf("", { "" }, "pp"), - arrayOf("audio_speaker_setup", { Lang["MENU_OPTIONS_SPEAKER_SETUP"] }, "textsel,headphone=MENU_OPTIONS_SPEAKER_HEADPHONE,stereo=MENU_OPTIONS_SPEAKER_STEREO"), arrayOf("", { Lang["MENU_LABEL_AUDIO_ENGINE"] }, "h1"), - arrayOf("audio_buffer_size", { Lang["MENU_OPTIONS_AUDIO_BUFFER_SIZE"] }, "spinnersel,128,256,512,1024,2048"), - arrayOf("", { "(${Lang["MENU_LABEL_RESTART_REQUIRED"]})" }, "p"), + arrayOf("audio_speaker_setup", { Lang["MENU_OPTIONS_SPEAKER_SETUP"] }, "textsel,headphone=MENU_OPTIONS_SPEAKER_HEADPHONE,stereo=MENU_OPTIONS_SPEAKER_STEREO"), + arrayOf("audio_buffer_size", { Lang["MENU_OPTIONS_App.audioMixerBufferSize"] }, "spinnersel,128,256,512,1024,2048"), +// arrayOf("", { "(${Lang["MENU_LABEL_RESTART_REQUIRED"]})" }, "p"), arrayOf("", { "${Lang["MENU_LABEL_AUDIO_BUFFER_INSTRUCTION"]}" }, "p"), )) @@ -39,8 +40,18 @@ class UISoundControlPanel(remoCon: UIRemoCon?) : UICanvas() { override var height = ControlPanelCommon.getMenuHeight("basegame.soundcontrolpanel") + private var oldBufferSize = App.getConfigInt("audio_buffer_size") + override fun updateUI(delta: Float) { uiItems.forEach { it.update(delta) } + + App.getConfigInt("audio_buffer_size").let { + if (it != oldBufferSize) { + oldBufferSize = it + + App.renewAudioProcessor(it) + } + } } override fun renderUI(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) { diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index 8d4f9d2c2..f1fbddea2 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -13,8 +13,6 @@ import net.torvald.terrarum.Terrarum.mouseTileX import net.torvald.terrarum.Terrarum.mouseTileY import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.audio.* -import net.torvald.terrarum.audio.AudioMixer.dynamicSourceCount -import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE import net.torvald.terrarum.audio.dsp.* import net.torvald.terrarum.controller.TerrarumController import net.torvald.terrarum.gameworld.GameWorld @@ -136,7 +134,7 @@ class BasicDebugInfoWindow : UICanvas() { showWeatherInfo = showWeatherInfo xor (Gdx.input.isKeyJustPressed(KEY_WEATHERS) && Gdx.input.isKeyPressed(Keys.CONTROL_LEFT)) showAudioMixer = showAudioMixer xor (Gdx.input.isKeyJustPressed(KEY_AUDIOMIXER) && Gdx.input.isKeyPressed(Keys.CONTROL_LEFT)) - AudioMixer.masterTrack.filters[2].bypass = !showAudioMixer + App.audioMixer.masterTrack.filters[2].bypass = !showAudioMixer drawMain(batch) if (showTimers) drawTimers(batch) @@ -438,10 +436,10 @@ class BasicDebugInfoWindow : UICanvas() { private fun drawAudioMixer(batch: SpriteBatch) { - val x = App.scr.width - 186 - (AudioMixer.tracks.size + 1) * (STRIP_W + stripGap) + val x = App.scr.width - 186 - (App.audioMixer.tracks.size + 1) * (STRIP_W + stripGap) val y = App.scr.height - 38 - stripH - val strips = AudioMixer.tracks + AudioMixer.masterTrack + val strips = App.audioMixer.tracks + App.audioMixer.masterTrack // batch.color = COL_MIXER_BACK // Toolkit.fillArea(batch, x - stripGap, y - stripGap, strips.size * (stripW + stripGap) + stripGap, stripH + 2*stripGap) @@ -457,7 +455,7 @@ class BasicDebugInfoWindow : UICanvas() { } - val dss = AudioMixer.dynamicTracks + val dss = App.audioMixer.dynamicTracks dss.forEachIndexed { index, track -> val px = x - (miniW + 5) * (1 + (index / 13)) val py = y + (miniH + stripGap) * (index % 13) @@ -588,7 +586,7 @@ class BasicDebugInfoWindow : UICanvas() { App.fontSmallNumbers.draw(batch, s, x + 3f, faderY - (i + 1) * 16f + 1f) } } - else if (track != AudioMixer.sfxSumBus) { + else if (track != App.audioMixer.sfxSumBus) { track.sidechainInputs.reversed().forEachIndexed { i, (side, mix) -> val mixDb = fullscaleToDecibels(mix) val perc = ((mixDb + 24.0).coerceAtLeast(0.0) / 24.0).toFloat() @@ -620,7 +618,7 @@ class BasicDebugInfoWindow : UICanvas() { // label batch.color = FILTER_NAME_ACTIVE App.fontSmallNumbers.draw(batch, "\u00C0", x.toFloat(), faderY - (i + 1) * 16f + 1f) - App.fontSmallNumbers.draw(batch, "DS($dynamicSourceCount)", x + 10f, faderY - (i + 1) * 16f + 1f) + App.fontSmallNumbers.draw(batch, "DS(${net.torvald.terrarum.App.audioMixer.dynamicSourceCount})", x + 10f, faderY - (i + 1) * 16f + 1f) } // fader @@ -1001,7 +999,7 @@ class BasicDebugInfoWindow : UICanvas() { } override fun endClosing(delta: Float) { - AudioMixer.masterTrack.filters[2].bypass = true + App.audioMixer.masterTrack.filters[2].bypass = true } override fun dispose() {