Audacity 3.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
17
18#include "AudioIOBase.h" // to inherit
19#include "PlaybackSchedule.h" // member variable
20
21#include <functional>
22#include <memory>
23#include <mutex>
24#include <thread>
25#include <utility>
26#include <wx/atomic.h> // member variable
27
28#include "PluginProvider.h" // for PluginID
29#include "Observer.h"
30#include "SampleCount.h"
31#include "SampleFormat.h"
32
33class wxArrayString;
34class AudioIOBase;
35class AudioIO;
36class RingBuffer;
37class Mixer;
39class Resample;
40
41class AudacityProject;
42
43class PlayableTrack;
45 std::vector < std::shared_ptr < const PlayableTrack > >;
46
47class Track;
48class WaveTrack;
49using WaveTrackArray = std::vector < std::shared_ptr < WaveTrack > >;
50using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >;
51
52struct PaStreamCallbackTimeInfo;
53typedef unsigned long PaStreamCallbackFlags;
54typedef int PaError;
55
56namespace RealtimeEffects {
57 class ProcessingScope;
58 class SuspensionScope;
59}
60
62
63enum class Acknowledge { eNone = 0, eStart, eStop };
64
71 enum Type {
76 bool on;
77};
78
83
84 // This is a subset of playbackTracks
86};
87
111 const void *inputBuffer, void *outputBuffer,
112 unsigned long framesPerBuffer,
113 const PaStreamCallbackTimeInfo *timeInfo,
114 PaStreamCallbackFlags statusFlags, void *userData );
115
116class AudioIOExt;
117
118class AUDACITY_DLL_API AudioIoCallback /* not final */
119 : public AudioIOBase
120{
121public:
124
125public:
126 // This function executes in a thread spawned by the PortAudio library
127 int AudioCallback(
128 constSamplePtr inputBuffer, float *outputBuffer,
129 unsigned long framesPerBuffer,
130 const PaStreamCallbackTimeInfo *timeInfo,
131 const PaStreamCallbackFlags statusFlags, void *userData);
132
135 class AUDACITY_DLL_API AudioIOExtIterator {
136 public:
137 using difference_type = ptrdiff_t;
141 using iterator_category = std::forward_iterator_tag;
142
143 explicit AudioIOExtIterator( AudioIoCallback &audioIO, bool end )
144 : mIterator{ end
145 ? audioIO.mAudioIOExt.end()
146 : audioIO.mAudioIOExt.begin() }
147 {}
148 AudioIOExtIterator &operator ++ () { ++mIterator; return *this; }
149 auto operator *() const -> AudioIOExt &;
150 friend inline bool operator == (
151 const AudioIOExtIterator &xx, const AudioIOExtIterator &yy)
152 {
153 return xx.mIterator == yy.mIterator;
154 }
155 friend inline bool operator != (
156 const AudioIOExtIterator &xx, const AudioIOExtIterator &yy)
157 {
158 return !(xx == yy);
159 }
160 private:
161 std::vector<std::unique_ptr<AudioIOExtBase>>::const_iterator mIterator;
162 };
166 AudioIOExtIterator begin() const { return first; }
167 AudioIOExtIterator end() const { return second; }
168 };
169
171 return {
172 AudioIOExtIterator{ *this, false },
173 AudioIOExtIterator{ *this, true }
174 };
175 }
177
178 std::shared_ptr< AudioIOListener > GetListener() const
179 { return mListener.lock(); }
180 void SetListener( const std::shared_ptr< AudioIOListener > &listener);
181
182 // Part of the callback
183 int CallbackDoSeek();
184
185 // Part of the callback
186 void CallbackCheckCompletion(
187 int &callbackReturn, unsigned long len);
188
191 // Helpers to determine if tracks have already been faded out.
192 unsigned CountSoloingTracks();
193 bool TrackShouldBeSilent( const WaveTrack &wt );
194 bool TrackHasBeenFadedOut( const WaveTrack &wt );
195 bool AllTracksAlreadySilent();
196
197 void CheckSoundActivatedRecordingLevel(
198 float *inputSamples,
199 unsigned long framesPerBuffer
200 );
201 void AddToOutputChannel( unsigned int chan,
202 float * outputMeterFloats,
203 float * outputFloats,
204 const float * tempBuf,
205 bool drop,
206 unsigned long len,
207 WaveTrack *vt
208 );
209 bool FillOutputBuffers(
210 float *outputBuffer,
211 unsigned long framesPerBuffer,
212 float *outputMeterFloats
213 );
214 void DrainInputBuffers(
215 constSamplePtr inputBuffer,
216 unsigned long framesPerBuffer,
217 const PaStreamCallbackFlags statusFlags,
218 float * tempFloats
219 );
220 void UpdateTimePosition(
221 unsigned long framesPerBuffer
222 );
223 void DoPlaythrough(
224 constSamplePtr inputBuffer,
225 float *outputBuffer,
226 unsigned long framesPerBuffer,
227 float *outputMeterFloats
228 );
229 void SendVuInputMeterData(
230 const float *inputSamples,
231 unsigned long framesPerBuffer
232 );
233 void SendVuOutputMeterData(
234 const float *outputMeterFloats,
235 unsigned long framesPerBuffer
236 );
237
243 size_t GetCommonlyReadyPlayback();
244
247
248#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
249 bool mAILAActive;
250 bool mAILAClipped;
251 int mAILATotalAnalysis;
252 int mAILAAnalysisCounter;
253 double mAILAMax;
254 double mAILAGoalPoint;
255 double mAILAGoalDelta;
256 double mAILAAnalysisTime;
257 double mAILALastStartTime;
258 double mAILAChangeFactor;
259 double mAILATopLevel;
260 double mAILAAnalysisEndTime;
261 double mAILAAbsolutStartTime;
262 unsigned short mAILALastChangeType; //0 - no change, 1 - increase change, 2 - decrease change
263#endif
264
265 std::thread mAudioThread;
266 std::atomic<bool> mFinishAudioThread{ false };
267
274 // Temporary buffers, each as large as the playback buffers
275 std::vector<SampleBuffer> mScratchBuffers;
276 std::vector<float *> mScratchPointers;
277
278 std::vector<std::unique_ptr<Mixer>> mPlaybackMixers;
279
280 std::atomic<float> mMixerOutputVol{ 1.0 };
282 double mFactor;
283 unsigned long mMaxFramesOutput; // The actual number of frames output.
286
287 double mSeek;
290
295
300
308 unsigned long long mLostSamples{ 0 };
312
313 std::atomic<Acknowledge> mAudioThreadAcknowledge;
314
315 // Sync start/stop of AudioThread processing
316 void StartAudioThreadAndWait();
317 void StopAudioThreadAndWait();
318
319 // Async start/stop + wait of AudioThread processing.
320 // Provided to allow more flexibility, however use with caution:
321 // never call Stop between Start and the wait for Started (and the converse)
322 void StartAudioThread();
323 void WaitForAudioThreadStarted();
324 void StopAudioThread();
325 void WaitForAudioThreadStopped();
326
327 void ProcessOnceAndWait( std::chrono::milliseconds sleepTime = std::chrono::milliseconds(50) );
328
329
330
331 std::atomic<bool> mForceFadeOut{ false };
332
334
338
339protected:
340
342 return mMixerOutputVol.load(std::memory_order_relaxed); }
343 void SetMixerOutputVol(float value) {
344 mMixerOutputVol.store(value, std::memory_order_relaxed); }
345
349 std::weak_ptr< AudioIOListener > mListener;
350
351 bool mUsingAlsa { false };
352
353 // For cacheing supported sample rates
354 static double mCachedBestRateOut;
357
358 // Serialize main thread and PortAudio thread's attempts to pause and change
359 // the state used by the third, Audio thread.
361
362protected:
363 // A flag tested and set in one thread, cleared in another. Perhaps
364 // this guarantee of atomicity is more cautious than necessary.
365 wxAtomicInt mRecordingException {};
367 { wxAtomicInc( mRecordingException ); }
369 { if (mRecordingException) wxAtomicDec( mRecordingException ); }
370
371 std::vector< std::pair<double, double> > mLostCaptureIntervals;
373 bool mDetectDropouts{ true };
374
375public:
376 // Pairs of starting time and duration
377 const std::vector< std::pair<double, double> > &LostCaptureIntervals()
378 { return mLostCaptureIntervals; }
379
380 // Used only for testing purposes in alpha builds
381 bool mSimulateRecordingErrors{ false };
382
383 // Whether to check the error code passed to audacityAudioCallback to
384 // detect more dropouts
385 std::atomic<bool> mDetectUpstreamDropouts{ true };
386
387protected:
388 RecordingSchedule mRecordingSchedule{};
390
391 struct TransportState;
393 std::unique_ptr<TransportState> mpTransportState;
394
395private:
402};
403
404struct PaStreamInfo;
405
406class AUDACITY_DLL_API AudioIO final
407 : public AudioIoCallback
408 , public Observer::Publisher<AudioIOEvent>
409{
410
411 AudioIO();
412 ~AudioIO();
413 void StartThread();
414
415public:
416 // This might return null during application startup or shutdown
417 static AudioIO *Get();
418
420
423 std::shared_ptr<RealtimeEffectState>
424 AddState(AudacityProject &project, Track *pTrack, const PluginID & id);
425
427 void RemoveState(AudacityProject &project,
428 Track *pTrack, const std::shared_ptr<RealtimeEffectState> &pState);
429
430 RealtimeEffects::SuspensionScope SuspensionScope();
431
439 void StartMonitoring( const AudioIOStartStreamOptions &options );
440
448 int StartStream(const TransportTracks &tracks,
449 double t0, double t1,
450 double mixerLimit,
451 const AudioIOStartStreamOptions &options);
452
458 void StopStream() override;
461 void SeekStream(double seconds) { mSeek = seconds; }
462
463 using PostRecordingAction = std::function<void()>;
464
466
467 void CallAfterRecording(PostRecordingAction action);
468
469public:
470 wxString LastPaErrorString();
471
472 wxLongLong GetLastPlaybackTime() const { return mLastPlaybackTimeMillis; }
473 std::shared_ptr<AudacityProject> GetOwningProject() const
474 { return mOwningProject.lock(); }
475
477 void SetPaused(bool state);
478
479 /* Mixer services are always available. If no stream is running, these
480 * methods use whatever device is specified by the preferences. If a
481 * stream *is* running, naturally they manipulate the mixer associated
482 * with that stream. If no mixer is available, output is emulated and
483 * input is stuck at 1.0f (a gain is applied to output samples).
484 */
485 void SetMixer(int inputSource, float inputVolume,
486 float playbackVolume);
487 void GetMixer(int *inputSource, float *inputVolume,
488 float *playbackVolume);
495 bool InputMixerWorks();
496
501 wxArrayString GetInputSourceNames();
502
503 sampleFormat GetCaptureFormat() { return mCaptureFormat; }
504 unsigned GetNumPlaybackChannels() const { return mNumPlaybackChannels; }
505 unsigned GetNumCaptureChannels() const { return mNumCaptureChannels; }
506
507 // Meaning really capturing, not just pre-rolling
508 bool IsCapturing() const;
509
513 static bool ValidateDeviceNames(const wxString &play, const wxString &rec);
514
518 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
519 void AILAInitialize();
520 void AILADisable();
521 bool AILAIsActive();
522 void AILAProcess(double maxPeak);
523 void AILASetStartTime();
524 double AILAGetLastDecisionTime();
525 #endif
526
527 bool IsAvailable(AudacityProject &project) const;
528
539 double GetBestRate(bool capturing, bool playing, double sampleRate);
540
547 double GetStreamTime();
548
549 static void AudioThread(std::atomic<bool> &finish);
550
551 static void Init();
552 static void Deinit();
553
556 void DelayActions(bool recording);
557
558private:
559
560 bool DelayingActions() const;
561
564 void SetMeters();
565
576 bool StartPortAudioStream(const AudioIOStartStreamOptions &options,
577 unsigned int numPlaybackChannels,
578 unsigned int numCaptureChannels,
579 sampleFormat captureFormat);
580
581 void SetOwningProject( const std::shared_ptr<AudacityProject> &pProject );
582 void ResetOwningProject();
583
590 void TrackBufferExchange();
591
593 void FillPlayBuffers();
594 void TransformPlayBuffers(
595 std::optional<RealtimeEffects::ProcessingScope> &scope);
596
598 void DrainRecordBuffers();
599
605 size_t GetCommonlyFreePlayback();
606
613 size_t GetCommonlyAvailCapture();
614
620 bool AllocateBuffers(
621 const AudioIOStartStreamOptions &options,
622 const TransportTracks &tracks, double t0, double t1, double sampleRate );
623
627 void StartStreamCleanup(bool bOnlyBuffers = false);
628
631
632 bool mDelayingActions{ false };
633};
634
635#endif
int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Definition: AudioIO.cpp:2332
std::vector< std::shared_ptr< WaveTrack > > WaveTrackArray
Definition: AudioIO.h:49
int PaError
Definition: AudioIO.h:54
bool ValidateDeviceNames()
unsigned long PaStreamCallbackFlags
Definition: AudioIO.h:52
std::vector< std::shared_ptr< const WaveTrack > > WaveTrackConstArray
Definition: AudioIO.h:50
Acknowledge
Definition: AudioIO.h:63
std::vector< std::shared_ptr< const PlayableTrack > > PlayableTrackConstArray
Definition: AudioIO.h:45
static TransactionScope::Factory::Scope scope
wxString PluginID
Definition: EffectManager.h:30
Vector operator*(const Vector &left, const Vector &right)
Definition: Matrix.cpp:153
Generalized interface for discovery of plug-ins for one protocol.
sampleFormat
Definition: SampleFormat.h:29
const char * constSamplePtr
Definition: SampleFormat.h:50
bool operator!=(const Tags &lhs, const Tags &rhs)
Definition: Tags.h:133
Memory.h template class for making an array of float, bool, etc.
Definition: MemoryX.h:27
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
A singleton object supporting queries of the state of any active audio streams, and audio device capa...
Definition: AudioIOBase.h:103
std::vector< std::unique_ptr< AudioIOExtBase > > mAudioIOExt
Definition: AudioIOBase.h:323
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:91
virtual void StopStream()=0
void SetMixer(int inputSource)
AudioIO uses the PortAudio library to play and record sound.
Definition: AudioIO.h:409
std::shared_ptr< AudacityProject > GetOwningProject() const
Definition: AudioIO.h:473
std::mutex mPostRecordingActionMutex
Definition: AudioIO.h:629
PostRecordingAction mPostRecordingAction
Definition: AudioIO.h:630
unsigned GetNumCaptureChannels() const
Definition: AudioIO.h:505
void SeekStream(double seconds)
Move the playback / recording position of the current stream by the specified amount from where it is...
Definition: AudioIO.h:461
sampleFormat GetCaptureFormat()
Definition: AudioIO.h:503
wxLongLong GetLastPlaybackTime() const
Definition: AudioIO.h:472
std::function< void()> PostRecordingAction
Definition: AudioIO.h:463
unsigned GetNumPlaybackChannels() const
Definition: AudioIO.h:504
std::vector< std::unique_ptr< AudioIOExtBase > >::const_iterator mIterator
Definition: AudioIO.h:161
AudioIOExtIterator(AudioIoCallback &audioIO, bool end)
Definition: AudioIO.h:143
std::forward_iterator_tag iterator_category
Definition: AudioIO.h:141
AudioIoCallback is a class that implements the callback required by PortAudio. The callback needs to ...
Definition: AudioIO.h:120
static int mNextStreamToken
Definition: AudioIO.h:281
std::shared_ptr< AudioIOListener > GetListener() const
Definition: AudioIO.h:178
bool mbMicroFades
Definition: AudioIO.h:285
double mSeek
Definition: AudioIO.h:287
std::unique_ptr< TransportState > mpTransportState
Holds some state for duration of playback or recording.
Definition: AudioIO.h:391
const std::vector< std::pair< double, double > > & LostCaptureIntervals()
Definition: AudioIO.h:377
wxMutex mSuspendAudioThread
Definition: AudioIO.h:360
AudioIOExtRange Extensions()
Definition: AudioIO.h:170
float GetMixerOutputVol()
Definition: AudioIO.h:341
PlaybackSchedule mPlaybackSchedule
Definition: AudioIO.h:389
std::vector< float * > mScratchPointers
pointing into mScratchBuffers
Definition: AudioIO.h:276
std::atomic< Acknowledge > mAudioThreadAcknowledge
Definition: AudioIO.h:313
size_t mPlaybackSamplesToCopy
Preferred batch size for replenishing the playback RingBuffer.
Definition: AudioIO.h:292
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopRunning
Definition: AudioIO.h:310
static double mCachedBestRateOut
Definition: AudioIO.h:354
std::vector< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:278
PlaybackPolicy::Duration mPlaybackRingBufferSecs
Definition: AudioIO.h:288
std::thread mAudioThread
Definition: AudioIO.h:265
int mCallbackReturn
Definition: AudioIO.h:190
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopActive
Definition: AudioIO.h:311
void ClearRecordingException()
Definition: AudioIO.h:368
long mNumPauseFrames
How many frames of zeros were output due to pauses?
Definition: AudioIO.h:246
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:306
void SetRecordingException()
Definition: AudioIO.h:366
std::atomic< bool > mAudioThreadShouldCallTrackBufferExchangeOnce
Definition: AudioIO.h:309
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:333
int mbHasSoloTracks
Definition: AudioIO.h:189
WaveTrackArray mPlaybackTracks
Definition: AudioIO.h:273
PaError mLastPaError
Definition: AudioIO.h:337
static bool mCachedBestRatePlaying
Definition: AudioIO.h:355
bool mSoftwarePlaythrough
Definition: AudioIO.h:298
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
Definition: AudioIO.h:269
WaveTrackArray mCaptureTracks
Definition: AudioIO.h:270
unsigned long mMaxFramesOutput
Definition: AudioIO.h:283
double mLastRecordingOffset
Not (yet) used; should perhaps be atomic when it is.
Definition: AudioIO.h:336
size_t mPlaybackQueueMinimum
Occupancy of the queue we try to maintain, with bigger batches if needed.
Definition: AudioIO.h:294
std::weak_ptr< AudioIOListener > mListener
Definition: AudioIO.h:349
ArrayOf< std::unique_ptr< Resample > > mResample
Definition: AudioIO.h:268
double mCaptureRingBufferSecs
Definition: AudioIO.h:289
float mSilenceLevel
Definition: AudioIO.h:302
unsigned int mNumCaptureChannels
Definition: AudioIO.h:304
void SetMixerOutputVol(float value)
Definition: AudioIO.h:343
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:371
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:301
double mFactor
Definition: AudioIO.h:282
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
Definition: AudioIO.h:272
double mMinCaptureSecsToCopy
Definition: AudioIO.h:296
std::vector< SampleBuffer > mScratchBuffers
Definition: AudioIO.h:275
static bool mCachedBestRateCapturing
Definition: AudioIO.h:356
sampleFormat mCaptureFormat
Definition: AudioIO.h:307
Functions for doing the mixdown of the tracks.
Definition: Mix.h:58
An object that sends messages to an open-ended list of subscribed callbacks.
Definition: Observer.h:108
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:909
std::chrono::duration< double > Duration
Brackets one block of processing in one thread.
Brackets one suspension of processing in the main thread.
Interface to libsoxr.
Definition: Resample.h:27
Holds streamed audio samples.
Definition: RingBuffer.h:17
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
A Track that contains audio waveform data.
Definition: WaveTrack.h:57
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
bool on
Definition: AudioIO.h:76
enum AudioIOEvent::Type type
AudacityProject * pProject
Definition: AudioIO.h:70
struct holding stream options, including a pointer to the time warp info and AudioIOListener and whet...
Definition: AudioIOBase.h:44
AudioIOExtIterator begin() const
Definition: AudioIO.h:166
AudioIOExtIterator end() const
Definition: AudioIO.h:167
AudioIOExtIterator first
Definition: AudioIO.h:164
AudioIOExtIterator second
Definition: AudioIO.h:165
PlayableTrackConstArray otherPlayableTracks
Definition: AudioIO.h:82
WaveTrackConstArray prerollTracks
Definition: AudioIO.h:85
WaveTrackArray captureTracks
Definition: AudioIO.h:81
WaveTrackArray playbackTracks
Definition: AudioIO.h:80