Audacity  2.2.2
AudioIO.h
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  AudioIO.h
6 
7  Dominic Mazzoni
8 
9  Use the PortAudio library to play and record sound
10 
11 **********************************************************************/
12 
13 #ifndef __AUDACITY_AUDIO_IO__
14 #define __AUDACITY_AUDIO_IO__
15 
16 #include "portaudio.h"
17 #include "Audacity.h"
18 #include "Experimental.h"
19 
20 #include "MemoryX.h"
21 #include <utility>
22 #include <vector>
23 #include <wx/atomic.h>
24 #include <wx/weakref.h>
25 
26 #ifdef USE_MIDI
27 
28 // TODO: Put the relative paths into automake.
29 
30 #ifdef EXPERIMENTAL_MIDI_OUT
31 #include "../lib-src/portmidi/pm_common/portmidi.h"
32 #include "../lib-src/portmidi/porttime/porttime.h"
33 #include <cstring> // Allegro include fails if this header isn't included do to no memcpy
34 #include "../lib-src/header-substitutes/allegro.h"
35 
36 class NoteTrack;
37 using NoteTrackArray = std::vector < std::shared_ptr< NoteTrack > >;
38 
39 #endif // EXPERIMENTAL_MIDI_OUT
40 
41 #endif // USE_MIDI
42 
43 #if USE_PORTMIXER
44 #include "../lib-src/portmixer/include/portmixer.h"
45 #endif
46 
47 #include <wx/event.h>
48 #include <wx/string.h>
49 #include <wx/thread.h>
50 
51 #include "SampleFormat.h"
52 
53 class AudioIO;
54 class RingBuffer;
55 class Mixer;
56 class Resample;
57 class TimeTrack;
58 class AudioThread;
59 class MeterPanel;
60 class SelectedRegion;
61 
62 class AudacityProject;
63 
64 class WaveTrack;
65 using WaveTrackArray = std::vector < std::shared_ptr < WaveTrack > >;
66 using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >;
67 
68 extern AUDACITY_DLL_API AudioIO *gAudioIO;
69 
70 void InitAudioIO();
71 void DeinitAudioIO();
72 wxString DeviceName(const PaDeviceInfo* info);
73 wxString HostName(const PaDeviceInfo* info);
74 bool ValidateDeviceNames();
75 
76 class AudioIOListener;
77 
78 // #include <cfloat> if you need this constant
79 #define BAD_STREAM_TIME (-DBL_MAX)
80 
81 #define MAX_MIDI_BUFFER_SIZE 5000
82 #define DEFAULT_SYNTH_LATENCY 5
83 
84 #define DEFAULT_LATENCY_DURATION 100.0
85 #define DEFAULT_LATENCY_CORRECTION -130.0
86 
87 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
88  #define AILA_DEF_TARGET_PEAK 92
89  #define AILA_DEF_DELTA_PEAK 2
90  #define AILA_DEF_ANALYSIS_TIME 1000
91  #define AILA_DEF_NUMBER_ANALYSIS 5
92 #endif
93 
94 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
95  EVT_AUDIOIO_PLAYBACK, wxCommandEvent);
96 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
97  EVT_AUDIOIO_CAPTURE, wxCommandEvent);
98 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
99  EVT_AUDIOIO_MONITOR, wxCommandEvent);
100 
101 // PRL:
102 // If we always run a portaudio output stream (even just to produce silence)
103 // whenever we play Midi, then we might use just one thread for both.
104 // I thought this would improve MIDI synch problems on Linux/ALSA, but RBD
105 // convinced me it was neither a necessary nor sufficient fix. Perhaps too the
106 // MIDI thread might block in some error situations but we should then not
107 // also block the audio thread.
108 // So leave the separate thread ENABLED.
109 #define USE_MIDI_THREAD
110 
111 struct ScrubbingOptions;
112 
113 // To avoid growing the argument list of StartStream, add fields here
115 {
116  explicit
118  : timeTrack(NULL)
119  , listener(NULL)
120  , rate(rate_)
121  , playLooped(false)
122  , cutPreviewGapStart(0.0)
123  , cutPreviewGapLen(0.0)
124  , pStartTime(NULL)
125  {}
126 
129  double rate;
133  double * pStartTime;
134 
135 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
136  // Non-null value indicates that scrubbing will happen
137  // (do not specify a time track, looping, or recording, which
138  // are all incompatible with scrubbing):
140 #endif
141 };
142 
143 // This workaround makes pause and stop work when output is to GarageBand,
144 // which seems not to implement the notes-off message correctly.
145 #define AUDIO_IO_GB_MIDI_WORKAROUND
146 
147 class AUDACITY_DLL_API AudioIO final {
148 
149  public:
150  AudioIO();
151  ~AudioIO();
152 
153  AudioIOListener* GetListener() { return mListener; }
154  void SetListener(AudioIOListener* listener);
155 
163  void StartMonitoring(double sampleRate);
164 
172  int StartStream(const WaveTrackConstArray &playbackTracks, const WaveTrackArray &captureTracks,
173 #ifdef EXPERIMENTAL_MIDI_OUT
174  const NoteTrackArray &midiTracks,
175 #endif
176  double t0, double t1,
177  const AudioIOStartStreamOptions &options);
178 
184  void StopStream();
187  void SeekStream(double seconds) { mSeek = seconds; }
188 
189 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
190  bool IsScrubbing() { return IsBusy() && mScrubQueue != 0; }
191 
202  bool EnqueueScrub(double endTimeOrSpeed, const ScrubbingOptions &options);
203 
206  double GetLastTimeInScrubQueue() const;
207 #endif
208 
213  bool IsBusy();
214 
221  bool IsStreamActive();
222  bool IsStreamActive(int token);
223 
224  wxLongLong GetLastPlaybackTime() const { return mLastPlaybackTimeMillis; }
225  AudacityProject *GetOwningProject() const { return mOwningProject; }
226 
227 #ifdef EXPERIMENTAL_MIDI_OUT
228 
232  PmTimestamp MidiTime();
233 
234  // Note: audio code solves the problem of soloing/muting tracks by scanning
235  // all playback tracks on every call to the audio buffer fill routine.
236  // We do the same for Midi, but it seems wasteful for at least two
237  // threads to be frequently polling to update status. This could be
238  // eliminated (also with a reduction in code I think) by updating mHasSolo
239  // each time a solo button is activated or deactivated. For now, I'm
240  // going to do this polling in the FillMidiBuffer routine to localize
241  // changes for midi to the midi code, but I'm declaring the variable
242  // here so possibly in the future, Audio code can use it too. -RBD
243  private:
244  bool mHasSolo; // is any playback solo button pressed?
245  public:
246  bool SetHasSolo(bool hasSolo);
247  bool GetHasSolo() { return mHasSolo; }
248 #endif
249 
255  bool IsAudioTokenActive(int token);
256 
259  bool IsMonitoring();
260 
262  void SetPaused(bool state);
264  bool IsPaused();
265 
266  /* Mixer services are always available. If no stream is running, these
267  * methods use whatever device is specified by the preferences. If a
268  * stream *is* running, naturally they manipulate the mixer associated
269  * with that stream. If no mixer is available, output is emulated and
270  * input is stuck at 1.0f (a gain is applied to output samples).
271  */
272  void SetMixer(int inputSource);
273  void SetMixer(int inputSource, float inputVolume,
274  float playbackVolume);
275  void GetMixer(int *inputSource, float *inputVolume,
276  float *playbackVolume);
283  bool InputMixerWorks();
284 
291  bool OutputMixerEmulated();
292 
297  wxArrayString GetInputSourceNames();
298 
307  void HandleDeviceChange();
308 
321  static std::vector<long> GetSupportedPlaybackRates(int DevIndex = -1,
322  double rate = 0.0);
323 
336  static std::vector<long> GetSupportedCaptureRates(int devIndex = -1,
337  double rate = 0.0);
338 
353  static std::vector<long> GetSupportedSampleRates(int playDevice = -1,
354  int recDevice = -1,
355  double rate = 0.0);
356 
365  static int GetOptimalSupportedSampleRate();
366 
373  double GetStreamTime();
374 
375  sampleFormat GetCaptureFormat() { return mCaptureFormat; }
376  unsigned GetNumPlaybackChannels() const { return mNumPlaybackChannels; }
377  unsigned GetNumCaptureChannels() const { return mNumCaptureChannels; }
378 
383  static const int StandardRates[];
385  static const int NumStandardRates;
386 
390  wxString GetDeviceInfo();
391 
392 #ifdef EXPERIMENTAL_MIDI_OUT
393 
394  wxString GetMidiDeviceInfo();
395 #endif
396 
400  static bool ValidateDeviceNames(const wxString &play, const wxString &rec);
401 
405  #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
406  void AILAInitialize();
407  void AILADisable();
408  bool AILAIsActive();
409  void AILAProcess(double maxPeak);
410  void AILASetStartTime();
411  double AILAGetLastDecisionTime();
412  #endif
413 
414  bool IsAvailable(AudacityProject *projecT);
415  void SetCaptureMeter(AudacityProject *project, MeterPanel *meter);
416  void SetPlaybackMeter(AudacityProject *project, MeterPanel *meter);
417 
418 private:
421  void SetMeters();
422 
433  double GetBestRate(bool capturing, bool playing, double sampleRate);
434 
445  bool StartPortAudioStream(double sampleRate,
446  unsigned int numPlaybackChannels,
447  unsigned int numCaptureChannels,
448  sampleFormat captureFormat);
449  void FillBuffers();
450 
451 #ifdef EXPERIMENTAL_MIDI_OUT
452  void PrepareMidiIterator(bool send = true, double offset = 0);
453  bool StartPortMidiStream();
454 
455  // Compute nondecreasing time stamps, accounting for pauses, but not the
456  // synth latency.
457  double UncorrectedMidiEventTime();
458 
459  void OutputEvent();
460  void FillMidiBuffers();
461  void GetNextEvent();
462  double AudioTime() { return mT0 + mNumFrames / mRate; }
463  double PauseTime();
464  void AllNotesOff(bool looping = false);
465 #endif
466 
472  size_t GetCommonlyAvailPlayback();
473 
480  size_t GetCommonlyAvailCapture();
481 
489  static int getRecordDevIndex(const wxString &devName = wxEmptyString);
494 #if USE_PORTMIXER
495  static int getRecordSourceIndex(PxMixer *portMixer);
496 #endif
497 
505  static int getPlayDevIndex(const wxString &devName = wxEmptyString);
506 
511  static const int RatesToTry[];
513  static const int NumRatesToTry;
514 
516  bool ReversedTime() const
517  {
518  return mT1 < mT0;
519  }
526  double LimitStreamTime(double absoluteTime) const;
527 
534  double NormalizeStreamTime(double absoluteTime) const;
535 
539  void StartStreamCleanup(bool bOnlyBuffers = false);
540 
541 #ifdef EXPERIMENTAL_MIDI_OUT
542  // MIDI_PLAYBACK:
543  PmStream *mMidiStream;
544  PmError mLastPmError;
545 
547  long mSynthLatency; // ms
548 
549  // These fields are used to synchronize MIDI with audio:
550 
552  volatile double mAudioCallbackClockTime;
553 
555  volatile long mNumFrames;
557  volatile long mNumPauseFrames;
559  volatile int mMidiLoopPasses;
560  inline double MidiLoopOffset() { return mMidiLoopPasses * (mT1 - mT0); }
561 
562  volatile long mAudioFramesPerBuffer;
565  volatile bool mMidiPaused;
568  PmTimestamp mMaxMidiTimestamp;
569 
573  double mSystemMinusAudioTime;
576  double mAudioOutLatency;
577 
578  // Next two are used to adjust the previous two, if
579  // PortAudio does not provide the info (using ALSA):
580 
583  double mStartTime;
585  long mCallbackCount;
586 
589  volatile double mSystemMinusAudioTimePlusLatency;
590 
591  Alg_seq_ptr mSeq;
592  std::unique_ptr<Alg_iterator> mIterator;
594  Alg_event_ptr mNextEvent;
595 
596 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
597  std::vector< std::pair< int, int > > mPendingNotesOff;
598 #endif
599 
602  double mNextEventTime;
604  NoteTrack *mNextEventTrack;
606  bool mMidiOutputComplete{ true };
608  bool mNextIsNoteOn;
610  bool mMidiStreamActive;
613  bool mSendMidiState;
614  NoteTrackArray mMidiPlaybackTracks;
615 #endif
616 
617 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
618  bool mAILAActive;
619  bool mAILAClipped;
620  int mAILATotalAnalysis;
621  int mAILAAnalysisCounter;
622  double mAILAMax;
623  double mAILAGoalPoint;
624  double mAILAGoalDelta;
625  double mAILAAnalysisTime;
626  double mAILALastStartTime;
627  double mAILAChangeFactor;
628  double mAILATopLevel;
629  double mAILAAnalysisEndTime;
630  double mAILAAbsolutStartTime;
631  unsigned short mAILALastChangeType; //0 - no change, 1 - increase change, 2 - decrease change
632 #endif
633 
634  std::unique_ptr<AudioThread> mThread;
635 #ifdef EXPERIMENTAL_MIDI_OUT
636 #ifdef USE_MIDI_THREAD
637  std::unique_ptr<AudioThread> mMidiThread;
638 #endif
639 #endif
645 
647  volatile int mStreamToken;
648  static int mNextStreamToken;
649  double mFactor;
651  double mRate;
653  double mT0;
655  double mT1;
657  double mTime;
658 
662  double mWarpedTime;
663 
668 
669  double mSeek;
675  bool mPaused;
676  PaStream *mPortStreamV19;
679  bool mPauseRec;
681  unsigned int mNumCaptureChannels;
682  unsigned int mNumPlaybackChannels;
684  unsigned long long mLostSamples{ 0 };
688 
690 
691 #ifdef EXPERIMENTAL_MIDI_OUT
692  volatile bool mMidiThreadFillBuffersLoopRunning;
693  volatile bool mMidiThreadFillBuffersLoopActive;
694 #endif
695 
696  volatile double mLastRecordingOffset;
697  PaError mLastPaError;
698 
700  wxWeakRef<MeterPanel> mInputMeter{};
703  volatile bool mUpdatingMeters;
704 
705  #if USE_PORTMIXER
706  PxMixer *mPortMixer;
707  float mPreviousHWPlaythrough;
708  #endif /* USE_PORTMIXER */
709 
720 
721  volatile enum {
724 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
726 #endif
727  } mPlayMode;
730 
732 
734 
735  friend class AudioThread;
736 #ifdef EXPERIMENTAL_MIDI_OUT
737  friend class MidiThread;
738 #endif
739 
740  friend void InitAudioIO();
741 
743 
744  bool mUsingAlsa { false };
745 
746  // For cacheing supported sample rates
748  static std::vector<long> mCachedPlaybackRates;
750  static std::vector<long> mCachedCaptureRates;
751  static std::vector<long> mCachedSampleRates;
752  static double mCachedBestRateIn;
753  static double mCachedBestRateOut;
754 
777  friend int audacityAudioCallback(
778  const void *inputBuffer, void *outputBuffer,
779  unsigned long framesPerBuffer,
780  const PaStreamCallbackTimeInfo *timeInfo,
781  PaStreamCallbackFlags statusFlags, void *userData );
782 
783  // Serialize main thread and PortAudio thread's attempts to pause and change
784  // the state used by the third, Audio thread.
786 
787 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
788  struct ScrubQueue;
789  std::unique_ptr<ScrubQueue> mScrubQueue;
790 
793 #endif
794 
795  // A flag tested and set in one thread, cleared in another. Perhaps
796  // this guarantee of atomicity is more cautious than necessary.
797  wxAtomicInt mRecordingException {};
799  { wxAtomicInc( mRecordingException ); }
801  { if (mRecordingException) wxAtomicDec( mRecordingException ); }
802 
803  std::vector< std::pair<double, double> > mLostCaptureIntervals;
804  bool mDetectDropouts{ true };
805 
806 public:
807  // Pairs of starting time and duration
808  const std::vector< std::pair<double, double> > &LostCaptureIntervals()
809  { return mLostCaptureIntervals; }
810 
811  // Used only for testing purposes in alpha builds
812  bool mSimulateRecordingErrors{ false };
813 
814  // Whether to check the error code passed to audacityAudioCallback to
815  // detect more dropouts
816  bool mDetectUpstreamDropouts{ true };
817 };
818 
819 #endif
AudioIO uses the PortAudio library to play and record sound.
Definition: AudioIO.h:147
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, EVT_AUDIOIO_PLAYBACK, wxCommandEvent)
double mMinCaptureSecsToCopy
Definition: AudioIO.h:673
static std::vector< long > mCachedSampleRates
Definition: AudioIO.h:751
TimeTrack * timeTrack
Definition: AudioIO.h:127
static double mCachedBestRateIn
Definition: AudioIO.h:752
static int mNextStreamToken
Definition: AudioIO.h:648
wxLongLong GetLastPlaybackTime() const
Definition: AudioIO.h:224
sampleCount mScrubDuration
Definition: AudioIO.h:792
const std::vector< std::pair< double, double > > & LostCaptureIntervals()
Definition: AudioIO.h:808
volatile bool mUpdatingMeters
Definition: AudioIO.h:703
float mMixerOutputVol
Definition: AudioIO.h:719
unsigned GetNumCaptureChannels() const
Definition: AudioIO.h:377
double mTime
Current time position during playback, in seconds. Between mT0 and mT1.
Definition: AudioIO.h:657
bool mInputMixerWorks
Can we control the hardware input level?
Definition: AudioIO.h:718
bool mSoftwarePlaythrough
Definition: AudioIO.h:677
void DeinitAudioIO()
Definition: AudioIO.cpp:1149
AudioIOStartStreamOptions(double rate_)
Definition: AudioIO.h:117
const TimeTrack * mTimeTrack
Definition: AudioIO.h:742
MeterPanel * mOutputMeter
Definition: AudioIO.h:701
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
Definition: AudioIO.h:643
ScrubbingOptions * pScrubbingOptions
Definition: AudioIO.h:139
AudioIOListener * GetListener()
Definition: AudioIO.h:153
MeterPanel is a panel that paints the meter used for monitoring or playback.
Definition: Meter.h:97
bool ValidateDeviceNames()
float mSilenceLevel
Definition: AudioIO.h:680
ArrayOf< std::unique_ptr< Resample > > mResample
Definition: AudioIO.h:640
AUDACITY_DLL_API AudioIO * gAudioIO
Definition: AudioIO.cpp:482
sampleFormat mCaptureFormat
Definition: AudioIO.h:683
GrowableSampleBuffer mSilentBuf
Definition: AudioIO.h:731
ArrayOf< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:646
std::unique_ptr< ScrubQueue > mScrubQueue
Definition: AudioIO.h:788
double mWarpedTime
Definition: AudioIO.h:662
static int mCachedPlaybackIndex
Definition: AudioIO.h:747
wxMutex mSuspendAudioThread
Definition: AudioIO.h:785
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
static std::vector< long > mCachedPlaybackRates
Definition: AudioIO.h:748
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:29
bool mPaused
True if audio playback is paused.
Definition: AudioIO.h:675
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
Definition: AudioIO.h:641
bool ReversedTime() const
True if the end time is before the start time.
Definition: AudioIO.h:516
volatile int mStreamToken
Definition: AudioIO.h:647
Defines a selected portion of a project.
WaveTrackArray mCaptureTracks
Definition: AudioIO.h:642
bool mEmulateMixerOutputVol
Definition: AudioIO.h:710
std::vector< std::shared_ptr< WaveTrack > > WaveTrackArray
Definition: AudioIO.h:65
PaStream * mPortStreamV19
Definition: AudioIO.h:676
struct holding stream options, including a pointer to the TimeTrack and AudioIOListener and whether t...
Definition: AudioIO.h:114
static std::vector< long > mCachedCaptureRates
Definition: AudioIO.h:750
void ClearRecordingException()
Definition: AudioIO.h:800
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:66
double mCaptureRingBufferSecs
Definition: AudioIO.h:671
sampleFormat
Definition: Types.h:188
int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
wxString DeviceName(const PaDeviceInfo *info)
Definition: AudioIO.cpp:1154
AudacityProject * GetOwningProject() const
Definition: AudioIO.h:225
AudacityProject * mOwningProject
Definition: AudioIO.h:699
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:689
AudioIOListener * mListener
Definition: AudioIO.h:733
volatile bool mAudioThreadShouldCallFillBuffersOnce
Definition: AudioIO.h:685
bool IsScrubbing()
Definition: AudioIO.h:190
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:682
double mSeek
Definition: AudioIO.h:669
std::vector< std::shared_ptr< NoteTrack > > NoteTrackArray
Definition: Track.h:53
unsigned int mNumCaptureChannels
Definition: AudioIO.h:681
std::unique_ptr< AudioThread > mThread
Definition: AudioIO.h:634
wxString HostName(const PaDeviceInfo *info)
Definition: AudioIO.cpp:1161
double mRate
Audio playback rate in samples per second.
Definition: AudioIO.h:651
Monitors record play start/stop and new blockfiles. Has callbacks for these events.
bool mUpdateMeters
Definition: AudioIO.h:702
Holds streamed audio samples.
Definition: RingBuffer.h:18
volatile double mLastRecordingOffset
Definition: AudioIO.h:696
Interface to libsoxr.
Definition: Resample.h:32
static int mCachedCaptureIndex
Definition: AudioIO.h:749
static const int NumStandardRates
How many standard sample rates there are.
Definition: AudioIO.h:385
Memory.h template class for making an array of float, bool, etc.
Definition: MemoryX.h:86
sampleFormat GetCaptureFormat()
Definition: AudioIO.h:375
void InitAudioIO()
Definition: AudioIO.cpp:1116
double mWarpedLength
Definition: AudioIO.h:667
double mCutPreviewGapLen
Definition: AudioIO.h:729
double mT0
Playback starts at offset of mT0, which is measured in seconds.
Definition: AudioIO.h:653
double mCutPreviewGapStart
Definition: AudioIO.h:728
static double mCachedBestRateOut
Definition: AudioIO.h:753
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:803
AudioIOListener * listener
Definition: AudioIO.h:128
static const int NumRatesToTry
How many sample rates to try.
Definition: AudioIO.h:513
volatile bool mAudioThreadFillBuffersLoopActive
Definition: AudioIO.h:687
Functions for doing the mixdown of the tracks.
Definition: Mix.h:80
double mFactor
Definition: AudioIO.h:649
PaError mLastPaError
Definition: AudioIO.h:697
size_t mPlaybackSamplesToCopy
Definition: AudioIO.h:672
void SeekStream(double seconds)
Move the playback / recording position of the current stream by the specified amount from where it is...
Definition: AudioIO.h:187
unsigned GetNumPlaybackChannels() const
Definition: AudioIO.h:376
double mT1
Playback ends at offset of mT1, which is measured in seconds. Note that mT1 may be less than mT0 duri...
Definition: AudioIO.h:655
volatile bool mAudioThreadFillBuffersLoopRunning
Definition: AudioIO.h:686
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:679
void SetRecordingException()
Definition: AudioIO.h:798
bool mSilentScrub
Definition: AudioIO.h:791
WaveTrackConstArray mPlaybackTracks
Definition: AudioIO.h:644
A Track that is used for Midi notes. (Somewhat old code).
double mPlaybackRingBufferSecs
Definition: AudioIO.h:670
Defined different on Mac and other platforms (on Mac it does not use wxWidgets wxThread), this class sits in a thread loop reading and writing audio.
Definition: AudioIO.cpp:1094