From 7c67133ff788929bcfed30240e6738d8d8d14e81 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 23 Sep 2017 23:57:29 -0400 Subject: [PATCH] Roger's changed FillMidiBuffers loop test (seems harmless, all OSs) --- src/AudioIO.cpp | 27 ++++++++++++++++++++++++--- src/AudioIO.h | 2 ++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 0c0034b96..289c9ccb8 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -283,6 +283,8 @@ writing audio. #ifdef EXPERIMENTAL_MIDI_OUT #define MIDI_SLEEP 10 /* milliseconds */ + // how long do we think the thread might be delayed due to other threads? + #define THREAD_LATENCY 10 /* milliseconds */ #define ROUND(x) (int) ((x)+0.5) //#include #include "../lib-src/portmidi/pm_common/portmidi.h" @@ -1444,6 +1446,7 @@ bool AudioIO::StartPortAudioStream(double sampleRate, #ifdef EXPERIMENTAL_MIDI_OUT mNumFrames = 0; mNumPauseFrames = 0; + mAudioOutLatency = 0.0; // set when stream is opened #endif mOwningProject = GetActiveProject(); mInputMeter = NULL; @@ -1587,6 +1590,14 @@ bool AudioIO::StartPortAudioStream(double sampleRate, } #endif + // We use audio latency to estimate how far ahead of DACS we are writing + if (mPortStreamV19 != NULL && mLastPaError == paNoError) { + const PaStreamInfo* info = Pa_GetStreamInfo(mPortStreamV19); + // this is an initial guess, but for PA/Linux/ALSA it's wrong and will be + // updated with a better value: + mAudioOutLatency = info->outputLatency; + } + return (mLastPaError == paNoError); } @@ -4057,10 +4068,20 @@ void AudioIO::FillMidiBuffers() break; } SetHasSolo(hasSolo); - double time = AudioTime(); + // If we compute until mNextEventTime > current audio track time, + // we would have a built-in compute-ahead of mAudioOutLatency, and + // it's probably good to compute MIDI when we compute audio (so when + // we stop, both stop about the same time). + double time = AudioTime(); // compute to here + // But if mAudioOutLatency is very low, we might need some extra + // compute-ahead to deal with mSynthLatency or even this thread. + double actual_latency = (MIDI_SLEEP + THREAD_LATENCY + + MIDI_MINIMAL_LATENCY_MS + mSynthLatency) * 0.001; + if (actual_latency > mAudioOutLatency) { + time += actual_latency - mAudioOutLatency; + } while (mNextEvent && - UncorrectedMidiEventTime() < - time + ((MIDI_SLEEP + mSynthLatency) * 0.001)) { + UncorrectedMidiEventTime() < time) { OutputEvent(); GetNextEvent(); } diff --git a/src/AudioIO.h b/src/AudioIO.h index cc5a03015..2e9a024c6 100644 --- a/src/AudioIO.h +++ b/src/AudioIO.h @@ -565,6 +565,8 @@ private: /// stream closing until last message has been delivered PmTimestamp mMaxMidiTimestamp; + /// audio output latency reported by PortAudio + double mAudioOutLatency; Alg_seq_ptr mSeq; std::unique_ptr mIterator;