1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-25 16:48:44 +02:00

Reorganize logic of initializing queue entries

This commit is contained in:
Paul Licameli 2016-05-24 11:40:34 -04:00
parent 4f2ee32a1a
commit b14fa507c9
2 changed files with 63 additions and 78 deletions

View File

@ -535,17 +535,17 @@ private:
double maxSpeed, bool adjustStart, double maxSpeed, bool adjustStart,
const ScrubbingOptions &options) const ScrubbingOptions &options)
{ {
if (duration <= 0) wxASSERT(duration > 0);
return false; double speed = static_cast<double>(std::abs(s1 - s0)) / duration;
double speed = double(abs(s1 - s0)) / duration; bool adjustedSpeed = false;
bool maxed = false;
// May change the requested speed (or reject) // May change the requested speed and duration
if (!adjustStart && speed > maxSpeed) if (!adjustStart && speed > maxSpeed)
{ {
// Reduce speed to the maximum selected in the user interface. // Reduce speed to the maximum selected in the user interface.
speed = maxSpeed; speed = maxSpeed;
maxed = true; mGoal = s1;
adjustedSpeed = true;
} }
else if (!adjustStart && else if (!adjustStart &&
previous && previous &&
@ -557,86 +557,71 @@ private:
// continue at no less than maximum. (Without this // continue at no less than maximum. (Without this
// the final catch-up can make a slow scrub interval // the final catch-up can make a slow scrub interval
// that drops the pitch and sounds wrong.) // that drops the pitch and sounds wrong.)
duration = lrint(speed * duration / maxSpeed); // Trim the duration.
if (duration <= 0) duration = std::max(0L, lrint(speed * duration / maxSpeed));
{
previous->mGoal = -1;
return false;
}
speed = maxSpeed; speed = maxSpeed;
maxed = true; mGoal = s1;
} adjustedSpeed = true;
if (speed < ScrubbingOptions::MinAllowedScrubSpeed())
// Mixers were set up to go only so slowly, not slower.
// This will put a request for some silence in the work queue.
speed = 0.0;
// Before we change s1:
mGoal = maxed ? s1 : -1;
// May change s1 or s0 to match speed change:
if (adjustStart)
{
bool silent = false;
// Adjust s1 first, and duration, if s1 is out of bounds.
// (Assume s0 is in bounds, because it is the last scrub's s1 which was checked.)
if (s1 != s0)
{
const long newS1 = std::max(options.minSample, std::min(options.maxSample, s1));
if (s1 != newS1)
{
long newDuration = long(duration * double(newS1 - s0) / (s1 - s0));
s1 = newS1;
if (newDuration == 0)
// Enqueue a silent scrub with s0 == s1
silent = true;
else
// Shorten
duration = newDuration;
}
}
if (!silent)
{
// When playback follows a fast mouse movement by "stuttering"
// at maximum playback, don't make stutters too short to be useful.
if (duration < options.minStutter)
return false;
// Limit diff because this is seeking.
const long diff = lrint(std::min(1.0, speed) * duration);
if (s0 < s1)
s0 = s1 - diff;
else
s0 = s1 + diff;
}
} }
else else
mGoal = -1;
if (speed < ScrubbingOptions::MinAllowedScrubSpeed()) {
// Mixers were set up to go only so slowly, not slower.
// This will put a request for some silence in the work queue.
adjustedSpeed = true;
speed = 0.0;
}
// May change s1 or s0 to match speed change or stay in bounds of the project
if (adjustedSpeed && !adjustStart)
{ {
// adjust end // adjust s1
const long diff = lrint(speed * duration); const long diff = lrint(speed * duration);
if (s0 < s1) if (s0 < s1)
s1 = s0 + diff; s1 = s0 + diff;
else else
s1 = s0 - diff; s1 = s0 - diff;
}
// Adjust s1 again, and duration, if s1 is out of bounds. (Assume s0 is in bounds.) bool silent = false;
if (s1 != s0)
{ // Adjust s1 (again), and duration, if s1 is out of bounds,
const long newS1 = std::max(options.minSample, std::min(options.maxSample, s1)); // or abandon if a stutter is too short.
if (s1 != newS1) // (Assume s0 is in bounds, because it equals the last scrub's s1 which was checked.)
{ if (s1 != s0)
long newDuration = long(duration * double(newS1 - s0) / (s1 - s0)); {
s1 = newS1; long newDuration = duration;
if (newDuration == 0) const long newS1 = std::max(options.minSample, std::min(options.maxSample, s1));
// Enqueue a silent scrub with s0 == s1 if(s1 != newS1)
; newDuration = std::max(0L,
else static_cast<long>(duration * static_cast<double>(newS1 - s0) / (s1 - s0))
// Shorten );
duration = newDuration; // When playback follows a fast mouse movement by "stuttering"
} // at maximum playback, don't make stutters too short to be useful.
if (options.adjustStart && newDuration < options.minStutter)
return false;
else if (newDuration == 0) {
// Enqueue a silent scrub with s0 == s1
silent = true;
s1 = s0;
} }
else if (s1 != newS1) {
// Shorten
duration = newDuration;
s1 = newS1;
}
}
if (adjustStart && !silent)
{
// Limit diff because this is seeking.
const long diff = lrint(std::min(maxSpeed, speed) * duration);
if (s0 < s1)
s0 = s1 - diff;
else
s0 = s1 + diff;
} }
mS0 = s0; mS0 = s0;

View File

@ -411,6 +411,8 @@ void Scrubber::ContinueScrubbing()
else { else {
const double time = viewInfo.PositionToTime(position.x, trackPanel->GetLeftOffset()); const double time = viewInfo.PositionToTime(position.x, trackPanel->GetLeftOffset());
mOptions.adjustStart = seek; mOptions.adjustStart = seek;
auto maxSpeed = (mDragging || !seek) ? mOptions.maxSpeed : 1.0;
if (seek) if (seek)
// Cause OnTimer() to suppress the speed display // Cause OnTimer() to suppress the speed display
mScrubSpeedDisplayCountdown = 1; mScrubSpeedDisplayCountdown = 1;
@ -418,12 +420,10 @@ void Scrubber::ContinueScrubbing()
if (mSmoothScrollingScrub) { if (mSmoothScrollingScrub) {
const double speed = FindScrubSpeed(seek, time); const double speed = FindScrubSpeed(seek, time);
mOptions.enqueueBySpeed = true; mOptions.enqueueBySpeed = true;
result = gAudioIO->EnqueueScrub(speed, mOptions.maxSpeed, mOptions); result = gAudioIO->EnqueueScrub(speed, maxSpeed, mOptions);
} }
else { else {
mOptions.enqueueBySpeed = false; mOptions.enqueueBySpeed = false;
auto maxSpeed =
(mDragging || !seek) ? mOptions.maxSpeed : 1.0;
result = gAudioIO->EnqueueScrub(time, maxSpeed, mOptions); result = gAudioIO->EnqueueScrub(time, maxSpeed, mOptions);
} }
} }