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:
parent
ffe596c760
commit
c585bb16fb
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user