#include #include 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; } void audioDestroy(AudioContext *aud) { SDL_CloseAudioDevice(aud->id); } 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; }