all repos — mgba @ 7c8401e7f89266f2666aa297853e563baaa7d3de

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	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}