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.Actor
import net.torvald.terrarum.gameactors.ActorID import net.torvald.terrarum.gameactors.ActorID
import net.torvald.terrarum.gameactors.ActorWithBody 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.gameactors.faction.FactionCodex
import net.torvald.terrarum.gameworld.fmod import net.torvald.terrarum.gameworld.fmod
import net.torvald.terrarum.itemproperties.CraftingCodex import net.torvald.terrarum.itemproperties.CraftingCodex
@@ -91,7 +92,7 @@ object Terrarum : Disposable {
/** /**
* To be used with physics simulator. This is a magic number. * 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!!) // 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 // 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 { 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 ww = INGAME.world.width * TILE_SIZED
val apos1 = a.centrePosVector val apos1 = a
val apos2 = Vector2(apos1.x + ww, apos1.y) val apos2 = Vector2(apos1.x + ww, apos1.y)
val apos3 = 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)) val dist = min(min(bpos.distanceSquared(apos1), bpos.distanceSquared(apos2)), bpos.distanceSquared(apos3))
return dist.sqrt() 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 finL = FloatArray(fetchSize + 2 * PADSIZE)
private val finR = FloatArray(fetchSize + 2 * PADSIZE) private val finR = FloatArray(fetchSize + 2 * PADSIZE)
private val fmidL = 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()) 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 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 foutR = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
private val readBuf = ByteArray(fetchSize * 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 com.badlogic.gdx.utils.Queue
import net.torvald.reflection.forceInvoke 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_RATE
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED
import net.torvald.terrarum.audio.dsp.BinoPan import net.torvald.terrarum.audio.dsp.BinoPan
import net.torvald.terrarum.audio.dsp.Lowpass import net.torvald.terrarum.audio.dsp.Lowpass
import net.torvald.terrarum.audio.dsp.NullFilter import net.torvald.terrarum.audio.dsp.NullFilter
import net.torvald.terrarum.distBetweenActors
import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.relativeXposition import net.torvald.terrarum.gameactors.ActorWithBody.Companion.GAME_TO_SI_VELO
import net.torvald.terrarum.sqr import org.dyn4j.geometry.Vector2
import kotlin.math.* 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) (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 { 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) @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] * [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 @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_DIST = 1.0 / 4096.0
@Transient const val PHYS_EPSILON_VELO = 1.0 / 65536.0 @Transient const val PHYS_EPSILON_VELO = 1.0 / 65536.0