Audacity  3.0.3
Public Types | Public Member Functions | Public Attributes | List of all members
AudioIOBase::PlaybackSchedule Struct Reference

#include <AudioIOBase.h>

Collaboration diagram for AudioIOBase::PlaybackSchedule:
[legend]

Public Types

enum  { PLAY_STRAIGHT, PLAY_LOOPED }
 

Public Member Functions

void Init (double t0, double t1, const AudioIOStartStreamOptions &options, const RecordingSchedule *pRecordingSchedule)
 
bool ReversedTime () const
 True if the end time is before the start time. More...
 
double GetTrackTime () const
 Get current track time value, unadjusted. More...
 
void SetTrackTime (double time)
 Set current track time value, unadjusted. More...
 
double ClampTrackTime (double trackTime) const
 Clamps argument to be between mT0 and mT1. More...
 
double LimitTrackTime () const
 Clamps mTime to be between mT0 and mT1. More...
 
double NormalizeTrackTime () const
 Normalizes mTime, clamping it and handling gaps from cut preview. More...
 
void ResetMode ()
 
bool PlayingStraight () const
 
bool Looping () const
 
bool Scrubbing () const
 
bool PlayingAtSpeed () const
 
bool Interactive () const
 
bool PassIsComplete () const
 
bool Overruns (double trackTime) const
 
double AdvancedTrackTime (double trackTime, double realElapsed, double speed) const
 
void TrackTimeUpdate (double realElapsed)
 
double RealDuration (double trackTime1) const
 
double RealTimeRemaining () const
 
void RealTimeAdvance (double increment)
 
void RealTimeInit (double trackTime)
 
void RealTimeRestart ()
 

Public Attributes

double mT0
 Playback starts at offset of mT0, which is measured in seconds. More...
 
double mT1
 Playback ends at offset of mT1, which is measured in seconds. Note that mT1 may be less than mT0 during scrubbing. More...
 
std::atomic< double > mTime
 
double mWarpedTime
 
double mWarpedLength
 
const BoundedEnvelopemEnvelope
 
enum AudioIOBase::PlaybackSchedule:: { ... }  PLAY_STRAIGHT
 
double mCutPreviewGapStart
 
double mCutPreviewGapLen
 

Detailed Description

Definition at line 328 of file AudioIOBase.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
PLAY_STRAIGHT 
PLAY_LOOPED 

Definition at line 359 of file AudioIOBase.h.

359  {
361  PLAY_LOOPED,
362 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
363  PLAY_SCRUB,
364  PLAY_AT_SPEED, // a version of PLAY_SCRUB.
365  PLAY_KEYBOARD_SCRUB,
366 #endif
367  } mPlayMode { PLAY_STRAIGHT };

Member Function Documentation

◆ AdvancedTrackTime()

double AudioIOBase::PlaybackSchedule::AdvancedTrackTime ( double  trackTime,
double  realElapsed,
double  speed 
) const

Definition at line 1237 of file AudioIOBase.cpp.

1239 {
1240  if (ReversedTime())
1241  realElapsed *= -1.0;
1242 
1243  // Defense against cases that might cause loops not to terminate
1244  if ( fabs(mT0 - mT1) < 1e-9 )
1245  return mT0;
1246 
1247  if (mEnvelope) {
1248  wxASSERT( speed == 1.0 );
1249 
1250  double total=0.0;
1251  bool foundTotal = false;
1252  do {
1253  auto oldTime = time;
1254  if (foundTotal && fabs(realElapsed) > fabs(total))
1255  // Avoid SolveWarpedLength
1256  time = mT1;
1257  else
1258  time = SolveWarpedLength(*mEnvelope, time, realElapsed);
1259 
1260  if (!Looping() || !Overruns( time ))
1261  break;
1262 
1263  // Bug1922: The part of the time track outside the loop should not
1264  // influence the result
1265  double delta;
1266  if (foundTotal && oldTime == mT0)
1267  // Avoid integrating again
1268  delta = total;
1269  else {
1270  delta = ComputeWarpedLength(*mEnvelope, oldTime, mT1);
1271  if (oldTime == mT0)
1272  foundTotal = true, total = delta;
1273  }
1274  realElapsed -= delta;
1275  time = mT0;
1276  } while ( true );
1277  }
1278  else {
1279  time += realElapsed * fabs(speed);
1280 
1281  // Wrap to start if looping
1282  if (Looping()) {
1283  while ( Overruns( time ) ) {
1284  // LL: This is not exactly right, but I'm at my wits end trying to
1285  // figure it out. Feel free to fix it. :-)
1286  // MB: it's much easier than you think, mTime isn't warped at all!
1287  time -= mT1 - mT0;
1288  }
1289  }
1290  }
1291 
1292  return time;
1293 }

References anonymous_namespace{AudioIOBase.cpp}::ComputeWarpedLength(), and anonymous_namespace{AudioIOBase.cpp}::SolveWarpedLength().

Referenced by AudioIoCallback::TimeQueue::Producer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClampTrackTime()

double AudioIOBase::PlaybackSchedule::ClampTrackTime ( double  trackTime) const

Clamps argument to be between mT0 and mT1.

Returns the bound if the value is out of bounds; does not wrap. Returns a time in seconds.

Definition at line 457 of file AudioIOBase.cpp.

458 {
459  if (ReversedTime())
460  return std::max(mT1, std::min(mT0, trackTime));
461  else
462  return std::max(mT0, std::min(mT1, trackTime));
463 }

References min().

Referenced by AudioIoCallback::CallbackDoSeek(), and AudioIO::StartStream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTrackTime()

double AudioIOBase::PlaybackSchedule::GetTrackTime ( ) const
inline

Get current track time value, unadjusted.

Returns a time in seconds.

Definition at line 386 of file AudioIOBase.h.

387  { return mTime.load(std::memory_order_relaxed); }

Referenced by AudioIoCallback::CallbackDoSeek(), AudioIoCallback::FillInputBuffers(), AudioIO::IsCapturing(), and AudioIO::StartStream().

Here is the caller graph for this function:

◆ Init()

void AudioIOBase::PlaybackSchedule::Init ( double  t0,
double  t1,
const AudioIOStartStreamOptions options,
const RecordingSchedule pRecordingSchedule 
)

Definition at line 382 of file AudioIOBase.cpp.

386 {
387  if ( pRecordingSchedule )
388  // It does not make sense to apply the time warp during overdub recording,
389  // which defeats the purpose of making the recording synchronized with
390  // the existing audio. (Unless we figured out the inverse warp of the
391  // captured samples in real time.)
392  // So just quietly ignore the time track.
393  mEnvelope = nullptr;
394  else
395  mEnvelope = options.envelope;
396 
397  mT0 = t0;
398  if (pRecordingSchedule)
399  mT0 -= pRecordingSchedule->mPreRoll;
400 
401  mT1 = t1;
402  if (pRecordingSchedule)
403  // adjust mT1 so that we don't give paComplete too soon to fill up the
404  // desired length of recording
405  mT1 -= pRecordingSchedule->mLatencyCorrection;
406 
407  // Main thread's initialization of mTime
408  SetTrackTime( mT0 );
409 
410  mPlayMode = options.playLooped
415 
416 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
417  bool scrubbing = (options.pScrubbingOptions != nullptr);
418 
419  // Scrubbing is not compatible with looping or recording or a time track!
420  if (scrubbing)
421  {
422  const auto &scrubOptions = *options.pScrubbingOptions;
423  if (pRecordingSchedule ||
424  Looping() ||
425  mEnvelope ||
426  scrubOptions.maxSpeed < ScrubbingOptions::MinAllowedScrubSpeed()) {
427  wxASSERT(false);
428  scrubbing = false;
429  }
430  else {
431  if (scrubOptions.isPlayingAtSpeed)
432  mPlayMode = PLAY_AT_SPEED;
433  else if (scrubOptions.isKeyboardScrubbing)
434  mPlayMode = PLAY_KEYBOARD_SCRUB;
435  else
436  mPlayMode = PLAY_SCRUB;
437  }
438  }
439 #endif
440 
441  mWarpedTime = 0.0;
442 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
443  if (Scrubbing())
444  mWarpedLength = 0.0f;
445  else
446 #endif
448 }

References AudioIOStartStreamOptions::cutPreviewGapLen, AudioIOStartStreamOptions::cutPreviewGapStart, AudioIOStartStreamOptions::envelope, Looping(), mCutPreviewGapLen, mCutPreviewGapStart, mEnvelope, ScrubbingOptions::MinAllowedScrubSpeed(), AudioIOBase::RecordingSchedule::mLatencyCorrection, AudioIOBase::RecordingSchedule::mPreRoll, mT0, mT1, mWarpedLength, mWarpedTime, PLAY_LOOPED, PLAY_STRAIGHT, AudioIOStartStreamOptions::playLooped, RealDuration(), Scrubbing(), and SetTrackTime().

Referenced by AudioIO::StartStream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Interactive()

bool AudioIOBase::PlaybackSchedule::Interactive ( ) const
inline

Definition at line 421 of file AudioIOBase.h.

421 { return Scrubbing() || PlayingAtSpeed(); }

Referenced by AudioThread::Entry(), AudioIO::FillBuffers(), AudioIoCallback::FillOutputBuffers(), AudioIO::StartStream(), and AudioIoCallback::UpdateTimePosition().

Here is the caller graph for this function:

◆ LimitTrackTime()

double AudioIOBase::PlaybackSchedule::LimitTrackTime ( ) const

Clamps mTime to be between mT0 and mT1.

Returns the bound if the value is out of bounds; does not wrap. Returns a time in seconds.

Definition at line 450 of file AudioIOBase.cpp.

451 {
452  // Track time readout for the main thread
453  // Allows for forward or backward play
454  return ClampTrackTime( GetTrackTime() );
455 }

◆ Looping()

bool AudioIOBase::PlaybackSchedule::Looping ( ) const
inline

Definition at line 418 of file AudioIOBase.h.

418 { return mPlayMode == PLAY_LOOPED; }

Referenced by AudioIO::FillBuffers(), and Init().

Here is the caller graph for this function:

◆ NormalizeTrackTime()

double AudioIOBase::PlaybackSchedule::NormalizeTrackTime ( ) const

Normalizes mTime, clamping it and handling gaps from cut preview.

Clamps the time (unless scrubbing), and skips over the cut section. Returns a time in seconds.

Definition at line 465 of file AudioIOBase.cpp.

466 {
467  // Track time readout for the main thread
468 
469  // dmazzoni: This function is needed for two reasons:
470  // One is for looped-play mode - this function makes sure that the
471  // position indicator keeps wrapping around. The other reason is
472  // more subtle - it's because PortAudio can query the hardware for
473  // the current stream time, and this query is not always accurate.
474  // Sometimes it's a little behind or ahead, and so this function
475  // makes sure that at least we clip it to the selection.
476  //
477  // msmeyer: There is also the possibility that we are using "cut preview"
478  // mode. In this case, we should jump over a defined "gap" in the
479  // audio.
480 
481  double absoluteTime;
482 
483 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
484  // Limit the time between t0 and t1 if not scrubbing.
485  // Should the limiting be necessary in any play mode if there are no bugs?
486  if (Interactive())
487  absoluteTime = GetTrackTime();
488  else
489 #endif
490  absoluteTime = LimitTrackTime();
491 
492  if (mCutPreviewGapLen > 0)
493  {
494  // msmeyer: We're in cut preview mode, so if we are on the right
495  // side of the gap, we jump over it.
496  if (absoluteTime > mCutPreviewGapStart)
497  absoluteTime += mCutPreviewGapLen;
498  }
499 
500  return absoluteTime;
501 }

Referenced by AudioIOBase::GetStreamTime().

Here is the caller graph for this function:

◆ Overruns()

bool AudioIOBase::PlaybackSchedule::Overruns ( double  trackTime) const

Definition at line 1203 of file AudioIOBase.cpp.

1204 {
1205  return (ReversedTime() ? trackTime <= mT1 : trackTime >= mT1);
1206 }

◆ PassIsComplete()

bool AudioIOBase::PlaybackSchedule::PassIsComplete ( ) const

Definition at line 1195 of file AudioIOBase.cpp.

1196 {
1197  // Test mTime within the PortAudio callback
1198  if (Scrubbing())
1199  return false; // but may be true if playing at speed
1200  return Overruns( GetTrackTime() );
1201 }

Referenced by AudioIoCallback::CallbackCheckCompletion(), and AudioIoCallback::FillInputBuffers().

Here is the caller graph for this function:

◆ PlayingAtSpeed()

bool AudioIOBase::PlaybackSchedule::PlayingAtSpeed ( ) const
inline

Definition at line 420 of file AudioIOBase.h.

420 { return mPlayMode == PLAY_AT_SPEED; }

Referenced by AudioIoCallback::CallbackCheckCompletion().

Here is the caller graph for this function:

◆ PlayingStraight()

bool AudioIOBase::PlaybackSchedule::PlayingStraight ( ) const
inline

Definition at line 417 of file AudioIOBase.h.

417 { return mPlayMode == PLAY_STRAIGHT; }

Referenced by AudioIoCallback::CallbackCheckCompletion(), and AudioIO::FillBuffers().

Here is the caller graph for this function:

◆ RealDuration()

double AudioIOBase::PlaybackSchedule::RealDuration ( double  trackTime1) const

Definition at line 1307 of file AudioIOBase.cpp.

1308 {
1309  double duration;
1310  if (mEnvelope)
1311  duration = ComputeWarpedLength(*mEnvelope, mT0, trackTime1);
1312  else
1313  duration = trackTime1 - mT0;
1314  return fabs(duration);
1315 }

References anonymous_namespace{AudioIOBase.cpp}::ComputeWarpedLength().

Referenced by Init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RealTimeAdvance()

void AudioIOBase::PlaybackSchedule::RealTimeAdvance ( double  increment)

Definition at line 1322 of file AudioIOBase.cpp.

1323 {
1324  mWarpedTime += increment;
1325 }

Referenced by AudioIO::FillBuffers().

Here is the caller graph for this function:

◆ RealTimeInit()

void AudioIOBase::PlaybackSchedule::RealTimeInit ( double  trackTime)

Definition at line 1327 of file AudioIOBase.cpp.

1328 {
1329  if (Scrubbing())
1330  mWarpedTime = 0.0;
1331  else
1332  mWarpedTime = RealDuration( trackTime );
1333 }

Referenced by AudioIoCallback::CallbackDoSeek(), and AudioIO::StartStream().

Here is the caller graph for this function:

◆ RealTimeRemaining()

double AudioIOBase::PlaybackSchedule::RealTimeRemaining ( ) const

Definition at line 1317 of file AudioIOBase.cpp.

1318 {
1319  return mWarpedLength - mWarpedTime;
1320 }

Referenced by AudioIO::FillBuffers().

Here is the caller graph for this function:

◆ RealTimeRestart()

void AudioIOBase::PlaybackSchedule::RealTimeRestart ( )

Definition at line 1335 of file AudioIOBase.cpp.

1336 {
1337  mWarpedTime = 0;
1338 }

Referenced by AudioIO::FillBuffers().

Here is the caller graph for this function:

◆ ResetMode()

void AudioIOBase::PlaybackSchedule::ResetMode ( )
inline

Definition at line 415 of file AudioIOBase.h.

415 { mPlayMode = PLAY_STRAIGHT; }

Referenced by AudioIO::StartStream(), and AudioIO::StopStream().

Here is the caller graph for this function:

◆ ReversedTime()

bool AudioIOBase::PlaybackSchedule::ReversedTime ( ) const
inline

True if the end time is before the start time.

Definition at line 377 of file AudioIOBase.h.

378  {
379  return mT1 < mT0;
380  }

◆ Scrubbing()

bool AudioIOBase::PlaybackSchedule::Scrubbing ( ) const
inline

Definition at line 419 of file AudioIOBase.h.

419 { return mPlayMode == PLAY_SCRUB || mPlayMode == PLAY_KEYBOARD_SCRUB; }

Referenced by Init().

Here is the caller graph for this function:

◆ SetTrackTime()

void AudioIOBase::PlaybackSchedule::SetTrackTime ( double  time)
inline

Set current track time value, unadjusted.

Definition at line 391 of file AudioIOBase.h.

392  { mTime.store(time, std::memory_order_relaxed); }

Referenced by AudioIoCallback::CallbackDoSeek(), Init(), AudioIO::StartStream(), and AudioIoCallback::UpdateTimePosition().

Here is the caller graph for this function:

◆ TrackTimeUpdate()

void AudioIOBase::PlaybackSchedule::TrackTimeUpdate ( double  realElapsed)

Definition at line 1295 of file AudioIOBase.cpp.

1296 {
1297  // Update mTime within the PortAudio callback
1298 
1299  if (Interactive())
1300  return;
1301 
1302  auto time = GetTrackTime();
1303  auto newTime = AdvancedTrackTime( time, realElapsed, 1.0 );
1304  SetTrackTime( newTime );
1305 }

Referenced by AudioIoCallback::UpdateTimePosition().

Here is the caller graph for this function:

Member Data Documentation

◆ mCutPreviewGapLen

double AudioIOBase::PlaybackSchedule::mCutPreviewGapLen

Definition at line 369 of file AudioIOBase.h.

Referenced by Init().

◆ mCutPreviewGapStart

double AudioIOBase::PlaybackSchedule::mCutPreviewGapStart

Definition at line 368 of file AudioIOBase.h.

Referenced by Init().

◆ mEnvelope

const BoundedEnvelope* AudioIOBase::PlaybackSchedule::mEnvelope

Definition at line 357 of file AudioIOBase.h.

Referenced by AudioIO::AllocateBuffers(), and Init().

◆ mT0

double AudioIOBase::PlaybackSchedule::mT0

Playback starts at offset of mT0, which is measured in seconds.

Definition at line 330 of file AudioIOBase.h.

Referenced by AudioIO::AllocateBuffers(), AudioIoCallback::ComputeMidiTimings(), Init(), AudioIO::IsCapturing(), and AudioIO::StartStream().

◆ mT1

double AudioIOBase::PlaybackSchedule::mT1

Playback ends at offset of mT1, which is measured in seconds. Note that mT1 may be less than mT0 during scrubbing.

Definition at line 332 of file AudioIOBase.h.

Referenced by Init().

◆ mTime

std::atomic<double> AudioIOBase::PlaybackSchedule::mTime

Current track time position during playback, in seconds. Initialized by the main thread but updated by worker threads during playback or recording, and periodically reread by the main thread for purposes such as display update.

Definition at line 337 of file AudioIOBase.h.

◆ mWarpedLength

double AudioIOBase::PlaybackSchedule::mWarpedLength

Real length to be played (if looping, for each pass) after warping via a time track, computed just once when starting the stream. Length in real seconds between mT0 and mT1. Always positive.

Definition at line 347 of file AudioIOBase.h.

Referenced by Init().

◆ mWarpedTime

double AudioIOBase::PlaybackSchedule::mWarpedTime

Accumulated real time (not track position), starting at zero (unlike mTime), and wrapping back to zero each time around looping play. Thus, it is the length in real seconds between mT0 and mTime.

Definition at line 342 of file AudioIOBase.h.

Referenced by AudioIO::FillBuffers(), and Init().

◆ PLAY_STRAIGHT

enum { ... } AudioIOBase::PlaybackSchedule::PLAY_STRAIGHT

Referenced by Init().


The documentation for this struct was generated from the following files:
AudioIOBase::PlaybackSchedule::mT0
double mT0
Playback starts at offset of mT0, which is measured in seconds.
Definition: AudioIOBase.h:330
AudioIOBase::PlaybackSchedule::PlayingAtSpeed
bool PlayingAtSpeed() const
Definition: AudioIOBase.h:420
AudioIOBase::PlaybackSchedule::PLAY_STRAIGHT
enum AudioIOBase::PlaybackSchedule::@0 PLAY_STRAIGHT
AudioIOBase::PlaybackSchedule::mCutPreviewGapLen
double mCutPreviewGapLen
Definition: AudioIOBase.h:369
AudioIOBase::PlaybackSchedule::LimitTrackTime
double LimitTrackTime() const
Clamps mTime to be between mT0 and mT1.
Definition: AudioIOBase.cpp:450
AudioIOBase::PlaybackSchedule::mT1
double mT1
Playback ends at offset of mT1, which is measured in seconds. Note that mT1 may be less than mT0 duri...
Definition: AudioIOBase.h:332
AudioIOStartStreamOptions::envelope
const BoundedEnvelope * envelope
Definition: AudioIOBase.h:91
ScrubbingOptions::MinAllowedScrubSpeed
static double MinAllowedScrubSpeed()
Definition: AudioIOBase.h:70
anonymous_namespace{AudioIOBase.cpp}::ComputeWarpedLength
double ComputeWarpedLength(const Envelope &env, double t0, double t1)
Compute the duration (in seconds at playback) of the specified region of the track.
Definition: AudioIOBase.cpp:1219
AudioIOStartStreamOptions::playLooped
bool playLooped
Definition: AudioIOBase.h:94
AudioIOBase::PlaybackSchedule::AdvancedTrackTime
double AdvancedTrackTime(double trackTime, double realElapsed, double speed) const
Definition: AudioIOBase.cpp:1237
AudioIOBase::PlaybackSchedule::Interactive
bool Interactive() const
Definition: AudioIOBase.h:421
AudioIOBase::PlaybackSchedule::mCutPreviewGapStart
double mCutPreviewGapStart
Definition: AudioIOBase.h:368
AudioIOBase::PlaybackSchedule::SetTrackTime
void SetTrackTime(double time)
Set current track time value, unadjusted.
Definition: AudioIOBase.h:391
AudioIOBase::PlaybackSchedule::PLAY_LOOPED
@ PLAY_LOOPED
Definition: AudioIOBase.h:361
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
AudioIOBase::PlaybackSchedule::mWarpedLength
double mWarpedLength
Definition: AudioIOBase.h:347
AudioIOStartStreamOptions::cutPreviewGapStart
double cutPreviewGapStart
Definition: AudioIOBase.h:95
AudioIOBase::PlaybackSchedule::GetTrackTime
double GetTrackTime() const
Get current track time value, unadjusted.
Definition: AudioIOBase.h:386
AudioIOStartStreamOptions::cutPreviewGapLen
double cutPreviewGapLen
Definition: AudioIOBase.h:96
AudioIOBase::PlaybackSchedule::ClampTrackTime
double ClampTrackTime(double trackTime) const
Clamps argument to be between mT0 and mT1.
Definition: AudioIOBase.cpp:457
AudioIOBase::PlaybackSchedule::mTime
std::atomic< double > mTime
Definition: AudioIOBase.h:337
AudioIOBase::PlaybackSchedule::Looping
bool Looping() const
Definition: AudioIOBase.h:418
AudioIOBase::PlaybackSchedule::ReversedTime
bool ReversedTime() const
True if the end time is before the start time.
Definition: AudioIOBase.h:377
AudioIOBase::PlaybackSchedule::Scrubbing
bool Scrubbing() const
Definition: AudioIOBase.h:419
anonymous_namespace{AudioIOBase.cpp}::SolveWarpedLength
double SolveWarpedLength(const Envelope &env, double t0, double length)
Compute how much unwarped time must have elapsed if length seconds of warped time has elapsed.
Definition: AudioIOBase.cpp:1231
AudioIOBase::PlaybackSchedule::RealDuration
double RealDuration(double trackTime1) const
Definition: AudioIOBase.cpp:1307
AudioIOBase::PlaybackSchedule::Overruns
bool Overruns(double trackTime) const
Definition: AudioIOBase.cpp:1203
AudioIOBase::PlaybackSchedule::mEnvelope
const BoundedEnvelope * mEnvelope
Definition: AudioIOBase.h:357
AudioIOBase::PlaybackSchedule::mWarpedTime
double mWarpedTime
Definition: AudioIOBase.h:342