From 8df23db41c14a522bdb04ce9a73ded1bf0531cef Mon Sep 17 00:00:00 2001 From: Robin Davies Date: Sat, 14 Sep 2024 06:46:50 -0400 Subject: [PATCH] Midi input causes audio glitches. --- src/AlsaDriver.cpp | 81 +++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp index 682a21b..90d9828 100644 --- a/src/AlsaDriver.cpp +++ b/src/AlsaDriver.cpp @@ -1422,45 +1422,58 @@ namespace pipedal } // snd_pcm_wait(captureHandle, 1); - - ssize_t framesRead; - if ((framesRead = ReadBuffer(captureHandle, this->rawCaptureBuffer, bufferSize)) < 0) + ssize_t framesToRead = bufferSize; + ssize_t framesRead = 0; + bool xrun = false; + while (framesToRead != 0) { - this->driverHost->OnUnderrun(); - auto state = snd_pcm_state(playbackHandle); - XrunRecoverInputUnderrun(captureHandle, framesRead); - continue; - } - else - { - cpuUse.AddSample(ProfileCategory::Read); - if (framesRead == 0) - continue; - if (framesRead != bufferSize) - { - throw PiPedalStateException("Invalid read."); - } - - (this->*copyInputFn)(framesRead); - cpuUse.AddSample(ProfileCategory::Driver); - - this->driverHost->OnProcess(framesRead); - - cpuUse.AddSample(ProfileCategory::Execute); - - (this->*copyOutputFn)(framesRead); - cpuUse.AddSample(ProfileCategory::Driver); - // process. - - ssize_t err = WriteBuffer(playbackHandle, rawPlaybackBuffer, framesRead); - - if (err < 0) + ssize_t thisTime = framesToRead; + ssize_t nFrames; + if ((nFrames = ReadBuffer( + captureHandle, + this->rawCaptureBuffer + this->captureFrameSize*framesRead, + bufferSize)) < 0) { this->driverHost->OnUnderrun(); - XrunRecoverOutputOverrun(playbackHandle, err); + auto state = snd_pcm_state(playbackHandle); + XrunRecoverInputUnderrun(captureHandle, nFrames); + xrun = true; + break; } - cpuUse.AddSample(ProfileCategory::Write); + framesRead += nFrames; + framesToRead -= nFrames; } + if (xrun) + { + continue; + } + cpuUse.AddSample(ProfileCategory::Read); + if (framesRead == 0) + continue; + if (framesRead != bufferSize) + { + throw PiPedalStateException("Invalid read."); + } + + (this->*copyInputFn)(framesRead); + cpuUse.AddSample(ProfileCategory::Driver); + + this->driverHost->OnProcess(framesRead); + + cpuUse.AddSample(ProfileCategory::Execute); + + (this->*copyOutputFn)(framesRead); + cpuUse.AddSample(ProfileCategory::Driver); + // process. + + ssize_t err = WriteBuffer(playbackHandle, rawPlaybackBuffer, framesRead); + + if (err < 0) + { + this->driverHost->OnUnderrun(); + XrunRecoverOutputOverrun(playbackHandle, err); + } + cpuUse.AddSample(ProfileCategory::Write); } } catch (const std::exception &e)