mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 20:44:05 +09:00
dynamic source tracking vol and lowpass and shits
This commit is contained in:
@@ -216,6 +216,7 @@ object AudioMixer: Disposable {
|
|||||||
|
|
||||||
dynamicTracks.forEach {
|
dynamicTracks.forEach {
|
||||||
it.filters[0] = BinoPan(0f)
|
it.filters[0] = BinoPan(0f)
|
||||||
|
it.filters[1] = Lowpass(SAMPLING_RATE / 2f)
|
||||||
sfxSumBus.addSidechainInput(it, 1.0)
|
sfxSumBus.addSidechainInput(it, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package net.torvald.terrarum.audio
|
package net.torvald.terrarum.audio
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Queue
|
import com.badlogic.gdx.utils.Queue
|
||||||
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.reflection.forceInvoke
|
import net.torvald.reflection.forceInvoke
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
|
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.BinoPan
|
||||||
|
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.distBetweenActors
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
@@ -37,7 +41,7 @@ class MixerTrackProcessor(val buffertaille: Int, val rate: Int, val track: Terra
|
|||||||
|
|
||||||
private var breakBomb = false
|
private var breakBomb = false
|
||||||
|
|
||||||
private val distFalloff = 1536.0
|
private val distFalloff = 1600.0
|
||||||
|
|
||||||
private fun printdbg(msg: Any) {
|
private fun printdbg(msg: Any) {
|
||||||
if (true) App.printdbg("AudioAdapter ${track.name}", msg)
|
if (true) App.printdbg("AudioAdapter ${track.name}", msg)
|
||||||
@@ -109,16 +113,22 @@ class MixerTrackProcessor(val buffertaille: Int, val rate: Int, val track: Terra
|
|||||||
if (track.trackingTarget == null || track.trackingTarget == AudioMixer.actorNowPlaying) {
|
if (track.trackingTarget == null || track.trackingTarget == AudioMixer.actorNowPlaying) {
|
||||||
track.volume = track.maxVolume
|
track.volume = track.maxVolume
|
||||||
(track.filters[0] as BinoPan).pan = 0f
|
(track.filters[0] as BinoPan).pan = 0f
|
||||||
|
(track.filters[1] as Lowpass).setCutoff(SAMPLING_RATE / 2f)
|
||||||
}
|
}
|
||||||
else if (track.trackingTarget is ActorWithBody) {
|
else if (track.trackingTarget is ActorWithBody) {
|
||||||
val relativeXpos = relativeXposition(AudioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody)
|
val relativeXpos = relativeXposition(AudioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody)
|
||||||
val distFromActor = distBetweenActors(AudioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody)
|
val distFromActor = distBetweenActors(AudioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody)
|
||||||
track.volume = track.maxVolume * getVolFun(distFromActor / distFalloff).coerceAtLeast(0.0)
|
val vol = track.maxVolume * getVolFun(distFromActor / distFalloff).coerceAtLeast(0.0)
|
||||||
|
track.volume = vol
|
||||||
(track.filters[0] as BinoPan).pan =
|
(track.filters[0] as BinoPan).pan =
|
||||||
if (relativeXpos <= -distFalloff) -1f
|
if (relativeXpos <= -distFalloff) -1f
|
||||||
else if (relativeXpos >= distFalloff) 1f
|
else if (relativeXpos >= distFalloff) 1f
|
||||||
else ((2*asin(relativeXpos / distFalloff)) / Math.PI).toFloat()
|
else ((2*asin(relativeXpos / distFalloff)) / Math.PI).toFloat()
|
||||||
// TODO lowpass filter by dist
|
(track.filters[1] as Lowpass).setCutoff(
|
||||||
|
(SAMPLING_RATED*0.5) / (24.0 * (distFromActor / distFalloff).sqr() + 1.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
// printdbg("dist=$distFromActor\tvol=${fullscaleToDecibels(vol)}\tcutoff=${(track.filters[1] as Lowpass).cutoff}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,12 +247,20 @@ class MixerTrackProcessor(val buffertaille: Int, val rate: Int, val track: Terra
|
|||||||
// } // uncomment to multithread
|
// } // uncomment to multithread
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.desmos.com/calculator/blcd4s69gl
|
|
||||||
private fun getVolFun(x: Double): Double {
|
private fun getVolFun(x: Double): Double {
|
||||||
|
// https://www.desmos.com/calculator/blcd4s69gl
|
||||||
// val K = 1.225
|
// val K = 1.225
|
||||||
// fun q(x: Double) = if (x >= 1.0) 0.5 else (K*x - K).pow(2.0) + 0.5
|
// fun q(x: Double) = if (x >= 1.0) 0.5 else (K*x - K).pow(2.0) + 0.5
|
||||||
// val x2 = x.pow(q(x))
|
// val x2 = x.pow(q(x))
|
||||||
return decibelsToFullscale(-20.0 * x)
|
|
||||||
|
// method 1.
|
||||||
|
//https://www.desmos.com/calculator/uzbjw10lna
|
||||||
|
val K = 512.0
|
||||||
|
return K.pow(-sqrt(1.0+x.sqr())) * K
|
||||||
|
|
||||||
|
|
||||||
|
// method 2.
|
||||||
|
// https://www.desmos.com/calculator/xxp5ipp85w
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FloatArray.applyVolume(volume: Float) = FloatArray(this.size) { (this[it] * volume) }
|
private fun FloatArray.applyVolume(volume: Float) = FloatArray(this.size) { (this[it] * volume) }
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ class FixtureJukebox : Electric {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Transient private var discCurrentlyPlaying: Int? = null
|
@Transient private var discCurrentlyPlaying: Int? = null
|
||||||
|
@Transient private var musicNowPlaying: MusicContainer? = null
|
||||||
|
|
||||||
@Transient private val testMusic = ModMgr.getGdxFile("basegame", "audio/music/discs/01 Thousands of Shards.ogg").let {
|
@Transient private val testMusic = ModMgr.getGdxFile("basegame", "audio/music/discs/01 Thousands of Shards.ogg").let {
|
||||||
MusicContainer("Thousands of Shards", it.file(), Gdx.audio.newMusic(it)) {
|
MusicContainer("Thousands of Shards", it.file(), Gdx.audio.newMusic(it)) {
|
||||||
discCurrentlyPlaying = null
|
discCurrentlyPlaying = null
|
||||||
|
musicNowPlaying = null
|
||||||
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f)
|
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,13 +71,17 @@ class FixtureJukebox : Electric {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun playDisc(index: Int) {
|
private fun playDisc(index: Int) {
|
||||||
|
musicNowPlaying = testMusic // todo use index
|
||||||
|
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, DEFAULT_FADEOUT_LEN / 2f) {
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, DEFAULT_FADEOUT_LEN / 2f) {
|
||||||
startAudio(testMusic)
|
startAudio(musicNowPlaying!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transient override var despawnHook: (FixtureBase) -> Unit = {
|
@Transient override var despawnHook: (FixtureBase) -> Unit = {
|
||||||
|
musicNowPlaying?.let { stopAudio(it) }
|
||||||
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f)
|
(INGAME.musicGovernor as TerrarumMusicGovernor).stopMusic(pauseLen = Math.random().toFloat() * 30f + 30f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +89,7 @@ class FixtureJukebox : Electric {
|
|||||||
super.reload()
|
super.reload()
|
||||||
// cannot resume playback, just stop the music
|
// cannot resume playback, just stop the music
|
||||||
discCurrentlyPlaying = null
|
discCurrentlyPlaying = null
|
||||||
|
musicNowPlaying = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
|
|||||||
Reference in New Issue
Block a user