mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-26 01:18:06 +02:00
Bug1932 followup: Times, not sample counts, in scrubbing options...
... because the correct rate is not known where options are constructed
This commit is contained in:
parent
ecb1cbdf3a
commit
06b5d2e945
@ -546,24 +546,23 @@ 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 rate, long maxDebt,
|
double rate, double maxDebt,
|
||||||
const ScrubbingOptions &options)
|
const ScrubbingOptions &options)
|
||||||
: mTrailingIdx(0)
|
: mTrailingIdx(0)
|
||||||
, mMiddleIdx(1)
|
, mMiddleIdx(1)
|
||||||
, mLeadingIdx(1)
|
, mLeadingIdx(1)
|
||||||
, mRate(rate)
|
, mRate(rate)
|
||||||
, mLastScrubTimeMillis(startClockMillis)
|
, mLastScrubTimeMillis(startClockMillis)
|
||||||
, mMaxDebt { maxDebt }
|
, mMaxDebt { lrint(maxDebt * rate) }
|
||||||
, mUpdating()
|
, mUpdating()
|
||||||
{
|
{
|
||||||
const auto s0 = std::max(options.minSample, std::min(options.maxSample,
|
const sampleCount s0 { llrint( mRate *
|
||||||
sampleCount(lrint(t0 * mRate))
|
std::max( options.minTime, std::min( options.maxTime, t0 ) ) ) };
|
||||||
));
|
const sampleCount s1 { llrint(t1 * mRate) };
|
||||||
const auto s1 = sampleCount(lrint(t1 * mRate));
|
|
||||||
Duration dd { *this };
|
Duration dd { *this };
|
||||||
auto actualDuration = std::max(sampleCount{1}, dd.duration);
|
auto actualDuration = std::max(sampleCount{1}, dd.duration);
|
||||||
auto success = mEntries[mMiddleIdx].Init(nullptr,
|
auto success = mEntries[mMiddleIdx].Init(nullptr,
|
||||||
s0, s1, actualDuration, options);
|
s0, s1, actualDuration, options, mRate);
|
||||||
if (success)
|
if (success)
|
||||||
++mLeadingIdx;
|
++mLeadingIdx;
|
||||||
else {
|
else {
|
||||||
@ -625,7 +624,7 @@ struct AudioIO::ScrubQueue
|
|||||||
: lrint(end * mRate) // end is a time
|
: lrint(end * mRate) // end is a time
|
||||||
);
|
);
|
||||||
auto success =
|
auto success =
|
||||||
current->Init(previous, s0, s1, actualDuration, options);
|
current->Init(previous, s0, s1, actualDuration, options, mRate);
|
||||||
if (success)
|
if (success)
|
||||||
mLeadingIdx = next;
|
mLeadingIdx = next;
|
||||||
else {
|
else {
|
||||||
@ -795,7 +794,7 @@ private:
|
|||||||
|
|
||||||
bool Init(Entry *previous, sampleCount s0, sampleCount s1,
|
bool Init(Entry *previous, sampleCount s0, sampleCount s1,
|
||||||
sampleCount &duration /* in/out */,
|
sampleCount &duration /* in/out */,
|
||||||
const ScrubbingOptions &options)
|
const ScrubbingOptions &options, double rate)
|
||||||
{
|
{
|
||||||
const bool &adjustStart = options.adjustStart;
|
const bool &adjustStart = options.adjustStart;
|
||||||
|
|
||||||
@ -865,8 +864,10 @@ private:
|
|||||||
// (Assume s0 is in bounds, because it equals the last scrub's s1 which was checked.)
|
// (Assume s0 is in bounds, because it equals the last scrub's s1 which was checked.)
|
||||||
if (s1 != s0)
|
if (s1 != s0)
|
||||||
{
|
{
|
||||||
|
sampleCount minSample { llrint(options.minTime * rate) };
|
||||||
|
sampleCount maxSample { llrint(options.maxTime * rate) };
|
||||||
auto newDuration = duration;
|
auto newDuration = duration;
|
||||||
const auto newS1 = std::max(options.minSample, std::min(options.maxSample, s1));
|
const auto newS1 = std::max(minSample, std::min(maxSample, s1));
|
||||||
if(s1 != newS1)
|
if(s1 != newS1)
|
||||||
newDuration = std::max( sampleCount{ 0 },
|
newDuration = std::max( sampleCount{ 0 },
|
||||||
sampleCount(
|
sampleCount(
|
||||||
@ -876,7 +877,8 @@ 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 (options.adjustStart && newDuration < options.minStutter)
|
if (options.adjustStart &&
|
||||||
|
newDuration < llrint( options.minStutterTime * rate ) )
|
||||||
return false;
|
return false;
|
||||||
else if (newDuration == 0) {
|
else if (newDuration == 0) {
|
||||||
// Enqueue a silent scrub with s0 == s1
|
// Enqueue a silent scrub with s0 == s1
|
||||||
@ -2260,8 +2262,7 @@ int AudioIO::StartStream(const TransportTracks &tracks,
|
|||||||
std::make_unique<ScrubQueue>(
|
std::make_unique<ScrubQueue>(
|
||||||
mPlaybackSchedule.mT0, mPlaybackSchedule.mT1,
|
mPlaybackSchedule.mT0, mPlaybackSchedule.mT1,
|
||||||
scrubOptions.startClockTimeMillis,
|
scrubOptions.startClockTimeMillis,
|
||||||
mRate,
|
mRate, 2 * scrubOptions.minStutterTime,
|
||||||
2 * scrubOptions.minStutter,
|
|
||||||
scrubOptions);
|
scrubOptions);
|
||||||
mScrubDuration = 0;
|
mScrubDuration = 0;
|
||||||
mSilentScrub = false;
|
mSilentScrub = false;
|
||||||
|
@ -378,14 +378,13 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
mOptions.minSample = 0;
|
mOptions.minTime = 0;
|
||||||
mOptions.maxSample =
|
mOptions.maxTime = std::max(0.0, mProject->GetTracks()->GetEndTime());
|
||||||
lrint(std::max(0.0, mProject->GetTracks()->GetEndTime()) * options.rate);
|
mOptions.minStutterTime =
|
||||||
mOptions.minStutter =
|
|
||||||
#ifdef DRAG_SCRUB
|
#ifdef DRAG_SCRUB
|
||||||
mDragging ? 0.0 :
|
mDragging ? 0.0 :
|
||||||
#endif
|
#endif
|
||||||
lrint(std::max(0.0, MinStutter) * options.rate);
|
std::max(0.0, MinStutter);
|
||||||
|
|
||||||
ControlToolBar::PlayAppearance appearance =
|
ControlToolBar::PlayAppearance appearance =
|
||||||
// commented out to fix Bug 1241
|
// commented out to fix Bug 1241
|
||||||
@ -472,9 +471,9 @@ bool Scrubber::StartSpeedPlay(double speed, double time0, double time1)
|
|||||||
|
|
||||||
if (time1 == time0)
|
if (time1 == time0)
|
||||||
time1 = std::max(0.0, mProject->GetTracks()->GetEndTime());
|
time1 = std::max(0.0, mProject->GetTracks()->GetEndTime());
|
||||||
mOptions.minSample = 0;
|
mOptions.minTime = 0;
|
||||||
mOptions.maxSample = lrint(time1 * options.rate);
|
mOptions.maxTime = time1;
|
||||||
mOptions.minStutter = lrint(std::max(0.0, MinStutter) * options.rate);
|
mOptions.minStutterTime = std::max(0.0, MinStutter);
|
||||||
mOptions.enqueueBySpeed = true;
|
mOptions.enqueueBySpeed = true;
|
||||||
mOptions.adjustStart = false;
|
mOptions.adjustStart = false;
|
||||||
mOptions.isPlayingAtSpeed = true;
|
mOptions.isPlayingAtSpeed = true;
|
||||||
|
@ -41,8 +41,8 @@ struct ScrubbingOptions {
|
|||||||
bool adjustStart {};
|
bool adjustStart {};
|
||||||
|
|
||||||
// usually from TrackList::GetEndTime()
|
// usually from TrackList::GetEndTime()
|
||||||
sampleCount maxSample {};
|
double maxTime {};
|
||||||
sampleCount minSample {};
|
double minTime {};
|
||||||
|
|
||||||
bool enqueueBySpeed {};
|
bool enqueueBySpeed {};
|
||||||
bool isPlayingAtSpeed{};
|
bool isPlayingAtSpeed{};
|
||||||
@ -56,7 +56,7 @@ struct ScrubbingOptions {
|
|||||||
|
|
||||||
// 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:
|
||||||
long minStutter {};
|
double minStutterTime {};
|
||||||
|
|
||||||
// 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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user