1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-04 09:39:42 +02:00

Have just one scrub enqueueing function: use options for distinctions

This commit is contained in:
Paul Licameli 2016-05-19 18:07:18 -04:00
parent cdbdd6480b
commit 3dcf802bdc
4 changed files with 40 additions and 49 deletions

View File

@ -385,14 +385,16 @@ struct AudioIO::ScrubQueue
, mLastScrubTimeMillis(startClockMillis)
, mUpdating()
{
bool success = InitEntry(mEntries[mMiddleIdx],
t0, t1, maxSpeed, false, NULL, false, options);
// Ignore options.adjustStart, pass false.
bool success = InitEntry(mEntries[mMiddleIdx], nullptr,
t0, t1, maxSpeed, false, false, options);
if (!success)
{
// StartClock equals now? Really?
--mLastScrubTimeMillis;
success = InitEntry(mEntries[mMiddleIdx],
t0, t1, maxSpeed, false, NULL, false, options);
success = InitEntry(mEntries[mMiddleIdx], nullptr,
t0, t1, maxSpeed, false, false, options);
}
wxASSERT(success);
@ -422,8 +424,7 @@ struct AudioIO::ScrubQueue
mAvailable.Signal();
}
bool Producer(double end, double maxSpeed, bool bySpeed, bool maySkip,
const ScrubbingOptions &options)
bool Producer(double end, double maxSpeed, const ScrubbingOptions &options)
{
// Main thread indicates a scrubbing interval
@ -440,8 +441,8 @@ struct AudioIO::ScrubQueue
// Might reject the request because of zero duration,
// or a too-short "stutter"
const bool success =
(InitEntry(mEntries[mLeadingIdx], startTime, end, maxSpeed,
bySpeed, &previous, maySkip, options));
(InitEntry(mEntries[mLeadingIdx], &previous, startTime, end, maxSpeed,
options.enqueueBySpeed, options.adjustStart, options));
if (success) {
mLeadingIdx = next;
mAvailable.Signal();
@ -534,7 +535,7 @@ private:
, mPlayed(0)
{}
bool Init(long s0, long s1, long duration, Entry *previous,
bool Init(Entry *previous, long s0, long s1, long duration,
double maxSpeed, long minStutter, long minSample, long maxSample,
bool adjustStart, const ScrubbingOptions &options)
{
@ -671,8 +672,8 @@ private:
long mPlayed;
};
bool InitEntry(Entry &entry, double t0, double end, double maxSpeed,
bool bySpeed, Entry *previous, bool maySkip,
bool InitEntry(Entry &entry, Entry *previous, double t0, double end, double maxSpeed,
bool bySpeed, bool adjustStart,
const ScrubbingOptions &options)
{
const wxLongLong clockTime(::wxGetLocalTimeMillis());
@ -683,8 +684,8 @@ private:
? s0 + lrint(duration * end) // end is a speed
: lrint(end * mRate); // end is a time
const bool success =
entry.Init(s0, s1, duration, previous, maxSpeed, mMinStutter,
mMinSample, mMaxSample, maySkip, options);
entry.Init(previous, s0, s1, duration, maxSpeed, mMinStutter,
mMinSample, mMaxSample, adjustStart, options);
if (success)
mLastScrubTimeMillis = clockTime;
return success;
@ -2470,18 +2471,11 @@ bool AudioIO::IsPaused()
}
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
bool AudioIO::EnqueueScrubByPosition(double endTime, double maxSpeed, bool maySkip, const ScrubbingOptions &options)
bool AudioIO::EnqueueScrub
(double endTimeOrSpeed, double maxSpeed, const ScrubbingOptions &options)
{
if (mScrubQueue)
return mScrubQueue->Producer(endTime, maxSpeed, false, maySkip, options);
else
return false;
}
bool AudioIO::EnqueueScrubBySignedSpeed(double speed, double maxSpeed, bool maySkip, const ScrubbingOptions &options)
{
if (mScrubQueue)
return mScrubQueue->Producer(speed, maxSpeed, true, maySkip, options);
return mScrubQueue->Producer(endTimeOrSpeed, maxSpeed, options);
else
return false;
}

View File

@ -188,34 +188,18 @@ class AUDACITY_DLL_API AudioIO final {
static double GetMaxScrubSpeed() { return 32.0; } // Is five octaves enough for your amusement?
static double GetMinScrubSpeed() { return 0.01; }
/** \brief enqueue a NEW end time, using the last end as the new start,
/** \brief enqueue a NEW scrub play interval, using the last end as the new start,
* to be played over the same duration, as between this and the last
* enqueuing (or the starting of the stream). Except, we do not exceed maximum
* scrub speed, so may need to adjust either the start or the end.
* If maySkip is true, then when mouse movement exceeds maximum scrub speed,
* If options.adjustStart is true, then when mouse movement exceeds maximum scrub speed,
* adjust the beginning of the scrub interval rather than the end, so that
* the scrub skips or "stutters" to stay near the cursor.
* But if the "stutter" is too short for the minimum, then there is no effect
* on the work queue.
* Return true if some work was really enqueued.
*/
bool EnqueueScrubByPosition(double endTime, double maxSpeed, bool maySkip,
const ScrubbingOptions &options);
/** \brief enqueue a NEW positive or negative scrubbing speed,
* using the last end as the NEW start,
* to be played over the same duration, as between this and the last
* enqueueing (or the starting of the stream). Except, we do not exceed maximum
* scrub speed, so may need to adjust either the start or the end.
* If maySkip is true, then when mouse movement exceeds maximum scrub speed,
* adjust the beginning of the scrub interval rather than the end, so that
* the scrub skips or "stutters" to stay near the cursor.
* But if the "stutter" is too short for the minimum, then there is no effect
* on the work queue.
* Return true if some work was really enqueued.
*/
bool EnqueueScrubBySignedSpeed(double speed, double maxSpeed, bool maySkip,
const ScrubbingOptions &options);
bool EnqueueScrub(double endTimeOrSpeed, double maxSpeed, const ScrubbingOptions &options);
/** \brief return the ending time of the last enqueued scrub interval.
*/

View File

@ -382,29 +382,37 @@ void Scrubber::ContinueScrubbing()
const auto &viewInfo = mProject->GetViewInfo();
bool result = false;
if (mPaused)
if (mPaused) {
// When paused, enqueue silent scrubs.
result = gAudioIO->EnqueueScrubBySignedSpeed(0, mMaxScrubSpeed, false, mOptions);
mOptions.adjustStart = false;
mOptions.enqueueBySpeed = true;
result = gAudioIO->EnqueueScrub(0, mMaxScrubSpeed, mOptions);
}
else if (mDragging && mSmoothScrollingScrub) {
const auto lastTime = gAudioIO->GetLastTimeInScrubQueue();
const auto delta = mLastScrubPosition - position.x;
const double time = viewInfo.OffsetTimeByPixels(lastTime, delta);
result = gAudioIO->EnqueueScrubByPosition(time, mMaxScrubSpeed, true, mOptions);
mOptions.adjustStart = true;
mOptions.enqueueBySpeed = false;
result = gAudioIO->EnqueueScrub(time, mMaxScrubSpeed, mOptions);
mLastScrubPosition = position.x;
}
else {
const double time = viewInfo.PositionToTime(position.x, trackPanel->GetLeftOffset());
mOptions.adjustStart = seek;
if (seek)
// Cause OnTimer() to suppress the speed display
mScrubSpeedDisplayCountdown = 1;
if (mSmoothScrollingScrub) {
const double speed = FindScrubSpeed(seek, time);
result = gAudioIO->EnqueueScrubBySignedSpeed(speed, mMaxScrubSpeed, seek, mOptions);
mOptions.enqueueBySpeed = true;
result = gAudioIO->EnqueueScrub(speed, mMaxScrubSpeed, mOptions);
}
else {
mOptions.enqueueBySpeed = false;
result = gAudioIO->EnqueueScrub(time, seek ? 1.0 : mMaxScrubSpeed, mOptions);
}
else
result = gAudioIO->EnqueueScrubByPosition
(time, seek ? 1.0 : mMaxScrubSpeed, seek, mOptions);
}
if (result)

View File

@ -23,6 +23,11 @@ class AudacityProject;
// For putting an increment of work in the scrubbing queue
struct ScrubbingOptions {
ScrubbingOptions() {}
bool adjustStart {};
bool enqueueBySpeed {};
};
// Scrub state object