doppler effect

This commit is contained in:
minjaesong
2024-01-21 03:23:25 +09:00
parent f34a6b7c9f
commit 3da37408a2
4 changed files with 34 additions and 12 deletions

View File

@@ -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()
}

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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