mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
doppler effect
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user