diff --git a/mt32emu_qt/src/audiodrv/AlsaAudioDriver.cpp b/mt32emu_qt/src/audiodrv/AlsaAudioDriver.cpp index 3f4a8f0..9d04d56 100644 --- a/mt32emu_qt/src/audiodrv/AlsaAudioDriver.cpp +++ b/mt32emu_qt/src/audiodrv/AlsaAudioDriver.cpp @@ -59,8 +59,7 @@ void *AlsaAudioStream::processingThread(void *userData) { framesInAudioBuffer = (quint32)delayp; } } - audioStream.updateTimeInfo(nanosNow, framesInAudioBuffer); - audioStream.synthRoute.render(audioStream.buffer, audioStream.bufferSize); + audioStream.renderAndUpdateState(audioStream.buffer, audioStream.bufferSize, nanosNow, framesInAudioBuffer); error = snd_pcm_writei(audioStream.stream, audioStream.buffer, audioStream.bufferSize); if (error < 0) { qDebug() << "snd_pcm_writei failed:" << snd_strerror(error) << "-> recovering..."; @@ -75,7 +74,6 @@ void *AlsaAudioStream::processingThread(void *userData) { // isErrorOccured = true; // break; } - audioStream.framesRendered(audioStream.bufferSize); } if (isErrorOccured) { snd_pcm_close(audioStream.stream); diff --git a/mt32emu_qt/src/audiodrv/AudioDriver.cpp b/mt32emu_qt/src/audiodrv/AudioDriver.cpp index d407ac5..184d0fc 100644 --- a/mt32emu_qt/src/audiodrv/AudioDriver.cpp +++ b/mt32emu_qt/src/audiodrv/AudioDriver.cpp @@ -82,6 +82,13 @@ quint64 AudioStream::computeMIDITimestamp(uint relativeFrameTime) const { return getRenderedFramesCount() + relativeFrameTime; } +// Only called from the rendering thread. +void AudioStream::renderAndUpdateState(MT32Emu::Bit16s *buffer, const quint32 frameCount, const MasterClockNanos measuredNanos, const quint32 framesInAudioBuffer) { + updateTimeInfo(measuredNanos, framesInAudioBuffer); + synthRoute.render(buffer, frameCount); + framesRendered(frameCount); +} + // Only called from the rendering thread. void AudioStream::updateTimeInfo(const MasterClockNanos measuredNanos, const quint32 framesInAudioBuffer) { const TimeInfo &timeInfo = timeInfos[getSnapshotReadIx(timeInfoChangeCount)]; diff --git a/mt32emu_qt/src/audiodrv/AudioDriver.h b/mt32emu_qt/src/audiodrv/AudioDriver.h index fb614d3..3d8e40f 100644 --- a/mt32emu_qt/src/audiodrv/AudioDriver.h +++ b/mt32emu_qt/src/audiodrv/AudioDriver.h @@ -40,6 +40,7 @@ protected: } timeInfos[2]; QAtomicInt timeInfoChangeCount; + void renderAndUpdateState(MT32Emu::Bit16s *buffer, const quint32 frameCount, const MasterClockNanos measuredNanos, const quint32 framesInAudioBuffer); void updateTimeInfo(const MasterClockNanos measuredNanos, const quint32 framesInAudioBuffer); bool isAutoLatencyMode() const; void framesRendered(quint32 frameCount); diff --git a/mt32emu_qt/src/audiodrv/CoreAudioDriver.cpp b/mt32emu_qt/src/audiodrv/CoreAudioDriver.cpp index 9388994..de58db3 100644 --- a/mt32emu_qt/src/audiodrv/CoreAudioDriver.cpp +++ b/mt32emu_qt/src/audiodrv/CoreAudioDriver.cpp @@ -93,11 +93,9 @@ void CoreAudioStream::renderOutputBuffer(void *userData, AudioQueueRef queue, Au qDebug() << "CoreAudio: AudioQueueGetCurrentTime() returns invalid sample time"; } } - stream->updateTimeInfo(nanosNow, framesInAudioBuffer); uint frameCount = buffer->mAudioDataByteSize >> 2; - stream->synthRoute.render((MT32Emu::Bit16s *)buffer->mAudioData, frameCount); - stream->framesRendered(frameCount); + stream->renderAndUpdateState((MT32Emu::Bit16s *)buffer->mAudioData, frameCount, nanosNow, framesInAudioBuffer); OSStatus res = AudioQueueEnqueueBuffer(queue, buffer, 0, NULL); if (res) qDebug() << "CoreAudio: AudioQueueEnqueueBuffer() failed with error code:" << res; diff --git a/mt32emu_qt/src/audiodrv/OSSAudioDriver.cpp b/mt32emu_qt/src/audiodrv/OSSAudioDriver.cpp index df8b6be..ad353fe 100644 --- a/mt32emu_qt/src/audiodrv/OSSAudioDriver.cpp +++ b/mt32emu_qt/src/audiodrv/OSSAudioDriver.cpp @@ -64,8 +64,7 @@ void *OSSAudioStream::processingThread(void *userData) { } else { framesInAudioBuffer = 0; } - audioStream.updateTimeInfo(nanosNow, framesInAudioBuffer); - audioStream.synthRoute.render(audioStream.buffer, audioStream.bufferSize); + audioStream.renderAndUpdateState(audioStream.buffer, audioStream.bufferSize, nanosNow, framesInAudioBuffer); error = write(audioStream.stream, audioStream.buffer, FRAME_SIZE * audioStream.bufferSize); if (error != int(FRAME_SIZE * audioStream.bufferSize)) { if (error == -1) { @@ -76,7 +75,6 @@ void *OSSAudioStream::processingThread(void *userData) { isErrorOccured = true; break; } - audioStream.framesRendered(audioStream.bufferSize); } if (isErrorOccured) { close(audioStream.stream); diff --git a/mt32emu_qt/src/audiodrv/PortAudioDriver.cpp b/mt32emu_qt/src/audiodrv/PortAudioDriver.cpp index 734a7ba..043c017 100644 --- a/mt32emu_qt/src/audiodrv/PortAudioDriver.cpp +++ b/mt32emu_qt/src/audiodrv/PortAudioDriver.cpp @@ -134,10 +134,8 @@ int PortAudioStream::paCallback(const void *inputBuffer, void *outputBuffer, uns } else { framesInAudioBuffer = 0; } - stream->updateTimeInfo(nanosNow, framesInAudioBuffer); + stream->renderAndUpdateState((Bit16s *)outputBuffer, quint32(frameCount), nanosNow, framesInAudioBuffer); - stream->synthRoute.render((Bit16s *)outputBuffer, frameCount); - stream->framesRendered(quint32(frameCount)); return paContinue; } diff --git a/mt32emu_qt/src/audiodrv/PulseAudioDriver.cpp b/mt32emu_qt/src/audiodrv/PulseAudioDriver.cpp index 8e8cd6b..a5feab6 100644 --- a/mt32emu_qt/src/audiodrv/PulseAudioDriver.cpp +++ b/mt32emu_qt/src/audiodrv/PulseAudioDriver.cpp @@ -151,8 +151,7 @@ void *PulseAudioStream::processingThread(void *userData) { } else { framesInAudioBuffer = 0; } - audioStream.updateTimeInfo(nanosNow, framesInAudioBuffer); - audioStream.synthRoute.render(audioStream.buffer, audioStream.bufferSize); + audioStream.renderAndUpdateState(audioStream.buffer, audioStream.bufferSize, nanosNow, framesInAudioBuffer); if (_pa_simple_write(audioStream.stream, audioStream.buffer, audioStream.bufferSize * FRAME_SIZE, &error) < 0) { qDebug() << "pa_simple_write() failed:" << _pa_strerror(error); _pa_simple_free(audioStream.stream); @@ -162,7 +161,6 @@ void *PulseAudioStream::processingThread(void *userData) { audioStream.processingThreadID = 0; return NULL; } - audioStream.framesRendered(audioStream.bufferSize); } audioStream.stopProcessing = false; audioStream.processingThreadID = 0; @@ -209,7 +207,7 @@ bool PulseAudioStream::start() { while (initFrames > 0) { if (_pa_simple_write(stream, buffer, FRAME_SIZE * bufferSize, &error) < 0) { qDebug() << "pa_simple_write() failed:" << _pa_strerror(error); - _pa_simple_free(stream); + _pa_simple_free(stream); stream = NULL; return false; } @@ -240,7 +238,7 @@ void PulseAudioStream::close() { if (_pa_simple_drain(stream, &error) < 0) { qDebug() << "pa_simple_drain() failed:" << _pa_strerror(error); } - _pa_simple_free(stream); + _pa_simple_free(stream); stream = NULL; } return; diff --git a/mt32emu_qt/src/audiodrv/QtAudioDriver.cpp b/mt32emu_qt/src/audiodrv/QtAudioDriver.cpp index b2f4427..56d9a00 100644 --- a/mt32emu_qt/src/audiodrv/QtAudioDriver.cpp +++ b/mt32emu_qt/src/audiodrv/QtAudioDriver.cpp @@ -51,10 +51,8 @@ public: } else { framesInAudioBuffer = 0; } - stream.updateTimeInfo(nanosNow, framesInAudioBuffer); uint framesToRender = uint(len >> 2); - stream.synthRoute.render((Bit16s *)data, framesToRender); - stream.framesRendered(framesToRender); + stream.renderAndUpdateState((Bit16s *)data, framesToRender, nanosNow, framesInAudioBuffer); return len; } diff --git a/mt32emu_qt/src/audiodrv/WinMMAudioDriver.cpp b/mt32emu_qt/src/audiodrv/WinMMAudioDriver.cpp index 2ba6edb..f5d1d03 100644 --- a/mt32emu_qt/src/audiodrv/WinMMAudioDriver.cpp +++ b/mt32emu_qt/src/audiodrv/WinMMAudioDriver.cpp @@ -150,9 +150,7 @@ void WinMMAudioProcessor::run() { } } DWORD framesInAudioBuffer = playCursor < renderPos ? renderPos - playCursor : (renderPos + stream.audioLatencyFrames) - playCursor; - stream.updateTimeInfo(nanosNow, framesInAudioBuffer); - stream.synthRoute.render(buf, frameCount); - stream.framesRendered(frameCount); + stream.renderAndUpdateState(buf, frameCount, nanosNow, framesInAudioBuffer); if (!stream.ringBufferMode && waveOutWrite(stream.hWaveOut, waveHdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { qDebug() << "WinMMAudioDriver: waveOutWrite failed, thread stopped"; stream.stopProcessing = true;