1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-18 17:10:05 +02:00

Move bounding times and minimum stutter length into ScrubOptions

This commit is contained in:
Paul Licameli 2016-05-20 19:32:07 -04:00
parent ffe596c760
commit c585bb16fb
3 changed files with 22 additions and 22 deletions

View File

@ -372,16 +372,12 @@ So a small, fixed queue size should be adequate.
struct AudioIO::ScrubQueue struct AudioIO::ScrubQueue
{ {
ScrubQueue(double t0, double t1, wxLongLong startClockMillis, ScrubQueue(double t0, double t1, wxLongLong startClockMillis,
double minTime, double maxTime, double rate, double maxSpeed,
double rate, double maxSpeed, double minStutter,
const ScrubbingOptions &options) const ScrubbingOptions &options)
: mTrailingIdx(0) : mTrailingIdx(0)
, mMiddleIdx(1) , mMiddleIdx(1)
, mLeadingIdx(2) , mLeadingIdx(2)
, mMinSample(minTime * rate)
, mMaxSample(maxTime * rate)
, mRate(rate) , mRate(rate)
, mMinStutter(lrint(std::max(0.0, minStutter) * mRate))
, mLastScrubTimeMillis(startClockMillis) , mLastScrubTimeMillis(startClockMillis)
, mUpdating() , mUpdating()
{ {
@ -536,8 +532,8 @@ private:
{} {}
bool Init(Entry *previous, long s0, long s1, long duration, bool Init(Entry *previous, long s0, long s1, long duration,
double maxSpeed, long minStutter, long minSample, long maxSample, double maxSpeed, bool adjustStart,
bool adjustStart, const ScrubbingOptions &options) const ScrubbingOptions &options)
{ {
if (duration <= 0) if (duration <= 0)
return false; return false;
@ -588,7 +584,7 @@ private:
// (Assume s0 is in bounds, because it is the last scrub's s1 which was checked.) // (Assume s0 is in bounds, because it is the last scrub's s1 which was checked.)
if (s1 != s0) if (s1 != s0)
{ {
const long newS1 = std::max(minSample, std::min(maxSample, s1)); const long newS1 = std::max(options.minSample, std::min(options.maxSample, s1));
if (s1 != newS1) if (s1 != newS1)
{ {
long newDuration = long(duration * double(newS1 - s0) / (s1 - s0)); long newDuration = long(duration * double(newS1 - s0) / (s1 - s0));
@ -606,7 +602,7 @@ private:
{ {
// When playback follows a fast mouse movement by "stuttering" // When playback follows a fast mouse movement by "stuttering"
// at maximum playback, don't make stutters too short to be useful. // at maximum playback, don't make stutters too short to be useful.
if (duration < minStutter) if (duration < options.minStutter)
return false; return false;
// Limit diff because this is seeking. // Limit diff because this is seeking.
const long diff = lrint(std::min(1.0, speed) * duration); const long diff = lrint(std::min(1.0, speed) * duration);
@ -628,7 +624,7 @@ private:
// Adjust s1 again, and duration, if s1 is out of bounds. (Assume s0 is in bounds.) // Adjust s1 again, and duration, if s1 is out of bounds. (Assume s0 is in bounds.)
if (s1 != s0) if (s1 != s0)
{ {
const long newS1 = std::max(minSample, std::min(maxSample, s1)); const long newS1 = std::max(options.minSample, std::min(options.maxSample, s1));
if (s1 != newS1) if (s1 != newS1)
{ {
long newDuration = long(duration * double(newS1 - s0) / (s1 - s0)); long newDuration = long(duration * double(newS1 - s0) / (s1 - s0));
@ -684,8 +680,7 @@ 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(previous, s0, s1, duration, maxSpeed, mMinStutter, entry.Init(previous, s0, s1, duration, maxSpeed, adjustStart, options);
mMinSample, mMaxSample, adjustStart, options);
if (success) if (success)
mLastScrubTimeMillis = clockTime; mLastScrubTimeMillis = clockTime;
return success; return success;
@ -696,9 +691,7 @@ private:
unsigned mTrailingIdx; unsigned mTrailingIdx;
unsigned mMiddleIdx; unsigned mMiddleIdx;
unsigned mLeadingIdx; unsigned mLeadingIdx;
const long mMinSample, mMaxSample;
const double mRate; const double mRate;
const long mMinStutter;
wxLongLong mLastScrubTimeMillis; wxLongLong mLastScrubTimeMillis;
mutable wxMutex mUpdating; mutable wxMutex mUpdating;
mutable wxCondition mAvailable { mUpdating }; mutable wxCondition mAvailable { mUpdating };
@ -1870,8 +1863,7 @@ int AudioIO::StartStream(const WaveTrackArray &playbackTracks,
const auto &scrubOptions = *options.pScrubbingOptions; const auto &scrubOptions = *options.pScrubbingOptions;
mScrubQueue = mScrubQueue =
new ScrubQueue(mT0, mT1, scrubOptions.startClockTimeMillis, new ScrubQueue(mT0, mT1, scrubOptions.startClockTimeMillis,
0.0, scrubOptions.maxTime, sampleRate, scrubOptions.maxSpeed,
sampleRate, scrubOptions.maxSpeed, scrubOptions.minStutter,
*options.pScrubbingOptions); *options.pScrubbingOptions);
mScrubDuration = 0; mScrubDuration = 0;
mSilentScrub = false; mSilentScrub = false;

View File

@ -48,6 +48,8 @@ enum {
ScrubPollInterval_ms = 50, ScrubPollInterval_ms = 50,
}; };
static const double MinStutter = 0.2;
namespace { namespace {
double FindScrubbingSpeed(const ViewInfo &viewInfo, double maxScrubSpeed, double screen, double timeAtMouse) double FindScrubbingSpeed(const ViewInfo &viewInfo, double maxScrubSpeed, double screen, double timeAtMouse)
{ {
@ -299,7 +301,6 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
options.pScrubbingOptions = &mOptions; options.pScrubbingOptions = &mOptions;
options.timeTrack = NULL; options.timeTrack = NULL;
mOptions.delay = (ScrubPollInterval_ms / 1000.0); mOptions.delay = (ScrubPollInterval_ms / 1000.0);
mOptions.minStutter = 0.2;
#ifdef USE_TRANSCRIPTION_TOOLBAR #ifdef USE_TRANSCRIPTION_TOOLBAR
if (!mAlwaysSeeking) { if (!mAlwaysSeeking) {
// Take the starting speed limit from the transcription toolbar, // Take the starting speed limit from the transcription toolbar,
@ -313,7 +314,12 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
mOptions.maxSpeed = mOptions.maxSpeed =
mDragging ? ScrubbingOptions::MaxAllowedScrubSpeed() : 1.0; mDragging ? ScrubbingOptions::MaxAllowedScrubSpeed() : 1.0;
#endif #endif
mOptions.maxTime = mProject->GetTracks()->GetEndTime(); mOptions.minSample = 0;
mOptions.maxSample =
lrint(std::max(0.0, mProject->GetTracks()->GetEndTime()) * options.rate);
mOptions.minStutter =
lrint(std::max(0.0, MinStutter) * options.rate);
ControlToolBar::PlayAppearance appearance = ControlToolBar::PlayAppearance appearance =
ControlToolBar::PlayAppearance::Scrub; ControlToolBar::PlayAppearance::Scrub;
const bool cutPreview = false; const bool cutPreview = false;

View File

@ -27,6 +27,10 @@ struct ScrubbingOptions {
bool adjustStart {}; bool adjustStart {};
// usually from TrackList::GetEndTime()
long maxSample {};
long minSample {};
bool enqueueBySpeed {}; bool enqueueBySpeed {};
double delay {}; double delay {};
@ -34,17 +38,15 @@ struct ScrubbingOptions {
// A limiting value for the speed of a scrub interval: // A limiting value for the speed of a scrub interval:
double maxSpeed { 1.0 }; double maxSpeed { 1.0 };
// When maximum speed scrubbing skips to follow the mouse, // When maximum speed scrubbing skips to follow the mouse,
// this is the minimum amount of playback allowed at the maximum speed: // this is the minimum amount of playback allowed at the maximum speed:
double minStutter {}; long minStutter {};
// Scrubbing needs the time of start of the mouse movement that began // Scrubbing needs the time of start of the mouse movement that began
// the scrub: // the scrub:
wxLongLong startClockTimeMillis { -1 }; wxLongLong startClockTimeMillis { -1 };
// usually from TrackList::GetEndTime()
double maxTime {};
static double MaxAllowedScrubSpeed() static double MaxAllowedScrubSpeed()
{ return 32.0; } // Is five octaves enough for your amusement? { return 32.0; } // Is five octaves enough for your amusement?
static double MinAllowedScrubSpeed() static double MinAllowedScrubSpeed()