1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-04 09:39:42 +02:00

Move some fields into ScrubbingOptions

This commit is contained in:
Paul Licameli 2016-05-20 00:03:16 -04:00
parent 671f60492d
commit ffe596c760
4 changed files with 44 additions and 64 deletions

View File

@ -1590,30 +1590,27 @@ int AudioIO::StartStream(const WaveTrackArray &playbackTracks,
mCaptureBuffers = NULL; mCaptureBuffers = NULL;
mResample = NULL; mResample = NULL;
double playbackTime = 4.0;
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
bool scrubbing = (options.pScrubbingOptions != nullptr); bool scrubbing = (options.pScrubbingOptions != nullptr);
// Scrubbing is not compatible with looping or recording or a time track! // Scrubbing is not compatible with looping or recording or a time track!
double maxScrubSpeed = options.maxScrubSpeed;
double minScrubStutter = options.minScrubStutter;
const double scrubDelay = scrubbing
? lrint(options.scrubDelay * sampleRate) / sampleRate
: -1;
if (scrubbing) if (scrubbing)
{ {
const auto &scrubOptions = *options.pScrubbingOptions;
if (mCaptureTracks->size() > 0 || if (mCaptureTracks->size() > 0 ||
mPlayMode == PLAY_LOOPED || mPlayMode == PLAY_LOOPED ||
mTimeTrack != NULL || mTimeTrack != NULL ||
options.maxScrubSpeed < scrubOptions.maxSpeed < ScrubbingOptions::MinAllowedScrubSpeed()) {
ScrubbingOptions::MinAllowedScrubSpeed())
{
wxASSERT(false); wxASSERT(false);
scrubbing = false; scrubbing = false;
} }
} else {
if (scrubbing) playbackTime = lrint(scrubOptions.delay * sampleRate) / sampleRate;
{ mPlayMode = PLAY_SCRUB;
mPlayMode = PLAY_SCRUB; }
} }
#endif #endif
@ -1654,11 +1651,6 @@ int AudioIO::StartStream(const WaveTrackArray &playbackTracks,
// mouse input, so make fillings more and shorter. // mouse input, so make fillings more and shorter.
// What Audio thread produces for playback is then consumed by the PortAudio // What Audio thread produces for playback is then consumed by the PortAudio
// thread, in many smaller pieces. // thread, in many smaller pieces.
double playbackTime = 4.0;
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
if (scrubbing)
playbackTime = scrubDelay;
#endif
mPlaybackSamplesToCopy = playbackTime * mRate; mPlaybackSamplesToCopy = playbackTime * mRate;
// Capacity of the playback buffer. // Capacity of the playback buffer.
@ -1875,10 +1867,11 @@ int AudioIO::StartStream(const WaveTrackArray &playbackTracks,
delete mScrubQueue; delete mScrubQueue;
if (scrubbing) if (scrubbing)
{ {
const auto &scrubOptions = *options.pScrubbingOptions;
mScrubQueue = mScrubQueue =
new ScrubQueue(mT0, mT1, options.scrubStartClockTimeMillis, new ScrubQueue(mT0, mT1, scrubOptions.startClockTimeMillis,
0.0, options.maxScrubTime, 0.0, scrubOptions.maxTime,
sampleRate, maxScrubSpeed, minScrubStutter, sampleRate, scrubOptions.maxSpeed, scrubOptions.minStutter,
*options.pScrubbingOptions); *options.pScrubbingOptions);
mScrubDuration = 0; mScrubDuration = 0;
mSilentScrub = false; mSilentScrub = false;

View File

@ -99,13 +99,6 @@ struct AudioIOStartStreamOptions
, cutPreviewGapStart(0.0) , cutPreviewGapStart(0.0)
, cutPreviewGapLen(0.0) , cutPreviewGapLen(0.0)
, pStartTime(NULL) , pStartTime(NULL)
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
, scrubDelay(0.0)
, maxScrubSpeed(1.0)
, minScrubStutter(0.0)
, scrubStartClockTimeMillis(-1)
, maxScrubTime(0.0)
#endif
{} {}
TimeTrack *timeTrack; TimeTrack *timeTrack;
@ -117,23 +110,6 @@ struct AudioIOStartStreamOptions
double * pStartTime; double * pStartTime;
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
double scrubDelay;
// We need a limiting value for the speed of the first scrub
// interval:
double maxScrubSpeed;
// When maximum speed scrubbing skips to follow the mouse,
// this is the minimum amount of playback at the maximum speed:
double minScrubStutter;
// Scrubbing needs the time of start of the mouse movement that began
// the scrub:
wxLongLong scrubStartClockTimeMillis;
// usually from TrackList::GetEndTime()
double maxScrubTime;
// Non-null value indicates that scrubbing will happen // Non-null value indicates that scrubbing will happen
// (do not specify a time track, looping, or recording, which // (do not specify a time track, looping, or recording, which
// are all incompatible with scrubbing): // are all incompatible with scrubbing):

View File

@ -142,11 +142,9 @@ void Scrubber::ScrubPoller::Notify()
Scrubber::Scrubber(AudacityProject *project) Scrubber::Scrubber(AudacityProject *project)
: mScrubToken(-1) : mScrubToken(-1)
, mScrubStartClockTimeMillis(-1)
, mPaused(true) , mPaused(true)
, mScrubSpeedDisplayCountdown(0) , mScrubSpeedDisplayCountdown(0)
, mScrubStartPosition(-1) , mScrubStartPosition(-1)
, mMaxScrubSpeed(-1.0)
, mScrubSeekPress(false) , mScrubSeekPress(false)
#ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL #ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL
, mSmoothScrollingScrub(false) , mSmoothScrollingScrub(false)
@ -243,7 +241,7 @@ void Scrubber::MarkScrubStart(
ctb->UpdateStatusBar(mProject); ctb->UpdateStatusBar(mProject);
mScrubStartPosition = xx; mScrubStartPosition = xx;
mScrubStartClockTimeMillis = ::wxGetLocalTimeMillis(); mOptions.startClockTimeMillis = ::wxGetLocalTimeMillis();
CheckMenuItem(); CheckMenuItem();
} }
@ -300,23 +298,22 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
AudioIOStartStreamOptions options(mProject->GetDefaultPlayOptions()); AudioIOStartStreamOptions options(mProject->GetDefaultPlayOptions());
options.pScrubbingOptions = &mOptions; options.pScrubbingOptions = &mOptions;
options.timeTrack = NULL; options.timeTrack = NULL;
options.scrubDelay = (ScrubPollInterval_ms / 1000.0); mOptions.delay = (ScrubPollInterval_ms / 1000.0);
options.scrubStartClockTimeMillis = mScrubStartClockTimeMillis; mOptions.minStutter = 0.2;
options.minScrubStutter = 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,
// but it may be varied during the scrub. // but it may be varied during the scrub.
mMaxScrubSpeed = options.maxScrubSpeed = mOptions.maxSpeed =
mProject->GetTranscriptionToolBar()->GetPlaySpeed(); mProject->GetTranscriptionToolBar()->GetPlaySpeed();
} }
#else #else
// That idea seems unpopular... just make it one for move-scrub, // That idea seems unpopular... just make it one for move-scrub,
// but big for drag-scrub // but big for drag-scrub
mMaxScrubSpeed = options.maxScrubSpeed = mOptions.maxSpeed =
mDragging ? ScrubbingOptions::MaxAllowedScrubSpeed() : 1.0; mDragging ? ScrubbingOptions::MaxAllowedScrubSpeed() : 1.0;
#endif #endif
options.maxScrubTime = mProject->GetTracks()->GetEndTime(); mOptions.maxTime = mProject->GetTracks()->GetEndTime();
ControlToolBar::PlayAppearance appearance = ControlToolBar::PlayAppearance appearance =
ControlToolBar::PlayAppearance::Scrub; ControlToolBar::PlayAppearance::Scrub;
const bool cutPreview = false; const bool cutPreview = false;
@ -325,7 +322,7 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
static const double maxScrubSpeedBase = static const double maxScrubSpeedBase =
pow(2.0, 1.0 / ScrubSpeedStepsPerOctave); pow(2.0, 1.0 / ScrubSpeedStepsPerOctave);
mLogMaxScrubSpeed = floor(0.5 + mLogMaxScrubSpeed = floor(0.5 +
log(mMaxScrubSpeed) / log(maxScrubSpeedBase) log(mOptions.maxSpeed) / log(maxScrubSpeedBase)
); );
#endif #endif
mScrubSpeedDisplayCountdown = 0; mScrubSpeedDisplayCountdown = 0;
@ -336,7 +333,7 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
} }
else else
// Wait to test again // Wait to test again
mScrubStartClockTimeMillis = ::wxGetLocalTimeMillis(); mOptions.startClockTimeMillis = ::wxGetLocalTimeMillis();
if (IsScrubbing()) { if (IsScrubbing()) {
using Mode = AudacityProject::PlaybackScroller::Mode; using Mode = AudacityProject::PlaybackScroller::Mode;
@ -392,7 +389,7 @@ void Scrubber::ContinueScrubbing()
// When paused, enqueue silent scrubs. // When paused, enqueue silent scrubs.
mOptions.adjustStart = false; mOptions.adjustStart = false;
mOptions.enqueueBySpeed = true; mOptions.enqueueBySpeed = true;
result = gAudioIO->EnqueueScrub(0, mMaxScrubSpeed, mOptions); result = gAudioIO->EnqueueScrub(0, mOptions.maxSpeed, mOptions);
} }
else if (mDragging && mSmoothScrollingScrub) { else if (mDragging && mSmoothScrollingScrub) {
const auto lastTime = gAudioIO->GetLastTimeInScrubQueue(); const auto lastTime = gAudioIO->GetLastTimeInScrubQueue();
@ -400,7 +397,7 @@ void Scrubber::ContinueScrubbing()
const double time = viewInfo.OffsetTimeByPixels(lastTime, delta); const double time = viewInfo.OffsetTimeByPixels(lastTime, delta);
mOptions.adjustStart = true; mOptions.adjustStart = true;
mOptions.enqueueBySpeed = false; mOptions.enqueueBySpeed = false;
result = gAudioIO->EnqueueScrub(time, mMaxScrubSpeed, mOptions); result = gAudioIO->EnqueueScrub(time, mOptions.maxSpeed, mOptions);
mLastScrubPosition = position.x; mLastScrubPosition = position.x;
} }
else { else {
@ -413,11 +410,11 @@ 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, mMaxScrubSpeed, mOptions); result = gAudioIO->EnqueueScrub(speed, mOptions.maxSpeed, mOptions);
} }
else { else {
mOptions.enqueueBySpeed = false; mOptions.enqueueBySpeed = false;
result = gAudioIO->EnqueueScrub(time, seek ? 1.0 : mMaxScrubSpeed, mOptions); result = gAudioIO->EnqueueScrub(time, seek ? 1.0 : mOptions.maxSpeed, mOptions);
} }
} }
@ -489,7 +486,7 @@ double Scrubber::FindScrubSpeed(bool seeking, double time) const
ViewInfo &viewInfo = mProject->GetViewInfo(); ViewInfo &viewInfo = mProject->GetViewInfo();
const double screen = mProject->GetScreenEndTime() - viewInfo.h; const double screen = mProject->GetScreenEndTime() - viewInfo.h;
return (seeking ? FindSeekSpeed : FindScrubbingSpeed) return (seeking ? FindSeekSpeed : FindScrubbingSpeed)
(viewInfo, mMaxScrubSpeed, screen, time); (viewInfo, mOptions.maxSpeed, screen, time);
} }
void Scrubber::HandleScrollWheel(int steps) void Scrubber::HandleScrollWheel(int steps)
@ -505,7 +502,7 @@ void Scrubber::HandleScrollWheel(int steps)
if (newSpeed >= ScrubbingOptions::MinAllowedScrubSpeed() && if (newSpeed >= ScrubbingOptions::MinAllowedScrubSpeed() &&
newSpeed <= ScrubbingOptions::MaxAllowedScrubSpeed()) { newSpeed <= ScrubbingOptions::MaxAllowedScrubSpeed()) {
mLogMaxScrubSpeed = newLogMaxScrubSpeed; mLogMaxScrubSpeed = newLogMaxScrubSpeed;
mMaxScrubSpeed = newSpeed; mOptions.maxSpeed = newSpeed;
if (!mSmoothScrollingScrub) if (!mSmoothScrollingScrub)
// Show the speed for one second // Show the speed for one second
mScrubSpeedDisplayCountdown = kOneSecondCountdown + 1; mScrubSpeedDisplayCountdown = kOneSecondCountdown + 1;

View File

@ -29,6 +29,22 @@ struct ScrubbingOptions {
bool enqueueBySpeed {}; bool enqueueBySpeed {};
double delay {};
// A limiting value for the speed of a scrub interval:
double maxSpeed { 1.0 };
// When maximum speed scrubbing skips to follow the mouse,
// this is the minimum amount of playback allowed at the maximum speed:
double minStutter {};
// Scrubbing needs the time of start of the mouse movement that began
// the scrub:
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()
@ -75,7 +91,7 @@ public:
bool ShouldDrawScrubSpeed(); bool ShouldDrawScrubSpeed();
double FindScrubSpeed(bool seeking, double time) const; double FindScrubSpeed(bool seeking, double time) const;
double GetMaxScrubSpeed() const { return mMaxScrubSpeed; } double GetMaxScrubSpeed() const { return mOptions.maxSpeed; }
void HandleScrollWheel(int steps); void HandleScrollWheel(int steps);
@ -123,12 +139,10 @@ private:
private: private:
int mScrubToken; int mScrubToken;
wxLongLong mScrubStartClockTimeMillis;
bool mPaused; bool mPaused;
int mScrubSpeedDisplayCountdown; int mScrubSpeedDisplayCountdown;
wxCoord mScrubStartPosition; wxCoord mScrubStartPosition;
wxCoord mLastScrubPosition {}; wxCoord mLastScrubPosition {};
double mMaxScrubSpeed;
bool mScrubSeekPress; bool mScrubSeekPress;
bool mSmoothScrollingScrub; bool mSmoothScrollingScrub;
bool mAlwaysSeeking {}; bool mAlwaysSeeking {};