mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 10:34:06 +09:00
mixer overlay
This commit is contained in:
@@ -51,6 +51,7 @@ import java.io.IOException;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static java.lang.Thread.MAX_PRIORITY;
|
||||||
import static net.torvald.terrarum.TerrarumKt.*;
|
import static net.torvald.terrarum.TerrarumKt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1192,6 +1193,7 @@ public class App implements ApplicationListener {
|
|||||||
|
|
||||||
AudioMixer.INSTANCE.getMasterVolume();
|
AudioMixer.INSTANCE.getMasterVolume();
|
||||||
audioManagerThread = new Thread(new AudioManagerRunnable(), "TerrarumAudioManager");
|
audioManagerThread = new Thread(new AudioManagerRunnable(), "TerrarumAudioManager");
|
||||||
|
audioManagerThread.setPriority(MAX_PRIORITY); // higher = more predictable; audio delay is very noticeable so it gets high priority
|
||||||
audioManagerThread.start();
|
audioManagerThread.start();
|
||||||
|
|
||||||
Terrarum.initialise();
|
Terrarum.initialise();
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import com.badlogic.gdx.backends.lwjgl3.audio.Lwjgl3Audio
|
|||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.terrarum.App
|
import net.torvald.terrarum.App
|
||||||
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.INDEX_AMB
|
||||||
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.INDEX_BGM
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF
|
||||||
import net.torvald.terrarum.modulebasegame.MusicContainer
|
import net.torvald.terrarum.modulebasegame.MusicContainer
|
||||||
@@ -27,22 +29,23 @@ object AudioMixer: Disposable {
|
|||||||
|
|
||||||
/** Returns a (master volume * bgm volume) */
|
/** Returns a (master volume * bgm volume) */
|
||||||
val musicVolume: Double
|
val musicVolume: Double
|
||||||
get() = (App.getConfigDouble("bgmvolume") * App.getConfigDouble("mastervolume"))
|
get() = App.getConfigDouble("bgmvolume")
|
||||||
|
|
||||||
/** Returns a (master volume * sfx volume */
|
/** Returns a (master volume * sfx volume */
|
||||||
val ambientVolume: Double
|
val ambientVolume: Double
|
||||||
get() = (App.getConfigDouble("sfxvolume") * App.getConfigDouble("mastervolume"))
|
get() = App.getConfigDouble("sfxvolume")
|
||||||
|
|
||||||
|
|
||||||
val tracks = Array(10) { TerrarumAudioMixerTrack(
|
val tracks = Array(10) { TerrarumAudioMixerTrack(
|
||||||
if (it == 0) "BGM Track"
|
if (it == 0) "BGM"
|
||||||
else if (it == 1) "AMB Track"
|
else if (it == 1) "AMB"
|
||||||
else "Audio Track #${it+1}"
|
else "Trk${it+1}"
|
||||||
) }
|
) }
|
||||||
|
|
||||||
val masterTrack = TerrarumAudioMixerTrack("Master", true).also { master ->
|
val masterTrack = TerrarumAudioMixerTrack("Master", true).also { master ->
|
||||||
tracks.forEach { master.addSidechainInput(it, 1.0) }
|
master.volume = masterVolume
|
||||||
master.filters[0] = Buffer
|
master.filters[0] = Buffer
|
||||||
|
tracks.forEachIndexed { i, it -> master.addSidechainInput(it, if (i == INDEX_BGM) musicVolume else if (i == INDEX_AMB) ambientVolume else 1.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val musicTrack: TerrarumAudioMixerTrack
|
val musicTrack: TerrarumAudioMixerTrack
|
||||||
@@ -59,6 +62,8 @@ object AudioMixer: Disposable {
|
|||||||
private var fadeLength = DEFAULT_FADEOUT_LEN
|
private var fadeLength = DEFAULT_FADEOUT_LEN
|
||||||
private var fadeoutFired = false
|
private var fadeoutFired = false
|
||||||
private var fadeinFired = false
|
private var fadeinFired = false
|
||||||
|
private var fadeTarget = 0.0
|
||||||
|
private var fadeStart = 0.0
|
||||||
|
|
||||||
private var lpAkku = 0.0
|
private var lpAkku = 0.0
|
||||||
private var lpLength = 0.4
|
private var lpLength = 0.4
|
||||||
@@ -75,24 +80,28 @@ object AudioMixer: Disposable {
|
|||||||
|
|
||||||
if (fadeoutFired) {
|
if (fadeoutFired) {
|
||||||
fadeAkku += delta
|
fadeAkku += delta
|
||||||
musicTrack.volume = (musicVolume * (1.0 - (fadeAkku / fadeLength))).coerceIn(0.0, 1.0)
|
val step = fadeAkku / fadeLength
|
||||||
|
musicTrack.volume = FastMath.interpolateLinear(step, fadeStart, fadeTarget)
|
||||||
|
|
||||||
if (fadeAkku >= fadeLength) {
|
if (fadeAkku >= fadeLength) {
|
||||||
fadeoutFired = false
|
fadeoutFired = false
|
||||||
musicTrack.volume = 0.0
|
musicTrack.volume = fadeTarget
|
||||||
musicTrack.currentTrack = null
|
|
||||||
|
if (fadeTarget == 0.0)
|
||||||
|
musicTrack.currentTrack = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fadeinFired) {
|
else if (fadeinFired) {
|
||||||
fadeAkku += delta
|
fadeAkku += delta
|
||||||
musicTrack.volume = (musicVolume * (fadeAkku / fadeLength)).coerceIn(0.0, 1.0)
|
val step = fadeAkku / fadeLength
|
||||||
|
musicTrack.volume = FastMath.interpolateLinear(step, fadeStart, fadeTarget)
|
||||||
|
|
||||||
if (musicTrack.isPlaying == false) {
|
if (musicTrack.isPlaying == false) {
|
||||||
musicTrack.play()
|
musicTrack.play()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fadeAkku >= fadeLength) {
|
if (fadeAkku >= fadeLength) {
|
||||||
musicTrack.volume = musicVolume
|
musicTrack.volume = fadeTarget
|
||||||
fadeinFired = false
|
fadeinFired = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +109,7 @@ object AudioMixer: Disposable {
|
|||||||
|
|
||||||
if (lpOutFired) {
|
if (lpOutFired) {
|
||||||
lpAkku += delta
|
lpAkku += delta
|
||||||
val x = (lpAkku / lpLength).coerceIn(0.0, 1.0)
|
val x = lpAkku / lpLength
|
||||||
val q = 400.0
|
val q = 400.0
|
||||||
val step = (q.pow(x) - 1) / (q - 1) // https://www.desmos.com/calculator/sttaq2qhzm
|
val step = (q.pow(x) - 1) / (q - 1) // https://www.desmos.com/calculator/sttaq2qhzm
|
||||||
val cutoff = FastMath.interpolateLinear(step, SAMPLING_RATED / 100.0, SAMPLING_RATED)
|
val cutoff = FastMath.interpolateLinear(step, SAMPLING_RATED / 100.0, SAMPLING_RATED)
|
||||||
@@ -113,7 +122,7 @@ object AudioMixer: Disposable {
|
|||||||
}
|
}
|
||||||
else if (lpInFired) {
|
else if (lpInFired) {
|
||||||
lpAkku += delta
|
lpAkku += delta
|
||||||
val x = (lpAkku / lpLength).coerceIn(0.0, 1.0)
|
val x = lpAkku / lpLength
|
||||||
val q = 400.0
|
val q = 400.0
|
||||||
val step = log((q-1) * x + 1.0, q) // https://www.desmos.com/calculator/sttaq2qhzm
|
val step = log((q-1) * x + 1.0, q) // https://www.desmos.com/calculator/sttaq2qhzm
|
||||||
val cutoff = FastMath.interpolateLinear(step, SAMPLING_RATED, SAMPLING_RATED / 100.0)
|
val cutoff = FastMath.interpolateLinear(step, SAMPLING_RATED, SAMPLING_RATED / 100.0)
|
||||||
@@ -129,7 +138,7 @@ object AudioMixer: Disposable {
|
|||||||
if (musicTrack.isPlaying != true && musicTrack.nextTrack != null) {
|
if (musicTrack.isPlaying != true && musicTrack.nextTrack != null) {
|
||||||
// printdbg(this, "Playing next music: ${nextMusic!!.name}")
|
// printdbg(this, "Playing next music: ${nextMusic!!.name}")
|
||||||
musicTrack.queueNext(null)
|
musicTrack.queueNext(null)
|
||||||
musicTrack.volume = musicVolume
|
musicTrack.volume = 1.0
|
||||||
musicTrack.play()
|
musicTrack.play()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,19 +154,23 @@ object AudioMixer: Disposable {
|
|||||||
requestFadeOut(DEFAULT_FADEOUT_LEN)
|
requestFadeOut(DEFAULT_FADEOUT_LEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun requestFadeOut(length: Double) {
|
fun requestFadeOut(length: Double, target: Double = 0.0) {
|
||||||
if (!fadeoutFired) {
|
if (!fadeoutFired) {
|
||||||
fadeLength = length.coerceAtLeast(1.0/1024.0)
|
fadeLength = length.coerceAtLeast(1.0/1024.0)
|
||||||
fadeAkku = 0.0
|
fadeAkku = 0.0
|
||||||
fadeoutFired = true
|
fadeoutFired = true
|
||||||
|
fadeTarget = target
|
||||||
|
fadeStart = musicTrack.volume
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun requestFadeIn(length: Double) {
|
fun requestFadeIn(length: Double, target: Double = 1.0) {
|
||||||
if (!fadeinFired) {
|
if (!fadeinFired) {
|
||||||
fadeLength = length.coerceAtLeast(1.0/1024.0)
|
fadeLength = length.coerceAtLeast(1.0/1024.0)
|
||||||
fadeAkku = 0.0
|
fadeAkku = 0.0
|
||||||
fadeinFired = true
|
fadeinFired = true
|
||||||
|
fadeTarget = target
|
||||||
|
fadeStart = musicTrack.volume
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ 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.audio.AudioMixer.masterVolume
|
||||||
|
import net.torvald.terrarum.audio.AudioMixer.musicVolume
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
@@ -35,7 +37,8 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
if (true) println("[AudioAdapter ${track.name}] $msg")
|
if (true) println("[AudioAdapter ${track.name}] $msg")
|
||||||
}
|
}
|
||||||
override fun run() {
|
override fun run() {
|
||||||
while (running) { synchronized(pauseLock) {
|
while (running) {
|
||||||
|
synchronized(pauseLock) {
|
||||||
if (!running) { // may have changed while waiting to
|
if (!running) { // may have changed while waiting to
|
||||||
// synchronize on pauseLock
|
// synchronize on pauseLock
|
||||||
breakBomb = true
|
breakBomb = true
|
||||||
@@ -90,11 +93,11 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
|
|
||||||
if (track.isMaster) {
|
if (track.isMaster) {
|
||||||
// TEST CODE must combine all the inputs
|
// TEST CODE must combine all the inputs
|
||||||
track.sidechainInputs[0]?.let {
|
track.sidechainInputs[TerrarumAudioMixerTrack.INDEX_BGM]?.let {
|
||||||
samplesL0 = it.first.processor.fout0[0]
|
samplesL0 = it.first.processor.fout0[0].applyVolume(musicVolume)
|
||||||
samplesR0 = it.first.processor.fout0[1]
|
samplesR0 = it.first.processor.fout0[1].applyVolume(musicVolume)
|
||||||
samplesL1 = it.first.processor.fout1[0]
|
samplesL1 = it.first.processor.fout1[0].applyVolume(musicVolume)
|
||||||
samplesR1 = it.first.processor.fout1[1]
|
samplesR1 = it.first.processor.fout1[1].applyVolume(musicVolume)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -164,7 +167,6 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
|
|
||||||
// by this time, the output buffer is filled with processed results, pause the execution
|
// by this time, the output buffer is filled with processed results, pause the execution
|
||||||
if (!track.isMaster) {
|
if (!track.isMaster) {
|
||||||
|
|
||||||
this.pause()
|
this.pause()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -176,7 +178,9 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
}
|
}
|
||||||
|
|
||||||
// printdbg("PUSHE; Queue size: ${track.pcmQueue.size}")
|
// printdbg("PUSHE; Queue size: ${track.pcmQueue.size}")
|
||||||
track.pcmQueue.addLast(fout1)
|
val masvol = masterVolume
|
||||||
|
track.volume = masvol
|
||||||
|
track.pcmQueue.addLast(fout1.map { it.applyVolume(masvol) })
|
||||||
}
|
}
|
||||||
|
|
||||||
// spin
|
// spin
|
||||||
@@ -210,8 +214,11 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
pauseLock.notifyAll() // Unblocks thread
|
pauseLock.notifyAll() // Unblocks thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FloatArray.applyVolume(musicVolume: Double) = FloatArray(this.size) { (this[it] * musicVolume).toFloat() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun <T> Queue<T>.removeFirstOrElse(function: () -> T): T {
|
private fun <T> Queue<T>.removeFirstOrElse(function: () -> T): T {
|
||||||
return if (this.isEmpty) {
|
return if (this.isEmpty) {
|
||||||
this.removeFirst()
|
this.removeFirst()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.badlogic.gdx.utils.Queue
|
|||||||
import net.torvald.reflection.forceInvoke
|
import net.torvald.reflection.forceInvoke
|
||||||
import net.torvald.terrarum.getHashStr
|
import net.torvald.terrarum.getHashStr
|
||||||
import net.torvald.terrarum.modulebasegame.MusicContainer
|
import net.torvald.terrarum.modulebasegame.MusicContainer
|
||||||
|
import java.lang.Thread.MAX_PRIORITY
|
||||||
import kotlin.math.log10
|
import kotlin.math.log10
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
@@ -18,7 +19,10 @@ class TerrarumAudioMixerTrack(val name: String, val isMaster: Boolean = false):
|
|||||||
const val SAMPLING_RATE = 48000
|
const val SAMPLING_RATE = 48000
|
||||||
const val SAMPLING_RATEF = 48000f
|
const val SAMPLING_RATEF = 48000f
|
||||||
const val SAMPLING_RATED = 48000.0
|
const val SAMPLING_RATED = 48000.0
|
||||||
const val BUFFER_SIZE = 8000
|
const val BUFFER_SIZE = 12000
|
||||||
|
|
||||||
|
const val INDEX_BGM = 0
|
||||||
|
const val INDEX_AMB = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
val hash = getHashStr()
|
val hash = getHashStr()
|
||||||
@@ -128,6 +132,7 @@ class TerrarumAudioMixerTrack(val name: String, val isMaster: Boolean = false):
|
|||||||
|
|
||||||
internal var processor = MixerTrackProcessor(BUFFER_SIZE, SAMPLING_RATE, this)
|
internal var processor = MixerTrackProcessor(BUFFER_SIZE, SAMPLING_RATE, this)
|
||||||
private val processorThread = Thread(processor).also {
|
private val processorThread = Thread(processor).also {
|
||||||
|
it.priority = MAX_PRIORITY // higher = more predictable; audio delay is very noticeable so it gets high priority
|
||||||
it.start()
|
it.start()
|
||||||
}
|
}
|
||||||
internal var pcmQueue = Queue<List<FloatArray>>()
|
internal var pcmQueue = Queue<List<FloatArray>>()
|
||||||
@@ -141,6 +146,7 @@ class TerrarumAudioMixerTrack(val name: String, val isMaster: Boolean = false):
|
|||||||
if (isMaster) {
|
if (isMaster) {
|
||||||
queueDispatcher = FeedSamplesToAdev(BUFFER_SIZE, SAMPLING_RATE, this)
|
queueDispatcher = FeedSamplesToAdev(BUFFER_SIZE, SAMPLING_RATE, this)
|
||||||
queueDispatcherThread = Thread(queueDispatcher).also {
|
queueDispatcherThread = Thread(queueDispatcher).also {
|
||||||
|
it.priority = MAX_PRIORITY // higher = more predictable; audio delay is very noticeable so it gets high priority
|
||||||
it.start()
|
it.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,6 +366,7 @@ class UIInventoryFull(
|
|||||||
INGAME.setTooltipMessage(null)
|
INGAME.setTooltipMessage(null)
|
||||||
|
|
||||||
AudioMixer.requestLowpassIn(0.4)
|
AudioMixer.requestLowpassIn(0.4)
|
||||||
|
AudioMixer.requestFadeOut(0.4, 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doClosing(delta: Float) {
|
override fun doClosing(delta: Float) {
|
||||||
@@ -375,6 +376,7 @@ class UIInventoryFull(
|
|||||||
INGAME.setTooltipMessage(null)
|
INGAME.setTooltipMessage(null)
|
||||||
|
|
||||||
AudioMixer.requestLowpassOut(0.4)
|
AudioMixer.requestLowpassOut(0.4)
|
||||||
|
AudioMixer.requestFadeIn(0.4, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun endOpening(delta: Float) {
|
override fun endOpening(delta: Float) {
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
private val stripGap = 1
|
private val stripGap = 1
|
||||||
private val stripFilterHeight = 32
|
private val stripFilterHeight = 32
|
||||||
private val stripFaderHeight = 200
|
private val stripFaderHeight = 200
|
||||||
private val stripH = stripFaderHeight + stripFilterHeight * 4
|
private val stripH = stripFaderHeight + stripFilterHeight * 4 + 16
|
||||||
|
|
||||||
private val COL_WELL = Color(0x374854_aa)
|
private val COL_WELL = Color(0x374854_aa)
|
||||||
private val COL_WELL2 = Color(0x3f5360_aa)
|
private val COL_WELL2 = Color(0x3f5360_aa)
|
||||||
@@ -409,11 +409,22 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
strips.forEachIndexed { index, track -> drawStrip(batch, x + index * (stripW + stripGap), y, track, index) }
|
strips.forEachIndexed { index, track -> drawStrip(batch, x + index * (stripW + stripGap), y, track, index) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val dbLow = 48.0
|
||||||
|
|
||||||
private fun drawStrip(batch: SpriteBatch, x: Int, y: Int, track: TerrarumAudioMixerTrack, index: Int) {
|
private fun drawStrip(batch: SpriteBatch, x: Int, y: Int, track: TerrarumAudioMixerTrack, index: Int) {
|
||||||
// back
|
// back
|
||||||
batch.color = if (track.isMaster) COL_WELL3 else trackBack[index % 2]
|
batch.color = if (track.isMaster) COL_WELL3 else trackBack[index % 2]
|
||||||
Toolkit.fillArea(batch, x, y, stripW, stripH)
|
Toolkit.fillArea(batch, x, y, stripW, stripH)
|
||||||
|
|
||||||
|
// strip/name separator
|
||||||
|
batch.color = COL_METER_GRAD2
|
||||||
|
Toolkit.fillArea(batch, x, y + stripH - 16, stripW, 2)
|
||||||
|
|
||||||
|
// name text
|
||||||
|
batch.color = FILTER_NAME_ACTIVE
|
||||||
|
App.fontSmallNumbers.draw(batch, track.name, x + 3f, y + stripH - 13f)
|
||||||
|
|
||||||
|
|
||||||
// filterbank back
|
// filterbank back
|
||||||
batch.color = COL_FILTER_WELL_BACK
|
batch.color = COL_FILTER_WELL_BACK
|
||||||
Toolkit.fillArea(batch, x, y, stripW, stripFilterHeight * 4)
|
Toolkit.fillArea(batch, x, y, stripW, stripFilterHeight * 4)
|
||||||
@@ -436,9 +447,9 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
// fader
|
// fader
|
||||||
val dB = track.dBfs
|
val dB = track.dBfs
|
||||||
val dBstr = dB.toIntAndFrac(2,1)
|
val dBstr = dB.toIntAndFrac(2,1)
|
||||||
val dBfs = dB.coerceIn(-96.0, 0.0).plus(96.0).div(96.0)
|
val dBfs = dB.coerceIn(-dbLow, 0.0).plus(dbLow).div(dbLow).toFloat()
|
||||||
batch.color = FILTER_NAME_ACTIVE
|
batch.color = FILTER_NAME_ACTIVE
|
||||||
App.fontSmallNumbers.draw(batch, dBstr, x+3f, faderY+1f)
|
App.fontSmallNumbers.draw(batch, dBstr, x+32f, faderY+1f)
|
||||||
|
|
||||||
// fader trough
|
// fader trough
|
||||||
batch.color = COL_METER_TROUGH
|
batch.color = COL_METER_TROUGH
|
||||||
@@ -455,7 +466,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
batch.color = FILTER_NAME_ACTIVE
|
batch.color = FILTER_NAME_ACTIVE
|
||||||
for (i in 0..16 step 2) {
|
for (i in 0..16 step 2) {
|
||||||
val y = faderY + 11f + i * 11
|
val y = faderY + 11f + i * 11
|
||||||
val s = (i*6).toString().padStart(2, ' ')
|
val s = (i*dbLow/16).roundToInt().toString().padStart(2, ' ')
|
||||||
App.fontSmallNumbers.draw(batch, s, x + 1f, y)
|
App.fontSmallNumbers.draw(batch, s, x + 1f, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,10 +477,17 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
val dBfs = fullscaleToDecibels(fs)
|
val dBfs = fullscaleToDecibels(fs)
|
||||||
|
|
||||||
val x = x + 19f + 7 * ch
|
val x = x + 19f + 7 * ch
|
||||||
val h = ((dBfs + 96.0) / 96.0 * -meterHeight).coerceAtMost(0.0).toFloat()
|
val h = ((dBfs + dbLow) / dbLow * -meterHeight).coerceAtMost(0.0).toFloat()
|
||||||
Toolkit.fillArea(batch, x, faderY + 18f + meterHeight, 6f, h)
|
Toolkit.fillArea(batch, x, faderY + 18f + meterHeight, 6f, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// slider trough
|
||||||
|
batch.color = COL_METER_TROUGH
|
||||||
|
Toolkit.fillArea(batch, x + 48, faderY + 16, 2, meterTroughHeight)
|
||||||
|
|
||||||
|
// slider handle
|
||||||
|
drawFaderHandle(batch, x + 48f, faderY + 18f + meterHeight - dBfs * meterHeight)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawFilterParam(batch: SpriteBatch, x: Int, y: Int, filter: TerrarumAudioFilter, track: TerrarumAudioMixerTrack) {
|
private fun drawFilterParam(batch: SpriteBatch, x: Int, y: Int, filter: TerrarumAudioFilter, track: TerrarumAudioMixerTrack) {
|
||||||
@@ -487,6 +505,38 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val FADER_HANDLE_D1 = Color(0xffffff_bb.toInt())
|
||||||
|
private val FADER_HANDLE_D2 = Color(0xdddddd_bb.toInt())
|
||||||
|
private val FADER_HANDLE_D3 = Color(0xeeeeee_bb.toInt())
|
||||||
|
private val FADER_HANDLE_U1 = Color(0xffffff_bb.toInt())
|
||||||
|
private val FADER_HANDLE_U2 = Color(0xaaaaaa_bb.toInt())
|
||||||
|
private val FADER_HANDLE_U3 = Color(0xbbbbbb_bb.toInt())
|
||||||
|
private val FADER_HANDLE_L = Color(0x777777_bb.toInt())
|
||||||
|
private val FADER_HANDLE_C = Color(0x444444_bb.toInt())
|
||||||
|
private val FADER_HANDLE_R = Color(0x666666_bb.toInt())
|
||||||
|
private fun drawFaderHandle(batch: SpriteBatch, cx: Float, cy: Float) {
|
||||||
|
batch.color = FADER_HANDLE_U1
|
||||||
|
Toolkit.fillArea(batch, cx - 4, cy - 6, 10f, 2f)
|
||||||
|
batch.color = FADER_HANDLE_U2
|
||||||
|
Toolkit.fillArea(batch, cx - 4, cy - 4, 10f, 1f)
|
||||||
|
batch.color = FADER_HANDLE_U3
|
||||||
|
Toolkit.fillArea(batch, cx - 4, cy - 3, 10f, 3f)
|
||||||
|
batch.color = FADER_HANDLE_D3
|
||||||
|
Toolkit.fillArea(batch, cx - 4, cy + 1, 10f, 3f)
|
||||||
|
batch.color = FADER_HANDLE_D2
|
||||||
|
Toolkit.fillArea(batch, cx - 4, cy + 4, 10f, 1f)
|
||||||
|
batch.color = FADER_HANDLE_D1
|
||||||
|
Toolkit.fillArea(batch, cx - 4, cy + 5, 10f, 2f)
|
||||||
|
|
||||||
|
batch.color = FADER_HANDLE_L
|
||||||
|
Toolkit.fillArea(batch, cx - 5, cy - 5, 1f, 11f)
|
||||||
|
batch.color = FADER_HANDLE_R
|
||||||
|
Toolkit.fillArea(batch, cx + 6, cy - 5, 1f, 11f)
|
||||||
|
batch.color = FADER_HANDLE_C
|
||||||
|
Toolkit.fillArea(batch, cx - 4, cy, 10f, 1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private val colHairline = Color(0xf22100ff.toInt())
|
private val colHairline = Color(0xf22100ff.toInt())
|
||||||
private val colGraph = Toolkit.Theme.COL_SELECTED
|
private val colGraph = Toolkit.Theme.COL_SELECTED
|
||||||
private val colGrapi = Toolkit.Theme.COL_SELECTED.cpy().mul(0.5f, 0.5f, 0.5f, 1f)
|
private val colGrapi = Toolkit.Theme.COL_SELECTED.cpy().mul(0.5f, 0.5f, 0.5f, 1f)
|
||||||
|
|||||||
Reference in New Issue
Block a user