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:
parent
cdbdd6480b
commit
3dcf802bdc
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user