Audacity  2.3.1
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 <atomic>
22 #include <utility>
23 #include <vector>
24 #include <wx/atomic.h>
25 #include <wx/weakref.h>
26 
27 #ifdef USE_MIDI
28 
29 // TODO: Put the relative paths into automake.
30 
31 #ifdef EXPERIMENTAL_MIDI_OUT
32 #include "../lib-src/portmidi/pm_common/portmidi.h"
33 #include "../lib-src/portmidi/porttime/porttime.h"
34 #include <cstring> // Allegro include fails if this header isn't included do to no memcpy
35 #include "../lib-src/header-substitutes/allegro.h"
36 
37 class NoteTrack;
38 using NoteTrackArray = std::vector < std::shared_ptr< NoteTrack > >;
39 using NoteTrackConstArray = std::vector < std::shared_ptr< const NoteTrack > >;
40 
41 #endif // EXPERIMENTAL_MIDI_OUT
42 
43 #endif // USE_MIDI
44 
45 #if USE_PORTMIXER
46 #include "../lib-src/portmixer/include/portmixer.h"
47 #endif
48 
49 #include <wx/event.h>
50 #include <wx/string.h>
51 #include <wx/thread.h>
52 
53 #include "SampleFormat.h"
54 
55 class AudioIO;
56 class RingBuffer;
57 class Mixer;
58 class Resample;
59 class TimeTrack;
60 class AudioThread;
61 class MeterPanel;
62 class SelectedRegion;
63 
64 class AudacityProject;
65 
66 class WaveTrack;
67 using WaveTrackArray = std::vector < std::shared_ptr < WaveTrack > >;
68 using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >;
69 
70 extern AUDACITY_DLL_API AudioIO *gAudioIO;
71 
72 void InitAudioIO();
73 void DeinitAudioIO();
74 wxString DeviceName(const PaDeviceInfo* info);
75 wxString HostName(const PaDeviceInfo* info);
76 bool ValidateDeviceNames();
77 
78 class AudioIOListener;
79 
80 // #include <cfloat> if you need this constant
81 #define BAD_STREAM_TIME (-DBL_MAX)
82 
83 #define MAX_MIDI_BUFFER_SIZE 5000
84 #define DEFAULT_SYNTH_LATENCY 5
85 
86 #define DEFAULT_LATENCY_DURATION 100.0
87 #define DEFAULT_LATENCY_CORRECTION -130.0
88 
89 #define AUDIO_PRE_ROLL_KEY (wxT("/AudioIO/PreRoll"))
90 #define DEFAULT_PRE_ROLL_SECONDS 5.0
91 
92 #define AUDIO_ROLL_CROSSFADE_KEY (wxT("/AudioIO/Crossfade"))
93 #define DEFAULT_ROLL_CROSSFADE_MS 10.0
94 
95 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
96  #define AILA_DEF_TARGET_PEAK 92
97  #define AILA_DEF_DELTA_PEAK 2
98  #define AILA_DEF_ANALYSIS_TIME 1000
99  #define AILA_DEF_NUMBER_ANALYSIS 5
100 #endif
101 
102 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
103  EVT_AUDIOIO_PLAYBACK, wxCommandEvent);
104 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
105  EVT_AUDIOIO_CAPTURE, wxCommandEvent);
106 wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
107  EVT_AUDIOIO_MONITOR, wxCommandEvent);
108 
109 // PRL:
110 // If we always run a portaudio output stream (even just to produce silence)
111 // whenever we play Midi, then we might use just one thread for both.
112 // I thought this would improve MIDI synch problems on Linux/ALSA, but RBD
113 // convinced me it was neither a necessary nor sufficient fix. Perhaps too the
114 // MIDI thread might block in some error situations but we should then not
115 // also block the audio thread.
116 // So leave the separate thread ENABLED.
117 #define USE_MIDI_THREAD
118 
119 struct ScrubbingOptions;
120 
121 using PRCrossfadeData = std::vector< std::vector < float > >;
122 
123 // To avoid growing the argument list of StartStream, add fields here
125 {
126  explicit
128  : timeTrack(NULL)
129  , listener(NULL)
130  , rate(rate_)
131  , playLooped(false)
132  , cutPreviewGapStart(0.0)
133  , cutPreviewGapLen(0.0)
134  , pStartTime(NULL)
135  , preRoll(0.0)
136  {}
137 
140  double rate;
144  double * pStartTime;
145  double preRoll;
146 
147 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
148  // Non-null value indicates that scrubbing will happen
149  // (do not specify a time track, looping, or recording, which
150  // are all incompatible with scrubbing):
152 #endif
153 
154  // contents may get swapped with empty vector
156 };
157 
161 #ifdef EXPERIMENTAL_MIDI_OUT
163 #endif
164 
165  // This is a subset of playbackTracks
167 };
168 
169 // This workaround makes pause and stop work when output is to GarageBand,
170 // which seems not to implement the notes-off message correctly.
171 #define AUDIO_IO_GB_MIDI_WORKAROUND
172 
196  const void *inputBuffer, void *outputBuffer,
197  unsigned long framesPerBuffer,
198  const PaStreamCallbackTimeInfo *timeInfo,
199  PaStreamCallbackFlags statusFlags, void *userData );
200 
201 // Communicate data from one writer to one reader.
202 // This is not a queue: it is not necessary for each write to be read.
203 // Rather loss of a message is allowed: writer may overwrite.
204 // Data must be default-constructible and either copyable or movable.
205 template<typename Data>
207  struct alignas( 64
209  //std::hardware_destructive_interference_size // C++17
212  std::atomic<bool> mBusy{ false };
213  Data mData;
214  } mSlots[2];
215 
216  std::atomic<unsigned char> mLastWrittenSlot{ 0 };
217 
218 public:
219  void Initialize();
220 
221  // Move data out (if available), or else copy it out
222  Data Read();
223 
224  // Copy data in
225  void Write( const Data &data );
226  // Move data in
227  void Write( Data &&data );
228 };
230 template<typename Data>
232 {
233  for (auto &slot : mSlots)
234  // Lock both slots first, maybe spinning a little
235  while ( slot.mBusy.exchange( true, std::memory_order_acquire ) )
236  {}
237 
238  mSlots[0].mData = {};
239  mSlots[1].mData = {};
240  mLastWrittenSlot.store( 0, std::memory_order_relaxed );
241 
242  for (auto &slot : mSlots)
243  slot.mBusy.exchange( false, std::memory_order_release );
244 }
246 template<typename Data>
248 {
249  // Whichever slot was last written, prefer to read that.
250  auto idx = mLastWrittenSlot.load( std::memory_order_relaxed );
251  idx = 1 - idx;
252  bool wasBusy = false;
253  do {
254  // This loop is unlikely to execute twice, but it might because the
255  // producer thread is writing a slot.
256  idx = 1 - idx;
257  wasBusy = mSlots[idx].mBusy.exchange( true, std::memory_order_acquire );
258  } while ( wasBusy );
259 
260  // Copy the slot
261  auto result = std::move( mSlots[idx].mData );
262 
263  mSlots[idx].mBusy.store( false, std::memory_order_release );
264 
265  return result;
266 }
268 template<typename Data>
269 void MessageBuffer<Data>::Write( const Data &data )
270 {
271  // Whichever slot was last written, prefer to write the other.
272  auto idx = mLastWrittenSlot.load( std::memory_order_relaxed );
273  bool wasBusy = false;
274  do {
275  // This loop is unlikely to execute twice, but it might because the
276  // consumer thread is reading a slot.
277  idx = 1 - idx;
278  wasBusy = mSlots[idx].mBusy.exchange( true, std::memory_order_acquire );
279  } while ( wasBusy );
280 
281  mSlots[idx].mData = data;
282  mLastWrittenSlot.store( idx, std::memory_order_relaxed );
283 
284  mSlots[idx].mBusy.store( false, std::memory_order_release );
285 }
287 template<typename Data>
288 void MessageBuffer<Data>::Write( Data &&data )
289 {
290  // Whichever slot was last written, prefer to write the other.
291  auto idx = mLastWrittenSlot.load( std::memory_order_relaxed );
292  bool wasBusy = false;
293  do {
294  // This loop is unlikely to execute twice, but it might because the
295  // consumer thread is reading a slot.
296  idx = 1 - idx;
297  wasBusy = mSlots[idx].mBusy.exchange( true, std::memory_order_acquire );
298  } while ( wasBusy );
299 
300  mSlots[idx].mData = std::move( data );
301  mLastWrittenSlot.store( idx, std::memory_order_relaxed );
302 
303  mSlots[idx].mBusy.store( false, std::memory_order_release );
304 }
305 
306 class AUDACITY_DLL_API AudioIoCallback {
307 public:
308  AudioIoCallback();
309  ~AudioIoCallback();
310 
311 public:
312  // This function executes in a thread spawned by the PortAudio library
313  int AudioCallback(
314  const void *inputBuffer, void *outputBuffer,
315  unsigned long framesPerBuffer,
316  const PaStreamCallbackTimeInfo *timeInfo,
317  const PaStreamCallbackFlags statusFlags, void *userData);
318 
319  // Part of the callback
320  PaStreamCallbackResult CallbackDoSeek();
321 
322  // Part of the callback
323  void CallbackCheckCompletion(
324  int &callbackReturn, unsigned long len);
326  int mbHasSoloTracks;
327  int mCallbackReturn;
328  // Helpers to determine if tracks have already been faded out.
329  unsigned CountSoloingTracks();
330  bool TrackShouldBeSilent( const WaveTrack &wt );
331  bool TrackHasBeenFadedOut( const WaveTrack &wt );
332  bool AllTracksAlreadySilent();
333 
334  // These eight functions do different parts of AudioCallback().
335  void ComputeMidiTimings(
336  const PaStreamCallbackTimeInfo *timeInfo,
337  unsigned long framesPerBuffer);
338  void CheckSoundActivatedRecordingLevel(const void *inputBuffer);
339  void AddToOutputChannel( unsigned int chan,
340  float * outputMeterFloats,
341  float * outputFloats,
342  float * tempFloats,
343  float * tempBuf,
344  bool drop,
345  unsigned long len,
346  WaveTrack *vt
347  );
348  bool FillOutputBuffers(
349  void *outputBuffer,
350  unsigned long framesPerBuffer,
351  float * tempFloats, float *outputMeterFloats
352  );
353  void FillInputBuffers(
354  const void *inputBuffer,
355  unsigned long framesPerBuffer,
356  const PaStreamCallbackFlags statusFlags,
357  float * tempFloats
358  );
359  void UpdateTimePosition(
360  unsigned long framesPerBuffer
361  );
362  void DoPlaythrough(
363  const void *inputBuffer,
364  void *outputBuffer,
365  unsigned long framesPerBuffer,
366  float *outputMeterFloats
367  );
368  void SendVuInputMeterData(
369  float *tempFloats,
370  const void *inputBuffer,
371  unsigned long framesPerBuffer
372  );
373  void SendVuOutputMeterData(
374  float *outputMeterFloats,
375  unsigned long framesPerBuffer
376  );
377 
378 
379 // Required by these functions...
380 #ifdef EXPERIMENTAL_MIDI_OUT
381  double AudioTime() { return mPlaybackSchedule.mT0 + mNumFrames / mRate; }
382 #endif
383 
385  bool IsPaused() const;
386 
387 
393  size_t GetCommonlyReadyPlayback();
394 
395 
396 #ifdef EXPERIMENTAL_MIDI_OUT
397  // MIDI_PLAYBACK:
398  PmStream *mMidiStream;
399  PmError mLastPmError;
402  long mSynthLatency; // ms
403 
404  // These fields are used to synchronize MIDI with audio:
407  volatile double mAudioCallbackClockTime;
410  volatile long mNumFrames;
412  volatile long mNumPauseFrames;
414  volatile int mMidiLoopPasses;
415  inline double MidiLoopOffset() {
416  return mMidiLoopPasses * (mPlaybackSchedule.mT1 - mPlaybackSchedule.mT0);
417  }
418 
419  volatile long mAudioFramesPerBuffer;
422  volatile bool mMidiPaused;
425  PmTimestamp mMaxMidiTimestamp;
426 
430  double mSystemMinusAudioTime;
433  double mAudioOutLatency;
434 
435  // Next two are used to adjust the previous two, if
436  // PortAudio does not provide the info (using ALSA):
437 
440  double mStartTime;
442  long mCallbackCount;
443 
446  volatile double mSystemMinusAudioTimePlusLatency;
448  Alg_seq_ptr mSeq;
449  std::unique_ptr<Alg_iterator> mIterator;
451  Alg_event_ptr mNextEvent;
453 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
454  std::vector< std::pair< int, int > > mPendingNotesOff;
455 #endif
456 
459  double mNextEventTime;
461  NoteTrack *mNextEventTrack;
463  bool mMidiOutputComplete{ true };
465  bool mNextIsNoteOn;
467  bool mMidiStreamActive;
470  bool mSendMidiState;
471  NoteTrackConstArray mMidiPlaybackTracks;
472 #endif
473 
474 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
475  bool mAILAActive;
476  bool mAILAClipped;
477  int mAILATotalAnalysis;
478  int mAILAAnalysisCounter;
479  double mAILAMax;
480  double mAILAGoalPoint;
481  double mAILAGoalDelta;
482  double mAILAAnalysisTime;
483  double mAILALastStartTime;
484  double mAILAChangeFactor;
485  double mAILATopLevel;
486  double mAILAAnalysisEndTime;
487  double mAILAAbsolutStartTime;
488  unsigned short mAILALastChangeType; //0 - no change, 1 - increase change, 2 - decrease change
489 #endif
490 
491  std::unique_ptr<AudioThread> mThread;
492 #ifdef EXPERIMENTAL_MIDI_OUT
493 #ifdef USE_MIDI_THREAD
494  std::unique_ptr<AudioThread> mMidiThread;
495 #endif
496 #endif
499  WaveTrackArray mCaptureTracks;
500  ArrayOf<std::unique_ptr<RingBuffer>> mPlaybackBuffers;
501  WaveTrackArray mPlaybackTracks;
504  volatile int mStreamToken;
505  static int mNextStreamToken;
506  double mFactor;
508  double mRate;
509  unsigned long mMaxFramesOutput; // The actual number of frames output.
510  bool mbMicroFades;
512  double mSeek;
513  double mPlaybackRingBufferSecs;
514  double mCaptureRingBufferSecs;
517  size_t mPlaybackSamplesToCopy;
519  size_t mPlaybackQueueMinimum;
520 
521  double mMinCaptureSecsToCopy;
523  bool mPaused;
524  PaStream *mPortStreamV19;
525  bool mSoftwarePlaythrough;
527  bool mPauseRec;
528  float mSilenceLevel;
529  unsigned int mNumCaptureChannels;
530  unsigned int mNumPlaybackChannels;
531  sampleFormat mCaptureFormat;
532  unsigned long long mLostSamples{ 0 };
533  volatile bool mAudioThreadShouldCallFillBuffersOnce;
534  volatile bool mAudioThreadFillBuffersLoopRunning;
535  volatile bool mAudioThreadFillBuffersLoopActive;
536 
537  wxLongLong mLastPlaybackTimeMillis;
539 #ifdef EXPERIMENTAL_MIDI_OUT
540  volatile bool mMidiThreadFillBuffersLoopRunning;
541  volatile bool mMidiThreadFillBuffersLoopActive;
542 #endif
544  volatile double mLastRecordingOffset;
545  PaError mLastPaError;
546 
547 protected:
549  AudacityProject *mOwningProject;
550  wxWeakRef<MeterPanel> mInputMeter{};
551  MeterPanel *mOutputMeter;
552  bool mUpdateMeters;
553  volatile bool mUpdatingMeters;
554 
555  #if USE_PORTMIXER
556  PxMixer *mPortMixer;
557  float mPreviousHWPlaythrough;
558  #endif /* USE_PORTMIXER */
559 
560  bool mEmulateMixerOutputVol;
568  bool mInputMixerWorks;
569  float mMixerOutputVol;
570 
571  AudioIOListener* mListener;
572 
573  friend class AudioThread;
574 #ifdef EXPERIMENTAL_MIDI_OUT
575  friend class MidiThread;
576 #endif
577 
578  friend void InitAudioIO();
579 
580  bool mUsingAlsa { false };
582  // For cacheing supported sample rates
583  static int mCachedPlaybackIndex;
584  static std::vector<long> mCachedPlaybackRates;
585  static int mCachedCaptureIndex;
586  static std::vector<long> mCachedCaptureRates;
587  static std::vector<long> mCachedSampleRates;
588  static double mCachedBestRateIn;
589  static double mCachedBestRateOut;
590 
591  // Serialize main thread and PortAudio thread's attempts to pause and change
592  // the state used by the third, Audio thread.
593  wxMutex mSuspendAudioThread;
594 
595 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
596 public:
597  struct ScrubState;
598  std::unique_ptr<ScrubState> mScrubState;
600  bool mSilentScrub;
601  double mScrubSpeed;
602  sampleCount mScrubDuration;
603 #endif
604 
605 protected:
606  // A flag tested and set in one thread, cleared in another. Perhaps
607  // this guarantee of atomicity is more cautious than necessary.
608  wxAtomicInt mRecordingException {};
609  void SetRecordingException()
610  { wxAtomicInc( mRecordingException ); }
611  void ClearRecordingException()
612  { if (mRecordingException) wxAtomicDec( mRecordingException ); }
614  std::vector< std::pair<double, double> > mLostCaptureIntervals;
615  bool mDetectDropouts{ true };
616 
617 public:
618  // Pairs of starting time and duration
619  const std::vector< std::pair<double, double> > &LostCaptureIntervals()
620  { return mLostCaptureIntervals; }
622  // Used only for testing purposes in alpha builds
623  bool mSimulateRecordingErrors{ false };
624 
625  // Whether to check the error code passed to audacityAudioCallback to
626  // detect more dropouts
627  bool mDetectUpstreamDropouts{ true };
629 protected:
631  double mPreRoll{};
632  double mLatencyCorrection{}; // negative value usually
633  double mDuration{};
634  PRCrossfadeData mCrossfadeData;
635 
636  // These are initialized by the main thread, then updated
637  // only by the thread calling FillBuffers:
638  double mPosition{};
639  bool mLatencyCorrected{};
640 
641  double TotalCorrection() const { return mLatencyCorrection - mPreRoll; }
642  double ToConsume() const;
643  double Consumed() const;
644  double ToDiscard() const;
645  } mRecordingSchedule{};
646 
649  double mT0;
651  double mT1;
656  std::atomic<double> mTime;
657 
661  double mWarpedTime;
662 
666  double mWarpedLength;
667 
668  // mWarpedTime and mWarpedLength are irrelevant when scrubbing,
669  // else they are used in updating mTime,
670  // and when not scrubbing or playing looped, mTime is also used
671  // in the test for termination of playback.
672 
673  // with ComputeWarpedLength, it is now possible the calculate the warped length with 100% accuracy
674  // (ignoring accumulated rounding errors during playback) which fixes the 'missing sound at the end' bug
675 
676  const TimeTrack *mTimeTrack;
677 
678  volatile enum {
679  PLAY_STRAIGHT,
680  PLAY_LOOPED,
681 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
682  PLAY_SCRUB,
683  PLAY_AT_SPEED, // a version of PLAY_SCRUB.
684 #endif
685  } mPlayMode { PLAY_STRAIGHT };
686  double mCutPreviewGapStart;
687  double mCutPreviewGapLen;
688 
689  void Init(
690  double t0, double t1,
691  const AudioIOStartStreamOptions &options,
692  const RecordingSchedule *pRecordingSchedule );
695  bool ReversedTime() const
696  {
697  return mT1 < mT0;
698  }
699 
704  double GetTrackTime() const
705  { return mTime.load(std::memory_order_relaxed); }
706 
709  void SetTrackTime( double time )
710  { mTime.store(time, std::memory_order_relaxed); }
711 
717  double ClampTrackTime( double trackTime ) const;
718 
724  double LimitTrackTime() const;
725 
731  double NormalizeTrackTime() const;
732 
733  void ResetMode() { mPlayMode = PLAY_STRAIGHT; }
735  bool PlayingStraight() const { return mPlayMode == PLAY_STRAIGHT; }
736  bool Looping() const { return mPlayMode == PLAY_LOOPED; }
737  bool Scrubbing() const { return mPlayMode == PLAY_SCRUB; }
738  bool PlayingAtSpeed() const { return mPlayMode == PLAY_AT_SPEED; }
739  bool Interactive() const { return Scrubbing() || PlayingAtSpeed(); }
740 
741  // Returns true if a loop pass, or the sole pass of straight play,
742  // is completed at the current value of mTime
743  bool PassIsComplete() const;
744 
745  // Returns true if time equals t1 or is on opposite side of t1, to t0
746  bool Overruns( double trackTime ) const;
747 
748  // Compute the NEW track time for the given one and a real duration,
749  // taking into account whether the schedule is for looping
750  double AdvancedTrackTime(
751  double trackTime, double realElapsed, double speed) const;
752 
753  // Use the function above in the callback after consuming samples from the
754  // playback ring buffers, during usual straight or looping play
755  void TrackTimeUpdate(double realElapsed);
756 
757  // Convert a nonnegative real duration to an increment of track time
758  // relative to mT0.
759  double TrackDuration(double realElapsed) const;
760 
761  // Convert time between mT0 and argument to real duration, according to
762  // time track if one is given; result is always nonnegative
763  double RealDuration(double trackTime1) const;
764 
765  // How much real time left?
766  double RealTimeRemaining() const;
767 
768  // Advance the real time position
769  void RealTimeAdvance( double increment );
770 
771  // Determine starting duration within the first pass -- sometimes not
772  // zero
773  void RealTimeInit( double trackTime );
774 
775  void RealTimeRestart();
776 
777  } mPlaybackSchedule;
778 
779  // Another circular buffer
780  // Holds track time values corresponding to every nth sample in the playback
781  // buffers, for some large n
782  struct TimeQueue {
783  Doubles mData;
784  size_t mSize{ 0 };
785  double mLastTime {};
786  // These need not be updated atomically, because we rely on the atomics
787  // in the playback ring buffers to supply the synchronization. Still,
788  // align them to avoid false sharing.
789  alignas(64) struct Cursor {
790  size_t mIndex {};
791  size_t mRemainder {};
792  } mHead, mTail;
793 
794  void Producer(
795  const PlaybackSchedule &schedule, double rate, double scrubSpeed,
796  size_t nSamples );
797  double Consumer( size_t nSamples, double rate );
798  } mTimeQueue;
799 
800 };
801 
802 class AUDACITY_DLL_API AudioIO final : public AudioIoCallback {
803 
804  public:
805  AudioIO();
806  ~AudioIO();
807 
808 
809 public:
810 
811  AudioIOListener* GetListener() { return mListener; }
812  void SetListener(AudioIOListener* listener);
813 
821  void StartMonitoring(double sampleRate);
822 
830  int StartStream(const TransportTracks &tracks,
831  double t0, double t1,
832  const AudioIOStartStreamOptions &options);
833 
839  void StopStream();
842  void SeekStream(double seconds) { mSeek = seconds; }
844 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
845  bool IsScrubbing() const { return IsBusy() && mScrubState != 0; }
846 
852  void UpdateScrub(double endTimeOrSpeed, const ScrubbingOptions &options);
853 
854  void StopScrub();
855 
858  double GetLastScrubTime() const;
859 #endif
860 
865  bool IsBusy() const;
866 
873  bool IsStreamActive() const;
874  bool IsStreamActive(int token) const;
875 
876 public:
877  wxString LastPaErrorString();
879  wxLongLong GetLastPlaybackTime() const { return mLastPlaybackTimeMillis; }
880  AudacityProject *GetOwningProject() const { return mOwningProject; }
881 
882 #ifdef EXPERIMENTAL_MIDI_OUT
883 
887  PmTimestamp MidiTime();
888 
889  // Note: audio code solves the problem of soloing/muting tracks by scanning
890  // all playback tracks on every call to the audio buffer fill routine.
891  // We do the same for Midi, but it seems wasteful for at least two
892  // threads to be frequently polling to update status. This could be
893  // eliminated (also with a reduction in code I think) by updating mHasSolo
894  // each time a solo button is activated or deactivated. For now, I'm
895  // going to do this polling in the FillMidiBuffer routine to localize
896  // changes for midi to the midi code, but I'm declaring the variable
897  // here so possibly in the future, Audio code can use it too. -RBD
898  private:
899  bool mHasSolo; // is any playback solo button pressed?
900  public:
901  bool SetHasSolo(bool hasSolo);
902  bool GetHasSolo() { return mHasSolo; }
903 #endif
904 
910  bool IsAudioTokenActive(int token) const;
911 
914  bool IsMonitoring() const;
915 
917  void SetPaused(bool state);
918 
919  /* Mixer services are always available. If no stream is running, these
920  * methods use whatever device is specified by the preferences. If a
921  * stream *is* running, naturally they manipulate the mixer associated
922  * with that stream. If no mixer is available, output is emulated and
923  * input is stuck at 1.0f (a gain is applied to output samples).
924  */
925  void SetMixer(int inputSource);
926  void SetMixer(int inputSource, float inputVolume,
927  float playbackVolume);
928  void GetMixer(int *inputSource, float *inputVolume,
929  float *playbackVolume);
936  bool InputMixerWorks();
937 
944  bool OutputMixerEmulated();
945 
950  wxArrayString GetInputSourceNames();
951 
960  void HandleDeviceChange();
961 
974  static std::vector<long> GetSupportedPlaybackRates(int DevIndex = -1,
975  double rate = 0.0);
976 
989  static std::vector<long> GetSupportedCaptureRates(int devIndex = -1,
990  double rate = 0.0);
991 
1006  static std::vector<long> GetSupportedSampleRates(int playDevice = -1,
1007  int recDevice = -1,
1008  double rate = 0.0);
1009 
1018  static int GetOptimalSupportedSampleRate();
1019 
1026  double GetStreamTime();
1028  sampleFormat GetCaptureFormat() { return mCaptureFormat; }
1029  unsigned GetNumPlaybackChannels() const { return mNumPlaybackChannels; }
1030  unsigned GetNumCaptureChannels() const { return mNumCaptureChannels; }
1031 
1032  // Meaning really capturing, not just pre-rolling
1033  bool IsCapturing() const;
1034 
1039  static const int StandardRates[];
1041  static const int NumStandardRates;
1042 
1046  wxString GetDeviceInfo();
1047 
1048 #ifdef EXPERIMENTAL_MIDI_OUT
1049 
1050  wxString GetMidiDeviceInfo();
1051 #endif
1052 
1056  static bool ValidateDeviceNames(const wxString &play, const wxString &rec);
1057 
1061  #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1062  void AILAInitialize();
1063  void AILADisable();
1064  bool AILAIsActive();
1065  void AILAProcess(double maxPeak);
1066  void AILASetStartTime();
1067  double AILAGetLastDecisionTime();
1068  #endif
1069 
1070  bool IsAvailable(AudacityProject *projecT) const;
1071  void SetCaptureMeter(AudacityProject *project, MeterPanel *meter);
1072  void SetPlaybackMeter(AudacityProject *project, MeterPanel *meter);
1073 
1084  double GetBestRate(bool capturing, bool playing, double sampleRate);
1085 
1086  friend class AudioThread;
1087 #ifdef EXPERIMENTAL_MIDI_OUT
1088  friend class MidiThread;
1089 #endif
1090 
1091  friend void InitAudioIO();
1092 
1093 
1094 
1095 
1096 private:
1099  void SetMeters();
1100 
1101 
1112  bool StartPortAudioStream(double sampleRate,
1113  unsigned int numPlaybackChannels,
1114  unsigned int numCaptureChannels,
1115  sampleFormat captureFormat);
1116  void FillBuffers();
1117 
1118 #ifdef EXPERIMENTAL_MIDI_OUT
1119  void PrepareMidiIterator(bool send = true, double offset = 0);
1120  bool StartPortMidiStream();
1121 
1122  // Compute nondecreasing real time stamps, accounting for pauses, but not the
1123  // synth latency.
1124  double UncorrectedMidiEventTime();
1125 
1126  void OutputEvent();
1127  void FillMidiBuffers();
1128  void GetNextEvent();
1129  double PauseTime();
1130  void AllNotesOff(bool looping = false);
1131 #endif
1132 
1138  size_t GetCommonlyFreePlayback();
1139 
1146  size_t GetCommonlyAvailCapture();
1147 
1155  static int getRecordDevIndex(const wxString &devName = wxEmptyString);
1160 #if USE_PORTMIXER
1161  static int getRecordSourceIndex(PxMixer *portMixer);
1162 #endif
1163 
1171  static int getPlayDevIndex(const wxString &devName = wxEmptyString);
1172 
1177  static const int RatesToTry[];
1179  static const int NumRatesToTry;
1180 
1186  bool AllocateBuffers(
1187  const AudioIOStartStreamOptions &options,
1188  const TransportTracks &tracks, double t0, double t1, double sampleRate,
1189  bool scrubbing );
1190 
1194  void StartStreamCleanup(bool bOnlyBuffers = false);
1195 };
#endif
AudioIO
AudioIO uses the PortAudio library to play and record sound.
Definition: AudioIO.h:800
wxDECLARE_EXPORTED_EVENT
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, EVT_AUDIOIO_PLAYBACK, wxCommandEvent)
AudioIoCallback
AudioIoCallback is a class that implements the callback required by PortAudio. The callback needs to ...
Definition: AudioIO.h:304
AudioIoCallback::RecordingSchedule
Definition: AudioIO.h:628
MidiTime
PmTimestamp MidiTime(void *WXUNUSED(info))
Definition: AudioIO.cpp:2269
AudioIOStartStreamOptions::timeTrack
TimeTrack * timeTrack
Definition: AudioIO.h:138
AudioIoCallback::PlaybackSchedule
Definition: AudioIO.h:645
AudioIOStartStreamOptions::rate
double rate
Definition: AudioIO.h:140
AudioIOStartStreamOptions::cutPreviewGapStart
double cutPreviewGapStart
Definition: AudioIO.h:142
TransportTracks::prerollTracks
WaveTrackConstArray prerollTracks
Definition: AudioIO.h:166
MessageBuffer::Read
Data Read()
Definition: AudioIO.h:245
MessageBuffer::mSlots
struct MessageBuffer::UpdateSlot mSlots[2]
AudioIoCallback::mCaptureFormat
sampleFormat mCaptureFormat
Definition: AudioIO.h:529
AudioIoCallback::mOwningProject
AudacityProject * mOwningProject
Definition: AudioIO.h:547
TransportTracks::playbackTracks
WaveTrackArray playbackTracks
Definition: AudioIO.h:159
AudioIoCallback::ScrubState
Definition: AudioIO.cpp:533
DeinitAudioIO
void DeinitAudioIO()
Definition: AudioIO.cpp:962
AudioIOStartStreamOptions::AudioIOStartStreamOptions
AudioIOStartStreamOptions(double rate_)
Definition: AudioIO.h:127
AudioIoCallback::mNumCaptureChannels
unsigned int mNumCaptureChannels
Definition: AudioIO.h:527
AudioIOStartStreamOptions::pScrubbingOptions
ScrubbingOptions * pScrubbingOptions
Definition: AudioIO.h:151
MessageBuffer::UpdateSlot::mData
Data mData
Definition: AudioIO.h:211
MeterPanel
MeterPanel is a panel that paints the meter used for monitoring or playback.
Definition: Meter.h:102
ValidateDeviceNames
bool ValidateDeviceNames()
MessageBuffer::Initialize
void Initialize()
Definition: AudioIO.h:229
gAudioIO
AUDACITY_DLL_API AudioIO * gAudioIO
Definition: AudioIO.cpp:491
MessageBuffer::mLastWrittenSlot
std::atomic< unsigned char > mLastWrittenSlot
Definition: AudioIO.h:214
MessageBuffer
Definition: AudioIO.h:206
AudioIoCallback::mLastPlaybackTimeMillis
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:535
NoteTrackArray
std::vector< std::shared_ptr< NoteTrack > > NoteTrackArray
Definition: AudioIO.h:38
AudacityProject
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:174
AudioIOStartStreamOptions::playLooped
bool playLooped
Definition: AudioIO.h:141
AudioIOStartStreamOptions::pCrossfadeData
PRCrossfadeData * pCrossfadeData
Definition: AudioIO.h:155
TimeTrack
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:29
MessageBuffer::UpdateSlot::mBusy
std::atomic< bool > mBusy
Definition: AudioIO.h:210
SelectedRegion
Defines a selected portion of a project.
Definition: SelectedRegion.h:37
audacityAudioCallback
int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Definition: AudioIO.cpp:4695
WaveTrackArray
std::vector< std::shared_ptr< WaveTrack > > WaveTrackArray
Definition: AudioIO.h:67
AudioIOStartStreamOptions
struct holding stream options, including a pointer to the TimeTrack and AudioIOListener and whether t...
Definition: AudioIO.h:124
WaveTrackConstArray
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:68
Audacity.h
sampleFormat
sampleFormat
Definition: Types.h:188
MessageBuffer::UpdateSlot
Definition: AudioIO.h:207
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
DeviceName
wxString DeviceName(const PaDeviceInfo *info)
Definition: AudioIO.cpp:967
Experimental.h
TransportTracks::midiTracks
NoteTrackConstArray midiTracks
Definition: AudioIO.h:162
sampleCount
Definition: Types.h:60
AudioIoCallback::mNumPlaybackChannels
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:528
SampleFormat.h
HostName
wxString HostName(const PaDeviceInfo *info)
Definition: AudioIO.cpp:974
MemoryX.h
TransportTracks
Definition: AudioIO.h:158
PRCrossfadeData
std::vector< std::vector< float > > PRCrossfadeData
Definition: AudioIO.h:121
AudioIOListener
Monitors record play start/stop and new blockfiles. Has callbacks for these events.
Definition: AudioIOListener.h:20
AudioIoCallback::InitAudioIO
friend void InitAudioIO()
Definition: AudioIO.cpp:929
RingBuffer
Holds streamed audio samples.
Definition: RingBuffer.h:17
MidiThread
Definition: AudioIO.cpp:916
Resample
Interface to libsoxr.
Definition: Resample.h:32
ScrubbingOptions
Definition: Scrubbing.h:39
AudioIoCallback::TimeQueue::Cursor
Definition: AudioIO.h:787
ArrayOf
This simplifies arrays of arrays, each array separately allocated with NEW[] But it might be better t...
Definition: MemoryX.h:82
MessageBuffer::Write
void Write(const Data &data)
Definition: AudioIO.h:267
InitAudioIO
void InitAudioIO()
Definition: AudioIO.cpp:929
AudioIoCallback::TimeQueue
Definition: AudioIO.h:780
AudioIOStartStreamOptions::listener
AudioIOListener * listener
Definition: AudioIO.h:139
Mixer
Functions for doing the mixdown of the tracks.
Definition: Mix.h:80
AudioIOStartStreamOptions::cutPreviewGapLen
double cutPreviewGapLen
Definition: AudioIO.h:143
AudioIOStartStreamOptions::pStartTime
double * pStartTime
Definition: AudioIO.h:144
NoteTrackConstArray
std::vector< std::shared_ptr< const NoteTrack > > NoteTrackConstArray
Definition: AudioIO.h:39
TransportTracks::captureTracks
WaveTrackArray captureTracks
Definition: AudioIO.h:160
AudioIoCallback::mListener
AudioIOListener * mListener
Definition: AudioIO.h:569
AudioIOStartStreamOptions::preRoll
double preRoll
Definition: AudioIO.h:145
NoteTrack
A Track that is used for Midi notes. (Somewhat old code).
Definition: NoteTrack.h:66
AudioThread
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:907