Files
cell/prosperon/sound.cm
2025-07-18 14:20:33 -05:00

98 lines
1.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 cant 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() {
voices = voices.filter(v => v.is_valid())
}
// play a oneshot; 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 }
}
// music with optional crossfade
var song
audio.music = function music(file, fade = 0.5) {
if (!file) {
if (song) song.volume = 0;
return;
}
if (!fade) {
song = audio.play(file);
song.loop = true;
return;
}
if (!song) {
song = audio.play(file);
song.volume = 1;
// tween.tween(song,'volume', 1, fade);
return;
}
var temp = audio.play(file);
if (!temp) return;
temp.volume = 1;
var temp2 = song;
// tween.tween(temp, 'volume', 1, fade);
// tween.tween(temp2, 'volume', 0, fade);
song = temp;
song.loop = true;
temp2.stop()
};
//
// 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