summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-11-22 16:30:19 +0100
committerMitya Selivanov <automainint@guattari.tech>2024-11-22 16:30:19 +0100
commit533aa1816b2c90b3935504b489e03e6ef87038a6 (patch)
tree09140f39264c2939a5eb2683d05827894f62dac3
parenteda1d8c0bf70fc582a02b32df82d600b8b1cbe25 (diff)
downloadreduced_system_layer-533aa1816b2c90b3935504b489e03e6ef87038a6.zip
Update audio
-rw-r--r--Dockerfile4
-rwxr-xr-xexamples/sinewave.c10
-rw-r--r--index.htm66
-rwxr-xr-xreduced_system_layer.c59
4 files changed, 75 insertions, 64 deletions
diff --git a/Dockerfile b/Dockerfile
index 050a515..ff21beb 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -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;
}
diff --git a/index.htm b/index.htm
index 6624c78..d4729bf 100644
--- a/index.htm
+++ b/index.htm
@@ -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;
}