2024-10-22 00:52:51 +00:00
|
|
|
#include <audio.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2024-10-24 02:50:44 +00:00
|
|
|
void audioCallback(void *userdata, uint8_t *stream, int len) {
|
|
|
|
AudioContext *aud;
|
|
|
|
SDL_assert(len == 834 * 4);
|
|
|
|
|
|
|
|
aud = userdata;
|
|
|
|
if (!aud->filled) {
|
|
|
|
/* too little data, play silence */
|
|
|
|
SDL_memset4(stream, 0, 834);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SDL_memcpy4(stream, aud->buffers[aud->current], 834);
|
|
|
|
++aud->current;
|
|
|
|
aud->current %= 2;
|
|
|
|
aud->filled -= 1;
|
|
|
|
}
|
|
|
|
|
2024-10-22 00:52:51 +00:00
|
|
|
int audioInit(AudioContext *aud) {
|
|
|
|
SDL_AudioSpec spec;
|
|
|
|
spec.freq = 41700;
|
2024-10-23 23:01:54 +00:00
|
|
|
spec.format = AUDIO_S16;
|
2024-10-22 00:52:51 +00:00
|
|
|
spec.channels = 2;
|
2024-10-24 02:50:44 +00:00
|
|
|
spec.samples = 834;
|
|
|
|
spec.callback = &audioCallback;
|
|
|
|
spec.userdata = aud;
|
2024-10-22 00:52:51 +00:00
|
|
|
|
2024-10-23 23:01:54 +00:00
|
|
|
aud->id = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
|
2024-10-22 00:52:51 +00:00
|
|
|
aud->paused = true;
|
2024-10-23 23:01:54 +00:00
|
|
|
if (!aud->id) {
|
|
|
|
fprintf(stderr, "could not open audio device: %s\n", SDL_GetError());
|
2024-10-22 00:52:51 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2024-10-24 02:50:44 +00:00
|
|
|
aud->current = 0;
|
|
|
|
aud->filled = 0;
|
2024-10-22 00:52:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-10-30 01:53:17 +00:00
|
|
|
void audioDestroy(AudioContext *aud) {
|
|
|
|
SDL_CloseAudioDevice(aud->id);
|
|
|
|
}
|
|
|
|
|
2024-10-22 00:52:51 +00:00
|
|
|
int audioUpdate(AudioContext *aud, void *data, uint32_t bytes) {
|
2024-10-24 02:50:44 +00:00
|
|
|
int filled;
|
2024-10-23 23:01:54 +00:00
|
|
|
if (!aud->id) return -1;
|
2024-10-24 02:50:44 +00:00
|
|
|
SDL_assert(bytes == 834 * 4);
|
2024-10-22 00:52:51 +00:00
|
|
|
|
2024-10-24 02:50:44 +00:00
|
|
|
SDL_LockAudioDevice(aud->id);
|
|
|
|
if (aud->filled < 2) {
|
|
|
|
int next = (aud->current + aud->filled) % 2;
|
|
|
|
SDL_memcpy4(aud->buffers[next], data, bytes / 4);
|
|
|
|
aud->filled += 1;
|
2024-10-22 00:52:51 +00:00
|
|
|
}
|
2024-10-24 02:50:44 +00:00
|
|
|
filled = aud->filled;
|
|
|
|
SDL_UnlockAudioDevice(aud->id);
|
2024-10-22 00:52:51 +00:00
|
|
|
|
|
|
|
if (aud->paused) {
|
2024-10-23 23:01:54 +00:00
|
|
|
SDL_PauseAudioDevice(aud->id, false);
|
2024-10-22 00:52:51 +00:00
|
|
|
aud->paused = false;
|
|
|
|
}
|
|
|
|
|
2024-10-24 02:50:44 +00:00
|
|
|
while (filled > 1) {
|
|
|
|
SDL_Delay(0);
|
|
|
|
filled = aud->filled;
|
|
|
|
}
|
|
|
|
|
2024-10-22 00:52:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|