Audacity  2.2.0
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 <vector>
22 #include <wx/atomic.h>
23 
24 #ifdef USE_MIDI
25 
26 // TODO: Put the relative paths into automake.
27 
28 #ifdef EXPERIMENTAL_MIDI_OUT
29 #include "../lib-src/portmidi/pm_common/portmidi.h"
30 #include "../lib-src/portmidi/porttime/porttime.h"
31 #include <cstring> // Allegro include fails if this header isn't included do to no memcpy
32 #include "../lib-src/portsmf/allegro.h"
33 
34 class NoteTrack;
35 using NoteTrackArray = std::vector < NoteTrack* >;
36 
37 #endif // EXPERIMENTAL_MIDI_OUT
38 
39 #endif // USE_MIDI
40 
41 #if USE_PORTMIXER
42 #include "../lib-src/portmixer/include/portmixer.h"
43 #endif
44 
45 #include <wx/event.h>
46 #include <wx/string.h>
47 #include <wx/thread.h>
48 
49 #include "SampleFormat.h"
50 
51 class AudioIO;
52 class RingBuffer;
53 class Mixer;
54 class Resample;
55 class TimeTrack;
56 class AudioThread;
57 class Meter;
58 class SelectedRegion;
59 
60 class AudacityProject;
61 
62 class WaveTrack;
63 using WaveTrackArray = std::vector < WaveTrack* >;
64 using ConstWaveTrackArray = std::vector < const WaveTrack* >;
65 
66 extern AUDACITY_DLL_API AudioIO *gAudioIO;
67 
68 void InitAudioIO();
69 void DeinitAudioIO();
70 wxString DeviceName(const PaDeviceInfo* info);
71 wxString HostName(const PaDeviceInfo* info);
72 bool ValidateDeviceNames();
73 
74 class AudioIOListener;
75 
76 // #include <cfloat> if you need this constant
77 #define BAD_STREAM_TIME (-DBL_MAX)
78 
79 #define MAX_MIDI_BUFFER_SIZE 5000
80 #define DEFAULT_SYNTH_LATENCY 5
81 
82 #define DEFAULT_LATENCY_DURATION 100.0
83 #define DEFAULT_LATENCY_CORRECTION -130.0
84 
85 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
86  #define AILA_DEF_TARGET_PEAK 92
87  #define AILA_DEF_DELTA_PEAK 2
88  #define AILA_DEF_ANALYSIS_TIME 1000
89  #define AILA_DEF_NUMBER_ANALYSIS 5
90 #endif
91 
92 DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_AUDIOIO_PLAYBACK, -1);
93 DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_AUDIOIO_CAPTURE, -1);
94 DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_AUDIOIO_MONITOR, -1);
95 
96 struct ScrubbingOptions;
97 
98 // To avoid growing the argument list of StartStream, add fields here
100 {
101  explicit
103  : timeTrack(NULL)
104  , listener(NULL)
105  , rate(rate_)
106  , playLooped(false)
107  , cutPreviewGapStart(0.0)
108  , cutPreviewGapLen(0.0)
109  , pStartTime(NULL)
110  {}
111 
114  double rate;
118  double * pStartTime;
119 
120 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
121  // Non-null value indicates that scrubbing will happen
122  // (do not specify a time track, looping, or recording, which
123  // are all incompatible with scrubbing):
125 #endif
126 };
127 
128 // This workaround makes pause and stop work when output is to GarageBand,
129 // which seems not to implement the notes-off message correctly.
130 #define AUDIO_IO_GB_MIDI_WORKAROUND
131 
132 class AUDACITY_DLL_API AudioIO final {
133 
134  public:
135  AudioIO();
136  ~AudioIO();
137 
138  AudioIOListener* GetListener() { return mListener; }
139  void SetListener(AudioIOListener* listener);
140 
148  void StartMonitoring(double sampleRate);
149 
157  int StartStream(const ConstWaveTrackArray &playbackTracks, const WaveTrackArray &captureTracks,
158 #ifdef EXPERIMENTAL_MIDI_OUT
159  const NoteTrackArray &midiTracks,
160 #endif
161  double t0, double t1,
162  const AudioIOStartStreamOptions &options);
163 
169  void StopStream();
172  void SeekStream(double seconds) { mSeek = seconds; }
173 
174 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
175  bool IsScrubbing() { return IsBusy() && mScrubQueue != 0; }
176 
187  bool EnqueueScrub(double endTimeOrSpeed, const ScrubbingOptions &options);
188 
191  double GetLastTimeInScrubQueue() const;
192 #endif
193 
198  bool IsBusy();
199 
206  bool IsStreamActive();
207  bool IsStreamActive(int token);
208 
209  wxLongLong GetLastPlaybackTime() const { return mLastPlaybackTimeMillis; }
210  AudacityProject *GetOwningProject() const { return mOwningProject; }
211 
212 #ifdef EXPERIMENTAL_MIDI_OUT
213 
217  PmTimestamp MidiTime();
218 
219  // Note: audio code solves the problem of soloing/muting tracks by scanning
220  // all playback tracks on every call to the audio buffer fill routine.
221  // We do the same for Midi, but it seems wasteful for at least two
222  // threads to be frequently polling to update status. This could be
223  // eliminated (also with a reduction in code I think) by updating mHasSolo
224  // each time a solo button is activated or deactivated. For now, I'm
225  // going to do this polling in the FillMidiBuffer routine to localize
226  // changes for midi to the midi code, but I'm declaring the variable
227  // here so possibly in the future, Audio code can use it too. -RBD
228  private:
229  bool mHasSolo; // is any playback solo button pressed?
230  public:
231  bool SetHasSolo(bool hasSolo);
232  bool GetHasSolo() { return mHasSolo; }
233 #endif
234 
240  bool IsAudioTokenActive(int token);
241 
244  bool IsMonitoring();
245 
247  void SetPaused(bool state);
249  bool IsPaused();
250 
251  /* Mixer services are always available. If no stream is running, these
252  * methods use whatever device is specified by the preferences. If a
253  * stream *is* running, naturally they manipulate the mixer associated
254  * with that stream. If no mixer is available, output is emulated and
255  * input is stuck at 1.0f (a gain is applied to output samples).
256  */
257  void SetMixer(int inputSource);
258  void SetMixer(int inputSource, float inputVolume,
259  float playbackVolume);
260  void GetMixer(int *inputSource, float *inputVolume,
261  float *playbackVolume);
268  bool InputMixerWorks();
269 
276  bool OutputMixerEmulated();
277 
282  wxArrayString GetInputSourceNames();
283 
292  void HandleDeviceChange();
293 
306  static wxArrayLong GetSupportedPlaybackRates(int DevIndex = -1,
307  double rate = 0.0);
308 
321  static wxArrayLong GetSupportedCaptureRates(int devIndex = -1,
322  double rate = 0.0);
323 
338  static wxArrayLong GetSupportedSampleRates(int playDevice = -1,
339  int recDevice = -1,
340  double rate = 0.0);
341 
350  static int GetOptimalSupportedSampleRate();
351 
358  double GetStreamTime();
359 
360  sampleFormat GetCaptureFormat() { return mCaptureFormat; }
361  unsigned GetNumPlaybackChannels() const { return mNumPlaybackChannels; }
362  unsigned GetNumCaptureChannels() const { return mNumCaptureChannels; }
363 
368  static const int StandardRates[];
370  static const int NumStandardRates;
371 
375  wxString GetDeviceInfo();
376 
377 #ifdef EXPERIMENTAL_MIDI_OUT
378 
379  wxString GetMidiDeviceInfo();
380 #endif
381 
385  static bool ValidateDeviceNames(const wxString &play, const wxString &rec);
386 
390  #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
391  void AILAInitialize();
392  void AILADisable();
393  bool AILAIsActive();
394  void AILAProcess(double maxPeak);
395  void AILASetStartTime();
396  double AILAGetLastDecisionTime();
397  #endif
398 
399  bool IsAvailable(AudacityProject *projecT);
400  void SetCaptureMeter(AudacityProject *project, Meter *meter);
401  void SetPlaybackMeter(AudacityProject *project, Meter *meter);
402  Meter * GetCaptureMeter();
403 
404 private:
407  void SetMeters();
408 
419  double GetBestRate(bool capturing, bool playing, double sampleRate);
420 
431  bool StartPortAudioStream(double sampleRate,
432  unsigned int numPlaybackChannels,
433  unsigned int numCaptureChannels,
434  sampleFormat captureFormat);
435  void FillBuffers();
436 
437 #ifdef EXPERIMENTAL_MIDI_OUT
438  void PrepareMidiIterator(bool send = true, double offset = 0);
439  bool StartPortMidiStream();
440  void OutputEvent();
441  void FillMidiBuffers();
442  void GetNextEvent();
443  double AudioTime() { return mT0 + mNumFrames / mRate; }
444  double PauseTime();
445  void AllNotesOff();
446 #endif
447 
453  size_t GetCommonlyAvailPlayback();
454 
461  size_t GetCommonlyAvailCapture();
462 
470  static int getRecordDevIndex(const wxString &devName = wxEmptyString);
475 #if USE_PORTMIXER
476  static int getRecordSourceIndex(PxMixer *portMixer);
477 #endif
478 
486  static int getPlayDevIndex(const wxString &devName = wxEmptyString);
487 
492  static const int RatesToTry[];
494  static const int NumRatesToTry;
495 
497  bool ReversedTime() const
498  {
499  return mT1 < mT0;
500  }
507  double LimitStreamTime(double absoluteTime) const;
508 
515  double NormalizeStreamTime(double absoluteTime) const;
516 
520  void StartStreamCleanup(bool bOnlyBuffers = false);
521 
522 #ifdef EXPERIMENTAL_MIDI_OUT
523  // MIDI_PLAYBACK:
524  PmStream *mMidiStream;
525  PmError mLastPmError;
527  long mMidiLatency;
529  long mSynthLatency;
530 
531  // These fields are used to synchronize MIDI with audio:
532 
534  volatile double mAudioCallbackClockTime;
537  volatile double mAudioCallbackOutputCurrentTime;
539  volatile double mAudioCallbackOutputDacTime;
541  volatile long mNumFrames;
543  volatile long mNumPauseFrames;
545  volatile double mMidiLoopOffset;
546  volatile long mAudioFramesPerBuffer;
549  volatile bool mMidiPaused;
550 
551  Alg_seq_ptr mSeq;
552  std::unique_ptr<Alg_iterator> mIterator;
554  Alg_event_ptr mNextEvent;
555 
556 #ifdef AUDIO_IO_GB_MIDI_WORKAROUND
557  std::vector< std::pair< int, int > > mPendingNotesOff;
558 #endif
559 
562  double mNextEventTime;
564  NoteTrack *mNextEventTrack;
566  bool mMidiOutputComplete;
568  bool mNextIsNoteOn;
570  bool mMidiStreamActive;
573  bool mSendMidiState;
574  NoteTrackArray mMidiPlaybackTracks;
575 #endif
576 
577 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
578  bool mAILAActive;
579  bool mAILAClipped;
580  int mAILATotalAnalysis;
581  int mAILAAnalysisCounter;
582  double mAILAMax;
583  double mAILAGoalPoint;
584  double mAILAGoalDelta;
585  double mAILAAnalysisTime;
586  double mAILALastStartTime;
587  double mAILAChangeFactor;
588  double mAILATopLevel;
589  double mAILAAnalysisEndTime;
590  double mAILAAbsolutStartTime;
591  unsigned short mAILALastChangeType; //0 - no change, 1 - increase change, 2 - decrease change
592 #endif
593 
594  std::unique_ptr<AudioThread> mThread;
595 #ifdef EXPERIMENTAL_MIDI_OUT
596  std::unique_ptr<AudioThread> mMidiThread;
597 #endif
603 
605  volatile int mStreamToken;
606  static int mNextStreamToken;
607  double mFactor;
609  double mRate;
611  double mT0;
613  double mT1;
615  double mTime;
618  double mWarpedTime;
622  double mSeek;
628  bool mPaused;
629  PaStream *mPortStreamV19;
632  bool mPauseRec;
634  unsigned int mNumCaptureChannels;
635  unsigned int mNumPlaybackChannels;
636  sampleFormat mCaptureFormat;
641 
643 
644 #ifdef EXPERIMENTAL_MIDI_OUT
645  volatile bool mMidiThreadFillBuffersLoopRunning;
646  volatile bool mMidiThreadFillBuffersLoopActive;
647 #endif
648 
649  volatile double mLastRecordingOffset;
650  PaError mLastPaError;
651 
656  volatile bool mUpdatingMeters;
657 
658  #if USE_PORTMIXER
659  PxMixer *mPortMixer;
660  float mPreviousHWPlaythrough;
661  #endif /* USE_PORTMIXER */
662 
673 
674  volatile enum {
677 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
679 #endif
680  } mPlayMode;
683 
685 
687 
688  friend class AudioThread;
689 #ifdef EXPERIMENTAL_MIDI_OUT
690  friend class MidiThread;
691 #endif
692 
693  friend void InitAudioIO();
694 
696 
697  // For cacheing supported sample rates
699  static wxArrayLong mCachedPlaybackRates;
701  static wxArrayLong mCachedCaptureRates;
702  static wxArrayLong mCachedSampleRates;
703  static double mCachedBestRateIn;
704  static double mCachedBestRateOut;
705 
728  friend int audacityAudioCallback(
729  const void *inputBuffer, void *outputBuffer,
730  unsigned long framesPerBuffer,
731  const PaStreamCallbackTimeInfo *timeInfo,
732  PaStreamCallbackFlags statusFlags, void *userData );
733 
734  // Serialize main thread and PortAudio thread's attempts to pause and change
735  // the state used by the third, Audio thread.
737 
738 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
739  struct ScrubQueue;
740  std::unique_ptr<ScrubQueue> mScrubQueue;
741 
743  sampleCount mScrubDuration;
744 #endif
745 
746  // A flag tested and set in one thread, cleared in another. Perhaps
747  // this guarantee of atomicity is more cautious than necessary.
748  wxAtomicInt mRecordingException {};
750  { wxAtomicInc( mRecordingException ); }
752  { if (mRecordingException) wxAtomicDec( mRecordingException ); }
753 };
754 
755 #endif
756 
AudioIO uses the PortAudio library to play and record sound.
Definition: AudioIO.h:132
static wxArrayLong mCachedPlaybackRates
Definition: AudioIO.h:699
double mMinCaptureSecsToCopy
Definition: AudioIO.h:626
TimeTrack * timeTrack
Definition: AudioIO.h:112
double rate
Definition: AudioIO.h:114
static double mCachedBestRateIn
Definition: AudioIO.h:703
static int mNextStreamToken
Definition: AudioIO.h:606
wxLongLong GetLastPlaybackTime() const
Definition: AudioIO.h:209
double cutPreviewGapStart
Definition: AudioIO.h:116
Meter * mInputMeter
Definition: AudioIO.h:653
sampleCount mScrubDuration
Definition: AudioIO.h:743
VU Meter, for displaying recording/playback level.
Definition: Meter.h:88
volatile bool mUpdatingMeters
Definition: AudioIO.h:656
float mMixerOutputVol
Definition: AudioIO.h:672
unsigned GetNumCaptureChannels() const
Definition: AudioIO.h:362
double mTime
Current time position during playback, in seconds. Between mT0 and mT1.
Definition: AudioIO.h:615
bool mInputMixerWorks
Can we control the hardware input level?
Definition: AudioIO.h:671
Definition: AudioIO.h:675
bool mSoftwarePlaythrough
Definition: AudioIO.h:630
void DeinitAudioIO()
Definition: AudioIO.cpp:924
AudioIOStartStreamOptions(double rate_)
Definition: AudioIO.h:102
const TimeTrack * mTimeTrack
Definition: AudioIO.h:695
int mLostSamples
Definition: AudioIO.h:637
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
Definition: AudioIO.h:601
ScrubbingOptions * pScrubbingOptions
Definition: AudioIO.h:124
AudioIOListener * GetListener()
Definition: AudioIO.h:138
bool ValidateDeviceNames()
float mSilenceLevel
Definition: AudioIO.h:633
ArrayOf< std::unique_ptr< Resample > > mResample
Definition: AudioIO.h:598
AUDACITY_DLL_API AudioIO * gAudioIO
Definition: AudioIO.cpp:301
sampleFormat mCaptureFormat
Definition: AudioIO.h:636
static wxArrayLong mCachedSampleRates
Definition: AudioIO.h:702
GrowableSampleBuffer mSilentBuf
Definition: AudioIO.h:684
Definition: AudioIO.h:676
ArrayOf< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:604
std::vector< const WaveTrack * > ConstWaveTrackArray
Definition: AudioIO.h:64
std::unique_ptr< ScrubQueue > mScrubQueue
Definition: AudioIO.h:739
double mWarpedTime
Definition: AudioIO.h:618
static int mCachedPlaybackIndex
Definition: AudioIO.h:698
wxMutex mSuspendAudioThread
Definition: AudioIO.h:736
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:161
bool playLooped
Definition: AudioIO.h:115
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:29
bool mPaused
True if audio playback is paused.
Definition: AudioIO.h:628
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
Definition: AudioIO.h:599
bool ReversedTime() const
True if the end time is before the start time.
Definition: AudioIO.h:497
volatile int mStreamToken
Definition: AudioIO.h:605
Defines a selected portion of a project.
Definition: SelectedRegion.h:37
WaveTrackArray mCaptureTracks
Definition: AudioIO.h:600
bool mEmulateMixerOutputVol
Definition: AudioIO.h:663
PaStream * mPortStreamV19
Definition: AudioIO.h:629
Definition: AudioIO.h:99
void ClearRecordingException()
Definition: AudioIO.h:751
double mCaptureRingBufferSecs
Definition: AudioIO.h:624
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:76
wxString DeviceName(const PaDeviceInfo *info)
Definition: AudioIO.cpp:929
AudacityProject * GetOwningProject() const
Definition: AudioIO.h:210
AudacityProject * mOwningProject
Definition: AudioIO.h:652
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:642
AudioIOListener * mListener
Definition: AudioIO.h:686
volatile bool mAudioThreadShouldCallFillBuffersOnce
Definition: AudioIO.h:638
bool IsScrubbing()
Definition: AudioIO.h:175
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:635
double mSeek
Definition: AudioIO.h:622
std::vector< WaveTrack * > WaveTrackArray
Definition: AudioIO.h:63
unsigned int mNumCaptureChannels
Definition: AudioIO.h:634
std::unique_ptr< AudioThread > mThread
Definition: AudioIO.h:594
wxString HostName(const PaDeviceInfo *info)
Definition: AudioIO.cpp:936
ConstWaveTrackArray mPlaybackTracks
Definition: AudioIO.h:602
double mRate
Audio playback rate in samples per second.
Definition: AudioIO.h:609
Definition: AudioIOListener.h:20
bool mUpdateMeters
Definition: AudioIO.h:655
Holds streamed audio samples.
Definition: RingBuffer.h:16
volatile double mLastRecordingOffset
Definition: AudioIO.h:649
Interface to libsoxr.
Definition: Resample.h:30
Definition: Scrubbing.h:35
static int mCachedCaptureIndex
Definition: AudioIO.h:700
static const int NumStandardRates
How many standard sample rates there are.
Definition: AudioIO.h:370
Definition: MemoryX.h:439
sampleFormat GetCaptureFormat()
Definition: AudioIO.h:360
void InitAudioIO()
Definition: AudioIO.cpp:893
double mWarpedLength
Definition: AudioIO.h:621
double mCutPreviewGapLen
Definition: AudioIO.h:682
std::vector< NoteTrack * > NoteTrackArray
Definition: Track.h:71
double mT0
Playback starts at offset of mT0, which is measured in seconds.
Definition: AudioIO.h:611
double mCutPreviewGapStart
Definition: AudioIO.h:681
Meter * mOutputMeter
Definition: AudioIO.h:654
static double mCachedBestRateOut
Definition: AudioIO.h:704
AudioIOListener * listener
Definition: AudioIO.h:113
Definition: SampleFormat.h:88
static const int NumRatesToTry
How many sample rates to try.
Definition: AudioIO.h:494
volatile bool mAudioThreadFillBuffersLoopActive
Definition: AudioIO.h:640
Functions for doing the mixdown of the tracks.
Definition: Mix.h:71
double mFactor
Definition: AudioIO.h:607
PaError mLastPaError
Definition: AudioIO.h:650
size_t mPlaybackSamplesToCopy
Definition: AudioIO.h:625
void SeekStream(double seconds)
Move the playback / recording position of the current stream by the specified amount from where it is...
Definition: AudioIO.h:172
double cutPreviewGapLen
Definition: AudioIO.h:117
double * pStartTime
Definition: AudioIO.h:118
unsigned GetNumPlaybackChannels() const
Definition: AudioIO.h:361
Definition: AudioIO.cpp:344
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:613
DECLARE_EXPORTED_EVENT_TYPE(AUDACITY_DLL_API, EVT_AUDIOIO_PLAYBACK,-1)
volatile bool mAudioThreadFillBuffersLoopRunning
Definition: AudioIO.h:639
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:632
void SetRecordingException()
Definition: AudioIO.h:749
bool mSilentScrub
Definition: AudioIO.h:742
static wxArrayLong mCachedCaptureRates
Definition: AudioIO.h:701
Definition: AudioIO.h:678
A Track that is used for Midi notes. (Somewhat old code).
double mPlaybackRingBufferSecs
Definition: AudioIO.h:623
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:871