sound track cacheing by track to remove any collision

This commit is contained in:
minjaesong
2024-04-02 17:15:23 +09:00
parent 918276a1be
commit 94152afcac
6 changed files with 55 additions and 10 deletions

View File

@@ -1971,7 +1971,7 @@ public class App implements ApplicationListener {
public static void playGUIsound(MusicContainer sound, double volume, float pan) { public static void playGUIsound(MusicContainer sound, double volume, float pan) {
if (!highPrioritySoundPlaying) { if (!highPrioritySoundPlaying) {
var it = audioMixer.getFreeGuiTrackNoMatterWhat(); var it = audioMixer.getFreeGuiTrack();
if (it != null) { if (it != null) {
it.stop(); it.stop();
it.setCurrentTrack(sound); it.setCurrentTrack(sound);

View File

@@ -1,6 +1,5 @@
package net.torvald.terrarum.audio package net.torvald.terrarum.audio
import net.torvald.reflection.forceInvoke
import net.torvald.terrarum.* import net.torvald.terrarum.*
import net.torvald.terrarum.audio.AudioMixer.Companion.DS_FLTIDX_LOW import net.torvald.terrarum.audio.AudioMixer.Companion.DS_FLTIDX_LOW
import net.torvald.terrarum.audio.AudioMixer.Companion.DS_FLTIDX_PAN import net.torvald.terrarum.audio.AudioMixer.Companion.DS_FLTIDX_PAN
@@ -13,7 +12,9 @@ import net.torvald.terrarum.audio.dsp.NullFilter
import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.gameactors.ActorWithBody.Companion.GAME_TO_SI_VELO import net.torvald.terrarum.gameactors.ActorWithBody.Companion.GAME_TO_SI_VELO
import org.dyn4j.geometry.Vector2 import org.dyn4j.geometry.Vector2
import kotlin.math.* import kotlin.math.absoluteValue
import kotlin.math.cosh
import kotlin.math.sqrt
/** /**
* Created by minjaesong on 2023-11-17. * Created by minjaesong on 2023-11-17.

View File

@@ -0,0 +1,21 @@
package net.torvald.terrarum.audio
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.tryDispose
class MusicCache(val trackName: String) : Disposable {
private val cache = HashMap<String, MusicContainer>()
fun getOrPut(music: MusicContainer?): MusicContainer? {
if (music != null && music.toRAM) { // for now only the on-the-RAM tracks are getting cached
println("Cacheing music ${music.name} for track $trackName")
return cache.getOrPut(music.name) { music.makeCopy() }
}
else return null
}
override fun dispose() {
cache.values.forEach { it.tryDispose() }
}
}

View File

@@ -29,7 +29,7 @@ data class MusicContainer(
val codec: String val codec: String
var samplesReadCount = 0L; internal set var samplesReadCount = 0L; internal set
val samplesTotal: Long var samplesTotal: Long
private val gdxMusic: Music = Gdx.audio.newMusic(FileHandle(file)) private val gdxMusic: Music = Gdx.audio.newMusic(FileHandle(file))
@@ -185,4 +185,22 @@ data class MusicContainer(
gdxMusic.dispose() gdxMusic.dispose()
soundBuf?.destroy() soundBuf?.destroy()
} }
fun makeCopy(): MusicContainer {
val new = MusicContainer(name, file, looping, false, songFinishedHook)
synchronized(this) {
if (this.toRAM) {
// perform unsafe memcpy
new.soundBuf = UnsafeHelper.allocate(this.soundBuf!!.size)
UnsafeHelper.memcpy(this.soundBuf!!, 0L, new.soundBuf!!, 0L, new.soundBuf!!.size)
// set toRAM flag
val toRamField = new.javaClass.getDeclaredField("toRAM")
UnsafeHelper.unsafe.putBoolean(new, UnsafeHelper.unsafe.objectFieldOffset(toRamField), true)
}
}
return new
}
} }

View File

@@ -43,7 +43,14 @@ class TerrarumAudioMixerTrack(
} }
var currentTrack: MusicContainer? = null var currentTrack: MusicContainer? = null
set(value) {
field = musicCache.getOrPut(value)
}
var nextTrack: MusicContainer? = null var nextTrack: MusicContainer? = null
set(value) {
field = musicCache.getOrPut(value)
}
var volume: TrackVolume = 1.0 var volume: TrackVolume = 1.0
get() = field get() = field
@@ -66,11 +73,14 @@ class TerrarumAudioMixerTrack(
var playStartedTime = 0L; internal set var playStartedTime = 0L; internal set
var checkedOutTime = 0L; internal set var checkedOutTime = 0L; internal set
private var musicCache = MusicCache(name)
fun copyStatusTo(other: TerrarumAudioMixerTrack) { fun copyStatusTo(other: TerrarumAudioMixerTrack) {
other.pullNextTrack = this.pullNextTrack other.pullNextTrack = this.pullNextTrack
other.currentTrack = this.currentTrack other.currentTrack = this.currentTrack
other.nextTrack = this.nextTrack other.nextTrack = this.nextTrack
other.volume = this.volume other.volume = this.volume
other.musicCache = this.musicCache
other.trackingTarget = this.trackingTarget other.trackingTarget = this.trackingTarget
other.streamPlaying.set(this.streamPlaying.get()) other.streamPlaying.set(this.streamPlaying.get())
other.playStartedTime = this.playStartedTime other.playStartedTime = this.playStartedTime
@@ -156,6 +166,7 @@ class TerrarumAudioMixerTrack(
processor.stop() processor.stop()
processorThread.join()*/ processorThread.join()*/
adev?.dispose() adev?.dispose()
musicCache.dispose()
} }
override fun equals(other: Any?) = this.hash == (other as TerrarumAudioMixerTrack).hash override fun equals(other: Any?) = this.hash == (other as TerrarumAudioMixerTrack).hash

View File

@@ -1,14 +1,8 @@
package net.torvald.terrarum.audio.dsp package net.torvald.terrarum.audio.dsp
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.reflection.forceInvoke
import net.torvald.terrarum.App import net.torvald.terrarum.App
import net.torvald.terrarum.audio.AudioHelper import net.torvald.terrarum.audio.AudioHelper
import net.torvald.terrarum.audio.AudioProcessBuf.Companion.MP3_CHUNK_SIZE
import net.torvald.terrarum.audio.decibelsToFullscale
import net.torvald.terrarum.serialise.toUint
import java.io.File
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
import kotlin.math.tanh import kotlin.math.tanh