mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
more musicplayer things
This commit is contained in:
@@ -65,21 +65,21 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
|
|
||||||
private val TRANSITION_LENGTH = 0.6f
|
private val TRANSITION_LENGTH = 0.6f
|
||||||
|
|
||||||
private var colourEdge = Color(0xFFFFFF_40.toInt())
|
private val colourBack = Color(0xffffff_99.toInt())
|
||||||
private val colourBack = Color.BLACK
|
|
||||||
|
|
||||||
private val colourText = Color(0xf0f0f0ff.toInt())
|
private val colourText = Color(0xffffff_cc.toInt())
|
||||||
private val colourMeter = Color(0xddddddff.toInt())
|
private val colourMeter = Color(0xeeeeee_cc.toInt())
|
||||||
private val colourMeter2 = Color(0xdddddd80.toInt())
|
private val colourMeter2 = Color(0xeeeeee_66.toInt())
|
||||||
|
|
||||||
private val colourControlButton = Color(0xddddddff.toInt())
|
private val colourControlButton = Color(0xeeeeee_cc.toInt())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setAsAlwaysVisible()
|
setAsAlwaysVisible()
|
||||||
|
|
||||||
// test code
|
// test code
|
||||||
// val albumDir = App.customMusicDir + "/Gapless Test"
|
val albumDir = App.customMusicDir + "/Gapless Test"
|
||||||
val albumDir = App.customMusicDir + "/FurryJoA 2023 Live"
|
// val albumDir = App.customMusicDir + "/FurryJoA 2023 Live"
|
||||||
|
// val albumDir = App.customMusicDir + "/Audio Test"
|
||||||
val playlistFile = JsonFetcher.invoke("$albumDir/playlist.json")
|
val playlistFile = JsonFetcher.invoke("$albumDir/playlist.json")
|
||||||
|
|
||||||
val diskJockeyingMode = playlistFile.get("diskJockeyingMode").asString()
|
val diskJockeyingMode = playlistFile.get("diskJockeyingMode").asString()
|
||||||
@@ -279,8 +279,15 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
relativeMouseY.toFloat() in _posY .. _posY+height
|
relativeMouseY.toFloat() in _posY .. _posY+height
|
||||||
|
|
||||||
override fun renderUI(batch: SpriteBatch, camera: OrthographicCamera) {
|
override fun renderUI(batch: SpriteBatch, camera: OrthographicCamera) {
|
||||||
|
val widthForFreqMeter = if (transitionOngoing && modeNext >= MODE_MOUSE_UP || mode >= MODE_MOUSE_UP)
|
||||||
|
uiWidthFromTextWidth(nameLength)
|
||||||
|
else
|
||||||
|
width
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
batch.end()
|
batch.end()
|
||||||
renderNameToFBO(batch, camera, currentMusicName)
|
renderNameToFBO(batch, camera, currentMusicName, widthForFreqMeter.toFloat())
|
||||||
batch.begin()
|
batch.begin()
|
||||||
|
|
||||||
|
|
||||||
@@ -294,10 +301,6 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
else
|
else
|
||||||
_posX
|
_posX
|
||||||
|
|
||||||
val widthForFreqMeter = if (transitionOngoing && modeNext >= MODE_MOUSE_UP || mode >= MODE_MOUSE_UP)
|
|
||||||
uiWidthFromTextWidth(nameLength)
|
|
||||||
else
|
|
||||||
width
|
|
||||||
|
|
||||||
blendNormalStraightAlpha(batch)
|
blendNormalStraightAlpha(batch)
|
||||||
drawBaloon(batch, _posX, _posY, width.toFloat(), (height - capsuleHeight.toFloat()).coerceAtLeast(0f))
|
drawBaloon(batch, _posX, _posY, width.toFloat(), (height - capsuleHeight.toFloat()).coerceAtLeast(0f))
|
||||||
@@ -310,30 +313,28 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
|
|
||||||
private fun drawBaloon(batch: SpriteBatch, x: Float, y: Float, width: Float, height: Float) {
|
private fun drawBaloon(batch: SpriteBatch, x: Float, y: Float, width: Float, height: Float) {
|
||||||
val x = x - capsuleMosaicSize
|
val x = x - capsuleMosaicSize
|
||||||
for (k in 0..3 step 3) {
|
batch.color = colourBack// (if (mouseUp) Color.MAROON else colourBack)
|
||||||
batch.color = if (k == 0) colourEdge else colourBack// (if (mouseUp) Color.MAROON else colourBack)
|
|
||||||
|
|
||||||
// top left
|
// top left
|
||||||
batch.draw(baloonTexture.get(k+0, 0), x, y, capsuleMosaicSize.toFloat(), capsuleMosaicSize.toFloat())
|
batch.draw(baloonTexture.get(0, 0), x, y, capsuleMosaicSize.toFloat(), capsuleMosaicSize.toFloat())
|
||||||
// top
|
// top
|
||||||
batch.draw(baloonTexture.get(k+1, 0), x + capsuleMosaicSize, y, width, capsuleMosaicSize.toFloat())
|
batch.draw(baloonTexture.get(1, 0), x + capsuleMosaicSize, y, width, capsuleMosaicSize.toFloat())
|
||||||
// top right
|
// top right
|
||||||
batch.draw(baloonTexture.get(k+2, 0), x + capsuleMosaicSize + width, y, capsuleMosaicSize.toFloat(), capsuleMosaicSize.toFloat())
|
batch.draw(baloonTexture.get(2, 0), x + capsuleMosaicSize + width, y, capsuleMosaicSize.toFloat(), capsuleMosaicSize.toFloat())
|
||||||
|
|
||||||
// left
|
// left
|
||||||
batch.draw(baloonTexture.get(k+0, 1), x, y + capsuleMosaicSize, capsuleMosaicSize.toFloat(), height)
|
batch.draw(baloonTexture.get(0, 1), x, y + capsuleMosaicSize, capsuleMosaicSize.toFloat(), height)
|
||||||
// centre
|
// centre
|
||||||
batch.draw(baloonTexture.get(k+1, 1), x + capsuleMosaicSize, y + capsuleMosaicSize, width, height)
|
batch.draw(baloonTexture.get(1, 1), x + capsuleMosaicSize, y + capsuleMosaicSize, width, height)
|
||||||
// right
|
// right
|
||||||
batch.draw(baloonTexture.get(k+2, 1), x + capsuleMosaicSize + width, y + capsuleMosaicSize, capsuleMosaicSize.toFloat(), height)
|
batch.draw(baloonTexture.get(2, 1), x + capsuleMosaicSize + width, y + capsuleMosaicSize, capsuleMosaicSize.toFloat(), height)
|
||||||
|
|
||||||
// bottom left
|
// bottom left
|
||||||
batch.draw(baloonTexture.get(k+0, 2), x, y + capsuleMosaicSize + height, capsuleMosaicSize.toFloat(), capsuleMosaicSize.toFloat())
|
batch.draw(baloonTexture.get(0, 2), x, y + capsuleMosaicSize + height, capsuleMosaicSize.toFloat(), capsuleMosaicSize.toFloat())
|
||||||
// bottom
|
// bottom
|
||||||
batch.draw(baloonTexture.get(k+1, 2), x + capsuleMosaicSize, y + capsuleMosaicSize + height, width, capsuleMosaicSize.toFloat())
|
batch.draw(baloonTexture.get(1, 2), x + capsuleMosaicSize, y + capsuleMosaicSize + height, width, capsuleMosaicSize.toFloat())
|
||||||
// bottom right
|
// bottom right
|
||||||
batch.draw(baloonTexture.get(k+2, 2), x + capsuleMosaicSize + width, y + capsuleMosaicSize + height, capsuleMosaicSize.toFloat(), capsuleMosaicSize.toFloat())
|
batch.draw(baloonTexture.get(2, 2), x + capsuleMosaicSize + width, y + capsuleMosaicSize + height, capsuleMosaicSize.toFloat(), capsuleMosaicSize.toFloat())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawControls(batch: SpriteBatch, posX: Float, posY: Float) {
|
private fun drawControls(batch: SpriteBatch, posX: Float, posY: Float) {
|
||||||
@@ -348,12 +349,12 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
|
|
||||||
if (alpha > 0f) {
|
if (alpha > 0f) {
|
||||||
val alpha0 = alpha.coerceIn(0f, 1f).organicOvershoot().coerceAtMost(1f)
|
val alpha0 = alpha.coerceIn(0f, 1f).organicOvershoot().coerceAtMost(1f)
|
||||||
batch.color = colourControlButton mul Color(1f, 1f, 1f, (if (reverse) 1f - alpha0 else alpha0).pow(2f))
|
batch.color = colourControlButton mul Color(1f, 1f, 1f, (if (reverse) 1f - alpha0 else alpha0).pow(3f))
|
||||||
val posX = Toolkit.hdrawWidthf - 100f
|
val posX = Toolkit.hdrawWidthf - 120f
|
||||||
val posY = posY + 10f
|
val posY = posY + 10f
|
||||||
for (i in 0..4) {
|
for (i in 0..4) {
|
||||||
val iconY = if (!AudioMixer.musicTrack.isPlaying && i == 2) 1 else 0
|
val iconY = if (!AudioMixer.musicTrack.isPlaying && i == 2) 1 else 0
|
||||||
batch.draw(controlButtons.get(i, iconY), posX + i * BUTTON_SIZE, posY)
|
batch.draw(controlButtons.get(i, iconY), posX + i * (BUTTON_SIZE + 8) + 4, posY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -363,8 +364,8 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
batch.draw(nameFBO.colorBufferTexture, posX - maskOffWidth, posY + height - capsuleHeight + 1)
|
batch.draw(nameFBO.colorBufferTexture, posX - maskOffWidth, posY + height - capsuleHeight + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderNameToFBO(batch: SpriteBatch, camera: OrthographicCamera, str: String) {
|
private fun renderNameToFBO(batch: SpriteBatch, camera: OrthographicCamera, str: String, width: Float) {
|
||||||
val windowEnd = width.toFloat() - METERS_WIDTH - maskOffWidth
|
val windowEnd = width - METERS_WIDTH - maskOffWidth
|
||||||
|
|
||||||
nameFBO.inAction(camera, batch) {
|
nameFBO.inAction(camera, batch) {
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
@@ -420,7 +421,7 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
// apply slope to the fft bins, also converts fullscale to decibels
|
// apply slope to the fft bins, also converts fullscale to decibels
|
||||||
for (bin in binHeights.indices) {
|
for (bin in binHeights.indices) {
|
||||||
val freqR = (TerrarumAudioMixerTrack.SAMPLING_RATED / FFTSIZE) * (bin + 1)
|
val freqR = (TerrarumAudioMixerTrack.SAMPLING_RATED / FFTSIZE) * (bin + 1)
|
||||||
val magn0 = fftOut.reim[2 * bin].absoluteValue / FFTSIZE * (freqR / 10.0) // apply slope
|
val magn0 = fftOut.reim[2 * bin].absoluteValue / FFTSIZE * (freqR / 20.0) // apply slope
|
||||||
val magn = FastMath.interpolateLinear(FFT_SMOOTHING_FACTOR, magn0, oldFFTmagn[bin])
|
val magn = FastMath.interpolateLinear(FFT_SMOOTHING_FACTOR, magn0, oldFFTmagn[bin])
|
||||||
val magnLog = fullscaleToDecibels(magn)
|
val magnLog = fullscaleToDecibels(magn)
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -177,7 +177,10 @@ object AudioMixer: Disposable {
|
|||||||
masterTrack.filters[0] = SoftClp
|
masterTrack.filters[0] = SoftClp
|
||||||
masterTrack.filters[1] = Buffer
|
masterTrack.filters[1] = Buffer
|
||||||
masterTrack.filters[2] = Spectro()
|
masterTrack.filters[2] = Spectro()
|
||||||
masterTrack.filters[3] = Vecto()
|
masterTrack.filters[3] = Vecto(2f)
|
||||||
|
|
||||||
|
musicTrack.filters[1] = Spectro()
|
||||||
|
ambientTrack.filters[1] = Spectro()
|
||||||
|
|
||||||
listOf(sumBus, convolveBusOpen, convolveBusCave).forEach {
|
listOf(sumBus, convolveBusOpen, convolveBusCave).forEach {
|
||||||
it.addSidechainInput(musicTrack, 1.0)
|
it.addSidechainInput(musicTrack, 1.0)
|
||||||
@@ -201,7 +204,7 @@ object AudioMixer: Disposable {
|
|||||||
masterTrack.addSidechainInput(fadeBus, 1.0)
|
masterTrack.addSidechainInput(fadeBus, 1.0)
|
||||||
masterTrack.addSidechainInput(guiTrack, 1.0)
|
masterTrack.addSidechainInput(guiTrack, 1.0)
|
||||||
|
|
||||||
musicTrack.filters[1] = Gain(0.5f)
|
musicTrack.filters[3] = Gain(0.5f)
|
||||||
|
|
||||||
dynamicTracks.forEach {
|
dynamicTracks.forEach {
|
||||||
it.filters[0] = BinoPan(0f)
|
it.filters[0] = BinoPan(0f)
|
||||||
|
|||||||
@@ -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 : TerrarumAudioFilter() {
|
class Spectro(val 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) }
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ class Spectro : TerrarumAudioFilter() {
|
|||||||
push(inbuf[0], inBuf[0])
|
push(inbuf[0], inBuf[0])
|
||||||
push(inbuf[1], inBuf[1])
|
push(inbuf[1], inBuf[1])
|
||||||
for (i in 0 until FFTSIZE) {
|
for (i in 0 until FFTSIZE) {
|
||||||
chsum.reim[2*i] = ((inBuf[0][i] + inBuf[1][i]) / 2f) * fftWin[i]
|
chsum.reim[2*i] = ((inBuf[0][i] + inBuf[1][i]) / 2f) * fftWin[i] * gain
|
||||||
}
|
}
|
||||||
|
|
||||||
// do fft
|
// do fft
|
||||||
@@ -74,7 +74,7 @@ class Spectro : TerrarumAudioFilter() {
|
|||||||
for (bin in 0 until FFTSIZE / 2) {
|
for (bin in 0 until FFTSIZE / 2) {
|
||||||
val freqL = (SAMPLING_RATED / FFTSIZE) * bin
|
val freqL = (SAMPLING_RATED / FFTSIZE) * bin
|
||||||
val freqR = (SAMPLING_RATED / FFTSIZE) * (bin + 1)
|
val freqR = (SAMPLING_RATED / FFTSIZE) * (bin + 1)
|
||||||
val magn0 = fftOut.reim[2 * bin].absoluteValue / FFTSIZE * (freqR / 10.0) // apply slope
|
val magn0 = fftOut.reim[2 * bin].absoluteValue / FFTSIZE * (freqR / 20.0) // apply slope
|
||||||
val magn = FastMath.interpolateLinear(BasicDebugInfoWindow.FFT_SMOOTHING_FACTOR, magn0, oldFFTmagn[bin])
|
val magn = FastMath.interpolateLinear(BasicDebugInfoWindow.FFT_SMOOTHING_FACTOR, magn0, oldFFTmagn[bin])
|
||||||
val magnLog = fullscaleToDecibels(magn)
|
val magnLog = fullscaleToDecibels(magn)
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ class Spectro : TerrarumAudioFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Vecto : TerrarumAudioFilter() {
|
class Vecto(val gain: Float = 1f) : TerrarumAudioFilter() {
|
||||||
val backbufL = Array((6144f / AUDIO_BUFFER_SIZE).roundToInt().coerceAtLeast(1)) {
|
val backbufL = Array((6144f / AUDIO_BUFFER_SIZE).roundToInt().coerceAtLeast(1)) {
|
||||||
FloatArray(AUDIO_BUFFER_SIZE)
|
FloatArray(AUDIO_BUFFER_SIZE)
|
||||||
}
|
}
|
||||||
@@ -115,8 +115,8 @@ class Vecto : TerrarumAudioFilter() {
|
|||||||
|
|
||||||
// plot dots
|
// plot dots
|
||||||
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
||||||
val y0 = +inbuf[0][i] * 2f
|
val y0 = +inbuf[0][i] * gain
|
||||||
val x0 = -inbuf[1][i] * 2f// rotate the domain by -90 deg
|
val x0 = -inbuf[1][i] * gain// rotate the domain by -90 deg
|
||||||
|
|
||||||
val x = (+x0*sqrt2p -y0*sqrt2p) * 1.4142
|
val x = (+x0*sqrt2p -y0*sqrt2p) * 1.4142
|
||||||
val y = (-x0*sqrt2p -y0*sqrt2p) * 1.4142 // further rotate by -45 deg then flip along the y axis
|
val y = (-x0*sqrt2p -y0*sqrt2p) * 1.4142 // further rotate by -45 deg then flip along the y axis
|
||||||
|
|||||||
@@ -148,6 +148,9 @@ class TerrarumMusicGovernor : MusicGovernor() {
|
|||||||
private var diskJockeyingMode = "intermittent" // intermittent, continuous
|
private var diskJockeyingMode = "intermittent" // intermittent, continuous
|
||||||
|
|
||||||
private fun registerSongsFromDir(musicDir: String, fileToName: ((String) -> String)?) {
|
private fun registerSongsFromDir(musicDir: String, fileToName: ((String) -> String)?) {
|
||||||
|
printdbg(this, "registerSongsFromDir $musicDir")
|
||||||
|
|
||||||
|
|
||||||
val fileToName = if (fileToName == null) {
|
val fileToName = if (fileToName == null) {
|
||||||
{ name: String -> name.substringBeforeLast('.').replace('_', ' ').split(" ").map { it.capitalize() }.joinToString(" ") }
|
{ name: String -> name.substringBeforeLast('.').replace('_', ' ').split(" ").map { it.capitalize() }.joinToString(" ") }
|
||||||
}
|
}
|
||||||
@@ -295,11 +298,11 @@ class TerrarumMusicGovernor : MusicGovernor() {
|
|||||||
if (!musicFired) {
|
if (!musicFired) {
|
||||||
musicFired = true
|
musicFired = true
|
||||||
|
|
||||||
val song = songs[musicBin.removeAt(0)]
|
|
||||||
// prevent same song to play twice
|
// prevent same song to play twice
|
||||||
if (musicBin.isEmpty()) {
|
if (musicBin.isEmpty()) {
|
||||||
restockMUsicBin()
|
restockMUsicBin()
|
||||||
}
|
}
|
||||||
|
val song = songs[musicBin.removeAt(0)]
|
||||||
|
|
||||||
startMusic(song)
|
startMusic(song)
|
||||||
}
|
}
|
||||||
@@ -322,11 +325,11 @@ class TerrarumMusicGovernor : MusicGovernor() {
|
|||||||
if (!ambFired) {
|
if (!ambFired) {
|
||||||
ambFired = true
|
ambFired = true
|
||||||
|
|
||||||
val song = ambients[ambientsBin.removeAt(0)]
|
|
||||||
// prevent same song to play twice
|
// prevent same song to play twice
|
||||||
if (ambientsBin.isEmpty()) {
|
if (ambientsBin.isEmpty()) {
|
||||||
ambientsBin = ArrayList(ambients.indices.toList().shuffled())
|
ambientsBin = ArrayList(ambients.indices.toList().shuffled())
|
||||||
}
|
}
|
||||||
|
val song = ambients[ambientsBin.removeAt(0)]
|
||||||
|
|
||||||
startAmbient(song)
|
startAmbient(song)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user