1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-29 14:48:39 +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) , mLastScrubTimeMillis(startClockMillis)
, mUpdating() , mUpdating()
{ {
bool success = InitEntry(mEntries[mMiddleIdx], // Ignore options.adjustStart, pass false.
t0, t1, maxSpeed, false, NULL, false, options);
bool success = InitEntry(mEntries[mMiddleIdx], nullptr,
t0, t1, maxSpeed, false, false, options);
if (!success) if (!success)
{ {
// StartClock equals now? Really? // StartClock equals now? Really?
--mLastScrubTimeMillis; --mLastScrubTimeMillis;
success = InitEntry(mEntries[mMiddleIdx], success = InitEntry(mEntries[mMiddleIdx], nullptr,
t0, t1, maxSpeed, false, NULL, false, options); t0, t1, maxSpeed, false, false, options);
} }
wxASSERT(success); wxASSERT(success);
@ -422,8 +424,7 @@ struct AudioIO::ScrubQueue
mAvailable.Signal(); mAvailable.Signal();
} }
bool Producer(double end, double maxSpeed, bool bySpeed, bool maySkip, bool Producer(double end, double maxSpeed, const ScrubbingOptions &options)
const ScrubbingOptions &options)
{ {
// Main thread indicates a scrubbing interval // Main thread indicates a scrubbing interval
@ -440,8 +441,8 @@ struct AudioIO::ScrubQueue
// Might reject the request because of zero duration, // Might reject the request because of zero duration,
// or a too-short "stutter" // or a too-short "stutter"
const bool success = const bool success =
(InitEntry(mEntries[mLeadingIdx], startTime, end, maxSpeed, (InitEntry(mEntries[mLeadingIdx], &previous, startTime, end, maxSpeed,
bySpeed, &previous, maySkip, options)); options.enqueueBySpeed, options.adjustStart, options));
if (success) { if (success) {
mLeadingIdx = next; mLeadingIdx = next;
mAvailable.Signal(); mAvailable.Signal();
@ -534,7 +535,7 @@ private:
, mPlayed(0) , 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, double maxSpeed, long minStutter, long minSample, long maxSample,
bool adjustStart, const ScrubbingOptions &options) bool adjustStart, const ScrubbingOptions &options)
{ {
@ -671,8 +672,8 @@ private:
long mPlayed; long mPlayed;
}; };
bool InitEntry(Entry &entry, double t0, double end, double maxSpeed, bool InitEntry(Entry &entry, Entry *previous, double t0, double end, double maxSpeed,
bool bySpeed, Entry *previous, bool maySkip, bool bySpeed, bool adjustStart,
const ScrubbingOptions &options) const ScrubbingOptions &options)
{ {
const wxLongLong clockTime(::wxGetLocalTimeMillis()); const wxLongLong clockTime(::wxGetLocalTimeMillis());
@ -683,8 +684,8 @@ private:
? s0 + lrint(duration * end) // end is a speed ? s0 + lrint(duration * end) // end is a speed
: lrint(end * mRate); // end is a time : lrint(end * mRate); // end is a time
const bool success = const bool success =
entry.Init(s0, s1, duration, previous, maxSpeed, mMinStutter, entry.Init(previous, s0, s1, duration, maxSpeed, mMinStutter,
mMinSample, mMaxSample, maySkip, options); mMinSample, mMaxSample, adjustStart, options);
if (success) if (success)
mLastScrubTimeMillis = clockTime; mLastScrubTimeMillis = clockTime;
return success; return success;
@ -2470,18 +2471,11 @@ bool AudioIO::IsPaused()
} }
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT #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) if (mScrubQueue)
return mScrubQueue->Producer(endTime, maxSpeed, false, maySkip, options); return mScrubQueue->Producer(endTimeOrSpeed, maxSpeed, 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);
else else
return false; 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 GetMaxScrubSpeed() { return 32.0; } // Is five octaves enough for your amusement?
static double GetMinScrubSpeed() { return 0.01; } 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 * 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 * 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. * 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 * adjust the beginning of the scrub interval rather than the end, so that
* the scrub skips or "stutters" to stay near the cursor. * 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 * But if the "stutter" is too short for the minimum, then there is no effect
* on the work queue. * on the work queue.
* Return true if some work was really enqueued. * Return true if some work was really enqueued.
*/ */
bool EnqueueScrubByPosition(double endTime, double maxSpeed, bool maySkip, bool EnqueueScrub(double endTimeOrSpeed, double maxSpeed, const ScrubbingOptions &options);
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);
/** \brief return the ending time of the last enqueued scrub interval. /** \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(); const auto &viewInfo = mProject->GetViewInfo();
bool result = false; bool result = false;
if (mPaused) if (mPaused) {
// When paused, enqueue silent scrubs. // 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) { else if (mDragging && mSmoothScrollingScrub) {
const auto lastTime = gAudioIO->GetLastTimeInScrubQueue(); const auto lastTime = gAudioIO->GetLastTimeInScrubQueue();
const auto delta = mLastScrubPosition - position.x; const auto delta = mLastScrubPosition - position.x;
const double time = viewInfo.OffsetTimeByPixels(lastTime, delta); 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; mLastScrubPosition = position.x;
} }
else { else {
const double time = viewInfo.PositionToTime(position.x, trackPanel->GetLeftOffset()); const double time = viewInfo.PositionToTime(position.x, trackPanel->GetLeftOffset());
mOptions.adjustStart = seek;
if (seek) if (seek)
// Cause OnTimer() to suppress the speed display // Cause OnTimer() to suppress the speed display
mScrubSpeedDisplayCountdown = 1; mScrubSpeedDisplayCountdown = 1;
if (mSmoothScrollingScrub) { if (mSmoothScrollingScrub) {
const double speed = FindScrubSpeed(seek, time); 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) if (result)

View File

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