all repos — mgba @ ae534aff74503630f3c4c8a38bfb5aef82754533

mGBA Game Boy Advance Emulator

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	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, audioContext->thread->fpsTarget, 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}