67 lines
1.5 KiB
Plaintext
67 lines
1.5 KiB
Plaintext
var soloud = use('soloud')
|
||
var tween = use('tween')
|
||
var io = use('io')
|
||
var res = use('resources')
|
||
var doc = use('doc')
|
||
|
||
soloud.init()
|
||
|
||
var audio = {}
|
||
var pcms = {}
|
||
|
||
// keep every live voice here so GC can’t collect it prematurely
|
||
var voices = []
|
||
|
||
// load-and-cache WAVs
|
||
audio.pcm = function pcm(file) {
|
||
file = res.find_sound(file); if (!file) return
|
||
if (pcms[file]) return pcms[file]
|
||
var buf = io.slurpbytes(file)
|
||
return pcms[file] = soloud.load_wav_mem(buf)
|
||
}
|
||
|
||
function cleanup() {
|
||
var cleaned_voices = voices.filter(v => !v.is_valid())
|
||
cleaned_voices.forEach(v => v.finish_hook?.())
|
||
voices = voices.filter(v => v.is_valid())
|
||
}
|
||
|
||
// play a one‑shot; returns the voice for volume/stop control
|
||
audio.play = function play(file) {
|
||
var pcm = audio.pcm(file); if (!pcm) return
|
||
var voice = soloud.play(pcm)
|
||
voices.push(voice)
|
||
return voice
|
||
}
|
||
|
||
// cry is just a play+stop closure
|
||
audio.cry = function cry(file) {
|
||
var v = audio.play(file); if (!v) return
|
||
return function() { v.stop(); v = null }
|
||
}
|
||
|
||
//
|
||
// pump + periodic cleanup
|
||
//
|
||
var ss = use('sdl_audio')
|
||
var feeder = ss.open_stream("playback")
|
||
feeder.set_format({format:"f32", channels:2, samplerate:44100})
|
||
feeder.resume()
|
||
|
||
var FRAMES = 1024
|
||
var CHANNELS = 2
|
||
var BYTES_PER_F = 4
|
||
var CHUNK_BYTES = FRAMES * CHANNELS * BYTES_PER_F
|
||
|
||
function pump() {
|
||
if (feeder.queued() < CHUNK_BYTES*3) {
|
||
feeder.put(soloud.mix(FRAMES))
|
||
cleanup()
|
||
}
|
||
$_.delay(pump, 1/240)
|
||
}
|
||
|
||
pump()
|
||
|
||
return audio
|