date marks for DSPs

This commit is contained in:
minjaesong
2024-01-21 15:14:17 +09:00
parent d927d1d240
commit c00dd4e0bf
17 changed files with 114 additions and 9 deletions

View File

@@ -144,7 +144,8 @@ class MixerTrackProcessor(bufferSize: Int, val rate: Int, val track: TerrarumAud
)
val isApproaching = if (distFromActorNext <= distFromActor) 1.0 else -1.0
val relativeSpeed = (sourceVec - listenerVec).magnitude * GAME_TO_SI_VELO * isApproaching
val dopplerFactor = (SPEED_OF_SOUND_AIR + relativeSpeed) / SPEED_OF_SOUND_AIR // >1: speedup, <1: speeddown
val soundSpeed = SPEED_OF_SOUND_AIR * 4f // using an arbitrary value for "gamification"
val dopplerFactor = (soundSpeed + relativeSpeed) / soundSpeed // >1: speedup, <1: speeddown
track.processor.streamBuf?.playbackSpeed = dopplerFactor.toFloat()

View File

@@ -22,6 +22,8 @@ import kotlin.math.tanh
* @param pan -1 for far-left, 0 for centre, 1 for far-right
* @param soundSpeed speed of the sound in meters per seconds
* @param earDist distance between ears in meters. Maximum: 16.0
*
* Created by minjaesong on 2023-11-23.
*/
class BinoPan(var pan: Float, var earDist: Float = EARDIST_DEFAULT): TerrarumAudioFilter() {

View File

@@ -9,6 +9,9 @@ import net.torvald.terrarum.ui.BasicDebugInfoWindow
import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.toIntAndFrac
import net.torvald.terrarum.ui.Toolkit
/**
* Created by minjaesong on 2023-11-23.
*/
class Bitcrush(var steps: Int, var inputGain: Float = 1f): TerrarumAudioFilter() {
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
for (ch in outbuf.indices) {

View File

@@ -4,6 +4,9 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App
import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.FILTER_NAME_ACTIVE
/**
* Created by minjaesong on 2023-11-18.
*/
object Buffer : TerrarumAudioFilter() {
init {
bypass = true

View File

@@ -21,6 +21,8 @@ import kotlin.math.roundToInt
* @param ir Binary file containing MONO IR (containing only two channels)
* @param crossfeed The amount of channel crossfeeding to simulate the true stereo IR. Fullscale (0.0 - 1.0)
* @param gain output gain. Fullscale (0.0 - 1.0)
*
* Created by minjaesong on 2023-11-25.
*/
class Convolv(ir: File, val crossfeed: Float, gain: Float = 1f / 256f): TerrarumAudioFilter() {

View File

@@ -6,6 +6,9 @@ import net.torvald.terrarum.audio.fullscaleToDecibels
import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.FILTER_NAME_ACTIVE
import kotlin.math.roundToInt
/**
* Created by minjaesong on 2023-11-25.
*/
class Gain(var gain: Float): TerrarumAudioFilter() {
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
for (i in 0 until App.audioBufferSize) {

View File

@@ -10,7 +10,9 @@ import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.COL_METER_GRAD2
import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.FILTER_NAME_ACTIVE
import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.STRIP_W
import net.torvald.terrarum.ui.Toolkit
/**
* Created by minjaesong on 2023-11-19.
*/
class Highpass(cutoff0: Float): TerrarumAudioFilter() {
var cutoff = cutoff0.toDouble(); private set

View File

@@ -0,0 +1,53 @@
package net.torvald.terrarum.audio.dsp
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App
import java.io.File
import kotlin.math.absoluteValue
import kotlin.math.tanh
/**
* Convolver with tanh saturator
*
* @param ir Binary file containing MONO IR (containing only two channels)
* @param crossfeed The amount of channel crossfeeding to simulate the true stereo IR. Fullscale (0.0 - 1.0)
* @param gain output gain. Fullscale (0.0 - 1.0)
*
* Created by minjaesong on 2024-01-21.
*/
class LoFi(ir: File, val crossfeed: Float, gain: Float = 1f / 256f): TerrarumAudioFilter(), DspCompressor {
override val downForce = arrayOf(1.0f, 1.0f)
internal val convolver = Convolv(ir, crossfeed, gain)
private val imm = listOf(FloatArray(App.audioBufferSize), FloatArray(App.audioBufferSize))
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
convolver.thru(inbuf, imm)
for (ch in imm.indices) {
val inn = imm[ch]
val out = outbuf[ch]
for (i in inn.indices) {
val u = inn[i]
val v = tanh(u)
val diff = (v.absoluteValue / u.absoluteValue)
out[i] = v
if (!diff.isNaN()) {
downForce[ch] = minOf(downForce[ch], diff)
}
}
}
}
override fun drawDebugView(batch: SpriteBatch, x: Int, y: Int) {
}
override val debugViewHeight = 0
override fun copyParamsFrom(other: TerrarumAudioFilter) {
this.convolver.copyParamsFrom((other as LoFi).convolver)
}
}

View File

@@ -11,6 +11,9 @@ import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.COL_METER_GRAD2
import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.FILTER_NAME_ACTIVE
import net.torvald.terrarum.ui.Toolkit
/**
* Created by minjaesong on 2023-11-17.
*/
class Lowpass(cutoff0: Float): TerrarumAudioFilter() {
var cutoff = cutoff0.toDouble(); private set

View File

@@ -2,6 +2,9 @@ package net.torvald.terrarum.audio.dsp
import com.badlogic.gdx.graphics.g2d.SpriteBatch
/**
* Created by minjaesong on 2023-11-17.
*/
object NullFilter : TerrarumAudioFilter() {
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
outbuf.forEachIndexed { index, outTrack ->

View File

@@ -6,6 +6,9 @@ import net.torvald.terrarum.App
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack
import kotlin.math.roundToInt
/**
* Created by minjaesong on 2023-11-23.
*/
class Reverb(val delayMS: Float = 36f, var feedback: Float = 0.92f, var lowpass: Float = 1200f): TerrarumAudioFilter() {
private val highpass = 80f

View File

@@ -5,8 +5,11 @@ import kotlin.math.absoluteValue
import kotlin.math.pow
import kotlin.math.sqrt
object SoftClp : TerrarumAudioFilter() {
val downForce = arrayOf(1.0f, 1.0f)
/**
* Created by minjaesong on 2023-11-20.
*/
object SoftClp : TerrarumAudioFilter(), DspCompressor {
override val downForce = arrayOf(1.0f, 1.0f)
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
downForce.fill(1.0f)

View File

@@ -11,6 +11,9 @@ import net.torvald.terrarum.ui.BasicDebugInfoWindow.Companion.STRIP_W
import net.torvald.terrarum.ui.Toolkit
import kotlin.math.*
/**
* Created by minjaesong on 2023-12-21.
*/
class Spectro(var gain: Float = 1f) : TerrarumAudioFilter() {
private val FFTSIZE = 1024
private val inBuf = Array(2) { FloatArray(FFTSIZE) }
@@ -99,7 +102,9 @@ class Spectro(var gain: Float = 1f) : TerrarumAudioFilter() {
}
}
/**
* Created by minjaesong on 2023-11-20.
*/
class Vecto(var gain: Float = 1f) : TerrarumAudioFilter() {
var backbufL = Array((6144f / App.audioBufferSize).roundToInt().coerceAtLeast(1)) {
FloatArray(App.audioBufferSize)

View File

@@ -2,9 +2,12 @@ package net.torvald.terrarum.audio.dsp
import com.badlogic.gdx.graphics.g2d.SpriteBatch
/**
* Created by minjaesong on 2023-11-17.
*/
abstract class TerrarumAudioFilter {
var bypass = false
protected abstract fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>)
abstract fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>)
operator fun invoke(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
if (bypass) {
outbuf.forEachIndexed { index, outTrack ->
@@ -18,6 +21,13 @@ abstract class TerrarumAudioFilter {
abstract fun copyParamsFrom(other: TerrarumAudioFilter)
}
/**
* Created by minjaesong on 2024-01-21.
*/
interface DspCompressor {
val downForce: Array<Float>
}
fun FloatArray.applyGain(gain: Float = 1f) = this.map { it * gain }.toFloatArray()
fun push(samples: FloatArray, buf: FloatArray) {
if (samples.size >= buf.size) {

View File

@@ -3,6 +3,9 @@ package net.torvald.terrarum.audio.dsp
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App
/**
* Created by minjaesong on 2023-11-24.
*/
object XYtoMS: TerrarumAudioFilter() {
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
for (i in 0 until App.audioBufferSize) {
@@ -24,6 +27,9 @@ object XYtoMS: TerrarumAudioFilter() {
}
}
/**
* Created by minjaesong on 2023-11-24.
*/
object MStoXY: TerrarumAudioFilter() {
override fun thru(inbuf: List<FloatArray>, outbuf: List<FloatArray>) {
for (i in 0 until App.audioBufferSize) {

View File

@@ -11,6 +11,7 @@ import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.audio.AudioMixer.Companion.DEFAULT_FADEOUT_LEN
import net.torvald.terrarum.audio.dsp.Convolv
import net.torvald.terrarum.audio.dsp.LoFi
import net.torvald.terrarum.audio.dsp.NullFilter
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameitems.ItemID
@@ -40,6 +41,8 @@ class FixtureJukebox : Electric {
@Transient private val backLamp: SheetSpriteAnimation
@Transient private val filterIndex = 2
internal val discInventory = ArrayList<ItemID>()
val musicIsPlaying: Boolean
@@ -114,7 +117,7 @@ class FixtureJukebox : Electric {
App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, DEFAULT_FADEOUT_LEN / 2f) {
startAudio(musicNowPlaying!!) {
it.filters[2] = Convolv(
it.filters[filterIndex] = LoFi(
ModMgr.getFile(
"basegame",
"audio/convolution/Soundwoofer - large_speaker_Marshall JVM 205C SM57 A 0 0 1.bin"
@@ -162,7 +165,7 @@ class FixtureJukebox : Electric {
private fun unloadConvolver(music: MusicContainer?) {
if (music != null) {
musicTracks[music]?.let {
it.filters[2] = NullFilter
it.filters[filterIndex] = NullFilter
}
}
}

View File

@@ -721,7 +721,7 @@ class BasicDebugInfoWindow : UICanvas() {
}
// comp marker
track.filters.filterIsInstance<SoftClp>().firstOrNull()?.let {
track.filters.filterIsInstance<DspCompressor>().firstOrNull()?.let {
for (ch in 0..1) {
val downForceNow = it.downForce[ch] * 1.0
if (downForceNow != 0.0) {