diff --git a/src/core/core.c b/src/core/core.c index b4ac89d86..c2de4c4f5 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -190,5 +190,6 @@ void mCoreLoadForeignConfig(struct mCore* core, const struct mCoreConfig* config #ifndef MINIMAL_CORE mDirectorySetMapOptions(&core->dirs, &core->opts); #endif + core->setAudioBufferSize(core, core->opts.audioBuffers); core->loadConfig(core, config); } diff --git a/src/core/core.h b/src/core/core.h index 9c5adaaa5..dcb4fcf90 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -55,6 +55,7 @@ struct mCore { struct blip_t* (*getAudioChannel)(struct mCore*, int ch); void (*setAudioBufferSize)(struct mCore*, size_t samples); + size_t (*getAudioBufferSize)(struct mCore*); void (*setAVStream)(struct mCore*, struct mAVStream*); diff --git a/src/core/sync.h b/src/core/sync.h index d4a76b0e7..8932951aa 100644 --- a/src/core/sync.h +++ b/src/core/sync.h @@ -21,6 +21,8 @@ struct mCoreSync { bool audioWait; Condition audioRequiredCond; Mutex audioBufferMutex; + + float fpsTarget; }; void mCoreSyncPostFrame(struct mCoreSync* sync); diff --git a/src/core/thread.c b/src/core/thread.c index 88712a177..86c9bb09c 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -15,6 +15,8 @@ #ifndef DISABLE_THREADING +static const float _defaultFPSTarget = 60.f; + #ifdef USE_PTHREADS static pthread_key_t _contextKey; static pthread_once_t _contextOnce = PTHREAD_ONCE_INIT; @@ -163,6 +165,10 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) { threadContext->state = THREAD_INITIALIZED; threadContext->logger.p = threadContext; + if (!threadContext->sync.fpsTarget) { + threadContext->sync.fpsTarget = _defaultFPSTarget; + } + MutexInit(&threadContext->stateMutex); ConditionInit(&threadContext->stateCond); @@ -184,6 +190,7 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) { threadContext->sync.audioWait = threadContext->core->opts.audioSync; threadContext->sync.videoFrameWait = threadContext->core->opts.videoSync; + threadContext->sync.fpsTarget = threadContext->core->opts.fpsTarget; MutexLock(&threadContext->stateMutex); ThreadCreate(&threadContext->thread, _mCoreThreadRun, threadContext); diff --git a/src/gb/core.c b/src/gb/core.c index 1b063491b..026497594 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -101,6 +101,11 @@ static void _GBCoreSetAudioBufferSize(struct mCore* core, size_t samples) { GBAudioResizeBuffer(&gb->audio, samples); } +static size_t _GBCoreGetAudioBufferSize(struct mCore* core) { + struct GB* gb = core->board; + return gb->audio.samples; +} + static void _GBCoreSetAVStream(struct mCore* core, struct mAVStream* stream) { // TODO } @@ -231,6 +236,7 @@ struct mCore* GBCoreCreate(void) { core->getVideoBuffer = _GBCoreGetVideoBuffer; core->getAudioChannel = _GBCoreGetAudioChannel; core->setAudioBufferSize = _GBCoreSetAudioBufferSize; + core->getAudioBufferSize = _GBCoreGetAudioBufferSize; core->setAVStream = _GBCoreSetAVStream; core->isROM = GBIsROM; core->loadROM = _GBCoreLoadROM; diff --git a/src/gba/core.c b/src/gba/core.c index b7f11c898..bdc35d0dc 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -132,6 +132,11 @@ static void _GBACoreSetAudioBufferSize(struct mCore* core, size_t samples) { GBAAudioResizeBuffer(&gba->audio, samples); } +static size_t _GBACoreGetAudioBufferSize(struct mCore* core) { + struct GBA* gba = core->board; + return gba->audio.samples; +} + static void _GBACoreSetAVStream(struct mCore* core, struct mAVStream* stream) { struct GBA* gba = core->board; gba->stream = stream; @@ -267,6 +272,7 @@ struct mCore* GBACoreCreate(void) { core->getVideoBuffer = _GBACoreGetVideoBuffer; core->getAudioChannel = _GBACoreGetAudioChannel; core->setAudioBufferSize = _GBACoreSetAudioBufferSize; + core->getAudioBufferSize = _GBACoreGetAudioBufferSize; core->setAVStream = _GBACoreSetAVStream; core->isROM = GBAIsROM; core->loadROM = _GBACoreLoadROM; diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index aaa7aa720..9dc5a33c0 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -18,8 +18,6 @@ using namespace QGBA; AudioDevice::AudioDevice(QObject* parent) : QIODevice(parent) , m_context(nullptr) - , m_drift(0) - , m_ratio(1.f) { setOpenMode(ReadOnly); } @@ -29,10 +27,12 @@ void AudioDevice::setFormat(const QAudioFormat& format) { LOG(QT, INFO) << tr("Can't set format of context-less audio device"); return; } - double fauxClock = GBAAudioCalculateRatio(1, 60, 1); // TODO: Put back fpsTarget + double fauxClock = GBAAudioCalculateRatio(1, m_context->sync.fpsTarget, 1); mCoreSyncLockAudio(&m_context->sync); - blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0), GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock); - blip_set_rates(m_context->core->getAudioChannel(m_context->core, 1), GBA_ARM7TDMI_FREQUENCY, format.sampleRate() * fauxClock); + blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0), + m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock); + blip_set_rates(m_context->core->getAudioChannel(m_context->core, 1), + m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock); mCoreSyncUnlockAudio(&m_context->sync); } @@ -41,8 +41,8 @@ void AudioDevice::setInput(mCoreThread* input) { } qint64 AudioDevice::readData(char* data, qint64 maxSize) { - if (maxSize > 0xFFFFFFFF) { - maxSize = 0xFFFFFFFF; + if (maxSize > 0xFFFFFFFFLL) { + maxSize = 0xFFFFFFFFLL; } if (!m_context->core) { diff --git a/src/platform/qt/AudioDevice.h b/src/platform/qt/AudioDevice.h index 249485919..3f95153be 100644 --- a/src/platform/qt/AudioDevice.h +++ b/src/platform/qt/AudioDevice.h @@ -28,8 +28,6 @@ protected: private: mCoreThread* m_context; - float m_drift; - float m_ratio; }; } diff --git a/src/platform/qt/AudioProcessorQt.cpp b/src/platform/qt/AudioProcessorQt.cpp index ddb8280a0..c20a66c9c 100644 --- a/src/platform/qt/AudioProcessorQt.cpp +++ b/src/platform/qt/AudioProcessorQt.cpp @@ -59,7 +59,7 @@ bool AudioProcessorQt::start() { m_device->setInput(input()); m_device->setFormat(m_audioOutput->format()); - m_audioOutput->setBufferSize(2048 * 4); // TODO? + m_audioOutput->setBufferSize(input()->core->getAudioBufferSize(input()->core) * 4); m_audioOutput->start(m_device); return m_audioOutput->state() == QAudio::ActiveState; diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index 8a10f4ac5..477f85779 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -101,7 +101,7 @@ GameController::GameController(QObject* parent) gba->video.renderer->disableBG[2] = !controller->m_videoLayers[2]; gba->video.renderer->disableBG[3] = !controller->m_videoLayers[3]; gba->video.renderer->disableOBJ = !controller->m_videoLayers[4];*/ - // TODO: Put back fpsTarget + controller->m_fpsTarget = context->sync.fpsTarget; if (mCoreLoadState(context->core, 0, controller->m_loadStateFlags)) { mCoreDeleteState(context->core, 0); @@ -239,6 +239,7 @@ void GameController::setConfig(const mCoreConfig* config) { if (isLoaded()) { threadInterrupt(); mCoreLoadForeignConfig(m_threadContext.core, config); + m_audioProcessor->setInput(&m_threadContext); threadContinue(); } } @@ -680,9 +681,9 @@ void GameController::setVideoLayerEnabled(int layer, bool enable) { void GameController::setFPSTarget(float fps) { threadInterrupt(); m_fpsTarget = fps; - // TODO: Put back fpsTarget + m_threadContext.sync.fpsTarget = fps; if (m_turbo && m_turboSpeed > 0) { - // TODO: Put back fpsTarget + m_threadContext.sync.fpsTarget *= m_turboSpeed; } if (m_audioProcessor) { redoSamples(m_audioProcessor->getBufferSamples()); @@ -805,15 +806,15 @@ void GameController::setTurboSpeed(float ratio) { void GameController::enableTurbo() { threadInterrupt(); if (!m_turbo) { - // TODO: Put back fpsTarget + m_threadContext.sync.fpsTarget = m_fpsTarget; m_threadContext.sync.audioWait = m_audioSync; m_threadContext.sync.videoFrameWait = m_videoSync; } else if (m_turboSpeed <= 0) { - // TODO: Put back fpsTarget + m_threadContext.sync.fpsTarget = m_fpsTarget; m_threadContext.sync.audioWait = false; m_threadContext.sync.videoFrameWait = false; } else { - // TODO: Put back fpsTarget + m_threadContext.sync.fpsTarget = m_fpsTarget * m_turboSpeed; m_threadContext.sync.audioWait = true; m_threadContext.sync.videoFrameWait = false; } @@ -927,7 +928,6 @@ void GameController::updateKeys() { } void GameController::redoSamples(int samples) { - // TODO: Put back audio buffers if (m_threadContext.core) { m_threadContext.core->setAudioBufferSize(m_threadContext.core, samples); } diff --git a/src/platform/sdl/sdl-audio.c b/src/platform/sdl/sdl-audio.c index d23b600ca..7001f7b04 100644 --- a/src/platform/sdl/sdl-audio.c +++ b/src/platform/sdl/sdl-audio.c @@ -38,15 +38,8 @@ bool mSDLInitAudio(struct mSDLAudio* context, struct GBAThread* threadContext) { } context->samples = context->obtainedSpec.samples; context->core = 0; - context->thread = 0; if (threadContext) { - context->thread = threadContext; - float ratio = GBAAudioCalculateRatio(0x8000, threadContext->fpsTarget, 44100); - threadContext->audioBuffers = context->samples / ratio; - if (context->samples > threadContext->audioBuffers) { - threadContext->audioBuffers = context->samples * 2; - } context->sync = &threadContext->sync; #if SDL_VERSION_ATLEAST(2, 0, 0) @@ -91,7 +84,7 @@ void mSDLResumeAudio(struct mSDLAudio* context) { static void _mSDLAudioCallback(void* context, Uint8* data, int len) { struct mSDLAudio* audioContext = context; - if (!context || (!audioContext->core && !audioContext->thread)) { + if (!context || !audioContext->core) { memset(data, 0, len); return; } @@ -102,16 +95,12 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { left = audioContext->core->getAudioChannel(audioContext->core, 0); right = audioContext->core->getAudioChannel(audioContext->core, 1); clockRate = audioContext->core->frequency(audioContext->core); - } else if (audioContext->thread) { - left = audioContext->thread->gba->audio.psg.left; - right = audioContext->thread->gba->audio.psg.right; - clockRate = GBA_ARM7TDMI_FREQUENCY; } double fauxClock = 1; - if (audioContext->thread) { - fauxClock = GBAAudioCalculateRatio(1, audioContext->thread->fpsTarget, 1); - } if (audioContext->sync) { + if (audioContext->sync->fpsTarget > 0) { + fauxClock = GBAAudioCalculateRatio(1, audioContext->sync->fpsTarget, 1); + } mCoreSyncLockAudio(audioContext->sync); } blip_set_rates(left, clockRate, audioContext->obtainedSpec.freq * fauxClock);