diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 7eeffcad4..628fff1cf 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -997,7 +997,6 @@ AudioIO::AudioIO() mMidiStreamActive = false; mSendMidiState = false; mIterator = NULL; - mMidiPlaySpeed = 1.0; mNumFrames = 0; mNumPauseFrames = 0; @@ -2388,7 +2387,6 @@ void AudioIO::StopStream() } mIterator.reset(); // just in case someone tries to reference it - mMidiPlaySpeed = 1.0; } #endif @@ -3021,6 +3019,9 @@ MidiThread::ExitCode MidiThread::Entry() if (gAudioIO->mNumPlaybackChannels != 0) { realTime -= 1; // with audio, MidiTime() runs ahead 1s } + + // XXX Is this still true now? It seems to break looping --Poke + // // The TrackPanel::OnTimer() method updates the time position // indicator every 200ms, so it tends to not advance the // indicator to the end of the selection (mT1) but instead stop @@ -3028,15 +3029,20 @@ MidiThread::ExitCode MidiThread::Entry() // down and the indicator is removed, but for a brief time, the // indicator is clearly stopped before reaching mT1. To avoid // this, we do not set mMidiOutputComplete until we are actually - // 0.22s beyond mT1 (even though we stop playing at mT1. This + // 0.22s beyond mT1 (even though we stop playing at mT1). This // gives OnTimer() time to wake up and draw the final time // position at mT1 before shutting down the stream. - double timeAtSpeed = (realTime - gAudioIO->mT0) * - gAudioIO->mMidiPlaySpeed + gAudioIO->mT0; + const double loopDelay = 0.220; + + double timeAtSpeed; + if (gAudioIO->mTimeTrack) + timeAtSpeed = gAudioIO->mTimeTrack->SolveWarpedLength(gAudioIO->mT0, realTime); + else + timeAtSpeed = realTime; gAudioIO->mMidiOutputComplete = (gAudioIO->mPlayMode == gAudioIO->PLAY_STRAIGHT && // PRL: what if scrubbing? - timeAtSpeed >= gAudioIO->mT1 + 0.220); + timeAtSpeed >= gAudioIO->mT1 + loopDelay); // !gAudioIO->mNextEvent); } } @@ -3849,8 +3855,13 @@ void AudioIO::OutputEvent() int command = -1; int data1 = -1; int data2 = -1; + + double eventTime; + if (mTimeTrack) + eventTime = mTimeTrack->ComputeWarpedLength(mT0, mNextEventTime) + mT0; + else + eventTime = mNextEventTime; // 0.0005 is for rounding - double eventTime = (mNextEventTime - mT0) / mMidiPlaySpeed + mT0; double time = eventTime + PauseTime() + 0.0005 - ((mMidiLatency + mSynthLatency) * 0.001); @@ -4028,7 +4039,11 @@ void AudioIO::FillMidiBuffers() time = AudioTime() - PauseTime(); } else { time = mT0 + Pt_Time() * 0.001 - PauseTime(); - double timeAtSpeed = (time - mT0) * mMidiPlaySpeed + mT0; + double timeAtSpeed; + if (mTimeTrack) + timeAtSpeed = mTimeTrack->SolveWarpedLength(mT0, time); + else + timeAtSpeed = time; if (mNumCaptureChannels <= 0) { // no audio callback, so move the time cursor here: double trackTime = timeAtSpeed - mMidiLoopOffset; @@ -4054,8 +4069,8 @@ void AudioIO::FillMidiBuffers() time += MIDI_SLEEP * 0.001; } while (mNextEvent && - (mNextEventTime - mT0) / mMidiPlaySpeed + mT0 < time + - ((MIDI_SLEEP + mSynthLatency) * 0.001)) { + (mTimeTrack ? (mTimeTrack->ComputeWarpedLength(mT0, mNextEventTime) + mT0) : mNextEventTime) + < time + ((MIDI_SLEEP + mSynthLatency) * 0.001)) { OutputEvent(); GetNextEvent(); } diff --git a/src/AudioIO.h b/src/AudioIO.h index 2342a032e..63ea85403 100644 --- a/src/AudioIO.h +++ b/src/AudioIO.h @@ -56,7 +56,6 @@ class TimeTrack; class AudioThread; class Meter; class SelectedRegion; -class TimeTrack; class AudacityProject; @@ -227,9 +226,6 @@ class AUDACITY_DLL_API AudioIO final { public: bool SetHasSolo(bool hasSolo); bool GetHasSolo() { return mHasSolo; } - /// Sets the speed for midi playback, based off of the transcription speed. - /// This takes a percentage, so passing 100 will play at normal speed. - void SetMidiPlaySpeed(double s) { mMidiPlaySpeed = s * 0.01; } #endif /** \brief Returns true if the stream is active, or even if audio I/O is @@ -527,9 +523,6 @@ private: long mMidiLatency; /// Latency of MIDI synthesizer long mSynthLatency; - /// A copy of TranscriptionToolBar::mPlaySpeed - a linear speed offset. - /// Should be replaced with use of mTimeTrack - double mMidiPlaySpeed; // These fields are used to synchronize MIDI with audio: diff --git a/src/toolbars/TranscriptionToolBar.cpp b/src/toolbars/TranscriptionToolBar.cpp index 662e35443..7e9cff642 100644 --- a/src/toolbars/TranscriptionToolBar.cpp +++ b/src/toolbars/TranscriptionToolBar.cpp @@ -475,9 +475,6 @@ void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview) // Start playing if (playRegionStart >= 0) { // playRegionEnd = playRegionStart + (playRegionEnd-playRegionStart)* 100.0/mPlaySpeed; -#ifdef EXPERIMENTAL_MIDI_OUT - gAudioIO->SetMidiPlaySpeed(mPlaySpeed); -#endif AudioIOStartStreamOptions options(p->GetDefaultPlayOptions()); options.playLooped = looped; options.timeTrack = mTimeTrack.get();