reloading the engine will copy track states from the old instance, obsoleting audioMixerRenewHooks

This commit is contained in:
minjaesong
2024-01-16 14:00:58 +09:00
parent f05cfe3cbb
commit 07c70a42f3
17 changed files with 106 additions and 10 deletions

View File

@@ -13,7 +13,6 @@ import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.GdxRuntimeException; import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.JsonValue; import com.badlogic.gdx.utils.JsonValue;
import com.github.strikerx3.jxinput.XInputDevice; import com.github.strikerx3.jxinput.XInputDevice;
import kotlin.jvm.functions.Function0;
import kotlin.text.Charsets; import kotlin.text.Charsets;
import net.torvald.getcpuname.GetCpuName; import net.torvald.getcpuname.GetCpuName;
import net.torvald.terrarum.audio.AudioMixer; import net.torvald.terrarum.audio.AudioMixer;
@@ -1060,7 +1059,7 @@ public class App implements ApplicationListener {
* Make sure to call App.audioMixerRenewHooks.remove(Object) whenever the class gets disposed of * Make sure to call App.audioMixerRenewHooks.remove(Object) whenever the class gets disposed of
* Key: the class that calls the hook, value: the actual operation (function) * Key: the class that calls the hook, value: the actual operation (function)
*/ */
public static HashMap<Object, Function0> audioMixerRenewHooks = new HashMap<>(); //public static HashMap<Object, Function0> audioMixerRenewHooks = new HashMap<>();
/** /**
* Init stuffs which needs GL context * Init stuffs which needs GL context
@@ -1242,24 +1241,39 @@ public class App implements ApplicationListener {
} }
public static void renewAudioProcessor(int bufferSize) { public static void renewAudioProcessor(int bufferSize) {
// copy music tracks
var dynaicTracks = audioMixer.getDynamicTracks();
var staticTracks = audioMixer.getTracks();
audioManagerThread.interrupt(); audioManagerThread.interrupt();
audioMixer.dispose(); audioMixer.dispose();
audioBufferSize = bufferSize; audioBufferSize = bufferSize;
audioMixer = new AudioMixer(audioBufferSize); audioMixer = new AudioMixer(audioBufferSize);
// paste music tracks
for (int i = 0; i < audioMixer.getDynamicTracks().length; i++) {
var track = audioMixer.getDynamicTracks()[i];
dynaicTracks[i].copyStatusFrom(track);
}
for (int i = 0; i < audioMixer.getTracks().length; i++) {
var track = audioMixer.getTracks()[i];
staticTracks[i].copyStatusFrom(track);
}
audioManagerThread = new Thread(new AudioManagerRunnable(audioMixer), "TerrarumAudioManager"); audioManagerThread = new Thread(new AudioManagerRunnable(audioMixer), "TerrarumAudioManager");
audioManagerThread.setPriority(MAX_PRIORITY); // higher = more predictable; audio delay is very noticeable so it gets high priority audioManagerThread.setPriority(MAX_PRIORITY); // higher = more predictable; audio delay is very noticeable so it gets high priority
audioManagerThread.start(); audioManagerThread.start();
for (var it : audioMixerRenewHooks.values()) { /*for (var it : audioMixerRenewHooks.values()) {
try { try {
it.invoke(); it.invoke();
} }
catch (Throwable e) { catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
} }*/
} }

View File

@@ -506,6 +506,7 @@ class AudioMixer(val bufferSize: Int): Disposable {
// feeder.stop() // feeder.stop()
// feedingThread.join() // feedingThread.join()
tracks.forEach { it.tryDispose() } tracks.forEach { it.tryDispose() }
dynamicTracks.forEach { it.tryDispose() }
masterTrack.tryDispose() masterTrack.tryDispose()
} }
} }

View File

@@ -61,7 +61,23 @@ class TerrarumAudioMixerTrack(
var trackingTarget: Actor? = null var trackingTarget: Actor? = null
var playStartedTime = 0L; private set internal var streamPlaying = false
var playStartedTime = 0L; internal set
fun copyStatusFrom(other: TerrarumAudioMixerTrack) {
other.pullNextTrack = this.pullNextTrack
other.currentTrack = this.currentTrack
other.nextTrack = this.nextTrack
other.volume = this.volume
other.trackingTarget = this.trackingTarget
other.streamPlaying = this.streamPlaying
other.playStartedTime = this.playStartedTime
filters.indices.forEach { i ->
other.filters[i].copyParamsFrom(this.filters[i])
}
}
inline fun <reified T> getFilter() = filters.filterIsInstance<T>().first()!! inline fun <reified T> getFilter() = filters.filterIsInstance<T>().first()!!
inline fun <reified T> getFilterOrNull() = filters.filterIsInstance<T>().firstOrNull() inline fun <reified T> getFilterOrNull() = filters.filterIsInstance<T>().firstOrNull()
@@ -119,7 +135,6 @@ class TerrarumAudioMixerTrack(
} }
internal var streamPlaying = false
fun play() { fun play() {
playStartedTime = System.nanoTime() playStartedTime = System.nanoTime()
streamPlaying = true streamPlaying = true

View File

@@ -140,4 +140,11 @@ class BinoPan(var pan: Float, var earDist: Float = EARDIST_DEFAULT): TerrarumAud
} }
override val debugViewHeight = 32 override val debugViewHeight = 32
override fun copyParamsFrom(other: TerrarumAudioFilter) {
if (other is BinoPan) {
this.pan = other.pan
this.earDist = other.earDist
}
}
} }

View File

@@ -35,4 +35,11 @@ class Bitcrush(var steps: Int, var inputGain: Float = 1f): TerrarumAudioFilter()
} }
override val debugViewHeight = 16 override val debugViewHeight = 16
override fun copyParamsFrom(other: TerrarumAudioFilter) {
if (other is Bitcrush) {
this.steps = other.steps
this.inputGain = other.inputGain
}
}
} }

View File

@@ -19,4 +19,7 @@ object Buffer : TerrarumAudioFilter() {
} }
override val debugViewHeight = 16 override val debugViewHeight = 16
override fun copyParamsFrom(other: TerrarumAudioFilter) {
}
} }

View File

@@ -155,4 +155,7 @@ class Convolv(ir: File, val crossfeed: Float, gain: Float = 1f / 256f): Terrarum
} }
override val debugViewHeight = 32 override val debugViewHeight = 32
override fun copyParamsFrom(other: TerrarumAudioFilter) {
}
} }

View File

@@ -20,4 +20,10 @@ class Gain(var gain: Float): TerrarumAudioFilter() {
} }
override val debugViewHeight = 16 override val debugViewHeight = 16
override fun copyParamsFrom(other: TerrarumAudioFilter) {
if (other is Gain) {
this.gain = other.gain
}
}
} }

View File

@@ -67,4 +67,10 @@ class Highpass(cutoff0: Float): TerrarumAudioFilter() {
} }
override val debugViewHeight = 16 override val debugViewHeight = 16
override fun copyParamsFrom(other: TerrarumAudioFilter) {
if (other is Highpass) {
setCutoff(other.cutoff)
}
}
} }

View File

@@ -67,4 +67,10 @@ class Lowpass(cutoff0: Float): TerrarumAudioFilter() {
} }
override val debugViewHeight = 16 override val debugViewHeight = 16
override fun copyParamsFrom(other: TerrarumAudioFilter) {
if (other is Lowpass) {
setCutoff(other.cutoff)
}
}
} }

View File

@@ -13,4 +13,7 @@ object NullFilter : TerrarumAudioFilter() {
} }
override val debugViewHeight = 0 override val debugViewHeight = 0
override fun copyParamsFrom(other: TerrarumAudioFilter) {
}
} }

View File

@@ -53,4 +53,7 @@ class Reverb(val delayMS: Float = 36f, var feedback: Float = 0.92f, var lowpass:
} }
override val debugViewHeight = 0 override val debugViewHeight = 0
override fun copyParamsFrom(other: TerrarumAudioFilter) {
}
} }

View File

@@ -56,4 +56,7 @@ object SoftClp : TerrarumAudioFilter() {
} }
override val debugViewHeight = 0 override val debugViewHeight = 0
override fun copyParamsFrom(other: TerrarumAudioFilter) {
}
} }

View File

@@ -11,7 +11,7 @@ import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.STRIP_W
import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.Toolkit
import kotlin.math.* import kotlin.math.*
class Spectro(val gain: Float = 1f) : TerrarumAudioFilter() { class Spectro(var gain: Float = 1f) : TerrarumAudioFilter() {
private val FFTSIZE = 1024 private val FFTSIZE = 1024
private val inBuf = Array(2) { FloatArray(FFTSIZE) } private val inBuf = Array(2) { FloatArray(FFTSIZE) }
@@ -91,10 +91,16 @@ class Spectro(val gain: Float = 1f) : TerrarumAudioFilter() {
} }
override val debugViewHeight = STRIP_W override val debugViewHeight = STRIP_W
override fun copyParamsFrom(other: TerrarumAudioFilter) {
if (other is Spectro) {
this.gain = other.gain
}
}
} }
class Vecto(val gain: Float = 1f) : TerrarumAudioFilter() { class Vecto(var gain: Float = 1f) : TerrarumAudioFilter() {
var backbufL = Array((6144f / App.audioBufferSize).roundToInt().coerceAtLeast(1)) { var backbufL = Array((6144f / App.audioBufferSize).roundToInt().coerceAtLeast(1)) {
FloatArray(App.audioBufferSize) FloatArray(App.audioBufferSize)
} }
@@ -154,4 +160,10 @@ class Vecto(val gain: Float = 1f) : TerrarumAudioFilter() {
} }
override val debugViewHeight = STRIP_W override val debugViewHeight = STRIP_W
override fun copyParamsFrom(other: TerrarumAudioFilter) {
if (other is Vecto) {
this.gain = other.gain
}
}
} }

View File

@@ -15,6 +15,7 @@ abstract class TerrarumAudioFilter {
} }
abstract fun drawDebugView(batch: SpriteBatch, x: Int, y: Int) abstract fun drawDebugView(batch: SpriteBatch, x: Int, y: Int)
abstract val debugViewHeight: Int abstract val debugViewHeight: Int
abstract fun copyParamsFrom(other: TerrarumAudioFilter)
} }
fun FloatArray.applyGain(gain: Float = 1f) = this.map { it * gain }.toFloatArray() fun FloatArray.applyGain(gain: Float = 1f) = this.map { it * gain }.toFloatArray()

View File

@@ -19,6 +19,9 @@ object XYtoMS: TerrarumAudioFilter() {
} }
override val debugViewHeight = 0 override val debugViewHeight = 0
override fun copyParamsFrom(other: TerrarumAudioFilter) {
}
} }
object MStoXY: TerrarumAudioFilter() { object MStoXY: TerrarumAudioFilter() {
@@ -37,4 +40,7 @@ object MStoXY: TerrarumAudioFilter() {
} }
override val debugViewHeight = 0 override val debugViewHeight = 0
override fun copyParamsFrom(other: TerrarumAudioFilter) {
}
} }

View File

@@ -69,7 +69,7 @@ class FixtureJukebox : Electric {
} }
App.audioMixerRenewHooks[this] = { stopGracefully() } // App.audioMixerRenewHooks[this] = { stopGracefully() }
} }
override val canBeDespawned: Boolean override val canBeDespawned: Boolean
@@ -177,7 +177,7 @@ class FixtureJukebox : Electric {
} }
override fun dispose() { override fun dispose() {
App.audioMixerRenewHooks.remove(this) // App.audioMixerRenewHooks.remove(this)
super.dispose() super.dispose()
// testMusic.gdxMusic.dispose() // testMusic.gdxMusic.dispose()
} }