src/platform/sdl/sdl-audio.c (view raw)
1#include "sdl-audio.h"
2
3#include "gba.h"
4#include "gba-thread.h"
5
6#define BUFFER_SIZE (GBA_AUDIO_SAMPLES >> 2)
7
8static void _GBASDLAudioCallback(void* context, Uint8* data, int len);
9
10bool GBASDLInitAudio(struct GBASDLAudio* context) {
11 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
12 GBALog(0, GBA_LOG_ERROR, "Could not initialize SDL sound system");
13 return false;
14 }
15
16 context->desiredSpec.freq = 44100;
17 context->desiredSpec.format = AUDIO_S16SYS;
18 context->desiredSpec.channels = 2;
19 context->desiredSpec.samples = context->samples;
20 context->desiredSpec.callback = _GBASDLAudioCallback;
21 context->desiredSpec.userdata = context;
22 context->audio = 0;
23 context->thread = 0;
24 context->drift = 0.f;
25 if (SDL_OpenAudio(&context->desiredSpec, &context->obtainedSpec) < 0) {
26 GBALog(0, GBA_LOG_ERROR, "Could not open SDL sound system");
27 return false;
28 }
29 context->samples = context->obtainedSpec.samples;
30 SDL_PauseAudio(0);
31 return true;
32}
33
34void GBASDLDeinitAudio(struct GBASDLAudio* context) {
35 UNUSED(context);
36 SDL_PauseAudio(1);
37 SDL_CloseAudio();
38 SDL_QuitSubSystem(SDL_INIT_AUDIO);
39}
40
41static void _GBASDLAudioCallback(void* context, Uint8* data, int len) {
42 struct GBASDLAudio* audioContext = context;
43 if (!context || !audioContext->audio) {
44 memset(data, 0, len);
45 return;
46 }
47 audioContext->ratio = GBAAudioCalculateRatio(audioContext->audio, audioContext->thread->fpsTarget, audioContext->obtainedSpec.freq);
48 struct GBAStereoSample* ssamples = (struct GBAStereoSample*) data;
49 len /= 2 * audioContext->obtainedSpec.channels;
50 if (audioContext->obtainedSpec.channels == 2) {
51 GBAAudioResampleNN(audioContext->audio, audioContext->ratio, &audioContext->drift, ssamples, len);
52 }
53}