diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-11-22 16:30:19 +0100 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-11-22 16:30:19 +0100 |
commit | 533aa1816b2c90b3935504b489e03e6ef87038a6 (patch) | |
tree | 09140f39264c2939a5eb2683d05827894f62dac3 | |
parent | eda1d8c0bf70fc582a02b32df82d600b8b1cbe25 (diff) | |
download | reduced_system_layer-533aa1816b2c90b3935504b489e03e6ef87038a6.zip |
Update audio
-rw-r--r-- | Dockerfile | 4 | ||||
-rwxr-xr-x | examples/sinewave.c | 10 | ||||
-rw-r--r-- | index.htm | 66 | ||||
-rwxr-xr-x | reduced_system_layer.c | 59 |
4 files changed, 75 insertions, 64 deletions
@@ -1,11 +1,11 @@ # sudo docker run -p 8080:80 -it $(sudo docker build -q .) -FROM alpine as build +FROM alpine AS build RUN apk add clang lld COPY examples /usr/examples COPY reduced_system_layer.c /usr/reduced_system_layer.c COPY graphics.c /usr/graphics.c -RUN clang --target=wasm32 -nostdlib -Wl,--no-entry,--allow-undefined -o /usr/index.wasm /usr/examples/graph.c +RUN clang --target=wasm32 -nostdlib -Wl,--no-entry,--allow-undefined -o /usr/index.wasm /usr/examples/sinewave.c FROM nginx:alpine EXPOSE 80 diff --git a/examples/sinewave.c b/examples/sinewave.c index 59d1161..e45f71e 100755 --- a/examples/sinewave.c +++ b/examples/sinewave.c @@ -73,15 +73,15 @@ i32 main(i32 argc, c8 **argv) { .graceful_exit = 1, }; - f64 frequency = 440. * 4; + f64 frequency = 440. * 6; for (i64 i = 0; i < AUDIO_SAMPLE_RATE; ++i) { f64 t = ((f64) i) / AUDIO_SAMPLE_RATE; f64 x = sin(t * frequency); - if (t < .1) - x *= t / .1; - if (t > .7) - x *= (1. - t) / .3; + if (t < .005) + x *= t / .005; + if (t > .1) + x *= (1. - t) / .9; frames[i * 2] = (f32) x * .5; frames[i * 2 + 1] = (f32) x * .5; } @@ -26,6 +26,11 @@ let num_samples = output[0][0].length; let num_frames = num_samples * num_channels; + if (num_frames > this.max_num_frames) { + console.error("Sound buffer overflow"); + return true; + } + let frames = new Float32Array(this.ring); if (num_frames <= this.max_num_frames - this.position) @@ -270,51 +275,40 @@ }, p_cleanup : () => {}, p_wait_events_impl : () => { wait_for_events = true; }, - p_sleep_for : (time) => { sleep_duration += time; }, - p_time : Date.now, + p_sleep_for_impl : (time) => { sleep_duration += time; }, + p_time_impl : Date.now, p_handle_audio_impl : (samples_elapsed) => { + if (!sound_ready) + return; + let num_frames = samples_elapsed * sound_num_channels; + if (num_frames > sound_max_num_frames) { + console.error("Sound buffer overflow"); + return; + } + + let dst = new Float32Array(sound_shared_ring); + let src = new Float32Array(memory.subarray(sound_buffer_address, sound_buffer_address + sound_max_num_frames * 4)); + if (num_frames <= sound_max_num_frames - sound_position) - new Uint8Array( - sound_shared_ring.slice( - sound_position * 4, - sound_position * 4 + num_frames * 4 - ) - ).set( - memory.subarray( - sound_buffer_address + sound_position * 4, - sound_buffer_address + sound_position * 4 + num_frames * 4 - ) - ); + for (let i = 0; i < num_frames; ++i) { + dst[sound_position + i] = src[sound_position + i]; + src[sound_position + i] = 0.0; + } else { let part_one = sound_max_num_frames - sound_position; let part_two = num_frames - part_one; - new Uint8Array( - sound_shared_ring.slice( - sound_position * 4, - sound_position * 4 + part_one * 4 - ) - ).set( - memory.subarray( - sound_buffer_address + sound_position * 4, - sound_buffer_address + sound_position * 4 + part_one * 4 - ) - ); - - new Uint8Array( - sound_shared_ring.slice( - 0, - part_two * 4 - ) - ).set( - memory.subarray( - sound_buffer_address, - sound_buffer_address + part_two * 4 - ) - ); + for (let i = 0; i < part_one; ++i) { + dst[sound_position + i] = src[sound_position + i]; + src[sound_position + i] = 0.0; + } + for (let i = 0; i < part_two; ++i) { + dst[i] = src[i]; + src[i] = 0.0; + } } sound_position = (sound_position + samples_elapsed * sound_num_channels) % sound_max_num_frames; diff --git a/reduced_system_layer.c b/reduced_system_layer.c index e65653e..c272711 100755 --- a/reduced_system_layer.c +++ b/reduced_system_layer.c @@ -163,7 +163,7 @@ enum { AUDIO_NUM_CHANNELS = 2, AUDIO_SAMPLE_RATE = 44100, - AUDIO_AVAIL_MIN = 64, + AUDIO_AVAIL_MIN = 256, MAX_NUM_AUDIO_FRAMES = 10 * AUDIO_SAMPLE_RATE * AUDIO_NUM_CHANNELS, // 10 seconds @@ -940,25 +940,25 @@ void p_handle_audio(i64 samples_elapsed) { i32 s; if (num_frames <= MAX_NUM_AUDIO_FRAMES - _sound_position) { - s = snd_pcm_writei(_sound_out, _sound_ring + _sound_position, num_frames); + s = snd_pcm_writei(_sound_out, _sound_ring + _sound_position, num_frames / AUDIO_NUM_CHANNELS); if (s < 0) fprintf(stderr, "%s:%d, %s: snd_pcm_writei failed: %s\n", __FILE__, __LINE__, __func__, snd_strerror(s)); - memset(_sound_ring + _sound_position, 0, num_frames); + memset(_sound_ring + _sound_position, 0, num_frames * sizeof *_sound_ring); } else { i64 part_one = MAX_NUM_AUDIO_FRAMES - _sound_position; - i64 part_two = num_frames - part_one; + i64 part_two = num_frames - part_one; - s = snd_pcm_writei(_sound_out, _sound_ring + _sound_position, part_one); + s = snd_pcm_writei(_sound_out, _sound_ring + _sound_position, part_one / AUDIO_NUM_CHANNELS); if (s < 0) fprintf(stderr, "%s:%d, %s: snd_pcm_writei failed: %s\n", __FILE__, __LINE__, __func__, snd_strerror(s)); - s = snd_pcm_writei(_sound_out, _sound_ring, part_two); + s = snd_pcm_writei(_sound_out, _sound_ring, part_two / AUDIO_NUM_CHANNELS); if (s < 0) fprintf(stderr, "%s:%d, %s: snd_pcm_writei failed: %s\n", __FILE__, __LINE__, __func__, snd_strerror(s)); - memset(_sound_ring + _sound_position, 0, part_one); - memset(_sound_ring, 0, part_two); + memset(_sound_ring + _sound_position, 0, part_one * sizeof *_sound_ring); + memset(_sound_ring, 0, part_two * sizeof *_sound_ring); } _sound_position = (_sound_position + num_frames) % MAX_NUM_AUDIO_FRAMES; @@ -971,6 +971,7 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) { return; if (delay_in_samples < 0) { + frames += -delay_in_samples * AUDIO_NUM_CHANNELS; num_samples -= delay_in_samples; delay_in_samples = 0; } @@ -990,13 +991,16 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) { i64 begin = (_sound_position + delay_in_samples) % MAX_NUM_AUDIO_FRAMES; if (num_frames <= MAX_NUM_AUDIO_FRAMES - begin) - memcpy(_sound_ring + begin, frames, num_frames * sizeof *frames); + for (i64 i = 0; i < num_frames; ++i) + _sound_ring[begin + i] += frames[i]; else { i64 part_one = MAX_NUM_AUDIO_FRAMES - begin; i64 part_two = num_frames - part_one; - memcpy(_sound_ring + begin, frames, part_one * sizeof *frames); - memcpy(_sound_ring, frames + part_one, part_two * sizeof *frames); + for (i64 i = 0; i < part_one; ++i) + _sound_ring[begin + i] += frames[i]; + for (i64 i = 0; i < part_two; ++i) + _sound_ring[i] += frames[part_one + i]; } } @@ -1563,6 +1567,18 @@ static i32 _num_events = 0; static i32 _input_size = 0; static b8 _key_pressed[MAX_NUM_KEYS] = {0}; +i32 p_time_impl(void); + +i64 p_time(void) { + return p_time_impl(); +} + +void p_sleep_for_impl(i32 duration); + +void p_sleep_for(i64 duration) { + p_sleep_for_impl((i32) duration); +} + i32 p_handle_events(void) { platform.input_size = _input_size; _input_size = 0; @@ -1689,15 +1705,15 @@ __attribute__((export_name("js_keyup"))) void js_keyup(u32 key, u32 mod) { i64 _sound_position = 0; f32 _sound_ring[MAX_NUM_AUDIO_FRAMES] = {0}; -void p_handle_audio_impl(i64 samples_elapsed); +void p_handle_audio_impl(i32 samples_elapsed); void p_handle_audio(i64 samples_elapsed) { if (samples_elapsed <= 0) return; - _sound_position = (_sound_position + samples_elapsed * AUDIO_NUM_CHANNELS) % MAX_NUM_AUDIO_FRAMES; - p_handle_audio_impl(samples_elapsed); + + _sound_position = (_sound_position + samples_elapsed * AUDIO_NUM_CHANNELS) % MAX_NUM_AUDIO_FRAMES; } void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) { @@ -1705,6 +1721,7 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) { return; if (delay_in_samples < 0) { + frames += -delay_in_samples * AUDIO_NUM_CHANNELS; num_samples -= delay_in_samples; delay_in_samples = 0; } @@ -1716,19 +1733,19 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) { if (num_frames > MAX_NUM_AUDIO_FRAMES) return; - i64 begin = (_sound_position + delay_in_samples) % MAX_NUM_AUDIO_FRAMES; + i64 begin = (_sound_position + AUDIO_AVAIL_MIN + delay_in_samples * AUDIO_NUM_CHANNELS) % MAX_NUM_AUDIO_FRAMES; if (num_frames <= MAX_NUM_AUDIO_FRAMES - begin) for (i64 i = 0; i < num_frames; ++i) - _sound_ring[begin + i] = frames[i]; + _sound_ring[begin + i] += frames[i]; else { i64 part_one = MAX_NUM_AUDIO_FRAMES - begin; - i64 part_two = num_frames - part_one; + i64 part_two = num_frames - part_one; for (i64 i = 0; i < part_one; ++i) - _sound_ring[begin + i] = frames[i]; + _sound_ring[begin + i] += frames[i]; for (i64 i = 0; i < part_two; ++i) - _sound_ring[i] = frames[part_one + i]; + _sound_ring[i] += frames[part_one + i]; } } @@ -1748,8 +1765,8 @@ __attribute__((export_name("js_sound_buffer"))) void *js_sound_buffer(void) { return _sound_ring; } -__attribute__((export_name("js_sound_sync"))) i64 js_sound_sync(void) { - _sound_position = AUDIO_AVAIL_MIN % MAX_NUM_AUDIO_FRAMES; +__attribute__((export_name("js_sound_sync"))) void js_sound_sync(void) { + _sound_position = 0; for (i64 i = 0; i < MAX_NUM_AUDIO_FRAMES; ++i) _sound_ring[i] = 0.f; } |