mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
footsteps using dynamic track wip
This commit is contained in:
BIN
assets/mods/basegame/audio/effects/steps/GRSS_1.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRSS_1.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRSS_2.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRSS_2.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRSS_3.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRSS_3.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRSS_4.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRSS_4.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRSS_5.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRSS_5.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRSS_6.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRSS_6.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRVL_1.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRVL_1.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRVL_2.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRVL_2.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRVL_3.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRVL_3.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRVL_4.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRVL_4.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRVL_5.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRVL_5.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRVL_6.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRVL_6.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/GRVL_7.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/GRVL_7.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_1.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_1.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_2.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_2.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_3.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_3.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_4.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_4.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_5.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_5.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_6.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_6.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_7.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_7.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_8.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_8.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/ROCK_9.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/ROCK_9.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/SAND_1.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/SAND_1.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/SAND_2.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/SAND_2.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/SAND_3.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/SAND_3.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/SAND_4.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/SAND_4.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/WOOD_1.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/WOOD_1.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/WOOD_2.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/WOOD_2.ogg
LFS
Normal file
Binary file not shown.
BIN
assets/mods/basegame/audio/effects/steps/WOOD_3.ogg
LFS
Normal file
BIN
assets/mods/basegame/audio/effects/steps/WOOD_3.ogg
LFS
Normal file
Binary file not shown.
@@ -261,7 +261,20 @@ $BULLET Ambient sound recordings:
|
||||
- crickets_02.ogg
|
||||
|
||||
Copyright (C) 2012, 2013, 2015, 2016, 2017 Klankbeeld
|
||||
Sound from <https://www.freesound.org/people/klankbeeld/>
|
||||
Sound from <https://www.freesound.org/people/klankbeeld>
|
||||
|
||||
|
||||
|
||||
$BULLET Footstep sound recordings:
|
||||
|
||||
- GRSS_01..06.ogg
|
||||
- GRVL_01..07.ogg
|
||||
- ROCK_01..09.ogg
|
||||
- SAND_01..04.ogg
|
||||
- WOOD_01..03.ogg
|
||||
|
||||
Copyright (C) 2020, 2021, 2022 Nox Sound
|
||||
Sound from <https://freesound.org/people/Nox_Sound>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boo
|
||||
actorContainerInactive.forEach { it.dispose() }
|
||||
world.dispose()
|
||||
|
||||
disposables.forEach(Consumer { it.tryDispose() })
|
||||
disposables.forEach { it.tryDispose() }
|
||||
}
|
||||
|
||||
////////////
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.Pixmap
|
||||
import com.badlogic.gdx.utils.JsonValue
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.App.setToGameConfig
|
||||
import net.torvald.terrarum.audio.AudioCodex
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.OreCodex
|
||||
import net.torvald.terrarum.blockproperties.WireCodex
|
||||
@@ -464,6 +465,16 @@ object ModMgr {
|
||||
return dir.listFiles()
|
||||
}
|
||||
}
|
||||
fun getGdxFiles(module: String, path: String): Array<FileHandle> {
|
||||
checkExistence(module)
|
||||
val dir = getGdxFile(module, path)
|
||||
if (!dir.isDirectory) {
|
||||
throw FileNotFoundException("The path is not a directory")
|
||||
}
|
||||
else {
|
||||
return dir.list()
|
||||
}
|
||||
}
|
||||
|
||||
/** Get a common file (literal file or directory) from all the installed mods. Files are guaranteed to exist. If a mod does not
|
||||
* contain the file, the mod will be skipped.
|
||||
@@ -668,6 +679,35 @@ object ModMgr {
|
||||
}
|
||||
}
|
||||
|
||||
object GameAudioLoader {
|
||||
val audioPath = listOf(
|
||||
"audio/music",
|
||||
"audio/effects",
|
||||
"audio/ambient",
|
||||
)
|
||||
|
||||
init {
|
||||
Terrarum.audioCodex = AudioCodex()
|
||||
}
|
||||
|
||||
private fun loadAudio(basename: String, file: FileHandle) {
|
||||
if (file.isDirectory)
|
||||
file.list().forEach { loadAudio("$basename.${it.nameWithoutExtension()}", it) }
|
||||
else {
|
||||
val id = basename
|
||||
val materialID = file.nameWithoutExtension().substringBefore('_')
|
||||
Terrarum.audioCodex.addToFootstepPool(materialID, file)
|
||||
printdbg(this, "Registering music $id")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic operator fun invoke(module: String) {
|
||||
audioPath.forEach {
|
||||
getGdxFiles(module, it).forEach { file -> loadAudio("audio.${file.name()}", file) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A sugar-library for easy texture pack creation
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@ import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||
import net.torvald.terrarum.audio.AudioCodex
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.FluidCodex
|
||||
import net.torvald.terrarum.blockproperties.OreCodex
|
||||
@@ -78,6 +79,7 @@ object Terrarum : Disposable {
|
||||
var apocryphas = HashMap<String, Any>(); internal set
|
||||
var fluidCodex = FluidCodex(); internal set
|
||||
var oreCodex = OreCodex(); internal set
|
||||
var audioCodex = AudioCodex(); internal set
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
34
src/net/torvald/terrarum/audio/AudioCodex.kt
Normal file
34
src/net/torvald/terrarum/audio/AudioCodex.kt
Normal file
@@ -0,0 +1,34 @@
|
||||
package net.torvald.terrarum.audio
|
||||
|
||||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.audio.Music
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.modulebasegame.MusicContainer
|
||||
import net.torvald.terrarum.tryDispose
|
||||
|
||||
typealias MaterialID = String
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-12-02.
|
||||
*/
|
||||
class AudioCodex: Disposable {
|
||||
|
||||
@Transient val footsteps = HashMap<MaterialID, HashSet<MusicContainer>>()
|
||||
|
||||
internal constructor()
|
||||
|
||||
fun addToFootstepPool(materialID: MaterialID, music: FileHandle) {
|
||||
if (footsteps[materialID] == null) footsteps[materialID] = HashSet()
|
||||
footsteps[materialID]!!.add(
|
||||
MusicContainer(music.nameWithoutExtension(), music.file(), Gdx.audio.newMusic(music)) {}
|
||||
)
|
||||
}
|
||||
|
||||
fun getRandomFootstep(materialID: MaterialID) = footsteps[materialID]?.random()
|
||||
|
||||
override fun dispose() {
|
||||
footsteps.values.forEach { it.forEach { it.gdxMusic.tryDispose() } }
|
||||
}
|
||||
}
|
||||
@@ -101,18 +101,14 @@ object AudioMixer: Disposable {
|
||||
* Return oldest dynamic track, even if the track is currently playing
|
||||
*/
|
||||
fun getFreeTrackNoMatterWhat(): TerrarumAudioMixerTrack {
|
||||
return dynamicTracks.minBy { it.playStartedTime }
|
||||
return getFreeTrack() ?: dynamicTracks.minBy { it.playStartedTime }
|
||||
}
|
||||
|
||||
/**
|
||||
* Return oldest dynamic track that is not playing
|
||||
*/
|
||||
fun getFreeTrack(): TerrarumAudioMixerTrack? {
|
||||
val oldestTrack = dynamicTracks.minBy { it.playStartedTime }
|
||||
return if (oldestTrack.isPlaying)
|
||||
null
|
||||
else
|
||||
oldestTrack
|
||||
return dynamicTracks.filter { it.trackingTarget == null && !it.isPlaying }.minByOrNull { it.playStartedTime }
|
||||
}
|
||||
|
||||
private val processingExecutor = ThreadExecutor()
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.audio
|
||||
|
||||
import com.badlogic.gdx.utils.Queue
|
||||
import net.torvald.reflection.forceInvoke
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.audio.dsp.BinoPan
|
||||
import net.torvald.terrarum.audio.dsp.NullFilter
|
||||
@@ -41,7 +42,7 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
||||
private val distFalloff = 2048.0
|
||||
|
||||
private fun printdbg(msg: Any) {
|
||||
if (true) println("[AudioAdapter ${track.name}] $msg")
|
||||
if (true) App.printdbg("AudioAdapter ${track.name}", msg)
|
||||
}
|
||||
override fun run() {
|
||||
// while (running) { // uncomment to multithread
|
||||
@@ -80,8 +81,8 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
||||
track.volume = track.maxVolume
|
||||
(track.filters[0] as BinoPan).pan = 0f
|
||||
}
|
||||
else {
|
||||
val relativeXpos = relativeXposition(AudioMixer.actorNowPlaying!!, track.trackingTarget!!)
|
||||
else if (track.trackingTarget is ActorWithBody) {
|
||||
val relativeXpos = relativeXposition(AudioMixer.actorNowPlaying!!, track.trackingTarget as ActorWithBody)
|
||||
track.volume = track.maxVolume * (1.0 - relativeXpos.absoluteValue.pow(0.5) / distFalloff)
|
||||
(track.filters[0] as BinoPan).pan = ((2*asin(relativeXpos / distFalloff)) / Math.PI).toFloat()
|
||||
}
|
||||
@@ -91,6 +92,10 @@ class MixerTrackProcessor(val bufferSize: Int, val rate: Int, val track: Terraru
|
||||
|
||||
// fetch deviceBufferSize amount of sample from the disk
|
||||
if (track.trackType != TrackType.MASTER && track.trackType != TrackType.BUS && track.streamPlaying) {
|
||||
if (track.trackType == TrackType.DYNAMIC_SOURCE) {
|
||||
printdbg("${track.name} streaming")
|
||||
}
|
||||
|
||||
streamBuf.fetchBytes {
|
||||
val bytesRead = track.currentTrack?.gdxMusic?.forceInvoke<Int>("read", arrayOf(it))
|
||||
if (bytesRead == null || bytesRead <= 0) { // some class (namely Mp3) may return 0 instead of negative value
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.torvald.reflection.forceInvoke
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.audio.dsp.NullFilter
|
||||
import net.torvald.terrarum.audio.dsp.TerrarumAudioFilter
|
||||
import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.getHashStr
|
||||
import net.torvald.terrarum.hashStrMap
|
||||
@@ -22,7 +23,7 @@ enum class TrackType {
|
||||
STATIC_SOURCE, DYNAMIC_SOURCE, BUS, MASTER
|
||||
}
|
||||
|
||||
class TerrarumAudioMixerTrack(val name: String, val trackType: TrackType, private val maxVolumeFun: () -> Double = {1.0}): Disposable {
|
||||
class TerrarumAudioMixerTrack(val name: String, val trackType: TrackType, var maxVolumeFun: () -> Double = {1.0}): Disposable {
|
||||
|
||||
companion object {
|
||||
const val SAMPLING_RATE = 48000
|
||||
@@ -57,7 +58,7 @@ class TerrarumAudioMixerTrack(val name: String, val trackType: TrackType, privat
|
||||
|
||||
val filters: Array<TerrarumAudioFilter> = Array(4) { NullFilter }
|
||||
|
||||
var trackingTarget: ActorWithBody? = null
|
||||
var trackingTarget: Actor? = null
|
||||
|
||||
var playStartedTime = 0L; private set
|
||||
|
||||
@@ -140,9 +141,16 @@ class TerrarumAudioMixerTrack(val name: String, val trackType: TrackType, privat
|
||||
fun stop() {
|
||||
currentTrack?.gdxMusic?.forceInvoke<Int>("reset", arrayOf())
|
||||
streamPlaying = false
|
||||
playStartedTime = 0L
|
||||
// playStartedTime = 0L
|
||||
|
||||
if (trackingTarget != null && currentTrack != null) {
|
||||
trackingTarget!!.onAudioInterrupt(currentTrack!!)
|
||||
}
|
||||
|
||||
fireSongFinishHook()
|
||||
// fireSoundFinishHook()
|
||||
|
||||
trackingTarget = null
|
||||
}
|
||||
|
||||
fun fireSongFinishHook() {
|
||||
|
||||
@@ -3,11 +3,13 @@ package net.torvald.terrarum.gameactors
|
||||
import com.badlogic.gdx.audio.Music
|
||||
import com.badlogic.gdx.audio.Sound
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.INGAME
|
||||
import net.torvald.terrarum.ReferencingRanges
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.audio.AudioMixer
|
||||
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack
|
||||
import net.torvald.terrarum.audio.TrackVolume
|
||||
import net.torvald.terrarum.modulebasegame.MusicContainer
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||
@@ -120,13 +122,17 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
printdbg(this, "Dynamic Source ${track?.name}")
|
||||
|
||||
return track
|
||||
}
|
||||
|
||||
open fun startAudio(music: MusicContainer) {
|
||||
open fun startAudio(music: MusicContainer, volume: TrackVolume = 1.0) {
|
||||
getTrackByAudio(music)?.let {
|
||||
it.trackingTarget = if (this is ActorWithBody) this else null
|
||||
it.stop()
|
||||
it.trackingTarget = this
|
||||
it.currentTrack = music
|
||||
it.maxVolumeFun = { volume }
|
||||
it.play()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
||||
import net.torvald.terrarum.audio.AudioCodex
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.blockproperties.BlockProp
|
||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||
@@ -2041,6 +2042,20 @@ open class ActorWithBody : Actor {
|
||||
makeDust0(tile, px, py, particleCount, collisionDamage, vecSum)
|
||||
}
|
||||
}
|
||||
|
||||
if (particleCount >= 1.0) {
|
||||
val volumeMax = (particleCount.pow(0.75) / 8.0).coerceIn(0.0, 2.0)
|
||||
val feetTileMats = feetTiles.map { BlockCodex[it.second].material }
|
||||
val feetTileCnt = feetTileMats.size.toDouble()
|
||||
val materialStats = feetTileMats.distinct().map { mat -> mat to feetTileMats.count { it == mat } }
|
||||
materialStats.forEach { (mat, cnt) ->
|
||||
Terrarum.audioCodex.getRandomFootstep(mat)?.let {
|
||||
val vol = volumeMax * (cnt / feetTileCnt)
|
||||
startAudio(it, vol)
|
||||
printdbg(this, "Playing footstep $mat (vol: $vol, file: ${it.file.name})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ class EntryPoint : ModuleEntryPoint() {
|
||||
ModMgr.GameOreLoader.invoke(moduleName)
|
||||
ModMgr.GameLanguageLoader.invoke(moduleName)
|
||||
ModMgr.GameCraftingRecipeLoader.invoke(moduleName)
|
||||
ModMgr.GameAudioLoader.invoke(moduleName)
|
||||
|
||||
if (App.IS_DEVELOPMENT_BUILD) {
|
||||
println("[EntryPoint] Crafting Recipes: ")
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.Terrarum.audioCodex
|
||||
import net.torvald.terrarum.Terrarum.getPlayerSaveFiledesc
|
||||
import net.torvald.terrarum.Terrarum.getWorldSaveFiledesc
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
@@ -1586,7 +1587,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
||||
}
|
||||
|
||||
musicGovernor.dispose()
|
||||
|
||||
audioCodex.dispose()
|
||||
super.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user