all repos — mgba @ c91c46ce97182d62185e4ff2bc33d9265557639d

mGBA Game Boy Advance Emulator

GBA Audio: Audio buffer sizes are now correct sizes for both sample rates
Jeffrey Pfau jeffrey@endrift.com
Sun, 21 Dec 2014 21:30:59 -0800
commit

c91c46ce97182d62185e4ff2bc33d9265557639d

parent

892a5e5d5e1845a6ece184a8bb46cb5e45892c28

M CHANGESCHANGES

@@ -22,6 +22,7 @@ - GBA Audio: Support 16-bit writes to FIFO audio

- GBA Memory: Properly initialize 1 Mb flash, and add debug logging - Qt: Properly set default video recording settings - GBA Audio: Make larger buffer sizes than 2048 actually work properly + - GBA Audio: Audio buffer sizes are now correct sizes for both sample rates Misc: - Qt: Disable sync to video by default - GBA: Exit cleanly on FATAL if the port supports it
M src/gba/gba-audio.csrc/gba/gba-audio.c

@@ -861,6 +861,6 @@ audio->eventDiff = state->audio.eventDiff;

audio->nextSample = state->audio.nextSample; } -float GBAAudioCalculateRatio(struct GBAAudio* audio, float desiredFPS, float desiredSampleRate) { - return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * audio->sampleRate); +float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) { + return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * inputSampleRate); }
M src/gba/gba-audio.hsrc/gba/gba-audio.h

@@ -263,6 +263,6 @@ struct GBASerializedState;

void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state); void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state); -float GBAAudioCalculateRatio(struct GBAAudio* audio, float desiredFPS, float desiredSampleRatio); +float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRatio); #endif
M src/platform/ffmpeg/ffmpeg-resample.csrc/platform/ffmpeg/ffmpeg-resample.c

@@ -10,14 +10,25 @@

#include <libavresample/avresample.h> #include <libavutil/opt.h> -struct AVAudioResampleContext* GBAAudioOpenLAVR(struct GBAAudio* audio, unsigned outputRate) { +struct AVAudioResampleContext* GBAAudioOpenLAVR(unsigned inputRate, unsigned outputRate) { AVAudioResampleContext *avr = avresample_alloc_context(); av_opt_set_int(avr, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(avr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); - av_opt_set_int(avr, "in_sample_rate", audio->sampleRate, 0); + av_opt_set_int(avr, "in_sample_rate", inputRate, 0); av_opt_set_int(avr, "out_sample_rate", outputRate, 0); av_opt_set_int(avr, "in_sample_fmt", AV_SAMPLE_FMT_S16P, 0); av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); + if (avresample_open(avr)) { + avresample_free(&avr); + return 0; + } + return avr; +} + +struct AVAudioResampleContext* GBAAudioReopenLAVR(struct AVAudioResampleContext* avr, unsigned inputRate, unsigned outputRate) { + avresample_close(avr); + av_opt_set_int(avr, "in_sample_rate", inputRate, 0); + av_opt_set_int(avr, "out_sample_rate", outputRate, 0); if (avresample_open(avr)) { avresample_free(&avr); return 0;
M src/platform/ffmpeg/ffmpeg-resample.hsrc/platform/ffmpeg/ffmpeg-resample.h

@@ -10,7 +10,8 @@ struct AVAudioResampleContext;

struct GBAAudio; struct GBAStereoSample; -struct AVAudioResampleContext* GBAAudioOpenLAVR(struct GBAAudio* audio, unsigned outputRate); +struct AVAudioResampleContext* GBAAudioOpenLAVR(unsigned inputRate, unsigned outputRate); +struct AVAudioResampleContext* GBAAudioReopenLAVR(struct AVAudioResampleContext* avr, unsigned inputRate, unsigned outputRate); unsigned GBAAudioResampleLAVR(struct GBAAudio* audio, struct AVAudioResampleContext* avr, struct GBAStereoSample* output, unsigned nSamples); #endif
M src/platform/qt/AudioDevice.cppsrc/platform/qt/AudioDevice.cpp

@@ -26,7 +26,7 @@ if (!GBAThreadHasStarted(m_context)) {

return; } GBAThreadInterrupt(m_context); - m_ratio = GBAAudioCalculateRatio(&m_context->gba->audio, m_context->fpsTarget, format.sampleRate()); + m_ratio = GBAAudioCalculateRatio(m_context->gba->audio.sampleRate, m_context->fpsTarget, format.sampleRate()); GBAThreadContinue(m_context); }
M src/platform/qt/GameController.cppsrc/platform/qt/GameController.cpp

@@ -278,11 +278,13 @@

void GameController::setAudioBufferSamples(int samples) { if (m_gameOpen) { threadInterrupt(); - m_threadContext.audioBuffers = samples; - GBAAudioResizeBuffer(&m_threadContext.gba->audio, samples); + float ratio = GBAAudioCalculateRatio(m_threadContext.gba->audio.sampleRate, m_threadContext.fpsTarget, 44100); + m_threadContext.audioBuffers = samples / ratio; + GBAAudioResizeBuffer(&m_threadContext.gba->audio, samples / ratio); threadContinue(); } else { - m_threadContext.audioBuffers = samples; + float ratio = GBAAudioCalculateRatio(0x8000, m_threadContext.fpsTarget, 44100); + m_threadContext.audioBuffers = samples / ratio; } QMetaObject::invokeMethod(m_audioProcessor, "setBufferSamples", Q_ARG(int, samples));
M src/platform/sdl/sdl-audio.csrc/platform/sdl/sdl-audio.c

@@ -38,6 +38,8 @@ return false;

} context->thread = threadContext; context->samples = context->obtainedSpec.samples; + float ratio = GBAAudioCalculateRatio(0x8000, threadContext->fpsTarget, 44100); + threadContext->audioBuffers = context->samples / ratio; if (context->samples > threadContext->audioBuffers) { threadContext->audioBuffers = context->samples * 2; }

@@ -77,7 +79,7 @@ memset(data, 0, len);

return; } #ifndef USE_FFMPEG - audioContext->ratio = GBAAudioCalculateRatio(&audioContext->thread->gba->audio, audioContext->thread->fpsTarget, audioContext->obtainedSpec.freq); + audioContext->ratio = GBAAudioCalculateRatio(audioContext->thread->gba->audio.sampleRate, audioContext->thread->fpsTarget, audioContext->obtainedSpec.freq); if (audioContext->ratio == INFINITY) { memset(data, 0, len); return;

@@ -88,12 +90,17 @@ if (audioContext->obtainedSpec.channels == 2) {

GBAAudioResampleNN(&audioContext->thread->gba->audio, audioContext->ratio, &audioContext->drift, ssamples, len); } #else + float ratio = GBAAudioCalculateRatio(audioContext->thread->gba->audio.sampleRate, audioContext->thread->fpsTarget, audioContext->thread->gba->audio.sampleRate); if (!audioContext->avr) { if (!audioContext->thread->gba->audio.sampleRate) { memset(data, 0, len); return; } - audioContext->avr = GBAAudioOpenLAVR(&audioContext->thread->gba->audio, audioContext->obtainedSpec.freq); + audioContext->ratio = ratio; + audioContext->avr = GBAAudioOpenLAVR(audioContext->thread->gba->audio.sampleRate / ratio, audioContext->obtainedSpec.freq); + } else if (ratio != audioContext->ratio) { + audioContext->ratio = ratio; + audioContext->avr = GBAAudioReopenLAVR(audioContext->avr, audioContext->thread->gba->audio.sampleRate / ratio, audioContext->obtainedSpec.freq); } struct GBAStereoSample* ssamples = (struct GBAStereoSample*) data; len /= 2 * audioContext->obtainedSpec.channels;
M src/platform/sdl/sdl-audio.hsrc/platform/sdl/sdl-audio.h

@@ -17,9 +17,9 @@

// State SDL_AudioSpec desiredSpec; SDL_AudioSpec obtainedSpec; + float ratio; #ifndef USE_FFMPEG float drift; - float ratio; #else struct AVAudioResampleContext* avr; #endif