SDL: Allow GBASDLAudio to be used without a thread context

This commit is contained in:
Jeffrey Pfau 2015-10-11 17:33:11 -07:00
parent a8110342ce
commit d31326a024
3 changed files with 35 additions and 20 deletions

View File

@ -41,7 +41,8 @@ Misc:
- All: Reset next event to cycles instead of zero to interrupt - All: Reset next event to cycles instead of zero to interrupt
- GBA Video: Remove lastHblank, as it is implied - GBA Video: Remove lastHblank, as it is implied
- GBA: Check for cycle count being too high - GBA: Check for cycle count being too high
- GBA Config: Add "override" layer for better one-time configuration` - GBA Config: Add "override" layer for better one-time configuration
- SDL: Allow GBASDLAudio to be used without a thread context
0.3.0: (2015-08-16) 0.3.0: (2015-08-16)
Features: Features:

View File

@ -41,19 +41,23 @@ bool GBASDLInitAudio(struct GBASDLAudio* context, struct GBAThread* threadContex
GBALog(0, GBA_LOG_ERROR, "Could not open SDL sound system"); GBALog(0, GBA_LOG_ERROR, "Could not open SDL sound system");
return false; return false;
} }
context->thread = threadContext;
context->samples = context->obtainedSpec.samples; context->samples = context->obtainedSpec.samples;
float ratio = GBAAudioCalculateRatio(0x8000, threadContext->fpsTarget, 44100);
threadContext->audioBuffers = context->samples / ratio; if (threadContext) {
if (context->samples > threadContext->audioBuffers) { context->thread = threadContext;
threadContext->audioBuffers = context->samples * 2; float ratio = GBAAudioCalculateRatio(0x8000, threadContext->fpsTarget, 44100);
} threadContext->audioBuffers = context->samples / ratio;
if (context->samples > threadContext->audioBuffers) {
threadContext->audioBuffers = context->samples * 2;
}
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_PauseAudioDevice(context->deviceId, 0); SDL_PauseAudioDevice(context->deviceId, 0);
#else #else
SDL_PauseAudio(0); SDL_PauseAudio(0);
#endif #endif
}
return true; return true;
} }
@ -89,12 +93,15 @@ void GBASDLResumeAudio(struct GBASDLAudio* context) {
static void _GBASDLAudioCallback(void* context, Uint8* data, int len) { static void _GBASDLAudioCallback(void* context, Uint8* data, int len) {
struct GBASDLAudio* audioContext = context; struct GBASDLAudio* audioContext = context;
if (!context || !audioContext->thread || !audioContext->thread->gba) { if (!context || (!audioContext->gba && (!audioContext->thread || !audioContext->thread->gba))) {
memset(data, 0, len); memset(data, 0, len);
return; return;
} }
if (!audioContext->gba) {
audioContext->gba = audioContext->thread->gba;
}
#if RESAMPLE_LIBRARY == RESAMPLE_NN #if RESAMPLE_LIBRARY == RESAMPLE_NN
audioContext->ratio = GBAAudioCalculateRatio(audioContext->thread->gba->audio.sampleRate, audioContext->thread->fpsTarget, audioContext->obtainedSpec.freq); audioContext->ratio = GBAAudioCalculateRatio(audioContext->gba->audio.sampleRate, audioContext->fpsTarget, audioContext->obtainedSpec.freq);
if (audioContext->ratio == INFINITY) { if (audioContext->ratio == INFINITY) {
memset(data, 0, len); memset(data, 0, len);
return; return;
@ -102,23 +109,29 @@ static void _GBASDLAudioCallback(void* context, Uint8* data, int len) {
struct GBAStereoSample* ssamples = (struct GBAStereoSample*) data; struct GBAStereoSample* ssamples = (struct GBAStereoSample*) data;
len /= 2 * audioContext->obtainedSpec.channels; len /= 2 * audioContext->obtainedSpec.channels;
if (audioContext->obtainedSpec.channels == 2) { if (audioContext->obtainedSpec.channels == 2) {
GBAAudioResampleNN(&audioContext->thread->gba->audio, audioContext->ratio, &audioContext->drift, ssamples, len); GBAAudioResampleNN(&audioContext->gba->audio, audioContext->ratio, &audioContext->drift, ssamples, len);
} }
#elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF #elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
double fauxClock = GBAAudioCalculateRatio(1, audioContext->thread->fpsTarget, 1); double fauxClock = 1;
GBASyncLockAudio(&audioContext->thread->sync); if (audioContext->thread) {
blip_set_rates(audioContext->thread->gba->audio.left, GBA_ARM7TDMI_FREQUENCY, audioContext->obtainedSpec.freq * fauxClock); GBAAudioCalculateRatio(1, audioContext->thread->fpsTarget, 1);
blip_set_rates(audioContext->thread->gba->audio.right, GBA_ARM7TDMI_FREQUENCY, audioContext->obtainedSpec.freq * fauxClock); GBASyncLockAudio(&audioContext->thread->sync);
}
blip_set_rates(audioContext->gba->audio.left, GBA_ARM7TDMI_FREQUENCY, audioContext->obtainedSpec.freq * fauxClock);
blip_set_rates(audioContext->gba->audio.right, GBA_ARM7TDMI_FREQUENCY, audioContext->obtainedSpec.freq * fauxClock);
len /= 2 * audioContext->obtainedSpec.channels; len /= 2 * audioContext->obtainedSpec.channels;
int available = blip_samples_avail(audioContext->thread->gba->audio.left); int available = blip_samples_avail(audioContext->gba->audio.left);
if (available > len) { if (available > len) {
available = len; available = len;
} }
blip_read_samples(audioContext->thread->gba->audio.left, (short*) data, available, audioContext->obtainedSpec.channels == 2); blip_read_samples(audioContext->gba->audio.left, (short*) data, available, audioContext->obtainedSpec.channels == 2);
if (audioContext->obtainedSpec.channels == 2) { if (audioContext->obtainedSpec.channels == 2) {
blip_read_samples(audioContext->thread->gba->audio.right, ((short*) data) + 1, available, 1); blip_read_samples(audioContext->gba->audio.right, ((short*) data) + 1, available, 1);
}
if (audioContext->thread) {
GBASyncConsumeAudio(&audioContext->thread->sync);
} }
GBASyncConsumeAudio(&audioContext->thread->sync);
if (available < len) { if (available < len) {
memset(((short*) data) + audioContext->obtainedSpec.channels * available, 0, (len - available) * audioContext->obtainedSpec.channels * sizeof(short)); memset(((short*) data) + audioContext->obtainedSpec.channels * available, 0, (len - available) * audioContext->obtainedSpec.channels * sizeof(short));
} }

View File

@ -31,6 +31,7 @@ struct GBASDLAudio {
#endif #endif
struct GBAThread* thread; struct GBAThread* thread;
struct GBA* gba;
}; };
bool GBASDLInitAudio(struct GBASDLAudio* context, struct GBAThread* threadContext); bool GBASDLInitAudio(struct GBASDLAudio* context, struct GBAThread* threadContext);