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#define FPS_TARGET 60.f
8
9static void _GBASDLAudioCallback(void* context, Uint8* data, int len);
10
11bool GBASDLInitAudio(struct GBASDLAudio* context) {
12 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
13 GBALog(0, GBA_LOG_ERROR, "Could not initialize SDL sound system");
14 return false;
15 }
16
17 context->desiredSpec.freq = 44100;
18 context->desiredSpec.format = AUDIO_S16SYS;
19 context->desiredSpec.channels = 2;
20 context->desiredSpec.samples = GBA_AUDIO_SAMPLES;
21 context->desiredSpec.callback = _GBASDLAudioCallback;
22 context->desiredSpec.userdata = context;
23 context->audio = 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 SDL_PauseAudio(0);
30 return true;
31}
32
33void GBASDLDeinitAudio(struct GBASDLAudio* context) {
34 UNUSED(context);
35 SDL_PauseAudio(1);
36 SDL_CloseAudio();
37 SDL_QuitSubSystem(SDL_INIT_AUDIO);
38}
39
40static void _GBASDLAudioCallback(void* context, Uint8* data, int len) {
41 struct GBASDLAudio* audioContext = context;
42 if (!context || !audioContext->audio) {
43 memset(data, 0, len);
44 return;
45 }
46 audioContext->ratio = GBAAudioCalculateRatio(audioContext->audio, FPS_TARGET, audioContext->obtainedSpec.freq);
47 struct GBAStereoSample* ssamples = (struct GBAStereoSample*) data;
48 len /= 2 * audioContext->obtainedSpec.channels;
49 if (audioContext->obtainedSpec.channels == 2) {
50 GBAAudioResampleNN(audioContext->audio, audioContext->ratio, &audioContext->drift, ssamples, len);
51 }
52}