proper gc rooting
This commit is contained in:
3
dsp.c
3
dsp.c
@@ -17,9 +17,8 @@ JSC_CCALL(dsp_mix_blobs,
|
||||
if (!JS_IsArray(vols_arr)) return JS_ThrowTypeError(js, "volumes must be an array");
|
||||
|
||||
int len = 0;
|
||||
JSValue len_val = JS_GetPropertyStr(js, blobs_arr, "length");
|
||||
JSValue len_val = JS_CellLength(js, blobs_arr);
|
||||
JS_ToInt32(js, &len, len_val);
|
||||
JS_FreeValue(js, len_val);
|
||||
|
||||
if (len == 0) {
|
||||
// Return empty stoned blob
|
||||
|
||||
15
flac.c
15
flac.c
@@ -28,10 +28,12 @@ static JSValue flac_make_info(JSContext *js, drflac *flac)
|
||||
JS_SetPropertyStr(js, obj.val, "channels", JS_NewInt32(js, flac->channels));
|
||||
JS_SetPropertyStr(js, obj.val, "sample_rate", JS_NewInt32(js, flac->sampleRate));
|
||||
JS_SetPropertyStr(js, obj.val, "bits_per_sample", JS_NewInt32(js, flac->bitsPerSample));
|
||||
JS_SetPropertyStr(js, obj.val, "total_pcm_frames", JS_NewFloat64(js, (double)flac->totalPCMFrameCount));
|
||||
JSValue pcm_count = JS_NewFloat64(js, (double)flac->totalPCMFrameCount);
|
||||
JS_SetPropertyStr(js, obj.val, "total_pcm_frames", pcm_count);
|
||||
JS_SetPropertyStr(js, obj.val, "decoded_bytes_per_frame",
|
||||
JS_NewInt32(js, (int)((size_t)flac->channels * sizeof(drflac_int32))));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "s32"));
|
||||
JSValue fmt = JS_NewString(js, "s32");
|
||||
JS_SetPropertyStr(js, obj.val, "format", fmt);
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
@@ -94,11 +96,14 @@ JSC_CCALL(flac_decode,
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, flac_make_info(js, flac));
|
||||
|
||||
// Update format info
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, "f32"));
|
||||
// Update format info — evaluate allocating calls in separate statements
|
||||
// (C argument evaluation order is unspecified; GC can invalidate .val)
|
||||
JSValue fmt = JS_NewString(js, "f32");
|
||||
JS_SetPropertyStr(js, result.val, "format", fmt);
|
||||
JS_SetPropertyStr(js, result.val, "decoded_bytes_per_frame", JS_NewInt32(js, (int)bytes_per_frame));
|
||||
|
||||
JS_SetPropertyStr(js, result.val, "pcm", js_new_blob_stoned_copy(js, pcm, bytes_read));
|
||||
JSValue pcm_blob = js_new_blob_stoned_copy(js, pcm, bytes_read);
|
||||
JS_SetPropertyStr(js, result.val, "pcm", pcm_blob);
|
||||
free(pcm);
|
||||
drflac_close(flac);
|
||||
JS_RETURN(result.val);
|
||||
|
||||
16
mp3.c
16
mp3.c
@@ -14,10 +14,12 @@ static JSValue mp3_make_info(JSContext *js, drmp3_uint32 channels, drmp3_uint32
|
||||
JS_SetPropertyStr(js, obj.val, "bits_per_sample", JS_NewInt32(js, 16));
|
||||
|
||||
double total_frames = frames == DRMP3_UINT64_MAX ? -1.0 : (double)frames;
|
||||
JS_SetPropertyStr(js, obj.val, "total_pcm_frames", JS_NewFloat64(js, total_frames));
|
||||
JSValue pcm_count = JS_NewFloat64(js, total_frames);
|
||||
JS_SetPropertyStr(js, obj.val, "total_pcm_frames", pcm_count);
|
||||
JS_SetPropertyStr(js, obj.val, "decoded_bytes_per_frame",
|
||||
JS_NewInt32(js, (int)((size_t)channels * sizeof(drmp3_int16))));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "s16"));
|
||||
JSValue fmt = JS_NewString(js, "s16");
|
||||
JS_SetPropertyStr(js, obj.val, "format", fmt);
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
@@ -85,11 +87,15 @@ JSC_CCALL(mp3_decode,
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, mp3_make_info(js, config.channels, config.sampleRate, frames));
|
||||
|
||||
// Update format info
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, "f32"));
|
||||
// Update format info — evaluate allocating calls before reading .val
|
||||
// (C argument evaluation order is unspecified; GC during allocation
|
||||
// can move the rooted object, invalidating an already-read .val)
|
||||
JSValue fmt = JS_NewString(js, "f32");
|
||||
JS_SetPropertyStr(js, result.val, "format", fmt);
|
||||
JS_SetPropertyStr(js, result.val, "decoded_bytes_per_frame", JS_NewInt32(js, (int)bytes_per_frame));
|
||||
|
||||
JS_SetPropertyStr(js, result.val, "pcm", js_new_blob_stoned_copy(js, pcm, total_bytes));
|
||||
JSValue pcm_blob = js_new_blob_stoned_copy(js, pcm, total_bytes);
|
||||
JS_SetPropertyStr(js, result.val, "pcm", pcm_blob);
|
||||
drmp3_free(pcm, NULL);
|
||||
JS_RETURN(result.val);
|
||||
)
|
||||
|
||||
16
soundwave.cm
16
soundwave.cm
@@ -139,16 +139,16 @@ soundwave.create = function(opts) {
|
||||
// Pull a chunk of audio from a voice, handling looping
|
||||
function pull_voice_chunk(voice, frames) {
|
||||
if (voice.stopped) return null
|
||||
|
||||
|
||||
var source = voice.source
|
||||
var total_frames = source.frames
|
||||
var pos = voice.pos
|
||||
var bytes_per_frame = player.channels * BYTES_PER_SAMPLE
|
||||
var bits_per_frame = bytes_per_frame * 8
|
||||
|
||||
|
||||
var out = Blob()
|
||||
var frames_written = 0
|
||||
|
||||
|
||||
var frames_available = null
|
||||
var frames_needed = null
|
||||
var frames_to_read = null
|
||||
@@ -172,13 +172,13 @@ soundwave.create = function(opts) {
|
||||
end_bit = (pos + frames_to_read) * bits_per_frame
|
||||
chunk = source.pcm.read_blob(start_bit, end_bit)
|
||||
out.write_blob(chunk)
|
||||
|
||||
|
||||
pos += frames_to_read
|
||||
frames_written += frames_to_read
|
||||
}
|
||||
|
||||
|
||||
voice.pos = pos
|
||||
|
||||
|
||||
// Pad with silence if needed
|
||||
var silence_frames = null
|
||||
var silence = null
|
||||
@@ -187,7 +187,7 @@ soundwave.create = function(opts) {
|
||||
silence = dsp.silence(silence_frames, player.channels)
|
||||
out.write_blob(silence)
|
||||
}
|
||||
|
||||
|
||||
stone(out)
|
||||
return out
|
||||
}
|
||||
@@ -259,7 +259,7 @@ soundwave.create = function(opts) {
|
||||
} else {
|
||||
mixed = dsp.mix_blobs(blobs, vols)
|
||||
}
|
||||
|
||||
|
||||
player.cleanup()
|
||||
return mixed
|
||||
}
|
||||
|
||||
15
wav.c
15
wav.c
@@ -29,7 +29,8 @@ static JSValue wav_make_info(JSContext *js, drwav *wav)
|
||||
JS_SetPropertyStr(js, obj.val, "sample_rate", JS_NewInt32(js, wav->sampleRate));
|
||||
JS_SetPropertyStr(js, obj.val, "bits_per_sample", JS_NewInt32(js, wav->bitsPerSample));
|
||||
JS_SetPropertyStr(js, obj.val, "format_tag", JS_NewInt32(js, wav->translatedFormatTag));
|
||||
JS_SetPropertyStr(js, obj.val, "total_pcm_frames", JS_NewFloat64(js, (double)wav->totalPCMFrameCount));
|
||||
JSValue pcm_count = JS_NewFloat64(js, (double)wav->totalPCMFrameCount);
|
||||
JS_SetPropertyStr(js, obj.val, "total_pcm_frames", pcm_count);
|
||||
JS_SetPropertyStr(js, obj.val, "bytes_per_frame", JS_NewInt32(js, (int)drwav_get_bytes_per_pcm_frame(wav)));
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
@@ -94,15 +95,19 @@ JSC_CCALL(wav_decode,
|
||||
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, wav_make_info(js, &wav));
|
||||
// Update format info to reflect f32
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, "f32"));
|
||||
// Update format info — evaluate allocating calls in separate statements
|
||||
// (C argument evaluation order is unspecified; GC can invalidate .val)
|
||||
JSValue fmt = JS_NewString(js, "f32");
|
||||
JS_SetPropertyStr(js, result.val, "format", fmt);
|
||||
JS_SetPropertyStr(js, result.val, "bytes_per_frame", JS_NewInt32(js, (int)bytes_per_frame));
|
||||
|
||||
if (pcm_bytes > 0) {
|
||||
JS_SetPropertyStr(js, result.val, "pcm", js_new_blob_stoned_copy(js, pcm, bytes_read));
|
||||
JSValue pcm_blob = js_new_blob_stoned_copy(js, pcm, bytes_read);
|
||||
JS_SetPropertyStr(js, result.val, "pcm", pcm_blob);
|
||||
free(pcm);
|
||||
} else {
|
||||
JS_SetPropertyStr(js, result.val, "pcm", js_new_blob_stoned_copy(js, NULL, 0));
|
||||
JSValue pcm_blob = js_new_blob_stoned_copy(js, NULL, 0);
|
||||
JS_SetPropertyStr(js, result.val, "pcm", pcm_blob);
|
||||
}
|
||||
|
||||
drwav_uninit(&wav);
|
||||
|
||||
Reference in New Issue
Block a user