mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-02 16:49:41 +02:00
Merge: Bugs 925, 926, 928 fixed again, better, for double click and shift too
This commit is contained in:
commit
4ba7a82ec9
@ -370,10 +370,13 @@ So a small, fixed queue size should be adequate.
|
||||
struct AudioIO::ScrubQueue
|
||||
{
|
||||
ScrubQueue(double t0, double t1, wxLongLong startClockMillis,
|
||||
double minTime, double maxTime,
|
||||
double rate, double maxSpeed, double minStutter)
|
||||
: mTrailingIdx(0)
|
||||
, mMiddleIdx(1)
|
||||
, mLeadingIdx(2)
|
||||
, mMinSample(minTime * rate)
|
||||
, mMaxSample(maxTime * rate)
|
||||
, mRate(rate)
|
||||
, mMinStutter(lrint(std::max(0.0, minStutter) * mRate))
|
||||
, mLastScrubTimeMillis(startClockMillis)
|
||||
@ -505,7 +508,8 @@ private:
|
||||
{}
|
||||
|
||||
bool Init(long s0, long s1, long duration, Entry *previous,
|
||||
double maxSpeed, long minStutter, bool adjustStart)
|
||||
double maxSpeed, long minStutter, long minSample, long maxSample,
|
||||
bool adjustStart)
|
||||
{
|
||||
if (duration <= 0)
|
||||
return false;
|
||||
@ -539,39 +543,76 @@ private:
|
||||
maxed = true;
|
||||
}
|
||||
|
||||
if (maxed)
|
||||
{
|
||||
// When playback follows a fast mouse movement by "stuttering"
|
||||
// at maximum playback, don't make stutters too short to be useful.
|
||||
if (adjustStart && duration < minStutter)
|
||||
return false;
|
||||
}
|
||||
else if (speed < GetMinScrubSpeed())
|
||||
if (speed < GetMinScrubSpeed())
|
||||
// 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;
|
||||
|
||||
// No more rejections.
|
||||
|
||||
// Before we change s1:
|
||||
mGoal = maxed ? s1 : -1;
|
||||
|
||||
// May change s1 or s0 to match speed change:
|
||||
long diff = lrint(speed * duration);
|
||||
if (adjustStart)
|
||||
{
|
||||
if (s0 < s1)
|
||||
s0 = s1 - diff;
|
||||
else
|
||||
s0 = s1 + diff;
|
||||
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(minSample, std::min(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 (maxed && duration < minStutter)
|
||||
return false;
|
||||
|
||||
const long diff = lrint(speed * duration);
|
||||
if (s0 < s1)
|
||||
s0 = s1 - diff;
|
||||
else
|
||||
s0 = s1 + diff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// adjust end
|
||||
const long diff = lrint(speed * duration);
|
||||
if (s0 < s1)
|
||||
s1 = s0 + diff;
|
||||
else
|
||||
s1 = s0 - diff;
|
||||
|
||||
// Adjust s1 again, and duration, if s1 is out of bounds. (Assume s0 is in bounds.)
|
||||
if (s1 != s0)
|
||||
{
|
||||
const long newS1 = std::max(minSample, std::min(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
|
||||
;
|
||||
else
|
||||
// Shorten
|
||||
duration = newDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mS0 = s0;
|
||||
@ -614,7 +655,8 @@ private:
|
||||
? s0 + lrint(duration * end) // end is a speed
|
||||
: lrint(end * mRate); // end is a time
|
||||
const bool success =
|
||||
entry.Init(s0, s1, duration, previous, maxSpeed, mMinStutter, maySkip);
|
||||
entry.Init(s0, s1, duration, previous, maxSpeed, mMinStutter,
|
||||
mMinSample, mMaxSample, maySkip);
|
||||
if (success)
|
||||
mLastScrubTimeMillis = clockTime;
|
||||
return success;
|
||||
@ -625,6 +667,7 @@ private:
|
||||
unsigned mTrailingIdx;
|
||||
unsigned mMiddleIdx;
|
||||
unsigned mLeadingIdx;
|
||||
const long mMinSample, mMaxSample;
|
||||
const double mRate;
|
||||
const long mMinStutter;
|
||||
wxLongLong mLastScrubTimeMillis;
|
||||
@ -1787,6 +1830,7 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks,
|
||||
{
|
||||
mScrubQueue =
|
||||
new ScrubQueue(mT0, mT1, options.scrubStartClockTimeMillis,
|
||||
0.0, options.maxScrubTime,
|
||||
sampleRate, maxScrubSpeed, minScrubStutter);
|
||||
mScrubDuration = 0;
|
||||
mSilentScrub = false;
|
||||
|
@ -90,6 +90,7 @@ struct AudioIOStartStreamOptions
|
||||
, maxScrubSpeed(1.0)
|
||||
, minScrubStutter(0.0)
|
||||
, scrubStartClockTimeMillis(-1)
|
||||
, maxScrubTime(0.0)
|
||||
#endif
|
||||
{}
|
||||
|
||||
@ -117,6 +118,9 @@ struct AudioIOStartStreamOptions
|
||||
// Scrubbing needs the time of start of the mouse movement that began
|
||||
// the scrub:
|
||||
wxLongLong scrubStartClockTimeMillis;
|
||||
|
||||
// usually from TrackList::GetEndTime()
|
||||
double maxScrubTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -2381,6 +2381,7 @@ bool TrackPanel::MaybeStartScrubbing(wxMouseEvent &event)
|
||||
// but it may be varied during the scrub.
|
||||
mMaxScrubSpeed = options.maxScrubSpeed =
|
||||
p->GetTranscriptionToolBar()->GetPlaySpeed();
|
||||
options.maxScrubTime = mTracks->GetEndTime();
|
||||
const bool cutPreview = false;
|
||||
const bool backwards = time1 < time0;
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL
|
||||
@ -2412,11 +2413,7 @@ bool TrackPanel::MaybeStartScrubbing(wxMouseEvent &event)
|
||||
bool TrackPanel::ContinueScrubbing(wxCoord position, bool maySkip)
|
||||
{
|
||||
wxCoord leadPosition = position;
|
||||
double newEnd =
|
||||
std::max(0.0,
|
||||
std::min(PositionToTime(leadPosition, GetLeftOffset()),
|
||||
mTracks->GetEndTime()
|
||||
));
|
||||
double newEnd = PositionToTime(leadPosition, GetLeftOffset());
|
||||
|
||||
if (maySkip)
|
||||
// Cause OnTimer() to suppress the speed display
|
||||
|
Loading…
x
Reference in New Issue
Block a user