mirror of https://github.com/mgba-emu/mgba.git
GBA Audio: Audio buffer sizes are now correct sizes for both sample rates
This commit is contained in:
parent
892a5e5d5e
commit
c91c46ce97
1
CHANGES
1
CHANGES
|
@ -22,6 +22,7 @@ Bugfixes:
|
|||
- 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
|
||||
|
|
|
@ -861,6 +861,6 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
#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);
|
||||
|
@ -25,6 +25,17 @@ struct AVAudioResampleContext* GBAAudioOpenLAVR(struct GBAAudio* audio, unsigned
|
|||
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;
|
||||
}
|
||||
return avr;
|
||||
}
|
||||
|
||||
unsigned GBAAudioResampleLAVR(struct GBAAudio* audio, struct AVAudioResampleContext* avr, struct GBAStereoSample* output, unsigned nSamples) {
|
||||
int16_t left[GBA_AUDIO_SAMPLES];
|
||||
int16_t right[GBA_AUDIO_SAMPLES];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,7 +26,7 @@ void AudioDevice::setFormat(const QAudioFormat& format) {
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -278,11 +278,13 @@ void GameController::keyReleased(int key) {
|
|||
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));
|
||||
|
|
|
@ -38,6 +38,8 @@ bool GBASDLInitAudio(struct GBASDLAudio* context, struct GBAThread* threadContex
|
|||
}
|
||||
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 @@ static void _GBASDLAudioCallback(void* context, Uint8* data, int 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 @@ static void _GBASDLAudioCallback(void* context, Uint8* data, int len) {
|
|||
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;
|
||||
|
|
|
@ -17,9 +17,9 @@ struct GBASDLAudio {
|
|||
// State
|
||||
SDL_AudioSpec desiredSpec;
|
||||
SDL_AudioSpec obtainedSpec;
|
||||
float ratio;
|
||||
#ifndef USE_FFMPEG
|
||||
float drift;
|
||||
float ratio;
|
||||
#else
|
||||
struct AVAudioResampleContext* avr;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue