mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-15 13:04:05 +09:00
BUFFER_SIZE is now strictly samples count
This commit is contained in:
@@ -2,7 +2,7 @@ package net.torvald.terrarum.audio
|
|||||||
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.BUFFER_SIZE
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE
|
||||||
import net.torvald.terrarum.ceilToInt
|
import net.torvald.terrarum.ceilToInt
|
||||||
import net.torvald.terrarum.floorToInt
|
import net.torvald.terrarum.floorToInt
|
||||||
@@ -33,7 +33,7 @@ class AudioProcessBuf(inputSamplingRate: Int, val audioReadFun: (ByteArray) -> I
|
|||||||
else
|
else
|
||||||
0.0
|
0.0
|
||||||
|
|
||||||
private val BS = BUFFER_SIZE / 4
|
private val BS = AUDIO_BUFFER_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
private val gcd = FastMath.getGCD(inputSamplingRate, SAMPLING_RATE) // 300 for 44100, 48000
|
private val gcd = FastMath.getGCD(inputSamplingRate, SAMPLING_RATE) // 300 for 44100, 48000
|
||||||
@@ -59,12 +59,12 @@ class AudioProcessBuf(inputSamplingRate: Int, val audioReadFun: (ByteArray) -> I
|
|||||||
|
|
||||||
var validSamplesInBuf = 0
|
var validSamplesInBuf = 0
|
||||||
|
|
||||||
val foutL = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
|
val foutL = FloatArray(internalBufferSize + samplesOut) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
|
||||||
val foutR = FloatArray(internalBufferSize) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
|
val foutR = FloatArray(internalBufferSize + samplesOut) // 640 for (44100, 48000), 512 for (48000, 48000) with BUFFER_SIZE = 512 * 4
|
||||||
|
|
||||||
fun fetchBytes() {
|
fun fetchBytes() {
|
||||||
val readCount = ((internalBufferSize - validSamplesInBuf) / samplesOut) * samplesIn // in samples (441 or 588 for 44100, 48000)
|
val readCount = ((internalBufferSize - validSamplesInBuf) / samplesOut.toFloat()).ceilToInt() * samplesIn // in samples (441 or 588 for 44100, 48000)
|
||||||
val writeCount = ((internalBufferSize - validSamplesInBuf) / samplesOut) * samplesOut // in samples (480 or 640 for 44100, 48000)
|
val writeCount = ((internalBufferSize - validSamplesInBuf) / samplesOut.toFloat()).ceilToInt() * samplesOut // in samples (480 or 640 for 44100, 48000)
|
||||||
val readBuf = ByteArray(readCount * 4)
|
val readBuf = ByteArray(readCount * 4)
|
||||||
val finL = FloatArray(readCount)
|
val finL = FloatArray(readCount)
|
||||||
val finR = FloatArray(readCount)
|
val finR = FloatArray(readCount)
|
||||||
@@ -73,47 +73,59 @@ class AudioProcessBuf(inputSamplingRate: Int, val audioReadFun: (ByteArray) -> I
|
|||||||
|
|
||||||
fun getFromReadBuf(i: Int, bytesRead: Int) = if (i < bytesRead) readBuf[i].toUint() else 0
|
fun getFromReadBuf(i: Int, bytesRead: Int) = if (i < bytesRead) readBuf[i].toUint() else 0
|
||||||
|
|
||||||
try {
|
if (readCount > 0) {
|
||||||
val bytesRead = audioReadFun(readBuf)
|
try {
|
||||||
|
val bytesRead = audioReadFun(readBuf)
|
||||||
|
printdbg(this, "Reading audio $readCount samples, got ${bytesRead?.div(4)} samples")
|
||||||
|
|
||||||
if (bytesRead == null || bytesRead <= 0) {
|
if (bytesRead == null || bytesRead <= 0) {
|
||||||
printdbg(this, "Music finished; bytesRead = $bytesRead")
|
printdbg(this, "Music finished; bytesRead = $bytesRead")
|
||||||
|
|
||||||
onAudioFinished()
|
onAudioFinished()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for(c in 0 until readCount) {
|
for (c in 0 until readCount) {
|
||||||
val sl = (getFromReadBuf(4 * c + 0, bytesRead) or getFromReadBuf(4 * c + 1, bytesRead).shl(8)).toShort()
|
val sl = (getFromReadBuf(4 * c + 0, bytesRead) or getFromReadBuf(
|
||||||
val sr = (getFromReadBuf(4 * c + 2, bytesRead) or getFromReadBuf(4 * c + 3, bytesRead).shl(8)).toShort()
|
4 * c + 1,
|
||||||
|
bytesRead
|
||||||
|
).shl(8)).toShort()
|
||||||
|
val sr = (getFromReadBuf(4 * c + 2, bytesRead) or getFromReadBuf(
|
||||||
|
4 * c + 3,
|
||||||
|
bytesRead
|
||||||
|
).shl(8)).toShort()
|
||||||
|
|
||||||
val fl = sl / 32767f
|
val fl = sl / 32767f
|
||||||
val fr = sr / 32767f
|
val fr = sr / 32767f
|
||||||
|
|
||||||
finL[c] = fl
|
finL[c] = fl
|
||||||
finR[c] = fr
|
finR[c] = fr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
catch (e: Throwable) {
|
||||||
catch (e: Throwable) {
|
e.printStackTrace()
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
if (doResample) {
|
|
||||||
// perform resampling
|
|
||||||
resampleBlock(finL, foutL)
|
|
||||||
resampleBlock(finR, foutR)
|
|
||||||
|
|
||||||
// fill in the output buffers
|
|
||||||
System.arraycopy(foutL, 0, this.foutL, validSamplesInBuf, writeCount)
|
|
||||||
System.arraycopy(foutR, 0, this.foutR, validSamplesInBuf, writeCount)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// fill in the output buffers
|
|
||||||
System.arraycopy(finL, 0, this.foutL, validSamplesInBuf, writeCount)
|
|
||||||
System.arraycopy(finR, 0, this.foutR, validSamplesInBuf, writeCount)
|
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
if (doResample) {
|
||||||
|
// perform resampling
|
||||||
|
resampleBlock(finL, foutL)
|
||||||
|
resampleBlock(finR, foutR)
|
||||||
|
|
||||||
validSamplesInBuf += writeCount
|
// fill in the output buffers
|
||||||
|
System.arraycopy(foutL, 0, this.foutL, validSamplesInBuf, writeCount)
|
||||||
|
System.arraycopy(foutR, 0, this.foutR, validSamplesInBuf, writeCount)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// fill in the output buffers
|
||||||
|
System.arraycopy(finL, 0, this.foutL, validSamplesInBuf, writeCount)
|
||||||
|
System.arraycopy(finR, 0, this.foutR, validSamplesInBuf, writeCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
validSamplesInBuf += writeCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printdbg(this, "Reading audio zero samples; Buffer: $validSamplesInBuf / $internalBufferSize samples")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
package net.torvald.terrarum.audio
|
package net.torvald.terrarum.audio
|
||||||
|
|
||||||
import com.badlogic.gdx.backends.lwjgl3.audio.Mp3
|
|
||||||
import com.badlogic.gdx.utils.Queue
|
import com.badlogic.gdx.utils.Queue
|
||||||
import javazoom.jl.decoder.Bitstream
|
|
||||||
import javazoom.jl.decoder.MP3Decoder
|
|
||||||
import net.torvald.reflection.extortField
|
|
||||||
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.dsp.BinoPan
|
import net.torvald.terrarum.audio.dsp.BinoPan
|
||||||
import net.torvald.terrarum.audio.dsp.NullFilter
|
import net.torvald.terrarum.audio.dsp.NullFilter
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.printStackTrace
|
|
||||||
import net.torvald.terrarum.relativeXposition
|
import net.torvald.terrarum.relativeXposition
|
||||||
import net.torvald.terrarum.sqr
|
import net.torvald.terrarum.sqr
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
@@ -18,7 +13,7 @@ import kotlin.math.*
|
|||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2023-11-17.
|
* Created by minjaesong on 2023-11-17.
|
||||||
*/
|
*/
|
||||||
class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: TerrarumAudioMixerTrack): Runnable {
|
class MixerTrackProcessor(val buffertaille: Int, val rate: Int, val track: TerrarumAudioMixerTrack): Runnable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val BACK_BUF_COUNT = 1
|
val BACK_BUF_COUNT = 1
|
||||||
@@ -29,7 +24,7 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
private val pauseLock = java.lang.Object()
|
private val pauseLock = java.lang.Object()
|
||||||
|
|
||||||
|
|
||||||
private val emptyBuf = FloatArray(bufferSize / 4)
|
private val emptyBuf = FloatArray(buffertaille)
|
||||||
|
|
||||||
|
|
||||||
internal var streamBuf: AudioProcessBuf? = null
|
internal var streamBuf: AudioProcessBuf? = null
|
||||||
@@ -123,8 +118,8 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
// get samples and apply the fader
|
// get samples and apply the fader
|
||||||
if (track.trackType == TrackType.MASTER || track.trackType == TrackType.BUS) {
|
if (track.trackType == TrackType.MASTER || track.trackType == TrackType.BUS) {
|
||||||
// combine all the inputs
|
// combine all the inputs
|
||||||
samplesL1 = FloatArray(bufferSize / 4)
|
samplesL1 = FloatArray(buffertaille)
|
||||||
samplesR1 = FloatArray(bufferSize / 4)
|
samplesR1 = FloatArray(buffertaille)
|
||||||
|
|
||||||
val sidechains = track.sidechainInputs
|
val sidechains = track.sidechainInputs
|
||||||
// add all up
|
// add all up
|
||||||
@@ -159,13 +154,13 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var fin1 = listOf(samplesL1, samplesR1)
|
var fin1 = listOf(samplesL1, samplesR1)
|
||||||
fout1 = listOf(FloatArray(bufferSize / 4), FloatArray(bufferSize / 4))
|
fout1 = listOf(FloatArray(buffertaille), FloatArray(buffertaille))
|
||||||
|
|
||||||
filterStack.forEachIndexed { index, it ->
|
filterStack.forEachIndexed { index, it ->
|
||||||
it(fin1, fout1)
|
it(fin1, fout1)
|
||||||
fin1 = fout1
|
fin1 = fout1
|
||||||
if (index < filterStack.lastIndex) {
|
if (index < filterStack.lastIndex) {
|
||||||
fout1 = listOf(FloatArray(bufferSize / 4), FloatArray(bufferSize / 4))
|
fout1 = listOf(FloatArray(buffertaille), FloatArray(buffertaille))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,7 +171,7 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
|||||||
maxSigLevel[index] = fl.toDouble()
|
maxSigLevel[index] = fl.toDouble()
|
||||||
}
|
}
|
||||||
fout1.map { it.sumOf { it.sqr().toDouble() } }.forEachIndexed { index, fl ->
|
fout1.map { it.sumOf { it.sqr().toDouble() } }.forEachIndexed { index, fl ->
|
||||||
maxRMS[index] = sqrt(fl / (bufferSize / 4))
|
maxRMS[index] = sqrt(fl / (buffertaille))
|
||||||
}
|
}
|
||||||
hasClipping.fill(false)
|
hasClipping.fill(false)
|
||||||
fout1.forEachIndexed { index, floats ->
|
fout1.forEachIndexed { index, floats ->
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import net.torvald.terrarum.App
|
|||||||
import net.torvald.terrarum.audio.dsp.NullFilter
|
import net.torvald.terrarum.audio.dsp.NullFilter
|
||||||
import net.torvald.terrarum.audio.dsp.TerrarumAudioFilter
|
import net.torvald.terrarum.audio.dsp.TerrarumAudioFilter
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
|
||||||
import net.torvald.terrarum.getHashStr
|
import net.torvald.terrarum.getHashStr
|
||||||
import net.torvald.terrarum.hashStrMap
|
import net.torvald.terrarum.hashStrMap
|
||||||
import net.torvald.terrarum.modulebasegame.MusicContainer
|
import net.torvald.terrarum.modulebasegame.MusicContainer
|
||||||
@@ -29,7 +28,7 @@ class TerrarumAudioMixerTrack(val name: String, val trackType: TrackType, var ma
|
|||||||
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
|
||||||
val BUFFER_SIZE = 4 * App.getConfigInt("audio_buffer_size") // n ms -> 384 * n
|
val AUDIO_BUFFER_SIZE = App.getConfigInt("audio_buffer_size") // n ms -> 384 * n
|
||||||
}
|
}
|
||||||
|
|
||||||
val hash = getHashStr()
|
val hash = getHashStr()
|
||||||
@@ -162,7 +161,7 @@ class TerrarumAudioMixerTrack(val name: String, val trackType: TrackType, var ma
|
|||||||
|
|
||||||
// 1st ring of the hell: the THREADING HELL //
|
// 1st ring of the hell: the THREADING HELL //
|
||||||
|
|
||||||
internal var processor = MixerTrackProcessor(BUFFER_SIZE, SAMPLING_RATE, this)
|
internal var processor = MixerTrackProcessor(AUDIO_BUFFER_SIZE, SAMPLING_RATE, this)
|
||||||
/*private val processorThread = Thread(processor).also { // uncomment to multithread
|
/*private val processorThread = Thread(processor).also { // uncomment to multithread
|
||||||
it.priority = MAX_PRIORITY // higher = more predictable; audio delay is very noticeable so it gets high priority
|
it.priority = MAX_PRIORITY // higher = more predictable; audio delay is very noticeable so it gets high priority
|
||||||
it.start()
|
it.start()
|
||||||
@@ -172,8 +171,8 @@ class TerrarumAudioMixerTrack(val name: String, val trackType: TrackType, var ma
|
|||||||
private lateinit var queueDispatcherThread: Thread
|
private lateinit var queueDispatcherThread: Thread
|
||||||
|
|
||||||
init {
|
init {
|
||||||
pcmQueue.addLast(listOf(FloatArray(BUFFER_SIZE / 4), FloatArray(BUFFER_SIZE / 4)))
|
pcmQueue.addLast(listOf(FloatArray(AUDIO_BUFFER_SIZE), FloatArray(AUDIO_BUFFER_SIZE)))
|
||||||
pcmQueue.addLast(listOf(FloatArray(BUFFER_SIZE / 4), FloatArray(BUFFER_SIZE / 4)))
|
pcmQueue.addLast(listOf(FloatArray(AUDIO_BUFFER_SIZE), FloatArray(AUDIO_BUFFER_SIZE)))
|
||||||
|
|
||||||
/*if (isMaster) { // uncomment to multithread
|
/*if (isMaster) { // uncomment to multithread
|
||||||
queueDispatcher = FeedSamplesToAdev(BUFFER_SIZE, SAMPLING_RATE, this)
|
queueDispatcher = FeedSamplesToAdev(BUFFER_SIZE, SAMPLING_RATE, this)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class BinoPan(var pan: Float, var earDist: Float = 0.18f): TerrarumAudioFilter()
|
|||||||
|
|
||||||
private val PANNING_CONST = 3.0 // 3dB panning rule
|
private val PANNING_CONST = 3.0 // 3dB panning rule
|
||||||
|
|
||||||
private val delayLine = FloatArray(TerrarumAudioMixerTrack.BUFFER_SIZE / 4)
|
private val delayLine = FloatArray(TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE)
|
||||||
|
|
||||||
private fun getFrom(index: Float, buf0: FloatArray, buf1: FloatArray): Float {
|
private fun getFrom(index: Float, buf0: FloatArray, buf1: FloatArray): Float {
|
||||||
val index = index.toInt() // TODO resampling
|
val index = index.toInt() // TODO resampling
|
||||||
@@ -55,7 +55,7 @@ class BinoPan(var pan: Float, var earDist: Float = 0.18f): TerrarumAudioFilter()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (ch in 0..1) {
|
for (ch in 0..1) {
|
||||||
for (i in 0 until TerrarumAudioMixerTrack.BUFFER_SIZE / 4) {
|
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
||||||
outbuf[ch][i] = getFrom(i - delays[ch], delayLine, inbuf[0]) * mults[ch]
|
outbuf[ch][i] = getFrom(i - delays[ch], delayLine, inbuf[0]) * mults[ch]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import net.torvald.terrarum.roundToFloat
|
|||||||
class Bitcrush(var steps: Int, var inputGain: Float = 1f): TerrarumAudioFilter() {
|
class Bitcrush(var steps: Int, var inputGain: Float = 1f): TerrarumAudioFilter() {
|
||||||
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
||||||
for (ch in outbuf.indices) {
|
for (ch in outbuf.indices) {
|
||||||
for (i in 0 until TerrarumAudioMixerTrack.BUFFER_SIZE / 4) {
|
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
||||||
val inn = ((inbuf[ch][i] * inputGain).coerceIn(-1f, 1f) + 1f) / 2f // 0f..1f
|
val inn = ((inbuf[ch][i] * inputGain).coerceIn(-1f, 1f) + 1f) / 2f // 0f..1f
|
||||||
val stepped = (inn * (steps - 1)).roundToFloat() / (steps - 1)
|
val stepped = (inn * (steps - 1)).roundToFloat() / (steps - 1)
|
||||||
val out = (stepped * 2f) - 1f // -1f..1f
|
val out = (stepped * 2f) - 1f // -1f..1f
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package net.torvald.terrarum.audio.dsp
|
package net.torvald.terrarum.audio.dsp
|
||||||
|
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.terrarum.App.measureDebugTime
|
|
||||||
import net.torvald.terrarum.App.setDebugTime
|
import net.torvald.terrarum.App.setDebugTime
|
||||||
import net.torvald.terrarum.audio.*
|
import net.torvald.terrarum.audio.*
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.BUFFER_SIZE
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() {
|
class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() {
|
||||||
@@ -13,7 +12,7 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() {
|
|||||||
private val convFFT: Array<ComplexArray>
|
private val convFFT: Array<ComplexArray>
|
||||||
private val inbuf: Array<ComplexArray>
|
private val inbuf: Array<ComplexArray>
|
||||||
|
|
||||||
private val BLOCKSIZE = TerrarumAudioMixerTrack.BUFFER_SIZE / 4
|
private val BLOCKSIZE = TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE
|
||||||
|
|
||||||
var processingSpeed = 1f; private set
|
var processingSpeed = 1f; private set
|
||||||
|
|
||||||
@@ -60,7 +59,7 @@ class Convolv(ir: File, val gain: Float = 1f / 256f): TerrarumAudioFilter() {
|
|||||||
|
|
||||||
// fill up part* dictionary
|
// fill up part* dictionary
|
||||||
// define "master" array
|
// define "master" array
|
||||||
var c = BUFFER_SIZE / 4
|
var c = AUDIO_BUFFER_SIZE
|
||||||
val master0 = arrayListOf(c)
|
val master0 = arrayListOf(c)
|
||||||
while (c < fftLen) {
|
while (c < fftLen) {
|
||||||
master0.add(c)
|
master0.add(c)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import net.torvald.terrarum.audio.TerrarumAudioMixerTrack
|
|||||||
|
|
||||||
class Gain(var gain: Float): TerrarumAudioFilter() {
|
class Gain(var gain: Float): TerrarumAudioFilter() {
|
||||||
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
||||||
for (i in 0 until TerrarumAudioMixerTrack.BUFFER_SIZE / 4) {
|
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
||||||
outbuf[0][i] = inbuf[0][i] * gain
|
outbuf[0][i] = inbuf[0][i] * gain
|
||||||
outbuf[1][i] = inbuf[1][i] * gain
|
outbuf[1][i] = inbuf[1][i] * gain
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class Reverb(val delayMS: Float = 36f, var feedback: Float = 0.92f, var lowpass:
|
|||||||
val alphaHi = RCHi / (RCHi + dt)
|
val alphaHi = RCHi / (RCHi + dt)
|
||||||
|
|
||||||
for (ch in outbuf.indices) {
|
for (ch in outbuf.indices) {
|
||||||
for (i in 0 until TerrarumAudioMixerTrack.BUFFER_SIZE / 4) {
|
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
||||||
val inn = inbuf[ch][i]
|
val inn = inbuf[ch][i]
|
||||||
|
|
||||||
// reverb
|
// reverb
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import net.torvald.terrarum.audio.TerrarumAudioMixerTrack
|
|||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class Scope : TerrarumAudioFilter() {
|
class Scope : TerrarumAudioFilter() {
|
||||||
val backbufL = Array((4096f / TerrarumAudioMixerTrack.BUFFER_SIZE * 4).roundToInt().coerceAtLeast(1)) { FloatArray(
|
val backbufL = Array((4096f / TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE).roundToInt().coerceAtLeast(1)) { FloatArray(
|
||||||
TerrarumAudioMixerTrack.BUFFER_SIZE / 4) }
|
TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) }
|
||||||
val backbufR = Array((4096f / TerrarumAudioMixerTrack.BUFFER_SIZE * 4).roundToInt().coerceAtLeast(1)) { FloatArray(
|
val backbufR = Array((4096f / TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE).roundToInt().coerceAtLeast(1)) { FloatArray(
|
||||||
TerrarumAudioMixerTrack.BUFFER_SIZE / 4) }
|
TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) }
|
||||||
|
|
||||||
private val sqrt2p = 0.7071067811865475
|
private val sqrt2p = 0.7071067811865475
|
||||||
|
|
||||||
@@ -17,11 +17,11 @@ class Scope : TerrarumAudioFilter() {
|
|||||||
backbufL[i] = backbufL[i - 1]
|
backbufL[i] = backbufL[i - 1]
|
||||||
backbufR[i] = backbufR[i - 1]
|
backbufR[i] = backbufR[i - 1]
|
||||||
}
|
}
|
||||||
backbufL[0] = FloatArray(TerrarumAudioMixerTrack.BUFFER_SIZE / 4)
|
backbufL[0] = FloatArray(TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE)
|
||||||
backbufR[0] = FloatArray(TerrarumAudioMixerTrack.BUFFER_SIZE / 4)
|
backbufR[0] = FloatArray(TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE)
|
||||||
|
|
||||||
// plot dots
|
// plot dots
|
||||||
for (i in 0 until TerrarumAudioMixerTrack.BUFFER_SIZE /4) {
|
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
||||||
val y0 = inbuf[0][i] * 0.7
|
val y0 = inbuf[0][i] * 0.7
|
||||||
val x0 = -inbuf[1][i] * 0.7 // rotate the domain by -90 deg
|
val x0 = -inbuf[1][i] * 0.7 // rotate the domain by -90 deg
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import net.torvald.terrarum.audio.TerrarumAudioMixerTrack
|
|||||||
|
|
||||||
object XYtoMS: TerrarumAudioFilter() {
|
object XYtoMS: TerrarumAudioFilter() {
|
||||||
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
||||||
for (i in 0 until TerrarumAudioMixerTrack.BUFFER_SIZE / 4) {
|
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
||||||
val X = inbuf[0][i]
|
val X = inbuf[0][i]
|
||||||
val Y = inbuf[1][i]
|
val Y = inbuf[1][i]
|
||||||
val M = (X + Y) / 2f
|
val M = (X + Y) / 2f
|
||||||
@@ -17,7 +17,7 @@ object XYtoMS: TerrarumAudioFilter() {
|
|||||||
|
|
||||||
object MStoXY: TerrarumAudioFilter() {
|
object MStoXY: TerrarumAudioFilter() {
|
||||||
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
|
||||||
for (i in 0 until TerrarumAudioMixerTrack.BUFFER_SIZE / 4) {
|
for (i in 0 until TerrarumAudioMixerTrack.AUDIO_BUFFER_SIZE) {
|
||||||
val M = inbuf[0][i]
|
val M = inbuf[0][i]
|
||||||
val S = inbuf[1][i]
|
val S = inbuf[1][i]
|
||||||
val X = M + S
|
val X = M + S
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import net.torvald.terrarum.Terrarum.mouseTileY
|
|||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
import net.torvald.terrarum.audio.*
|
import net.torvald.terrarum.audio.*
|
||||||
import net.torvald.terrarum.audio.AudioMixer.dynamicSourceCount
|
import net.torvald.terrarum.audio.AudioMixer.dynamicSourceCount
|
||||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.BUFFER_SIZE
|
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.AUDIO_BUFFER_SIZE
|
||||||
import net.torvald.terrarum.audio.dsp.*
|
import net.torvald.terrarum.audio.dsp.*
|
||||||
import net.torvald.terrarum.controller.TerrarumController
|
import net.torvald.terrarum.controller.TerrarumController
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
@@ -454,7 +454,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
private val oldRMS = Array(trackCount) { arrayOf(0.0, 0.0) }
|
private val oldRMS = Array(trackCount) { arrayOf(0.0, 0.0) }
|
||||||
private val oldComp = Array(trackCount) { arrayOf(0.0, 0.0) }
|
private val oldComp = Array(trackCount) { arrayOf(0.0, 0.0) }
|
||||||
|
|
||||||
private fun getSmoothingFactor(sampleCount: Int) = 1.0 - (BUFFER_SIZE / (4.0 * sampleCount))
|
private fun getSmoothingFactor(sampleCount: Int) = 1.0 - (AUDIO_BUFFER_SIZE / sampleCount)
|
||||||
private val PEAK_SMOOTHING_FACTOR = getSmoothingFactor(640)
|
private val PEAK_SMOOTHING_FACTOR = getSmoothingFactor(640)
|
||||||
private val LAMP_SMOOTHING_FACTOR = getSmoothingFactor(3200)
|
private val LAMP_SMOOTHING_FACTOR = getSmoothingFactor(3200)
|
||||||
private val RMS_SMOOTHING_FACTOR = getSmoothingFactor(12000)
|
private val RMS_SMOOTHING_FACTOR = getSmoothingFactor(12000)
|
||||||
@@ -756,7 +756,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
}
|
}
|
||||||
is Buffer -> {
|
is Buffer -> {
|
||||||
batch.color = FILTER_NAME_ACTIVE
|
batch.color = FILTER_NAME_ACTIVE
|
||||||
App.fontSmallNumbers.draw(batch, "Bs:${BUFFER_SIZE/4}", x+3f, y+1f)
|
App.fontSmallNumbers.draw(batch, "Bs:${AUDIO_BUFFER_SIZE}", x+3f, y+1f)
|
||||||
}
|
}
|
||||||
is Convolv -> {
|
is Convolv -> {
|
||||||
// processing speed bar
|
// processing speed bar
|
||||||
@@ -768,7 +768,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
|||||||
Toolkit.fillArea(batch, x.toFloat(), y+14f, stripW * perc, 2f)
|
Toolkit.fillArea(batch, x.toFloat(), y+14f, stripW * perc, 2f)
|
||||||
|
|
||||||
// filter length bar
|
// filter length bar
|
||||||
val g = FastMath.intLog2(BUFFER_SIZE / 4)
|
val g = FastMath.intLog2(AUDIO_BUFFER_SIZE)
|
||||||
val perc2 = (FastMath.intLog2(filter.fftLen).minus(g).toFloat() / (16f - g)).coerceIn(0f, 1f)
|
val perc2 = (FastMath.intLog2(filter.fftLen).minus(g).toFloat() / (16f - g)).coerceIn(0f, 1f)
|
||||||
batch.color = COL_METER_GRAD2
|
batch.color = COL_METER_GRAD2
|
||||||
Toolkit.fillArea(batch, x.toFloat(), y + 16f, stripW * perc2, 14f)
|
Toolkit.fillArea(batch, x.toFloat(), y + 16f, stripW * perc2, 14f)
|
||||||
|
|||||||
Reference in New Issue
Block a user