From 3da37408a2d563613e55557d00aa3f95e6e0b417 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sun, 21 Jan 2024 03:23:25 +0900 Subject: [PATCH] doppler effect --- src/net/torvald/terrarum/Terrarum.kt | 11 +++++++--- .../torvald/terrarum/audio/AudioProcessBuf.kt | 4 ++-- .../terrarum/audio/MixerTrackProcessor.kt | 22 ++++++++++++++----- .../terrarum/gameactors/ActorWithBody.kt | 9 ++++++-- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 7a8cb174c..2c76c123e 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -25,6 +25,7 @@ import net.torvald.terrarum.blockproperties.WireCodex import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameactors.ActorID import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameactors.ActorWithBody.Companion.METER import net.torvald.terrarum.gameactors.faction.FactionCodex import net.torvald.terrarum.gameworld.fmod import net.torvald.terrarum.itemproperties.CraftingCodex @@ -91,7 +92,7 @@ object Terrarum : Disposable { /** * To be used with physics simulator. This is a magic number. */ - const val PHYS_TIME_FRAME: Double = 26.0 + (2.0 / 3.0) + const val PHYS_TIME_FRAME: Double = METER // 26.0 + (2.0 / 3.0) // lower value == faster gravity response (IT WON'T HOTSWAP!!) // protip: using METER, game unit and SI unit will have same number @@ -973,11 +974,15 @@ inline fun Disposable.tryDispose() { } fun distBetweenActors(a: ActorWithBody, b: ActorWithBody): Double { + return distBetweenPoints(a.centrePosVector, b.centrePosVector) +} + +fun distBetweenPoints(a: Vector2, b: Vector2): Double { val ww = INGAME.world.width * TILE_SIZED - val apos1 = a.centrePosVector + val apos1 = a val apos2 = Vector2(apos1.x + ww, apos1.y) val apos3 = Vector2(apos1.x - ww, apos1.y) - val bpos = b.centrePosVector + val bpos = b val dist = min(min(bpos.distanceSquared(apos1), bpos.distanceSquared(apos2)), bpos.distanceSquared(apos3)) return dist.sqrt() } diff --git a/src/net/torvald/terrarum/audio/AudioProcessBuf.kt b/src/net/torvald/terrarum/audio/AudioProcessBuf.kt index 02103457f..dc0dac5ea 100644 --- a/src/net/torvald/terrarum/audio/AudioProcessBuf.kt +++ b/src/net/torvald/terrarum/audio/AudioProcessBuf.kt @@ -113,8 +113,8 @@ class AudioProcessBuf(val inputSamplingRate: Int, val audioReadFun: (ByteArray) private val finL = FloatArray(fetchSize + 2 * PADSIZE) private val finR = FloatArray(fetchSize + 2 * PADSIZE) - private val fmidL = FloatArray((fetchSize / q + 1.0).toInt()) - private val fmidR = FloatArray((fetchSize / q + 1.0).toInt()) + private val fmidL = FloatArray((fetchSize / q + 1.0).toInt() * 2) + private val fmidR = FloatArray((fetchSize / q + 1.0).toInt() * 2) private val foutL = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4 private val foutR = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4 private val readBuf = ByteArray(fetchSize * 4) diff --git a/src/net/torvald/terrarum/audio/MixerTrackProcessor.kt b/src/net/torvald/terrarum/audio/MixerTrackProcessor.kt index 934324ac8..f62aafa7c 100644 --- a/src/net/torvald/terrarum/audio/MixerTrackProcessor.kt +++ b/src/net/torvald/terrarum/audio/MixerTrackProcessor.kt @@ -2,16 +2,16 @@ package net.torvald.terrarum.audio import com.badlogic.gdx.utils.Queue import net.torvald.reflection.forceInvoke -import net.torvald.terrarum.App +import net.torvald.terrarum.* +import net.torvald.terrarum.audio.AudioMixer.Companion.SPEED_OF_SOUND_AIR import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED import net.torvald.terrarum.audio.dsp.BinoPan import net.torvald.terrarum.audio.dsp.Lowpass import net.torvald.terrarum.audio.dsp.NullFilter -import net.torvald.terrarum.distBetweenActors import net.torvald.terrarum.gameactors.ActorWithBody -import net.torvald.terrarum.relativeXposition -import net.torvald.terrarum.sqr +import net.torvald.terrarum.gameactors.ActorWithBody.Companion.GAME_TO_SI_VELO +import org.dyn4j.geometry.Vector2 import kotlin.math.* /** @@ -136,7 +136,19 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud (SAMPLING_RATED*0.5) / (24.0 * (distFromActor / distFalloff).sqr() + 1.0) ) -// printdbg("dist=$distFromActor\tvol=${fullscaleToDecibels(vol)}\tcutoff=${(track.filters[1] as Lowpass).cutoff}") + val sourceVec = (track.trackingTarget as ActorWithBody).let { it.externalV + (it.controllerV ?: Vector2()) } + val listenerVec = App.audioMixer.actorNowPlaying!!.let { it.externalV + (it.controllerV ?: Vector2()) } + val distFromActorNext = distBetweenPoints( + App.audioMixer.actorNowPlaying!!.centrePosVector + listenerVec, + (track.trackingTarget as ActorWithBody).centrePosVector + sourceVec + ) + val isApproaching = if (distFromActorNext <= distFromActor) 1.0 else -1.0 + val relativeSpeed = (sourceVec - listenerVec).magnitude * GAME_TO_SI_VELO * isApproaching + val dopplerFactor = (SPEED_OF_SOUND_AIR + relativeSpeed) / SPEED_OF_SOUND_AIR // >1: speedup, <1: speeddown + + track.processor.streamBuf?.playbackSpeed = dopplerFactor.toFloat() + +// printdbg("dist=$distFromActor\tvol=${fullscaleToDecibels(vol)}\tcutoff=${(track.filters[1] as Lowpass).cutoff}\tdopplerFactor=$dopplerFactor") } } else { diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index f7f429442..73e5ab3bb 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -2124,15 +2124,20 @@ open class ActorWithBody : Actor { */ @Transient const val SI_TO_GAME_ACC = METER / (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME) /** - * [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame] + * [m / s] * SI_TO_GAME_VEL0 -> [px / InternalFrame] */ - @Transient const val SI_TO_GAME_VEL = METER / Terrarum.PHYS_TIME_FRAME + @Transient const val SI_TO_GAME_VELO = METER / Terrarum.PHYS_TIME_FRAME /** * [px / InternalFrame^2] * GAME_TO_SI_ACC -> [m / s^2] */ @Transient const val GAME_TO_SI_ACC = (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME) / METER + /** + * [px / InternalFrame] * GAME_TO_SI_VELO -> [m / s] + */ + @Transient const val GAME_TO_SI_VELO = Terrarum.PHYS_TIME_FRAME / METER + @Transient const val PHYS_EPSILON_DIST = 1.0 / 4096.0 @Transient const val PHYS_EPSILON_VELO = 1.0 / 65536.0