From e89e32eeeac37e7c873e00ead7a74bf383d17438 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sun, 14 Jan 2024 19:37:41 +0900 Subject: [PATCH] option for speaker/headphone selection for appropriate panning --- assets/locales/en/terrarum.json | 3 +++ assets/locales/koKR/terrarum.json | 3 +++ src/net/torvald/terrarum/DefaultConfig.kt | 1 + .../torvald/terrarum/audio/AudioProcessBuf.kt | 18 ++++++++++++++---- src/net/torvald/terrarum/audio/dsp/BinoPan.kt | 9 +++++++-- .../modulebasegame/ui/UISoundControlPanel.kt | 2 ++ 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/assets/locales/en/terrarum.json b/assets/locales/en/terrarum.json index 1c9e2b760..494449008 100644 --- a/assets/locales/en/terrarum.json +++ b/assets/locales/en/terrarum.json @@ -48,6 +48,9 @@ "MENU_OPTIONS_SAVEFORMAT": "Savegame Format", "MENU_OPTIONS_SAVEFORMAT_FAST": "Faster Load", "MENU_OPTIONS_SAVEFORMAT_SMALL": "Smaller Size", + "MENU_OPTIONS_SPEAKER_HEADPHONE": "Headphone", + "MENU_OPTIONS_SPEAKER_SETUP": "Speaker Setup", + "MENU_OPTIONS_SPEAKER_STEREO": "Stereo", "MENU_OPTIONS_STREAMERS_LAYOUT": "Chat Overlay", "MENU_CREDIT_GPL_DNT" : "GPL", diff --git a/assets/locales/koKR/terrarum.json b/assets/locales/koKR/terrarum.json index af719ab28..1b6509004 100644 --- a/assets/locales/koKR/terrarum.json +++ b/assets/locales/koKR/terrarum.json @@ -48,5 +48,8 @@ "MENU_OPTIONS_SAVEFORMAT": "게임 저장 형식", "MENU_OPTIONS_SAVEFORMAT_FAST": "빠른 불러오기", "MENU_OPTIONS_SAVEFORMAT_SMALL": "작은 용량", + "MENU_OPTIONS_SPEAKER_HEADPHONE": "헤드폰", + "MENU_OPTIONS_SPEAKER_SETUP": "스피커 구성", + "MENU_OPTIONS_SPEAKER_STEREO": "스테레오", "MENU_OPTIONS_STREAMERS_LAYOUT": "채팅창 오버레이" } diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt index a72f7c0f8..7208d9fe2 100644 --- a/src/net/torvald/terrarum/DefaultConfig.kt +++ b/src/net/torvald/terrarum/DefaultConfig.kt @@ -25,6 +25,7 @@ object DefaultConfig { "audio_buffer_size" to 512, "audio_dynamic_source_max" to 128, + "audio_speaker_setup" to "headphone", // "headphone" or "stereo" "language" to App.getSysLang(), "notificationshowuptime" to 4000, // 4s diff --git a/src/net/torvald/terrarum/audio/AudioProcessBuf.kt b/src/net/torvald/terrarum/audio/AudioProcessBuf.kt index e8a0571fe..0be6a7be5 100644 --- a/src/net/torvald/terrarum/audio/AudioProcessBuf.kt +++ b/src/net/torvald/terrarum/audio/AudioProcessBuf.kt @@ -24,9 +24,18 @@ private data class Frac(var nom: Int, val denom: Int) { * * Created by minjaesong on 2023-11-17. */ -class AudioProcessBuf(inputSamplingRate: Int, val audioReadFun: (ByteArray) -> Int?, val onAudioFinished: () -> Unit) { +class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray) -> Int?, val onAudioFinished: () -> Unit) { - private val doResample = inputSamplingRate != SAMPLING_RATE + var playbackSpeed = 1f + set(value) { + field = value.coerceIn(0.5f, 2f) + } + + private val internalSamplingRate + get() = inputSamplingRate * playbackSpeed + + private val doResample + get() = (internalSamplingRate - SAMPLING_RATE).absoluteValue >= 0.5f companion object { private val epsilon: Double = Epsilon.E @@ -62,7 +71,7 @@ class AudioProcessBuf(inputSamplingRate: Int, val audioReadFun: (ByteArray) -> I arrayOf(48000,44100,32768,32000,24000,22050,16384,16000,12000,11025,8192,8000).forEachIndexed { ri, r -> arrayOf(128,256,512,1024,2048).forEachIndexed { bi, b -> - bufLut[b to r] = bl[bi * 12 + ri] + bufLut[b to r] = bl[bi * 12 + ri] * 2 } } } @@ -70,7 +79,8 @@ class AudioProcessBuf(inputSamplingRate: Int, val audioReadFun: (ByteArray) -> I private fun getOptimalBufferSize(rate: Int) = bufLut[BS to rate]!! } - private val q = inputSamplingRate.toDouble() / SAMPLING_RATE // <= 1.0 + 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 internalBufferSize = getOptimalBufferSize(inputSamplingRate)// fetchSize * 3 diff --git a/src/net/torvald/terrarum/audio/dsp/BinoPan.kt b/src/net/torvald/terrarum/audio/dsp/BinoPan.kt index 7ec546691..91da8e645 100644 --- a/src/net/torvald/terrarum/audio/dsp/BinoPan.kt +++ b/src/net/torvald/terrarum/audio/dsp/BinoPan.kt @@ -75,11 +75,16 @@ class BinoPan(var pan: Float, var earDist: Float = EARDIST_DEFAULT): TerrarumAud val timeDiffMax = earDist.coerceAtMost(EARDIST_MAX) / AudioMixer.SPEED_OF_SOUND * SAMPLING_RATEF val angle = pan * HALF_PI - val delayInSamples = (timeDiffMax * FastMath.sin(angle)).absoluteValue + val delayInSamples = if (App.getConfigString("audio_speaker_setup") == "headphone") + (timeDiffMax * FastMath.sin(angle)).absoluteValue + else 0f val volMultDbThis = PANNING_CONST * pan.absoluteValue val volMultFsThis = decibelsToFullscale(volMultDbThis).toFloat() - val volMultFsOther = 1f / volMultFsThis + val volMultFsOther = if (App.getConfigString("audio_speaker_setup") == "headphone") + 1f / volMultFsThis + else + (1f - pan.absoluteValue).coerceIn(0f, 1f) if (pan >= 0) { delays[L] = delayInSamples diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UISoundControlPanel.kt b/src/net/torvald/terrarum/modulebasegame/ui/UISoundControlPanel.kt index f9f055c34..1dba86cb2 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UISoundControlPanel.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UISoundControlPanel.kt @@ -27,6 +27,8 @@ class UISoundControlPanel(remoCon: UIRemoCon?) : UICanvas() { arrayOf("sfxvolume", { Lang["CREDITS_SFX"] }, "sliderd,0,1"), 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"),