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}
59
61
62enum class Acknowledge { eNone = 0, eStart, eStop };
63
70 enum Type {
75 bool on;
76};
77
82
83 // This is a subset of playbackTracks
85};
86
110 const void *inputBuffer, void *outputBuffer,
111 unsigned long framesPerBuffer,
112 const PaStreamCallbackTimeInfo *timeInfo,
113 PaStreamCallbackFlags statusFlags, void *userData );
114
115class AudioIOExt;
116
117class AUDACITY_DLL_API AudioIoCallback /* not final */
118 : public AudioIOBase
119{
120public:
123
124public:
125 // This function executes in a thread spawned by the PortAudio library
126 int AudioCallback(
127 constSamplePtr inputBuffer, float *outputBuffer,
128 unsigned long framesPerBuffer,
129 const PaStreamCallbackTimeInfo *timeInfo,
130 const PaStreamCallbackFlags statusFlags, void *userData);
131
134 class AUDACITY_DLL_API AudioIOExtIterator {
135 public:
136 using difference_type = ptrdiff_t;
140 using iterator_category = std::forward_iterator_tag;
141
142 explicit AudioIOExtIterator( AudioIoCallback &audioIO, bool end )
143 : mIterator{ end
144 ? audioIO.mAudioIOExt.end()
145 : audioIO.mAudioIOExt.begin() }
146 {}
147 AudioIOExtIterator &operator ++ () { ++mIterator; return *this; }
148 auto operator *() const -> AudioIOExt &;
149 friend inline bool operator == (
150 const AudioIOExtIterator &xx, const AudioIOExtIterator &yy)
151 {
152 return xx.mIterator == yy.mIterator;
153 }
154 friend inline bool operator != (
155 const AudioIOExtIterator &xx, const AudioIOExtIterator &yy)
156 {
157 return !(xx == yy);
158 }
159 private:
160 std::vector<std::unique_ptr<AudioIOExtBase>>::const_iterator mIterator;
161 };
165 AudioIOExtIterator begin() const { return first; }
166 AudioIOExtIterator end() const { return second; }
167 };
168
170 return {
171 AudioIOExtIterator{ *this, false },
172 AudioIOExtIterator{ *this, true }
173 };
174 }
176
177 std::shared_ptr< AudioIOListener > GetListener() const
178 { return mListener.lock(); }
179 void SetListener( const std::shared_ptr< AudioIOListener > &listener);
180
181 // Part of the callback
182 int CallbackDoSeek();
183
184 // Part of the callback
185 void CallbackCheckCompletion(
186 int &callbackReturn, unsigned long len);
187
190 // Helpers to determine if tracks have already been faded out.
191 unsigned CountSoloingTracks();
192 bool TrackShouldBeSilent( const WaveTrack &wt );
193 bool TrackHasBeenFadedOut( const WaveTrack &wt );
194 bool AllTracksAlreadySilent();
195
196 void CheckSoundActivatedRecordingLevel(
197 float *inputSamples,
198 unsigned long framesPerBuffer
199 );
200 void AddToOutputChannel( unsigned int chan,
201 float * outputMeterFloats,
202 float * outputFloats,
203 const float * tempBuf,
204 bool drop,
205 unsigned long len,
206 WaveTrack *vt
207 );
208 bool FillOutputBuffers(
209 float *outputBuffer,
210 unsigned long framesPerBuffer,
211 float *outputMeterFloats
212 );
213 void DrainInputBuffers(
214 constSamplePtr inputBuffer,
215 unsigned long framesPerBuffer,
216 const PaStreamCallbackFlags statusFlags,
217 float * tempFloats
218 );
219 void UpdateTimePosition(
220 unsigned long framesPerBuffer
221 );
222 void DoPlaythrough(
223 constSamplePtr inputBuffer,
224 float *outputBuffer,
225 unsigned long framesPerBuffer,
226 float *outputMeterFloats
227 );
228 void SendVuInputMeterData(
229 const float *inputSamples,
230 unsigned long framesPerBuffer
231 );
232 void SendVuOutputMeterData(
233 const float *outputMeterFloats,
234 unsigned long framesPerBuffer
235 );
236
242 size_t GetCommonlyReadyPlayback();
243
244 size_t GetCommonlyWrittenForPlayback();
245
248
249#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
250 bool mAILAActive;
251 bool mAILAClipped;
252 int mAILATotalAnalysis;
253 int mAILAAnalysisCounter;
254 double mAILAMax;
255 double mAILAGoalPoint;
256 double mAILAGoalDelta;
257 double mAILAAnalysisTime;
258 double mAILALastStartTime;
259 double mAILAChangeFactor;
260 double mAILATopLevel;
261 double mAILAAnalysisEndTime;
262 double mAILAAbsolutStartTime;
263 unsigned short mAILALastChangeType; //0 - no change, 1 - increase change, 2 - decrease change
264#endif
265
266 std::thread mAudioThread;
267 std::atomic<bool> mFinishAudioThread{ false };
268
275 // Temporary buffers, each as large as the playback buffers
276 std::vector<SampleBuffer> mScratchBuffers;
277 std::vector<float *> mScratchPointers;
278
279 std::vector<std::unique_ptr<Mixer>> mPlaybackMixers;
280
281 std::atomic<float> mMixerOutputVol{ 1.0 };
283 double mFactor;
284 unsigned long mMaxFramesOutput; // The actual number of frames output.
287
288 double mSeek;
291
296
301
309 unsigned long long mLostSamples{ 0 };
313
314 std::atomic<Acknowledge> mAudioThreadAcknowledge;
315
316 // Async start/stop + wait of AudioThread processing.
317 // Provided to allow more flexibility, however use with caution:
318 // never call Stop between Start and the wait for Started (and the converse)
319 void StartAudioThread();
320 void WaitForAudioThreadStarted();
321 void StopAudioThread();
322 void WaitForAudioThreadStopped();
323
324 void ProcessOnceAndWait( std::chrono::milliseconds sleepTime = std::chrono::milliseconds(50) );
325
326
327
328 std::atomic<bool> mForceFadeOut{ false };
329
331
335
336protected:
337
339 return mMixerOutputVol.load(std::memory_order_relaxed); }
340 void SetMixerOutputVol(float value) {
341 mMixerOutputVol.store(value, std::memory_order_relaxed); }
342
346 std::weak_ptr< AudioIOListener > mListener;
347
348 bool mUsingAlsa { false };
349
350 // For cacheing supported sample rates
351 static double mCachedBestRateOut;
354
355 // Serialize main thread and PortAudio thread's attempts to pause and change
356 // the state used by the third, Audio thread.
358
359protected:
360 // A flag tested and set in one thread, cleared in another. Perhaps
361 // this guarantee of atomicity is more cautious than necessary.
362 wxAtomicInt mRecordingException {};
364 { wxAtomicInc( mRecordingException ); }
366 { if (mRecordingException) wxAtomicDec( mRecordingException ); }
367
368 std::vector< std::pair<double, double> > mLostCaptureIntervals;
370 bool mDetectDropouts{ true };
371
372public:
373 // Pairs of starting time and duration
374 const std::vector< std::pair<double, double> > &LostCaptureIntervals()
375 { return mLostCaptureIntervals; }
376
377 // Used only for testing purposes in alpha builds
378 bool mSimulateRecordingErrors{ false };
379
380 // Whether to check the error code passed to audacityAudioCallback to
381 // detect more dropouts
382 std::atomic<bool> mDetectUpstreamDropouts{ true };
383
384protected:
385 RecordingSchedule mRecordingSchedule{};
387
388 struct TransportState;
390 std::unique_ptr<TransportState> mpTransportState;
391
392private:
399};
400
401struct PaStreamInfo;
402
403class AUDACITY_DLL_API AudioIO final
404 : public AudioIoCallback
405 , public Observer::Publisher<AudioIOEvent>
406{
407
408 AudioIO();
409 ~AudioIO();
410 void StartThread();
411
412public:
413 // This might return null during application startup or shutdown
414 static AudioIO *Get();
415
417
420 std::shared_ptr<RealtimeEffectState>
421 AddState(AudacityProject &project, Track *pTrack, const PluginID & id);
422
424
427 std::shared_ptr<RealtimeEffectState>
428 ReplaceState(AudacityProject &project,
429 Track *pTrack, size_t index, const PluginID & id);
430
432 void RemoveState(AudacityProject &project,
433 Track *pTrack, std::shared_ptr<RealtimeEffectState> pState);
434
442 void StartMonitoring( const AudioIOStartStreamOptions &options );
443
451 int StartStream(const TransportTracks &tracks,
452 double t0, double t1,
453 double mixerLimit,
454 const AudioIOStartStreamOptions &options);
455
461 void StopStream() override;
464 void SeekStream(double seconds) { mSeek = seconds; }
465
466 using PostRecordingAction = std::function<void()>;
467
469
470 void CallAfterRecording(PostRecordingAction action);
471
472public:
473 wxString LastPaErrorString();
474
475 wxLongLong GetLastPlaybackTime() const { return mLastPlaybackTimeMillis; }
476 std::shared_ptr<AudacityProject> GetOwningProject() const
477 { return mOwningProject.lock(); }
478
480 void SetPaused(bool state);
481
482 /* Mixer services are always available. If no stream is running, these
483 * methods use whatever device is specified by the preferences. If a
484 * stream *is* running, naturally they manipulate the mixer associated
485 * with that stream. If no mixer is available, output is emulated and
486 * input is stuck at 1.0f (a gain is applied to output samples).
487 */
488 void SetMixer(int inputSource, float inputVolume,
489 float playbackVolume);
490 void GetMixer(int *inputSource, float *inputVolume,
491 float *playbackVolume);
498 bool InputMixerWorks();
499
504 wxArrayString GetInputSourceNames();
505
506 sampleFormat GetCaptureFormat() { return mCaptureFormat; }
507 unsigned GetNumPlaybackChannels() const { return mNumPlaybackChannels; }
508 unsigned GetNumCaptureChannels() const { return mNumCaptureChannels; }
509
510 // Meaning really capturing, not just pre-rolling
511 bool IsCapturing() const;
512
516 static bool ValidateDeviceNames(const wxString &play, const wxString &rec);
517
521 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
522 void AILAInitialize();
523 void AILADisable();
524 bool AILAIsActive();
525 void AILAProcess(double maxPeak);
526 void AILASetStartTime();
527 double AILAGetLastDecisionTime();
528 #endif
529
530 bool IsAvailable(AudacityProject &project) const;
531
542 double GetBestRate(bool capturing, bool playing, double sampleRate);
543
550 double GetStreamTime();
551
552 static void AudioThread(std::atomic<bool> &finish);
553
554 static void Init();
555 static void Deinit();
556
559 void DelayActions(bool recording);
560
561private:
562
563 bool DelayingActions() const;
564
567 void SetMeters();
568
579 bool StartPortAudioStream(const AudioIOStartStreamOptions &options,
580 unsigned int numPlaybackChannels,
581 unsigned int numCaptureChannels,
582 sampleFormat captureFormat);
583
584 void SetOwningProject( const std::shared_ptr<AudacityProject> &pProject );
585 void ResetOwningProject();
586
593 void TrackBufferExchange();
594
596 void FillPlayBuffers();
597 void TransformPlayBuffers(
598 std::optional<RealtimeEffects::ProcessingScope> &scope);
599 bool ProcessPlaybackSlices(
600 std::optional<RealtimeEffects::ProcessingScope> &pScope,
601 size_t available);
602
604 void DrainRecordBuffers();
605
611 size_t GetCommonlyFreePlayback();
612
619 size_t GetCommonlyAvailCapture();
620
626 bool AllocateBuffers(
627 const AudioIOStartStreamOptions &options,
628 const TransportTracks &tracks, double t0, double t1, double sampleRate );
629
633 void StartStreamCleanup(bool bOnlyBuffers = false);
634
637
638 bool mDelayingActions{ false };
639};
640
641#endif
int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Definition: AudioIO.cpp:2397
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:62
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
This simplifies arrays of arrays, each array separately allocated with NEW[] But it might be better t...
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:406
std::shared_ptr< AudacityProject > GetOwningProject() const
Definition: AudioIO.h:476
std::mutex mPostRecordingActionMutex
Definition: AudioIO.h:635
PostRecordingAction mPostRecordingAction
Definition: AudioIO.h:636
unsigned GetNumCaptureChannels() const
Definition: AudioIO.h:508
void SeekStream(double seconds)
Move the playback / recording position of the current stream by the specified amount from where it is...
Definition: AudioIO.h:464
sampleFormat GetCaptureFormat()
Definition: AudioIO.h:506
wxLongLong GetLastPlaybackTime() const
Definition: AudioIO.h:475
std::function< void()> PostRecordingAction
Definition: AudioIO.h:466
unsigned GetNumPlaybackChannels() const
Definition: AudioIO.h:507
std::vector< std::unique_ptr< AudioIOExtBase > >::const_iterator mIterator
Definition: AudioIO.h:160
AudioIOExtIterator(AudioIoCallback &audioIO, bool end)
Definition: AudioIO.h:142
std::forward_iterator_tag iterator_category
Definition: AudioIO.h:140
AudioIoCallback is a class that implements the callback required by PortAudio. The callback needs to ...
Definition: AudioIO.h:119
static int mNextStreamToken
Definition: AudioIO.h:282
std::shared_ptr< AudioIOListener > GetListener() const
Definition: AudioIO.h:177
bool mbMicroFades
Definition: AudioIO.h:286
double mSeek
Definition: AudioIO.h:288
std::unique_ptr< TransportState > mpTransportState
Holds some state for duration of playback or recording.
Definition: AudioIO.h:388
const std::vector< std::pair< double, double > > & LostCaptureIntervals()
Definition: AudioIO.h:374
wxMutex mSuspendAudioThread
Definition: AudioIO.h:357
AudioIOExtRange Extensions()
Definition: AudioIO.h:169
float GetMixerOutputVol()
Definition: AudioIO.h:338
PlaybackSchedule mPlaybackSchedule
Definition: AudioIO.h:386
std::vector< float * > mScratchPointers
pointing into mScratchBuffers
Definition: AudioIO.h:277
std::atomic< Acknowledge > mAudioThreadAcknowledge
Definition: AudioIO.h:314
size_t mPlaybackSamplesToCopy
Preferred batch size for replenishing the playback RingBuffer.
Definition: AudioIO.h:293
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopRunning
Definition: AudioIO.h:311
static double mCachedBestRateOut
Definition: AudioIO.h:351
std::vector< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:279
PlaybackPolicy::Duration mPlaybackRingBufferSecs
Definition: AudioIO.h:289
std::thread mAudioThread
Definition: AudioIO.h:266
int mCallbackReturn
Definition: AudioIO.h:189
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopActive
Definition: AudioIO.h:312
void ClearRecordingException()
Definition: AudioIO.h:365
long mNumPauseFrames
How many frames of zeros were output due to pauses?
Definition: AudioIO.h:247
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:307
void SetRecordingException()
Definition: AudioIO.h:363
std::atomic< bool > mAudioThreadShouldCallTrackBufferExchangeOnce
Definition: AudioIO.h:310
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:330
int mbHasSoloTracks
Definition: AudioIO.h:188
WaveTrackArray mPlaybackTracks
Definition: AudioIO.h:274
PaError mLastPaError
Definition: AudioIO.h:334
static bool mCachedBestRatePlaying
Definition: AudioIO.h:352
bool mSoftwarePlaythrough
Definition: AudioIO.h:299
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
Definition: AudioIO.h:270
WaveTrackArray mCaptureTracks
Definition: AudioIO.h:271
unsigned long mMaxFramesOutput
Definition: AudioIO.h:284
double mLastRecordingOffset
Not (yet) used; should perhaps be atomic when it is.
Definition: AudioIO.h:333
size_t mPlaybackQueueMinimum
Occupancy of the queue we try to maintain, with bigger batches if needed.
Definition: AudioIO.h:295
std::weak_ptr< AudioIOListener > mListener
Definition: AudioIO.h:346
ArrayOf< std::unique_ptr< Resample > > mResample
Definition: AudioIO.h:269
double mCaptureRingBufferSecs
Definition: AudioIO.h:290
float mSilenceLevel
Definition: AudioIO.h:303
unsigned int mNumCaptureChannels
Definition: AudioIO.h:305
void SetMixerOutputVol(float value)
Definition: AudioIO.h:340
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:368
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:302
double mFactor
Definition: AudioIO.h:283
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
Definition: AudioIO.h:273
double mMinCaptureSecsToCopy
Definition: AudioIO.h:297
std::vector< SampleBuffer > mScratchBuffers
Definition: AudioIO.h:276
static bool mCachedBestRateCapturing
Definition: AudioIO.h:353
sampleFormat mCaptureFormat
Definition: AudioIO.h:308
Functions for doing the mixdown of the tracks.
Definition: Mix.h:26
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:916
std::chrono::duration< double > Duration
Brackets one block of processing in one 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:75
enum AudioIOEvent::Type type
AudacityProject * pProject
Definition: AudioIO.h:69
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:165
AudioIOExtIterator end() const
Definition: AudioIO.h:166
AudioIOExtIterator first
Definition: AudioIO.h:163
AudioIOExtIterator second
Definition: AudioIO.h:164
PlayableTrackConstArray otherPlayableTracks
Definition: AudioIO.h:81
WaveTrackConstArray prerollTracks
Definition: AudioIO.h:84
WaveTrackArray captureTracks
Definition: AudioIO.h:80
WaveTrackArray playbackTracks
Definition: AudioIO.h:79