fix sound destruction

This commit is contained in:
2025-07-18 14:20:33 -05:00
parent f49d4180ed
commit 7fb0d9e80a
2 changed files with 54 additions and 53 deletions

View File

@@ -4,45 +4,42 @@ var io = use('io')
var res = use('resources')
var doc = use('doc')
soloud.init();
soloud.init()
var audio = {};
audio[doc.sym] = `Audio docs.`
var audio = {}
var pcms = {}
var pcms = {};
// keep every live voice here so GC cant collect it prematurely
var voices = []
audio.pcm = function pcm(file)
{
file = res.find_sound(file);
if (!file) return//throw new Error(`Could not findfile ${file}`);
if (pcms[file]) return pcms[file];
var bytes = io.slurpbytes(file)
var newpcm = soloud.load_wav_mem(io.slurpbytes(file));
pcms[file] = newpcm;
return newpcm;
// 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;
return soloud.play(pcm);
};
audio.play[doc.sym] = `Given a file path, plays a sound. Returns a sound object.`
audio.cry = function cry(file) {
var voice = audio.play(file);
if (!voice) return;
return function() {
voice.stop();
voice = null;
var pcm = audio.pcm(file); if (!pcm) return
var voice = soloud.play(pcm)
voices.push(voice)
return voice
}
};
audio.cry[doc.sym] =
`Given a file path, plays a sound. Invoke the returned object to stop it.`
var song;
// 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 }
}
// Play 'file' for new song, cross fade for seconds
// music with optional crossfade
var song
audio.music = function music(file, fade = 0.5) {
if (!file) {
if (song) song.volume = 0;
@@ -71,33 +68,30 @@ audio.music = function music(file, fade = 0.5) {
// tween.tween(temp2, 'volume', 0, fade);
song = temp;
song.loop = true;
temp2.stop()
};
audio.music[doc.sym] = `Play the given music file, with an optional cross fade. The song will loop. When this is invoked again, the previous music is replaced.`
//
// 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 SAMPLES = FRAMES * CHANNELS
var CHUNK_BYTES = FRAMES * CHANNELS * BYTES_PER_F
function pump()
{
function pump() {
if (feeder.queued() < CHUNK_BYTES*3) {
var mm = soloud.mix(FRAMES)
feeder.put(mm)
feeder.put(soloud.mix(FRAMES))
cleanup()
}
$_.delay(pump, 1/240)
}
//pump()
pump()
return audio;
return audio

View File

@@ -177,6 +177,12 @@ static JSValue js_voice_setInaudibleBehavior(JSContext *js, JSValueConst self, i
return JS_NULL;
}
static JSValue js_voice_valid(JSContext *js, JSValueConst self, int argc, JSValue *argv)
{
unsigned int voice = *js2voice(js, self);
return JS_NewBool(js, Soloud_isValidVoiceHandle(soloud, voice));
}
SOLOUD_GETSET(Volume, number);
SOLOUD_GETSET(Pan, number)
SOLOUD_GETSET(Samplerate, number)
@@ -197,6 +203,7 @@ static const JSCFunctionListEntry js_voice_funcs[] = {
JS_CGETSET_DEF("loop", js_voice_get_Looping, js_voice_set_Looping),
JS_CGETSET_DEF("autoStop", js_voice_get_AutoStop, js_voice_set_AutoStop),
JS_CGETSET_DEF("protect", js_voice_get_ProtectVoice, js_voice_set_ProtectVoice),
JS_CFUNC_DEF("is_valid", 0, js_voice_valid),
};
static const JSCFunctionListEntry *js_Bus_funcs;