lemur/audio.c

65 lines
1.5 KiB
C

#include <audio.h>
#include <stdio.h>
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;
}
int audioInit(AudioContext *aud) {
SDL_AudioSpec spec;
spec.freq = 41700;
spec.format = AUDIO_S16;
spec.channels = 2;
spec.samples = 834;
spec.callback = &audioCallback;
spec.userdata = aud;
aud->id = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
aud->paused = true;
if (!aud->id) {
fprintf(stderr, "could not open audio device: %s\n", SDL_GetError());
return -1;
}
aud->current = 0;
aud->filled = 0;
return 0;
}
int audioUpdate(AudioContext *aud, void *data, uint32_t bytes) {
int filled;
if (!aud->id) return -1;
SDL_assert(bytes == 834 * 4);
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;
}
filled = aud->filled;
SDL_UnlockAudioDevice(aud->id);
if (aud->paused) {
SDL_PauseAudioDevice(aud->id, false);
aud->paused = false;
}
while (filled > 1) {
SDL_Delay(0);
filled = aud->filled;
}
return 0;
}