1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-01 14:43:48 +01:00

Define and pass around struct ScrubbingOptions, but nothing in it yet

This commit is contained in:
Paul Licameli
2016-05-19 17:18:55 -04:00
parent 36e5b4fbbc
commit cdbdd6480b
4 changed files with 47 additions and 25 deletions

View File

@@ -344,6 +344,8 @@ double AudioIO::mCachedBestRateOut;
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
#include "tracks/ui/Scrubbing.h"
/*
This work queue class, with the aid of the playback ring
buffers, coordinates three threads during scrub play:
@@ -371,7 +373,8 @@ struct AudioIO::ScrubQueue
{
ScrubQueue(double t0, double t1, wxLongLong startClockMillis,
double minTime, double maxTime,
double rate, double maxSpeed, double minStutter)
double rate, double maxSpeed, double minStutter,
const ScrubbingOptions &options)
: mTrailingIdx(0)
, mMiddleIdx(1)
, mLeadingIdx(2)
@@ -383,13 +386,13 @@ struct AudioIO::ScrubQueue
, mUpdating()
{
bool success = InitEntry(mEntries[mMiddleIdx],
t0, t1, maxSpeed, false, NULL, false);
t0, t1, maxSpeed, false, NULL, false, options);
if (!success)
{
// StartClock equals now? Really?
--mLastScrubTimeMillis;
success = InitEntry(mEntries[mMiddleIdx],
t0, t1, maxSpeed, false, NULL, false);
t0, t1, maxSpeed, false, NULL, false, options);
}
wxASSERT(success);
@@ -419,7 +422,8 @@ struct AudioIO::ScrubQueue
mAvailable.Signal();
}
bool Producer(double end, double maxSpeed, bool bySpeed, bool maySkip)
bool Producer(double end, double maxSpeed, bool bySpeed, bool maySkip,
const ScrubbingOptions &options)
{
// Main thread indicates a scrubbing interval
@@ -437,7 +441,7 @@ struct AudioIO::ScrubQueue
// or a too-short "stutter"
const bool success =
(InitEntry(mEntries[mLeadingIdx], startTime, end, maxSpeed,
bySpeed, &previous, maySkip));
bySpeed, &previous, maySkip, options));
if (success) {
mLeadingIdx = next;
mAvailable.Signal();
@@ -532,7 +536,7 @@ private:
bool Init(long s0, long s1, long duration, Entry *previous,
double maxSpeed, long minStutter, long minSample, long maxSample,
bool adjustStart)
bool adjustStart, const ScrubbingOptions &options)
{
if (duration <= 0)
return false;
@@ -668,7 +672,8 @@ private:
};
bool InitEntry(Entry &entry, double t0, double end, double maxSpeed,
bool bySpeed, Entry *previous, bool maySkip)
bool bySpeed, Entry *previous, bool maySkip,
const ScrubbingOptions &options)
{
const wxLongLong clockTime(::wxGetLocalTimeMillis());
const long duration =
@@ -678,8 +683,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,
mMinSample, mMaxSample, maySkip);
entry.Init(s0, s1, duration, previous, maxSpeed, mMinStutter,
mMinSample, mMaxSample, maySkip, options);
if (success)
mLastScrubTimeMillis = clockTime;
return success;
@@ -1585,11 +1590,14 @@ int AudioIO::StartStream(const WaveTrackArray &playbackTracks,
mResample = NULL;
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
bool scrubbing = (options.pScrubbingOptions != nullptr);
// Scrubbing is not compatible with looping or recording or a time track!
const double scrubDelay = lrint(options.scrubDelay * sampleRate) / sampleRate;
bool scrubbing = (scrubDelay > 0);
double maxScrubSpeed = options.maxScrubSpeed;
double minScrubStutter = options.minScrubStutter;
const double scrubDelay = scrubbing
? lrint(options.scrubDelay * sampleRate) / sampleRate
: -1;
if (scrubbing)
{
if (mCaptureTracks->size() > 0 ||
@@ -1864,7 +1872,8 @@ int AudioIO::StartStream(const WaveTrackArray &playbackTracks,
mScrubQueue =
new ScrubQueue(mT0, mT1, options.scrubStartClockTimeMillis,
0.0, options.maxScrubTime,
sampleRate, maxScrubSpeed, minScrubStutter);
sampleRate, maxScrubSpeed, minScrubStutter,
*options.pScrubbingOptions);
mScrubDuration = 0;
mSilentScrub = false;
}
@@ -2461,18 +2470,18 @@ bool AudioIO::IsPaused()
}
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
bool AudioIO::EnqueueScrubByPosition(double endTime, double maxSpeed, bool maySkip)
bool AudioIO::EnqueueScrubByPosition(double endTime, double maxSpeed, bool maySkip, const ScrubbingOptions &options)
{
if (mScrubQueue)
return mScrubQueue->Producer(endTime, maxSpeed, false, maySkip);
return mScrubQueue->Producer(endTime, maxSpeed, false, maySkip, options);
else
return false;
}
bool AudioIO::EnqueueScrubBySignedSpeed(double speed, double maxSpeed, bool maySkip)
bool AudioIO::EnqueueScrubBySignedSpeed(double speed, double maxSpeed, bool maySkip, const ScrubbingOptions &options)
{
if (mScrubQueue)
return mScrubQueue->Producer(speed, maxSpeed, true, maySkip);
return mScrubQueue->Producer(speed, maxSpeed, true, maySkip, options);
else
return false;
}

View File

@@ -85,6 +85,8 @@ DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_AUDIOIO_PLAYBACK, -1);
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_AUDIOIO_CAPTURE, -1);
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_AUDIOIO_MONITOR, -1);
struct ScrubbingOptions;
// To avoid growing the argument list of StartStream, add fields here
struct AudioIOStartStreamOptions
{
@@ -115,9 +117,6 @@ struct AudioIOStartStreamOptions
double * pStartTime;
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
// Positive value indicates that scrubbing will happen
// (do not specify a time track, looping, or recording, which
// are all incompatible with scrubbing):
double scrubDelay;
// We need a limiting value for the speed of the first scrub
@@ -134,6 +133,11 @@ struct AudioIOStartStreamOptions
// usually from TrackList::GetEndTime()
double maxScrubTime;
// Non-null value indicates that scrubbing will happen
// (do not specify a time track, looping, or recording, which
// are all incompatible with scrubbing):
ScrubbingOptions *pScrubbingOptions {};
#endif
};
@@ -195,7 +199,8 @@ class AUDACITY_DLL_API AudioIO final {
* on the work queue.
* Return true if some work was really enqueued.
*/
bool EnqueueScrubByPosition(double endTime, double maxSpeed, bool maySkip);
bool EnqueueScrubByPosition(double endTime, double maxSpeed, bool maySkip,
const ScrubbingOptions &options);
/** \brief enqueue a NEW positive or negative scrubbing speed,
* using the last end as the NEW start,
@@ -209,7 +214,8 @@ class AUDACITY_DLL_API AudioIO final {
* on the work queue.
* Return true if some work was really enqueued.
*/
bool EnqueueScrubBySignedSpeed(double speed, double maxSpeed, bool maySkip);
bool EnqueueScrubBySignedSpeed(double speed, double maxSpeed, bool maySkip,
const ScrubbingOptions &options);
/** \brief return the ending time of the last enqueued scrub interval.
*/

View File

@@ -149,6 +149,7 @@ Scrubber::Scrubber(AudacityProject *project)
, mProject(project)
, mPoller { std::make_unique<ScrubPoller>(*this) }
, mOptions {}
{
if (wxTheApp)
wxTheApp->Connect
@@ -291,6 +292,7 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
}
AudioIOStartStreamOptions options(mProject->GetDefaultPlayOptions());
options.pScrubbingOptions = &mOptions;
options.timeTrack = NULL;
options.scrubDelay = (ScrubPollInterval_ms / 1000.0);
options.scrubStartClockTimeMillis = mScrubStartClockTimeMillis;
@@ -382,12 +384,12 @@ void Scrubber::ContinueScrubbing()
bool result = false;
if (mPaused)
// When paused, enqueue silent scrubs.
result = gAudioIO->EnqueueScrubBySignedSpeed(0, mMaxScrubSpeed, false);
result = gAudioIO->EnqueueScrubBySignedSpeed(0, mMaxScrubSpeed, false, mOptions);
else if (mDragging && mSmoothScrollingScrub) {
const auto lastTime = gAudioIO->GetLastTimeInScrubQueue();
const auto delta = mLastScrubPosition - position.x;
const double time = viewInfo.OffsetTimeByPixels(lastTime, delta);
result = gAudioIO->EnqueueScrubByPosition(time, mMaxScrubSpeed, true);
result = gAudioIO->EnqueueScrubByPosition(time, mMaxScrubSpeed, true, mOptions);
mLastScrubPosition = position.x;
}
else {
@@ -398,11 +400,11 @@ void Scrubber::ContinueScrubbing()
if (mSmoothScrollingScrub) {
const double speed = FindScrubSpeed(seek, time);
result = gAudioIO->EnqueueScrubBySignedSpeed(speed, mMaxScrubSpeed, seek);
result = gAudioIO->EnqueueScrubBySignedSpeed(speed, mMaxScrubSpeed, seek, mOptions);
}
else
result = gAudioIO->EnqueueScrubByPosition
(time, seek ? 1.0 : mMaxScrubSpeed, seek);
(time, seek ? 1.0 : mMaxScrubSpeed, seek, mOptions);
}
if (result)

View File

@@ -21,6 +21,10 @@ Paul Licameli split from TrackPanel.cpp
class AudacityProject;
// For putting an increment of work in the scrubbing queue
struct ScrubbingOptions {
};
// Scrub state object
class Scrubber : public wxEvtHandler
{
@@ -130,6 +134,7 @@ private:
class ScrubPoller;
std::unique_ptr<ScrubPoller> mPoller;
ScrubbingOptions mOptions;
};
// Specialist in drawing the scrub speed, and listening for certain events