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#include "AudioIOBase.h" // to inherit
17#include "PlaybackSchedule.h" // member variable
18
19#include <functional>
20#include <memory>
21#include <mutex>
22#include <thread>
23#include <utility>
24#include <wx/atomic.h> // member variable
25
26#include "PluginProvider.h" // for PluginID
27#include "Observer.h"
28#include "SampleCount.h"
29#include "SampleFormat.h"
30
31class wxArrayString;
32class AudioIOBase;
33class AudioIO;
34class RingBuffer;
35class Mixer;
37class Resample;
38
39class AudacityProject;
40
41class PlayableTrack;
43 std::vector < std::shared_ptr < const PlayableTrack > >;
44
45class Track;
46class SampleTrack;
47using SampleTrackArray = std::vector < std::shared_ptr < SampleTrack > >;
48using SampleTrackConstArray = std::vector < std::shared_ptr < const SampleTrack > >;
49
52 std::vector < std::shared_ptr < WritableSampleTrack > >;
53
54struct PaStreamCallbackTimeInfo;
55typedef unsigned long PaStreamCallbackFlags;
56typedef int PaError;
57
58namespace RealtimeEffects {
59 class ProcessingScope;
60}
61
63
64enum class Acknowledge { eNone = 0, eStart, eStop };
65
72 enum Type {
77 bool on;
78};
79
80struct AUDIO_IO_API TransportTracks final {
81 TransportTracks() = default;
83 TrackList &trackList, bool selectedOnly,
84 bool nonWaveToo = false
85 );
86
90
91 // This is a subset of playbackTracks
93};
94
118 const void *inputBuffer, void *outputBuffer,
119 unsigned long framesPerBuffer,
120 const PaStreamCallbackTimeInfo *timeInfo,
121 PaStreamCallbackFlags statusFlags, void *userData );
122
123class AudioIOExt;
124
125class AUDIO_IO_API AudioIoCallback /* not final */
126 : public AudioIOBase
127{
128public:
131
132public:
133 // This function executes in a thread spawned by the PortAudio library
134 int AudioCallback(
135 constSamplePtr inputBuffer, float *outputBuffer,
136 unsigned long framesPerBuffer,
137 const PaStreamCallbackTimeInfo *timeInfo,
138 const PaStreamCallbackFlags statusFlags, void *userData);
139
142 class AUDIO_IO_API AudioIOExtIterator {
143 public:
144 using difference_type = ptrdiff_t;
148 using iterator_category = std::forward_iterator_tag;
149
150 explicit AudioIOExtIterator( AudioIoCallback &audioIO, bool end )
151 : mIterator{ end
152 ? audioIO.mAudioIOExt.end()
153 : audioIO.mAudioIOExt.begin() }
154 {}
155 AudioIOExtIterator &operator ++ () { ++mIterator; return *this; }
156 auto operator *() const -> AudioIOExt &;
157 friend inline bool operator == (
158 const AudioIOExtIterator &xx, const AudioIOExtIterator &yy)
159 {
160 return xx.mIterator == yy.mIterator;
161 }
162 friend inline bool operator != (
163 const AudioIOExtIterator &xx, const AudioIOExtIterator &yy)
164 {
165 return !(xx == yy);
166 }
167 private:
168 std::vector<std::unique_ptr<AudioIOExtBase>>::const_iterator mIterator;
169 };
173 AudioIOExtIterator begin() const { return first; }
174 AudioIOExtIterator end() const { return second; }
175 };
176
178 return {
179 AudioIOExtIterator{ *this, false },
180 AudioIOExtIterator{ *this, true }
181 };
182 }
184
185 std::shared_ptr< AudioIOListener > GetListener() const
186 { return mListener.lock(); }
187 void SetListener( const std::shared_ptr< AudioIOListener > &listener);
188
189 // Part of the callback
190 int CallbackDoSeek();
191
192 // Part of the callback
193 void CallbackCheckCompletion(
194 int &callbackReturn, unsigned long len);
195
198 // Helpers to determine if tracks have already been faded out.
199 unsigned CountSoloingTracks();
200
201 using OldChannelGains = std::array<float, 2>;
202 bool TrackShouldBeSilent( const SampleTrack &wt );
203 bool TrackHasBeenFadedOut(
204 const SampleTrack &wt, const OldChannelGains &gains);
205 bool AllTracksAlreadySilent();
206
207 void CheckSoundActivatedRecordingLevel(
208 float *inputSamples,
209 unsigned long framesPerBuffer
210 );
211
212 void AddToOutputChannel( unsigned int chan, // index into gains
213 float * outputMeterFloats,
214 float * outputFloats,
215 const float * tempBuf,
216 bool drop,
217 unsigned long len,
218 const SampleTrack *vt,
219 OldChannelGains &gains
220 );
221 bool FillOutputBuffers(
222 float *outputBuffer,
223 unsigned long framesPerBuffer,
224 float *outputMeterFloats
225 );
226 void DrainInputBuffers(
227 constSamplePtr inputBuffer,
228 unsigned long framesPerBuffer,
229 const PaStreamCallbackFlags statusFlags,
230 float * tempFloats
231 );
232 void UpdateTimePosition(
233 unsigned long framesPerBuffer
234 );
235 void DoPlaythrough(
236 constSamplePtr inputBuffer,
237 float *outputBuffer,
238 unsigned long framesPerBuffer,
239 float *outputMeterFloats
240 );
241 void SendVuInputMeterData(
242 const float *inputSamples,
243 unsigned long framesPerBuffer
244 );
245 void SendVuOutputMeterData(
246 const float *outputMeterFloats,
247 unsigned long framesPerBuffer
248 );
249
255 size_t GetCommonlyReadyPlayback();
256
257 size_t GetCommonlyWrittenForPlayback();
258
261
262#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
263 bool mAILAActive;
264 bool mAILAClipped;
265 int mAILATotalAnalysis;
266 int mAILAAnalysisCounter;
267 double mAILAMax;
268 double mAILAGoalPoint;
269 double mAILAGoalDelta;
270 double mAILAAnalysisTime;
271 double mAILALastStartTime;
272 double mAILAChangeFactor;
273 double mAILATopLevel;
274 double mAILAAnalysisEndTime;
275 double mAILAAbsolutStartTime;
276 unsigned short mAILALastChangeType; //0 - no change, 1 - increase change, 2 - decrease change
277#endif
278
279 std::thread mAudioThread;
280 std::atomic<bool> mFinishAudioThread{ false };
281
288 // Old gain is used in playback in linearly interpolating
289 // the gain.
290 std::vector<OldChannelGains> mOldChannelGains;
291 // Temporary buffers, each as large as the playback buffers
292 std::vector<SampleBuffer> mScratchBuffers;
293 std::vector<float *> mScratchPointers;
294
295 std::vector<std::unique_ptr<Mixer>> mPlaybackMixers;
296
297 std::atomic<float> mMixerOutputVol{ 1.0 };
299 double mFactor;
300 unsigned long mMaxFramesOutput; // The actual number of frames output.
303
304 double mSeek;
307
312
317
325 unsigned long long mLostSamples{ 0 };
329
330 std::atomic<Acknowledge> mAudioThreadAcknowledge;
331
332 // Async start/stop + wait of AudioThread processing.
333 // Provided to allow more flexibility, however use with caution:
334 // never call Stop between Start and the wait for Started (and the converse)
335 void StartAudioThread();
336 void WaitForAudioThreadStarted();
337 void StopAudioThread();
338 void WaitForAudioThreadStopped();
339
340 void ProcessOnceAndWait( std::chrono::milliseconds sleepTime = std::chrono::milliseconds(50) );
341
342
343
344 std::atomic<bool> mForceFadeOut{ false };
345
347
351
352protected:
353
355 return mMixerOutputVol.load(std::memory_order_relaxed); }
356 void SetMixerOutputVol(float value) {
357 mMixerOutputVol.store(value, std::memory_order_relaxed); }
358
362 std::weak_ptr< AudioIOListener > mListener;
363
364 bool mUsingAlsa { false };
365
366 // For cacheing supported sample rates
367 static double mCachedBestRateOut;
370
371 // Serialize main thread and PortAudio thread's attempts to pause and change
372 // the state used by the third, Audio thread.
374
375public:
376 // Whether an exception (as for exhaustion of resource space) was detected
377 // in recording, and not yet cleared at the end of the procedure to stop
378 // recording.
380 { return mRecordingException; }
381
382protected:
383 // A flag tested and set in one thread, cleared in another. Perhaps
384 // this guarantee of atomicity is more cautious than necessary.
385 wxAtomicInt mRecordingException {};
387 { wxAtomicInc( mRecordingException ); }
389 { if (mRecordingException) wxAtomicDec( mRecordingException ); }
390
391 std::vector< std::pair<double, double> > mLostCaptureIntervals;
393 bool mDetectDropouts{ true };
394
395public:
396 // Pairs of starting time and duration
397 const std::vector< std::pair<double, double> > &LostCaptureIntervals()
398 { return mLostCaptureIntervals; }
399
400 // Used only for testing purposes in alpha builds
401 bool mSimulateRecordingErrors{ false };
402
403 // Whether to check the error code passed to audacityAudioCallback to
404 // detect more dropouts
405 std::atomic<bool> mDetectUpstreamDropouts{ true };
406
407protected:
408 RecordingSchedule mRecordingSchedule{};
410
411 struct TransportState;
413 std::unique_ptr<TransportState> mpTransportState;
414
415private:
422};
423
424struct PaStreamInfo;
425
426class AUDIO_IO_API AudioIO final
427 : public AudioIoCallback
428 , public Observer::Publisher<AudioIOEvent>
429{
430
431 AudioIO();
432 ~AudioIO();
433 void StartThread();
434
435public:
436 // This might return null during application startup or shutdown
437 static AudioIO *Get();
438
440
443 std::shared_ptr<RealtimeEffectState>
444 AddState(AudacityProject &project, Track *pTrack, const PluginID & id);
445
447
450 std::shared_ptr<RealtimeEffectState>
451 ReplaceState(AudacityProject &project,
452 Track *pTrack, size_t index, const PluginID & id);
453
455 void RemoveState(AudacityProject &project,
456 Track *pTrack, std::shared_ptr<RealtimeEffectState> pState);
457
465 void StartMonitoring( const AudioIOStartStreamOptions &options );
466
474 int StartStream(const TransportTracks &tracks,
475 double t0, double t1,
476 double mixerLimit,
477 const AudioIOStartStreamOptions &options);
478
484 void StopStream() override;
487 void SeekStream(double seconds) { mSeek = seconds; }
488
489 using PostRecordingAction = std::function<void()>;
490
492
493 void CallAfterRecording(PostRecordingAction action);
494
495public:
496 wxString LastPaErrorString();
497
498 wxLongLong GetLastPlaybackTime() const { return mLastPlaybackTimeMillis; }
499 std::shared_ptr<AudacityProject> GetOwningProject() const
500 { return mOwningProject.lock(); }
501
503 void SetPaused(bool state);
504
505 /* Mixer services are always available. If no stream is running, these
506 * methods use whatever device is specified by the preferences. If a
507 * stream *is* running, naturally they manipulate the mixer associated
508 * with that stream. If no mixer is available, output is emulated and
509 * input is stuck at 1.0f (a gain is applied to output samples).
510 */
511 void SetMixer(int inputSource, float inputVolume,
512 float playbackVolume);
513 void GetMixer(int *inputSource, float *inputVolume,
514 float *playbackVolume);
521 bool InputMixerWorks();
522
527 wxArrayString GetInputSourceNames();
528
529 sampleFormat GetCaptureFormat() { return mCaptureFormat; }
530 unsigned GetNumPlaybackChannels() const { return mNumPlaybackChannels; }
531 unsigned GetNumCaptureChannels() const { return mNumCaptureChannels; }
532
533 // Meaning really capturing, not just pre-rolling
534 bool IsCapturing() const;
535
539 static bool ValidateDeviceNames(const wxString &play, const wxString &rec);
540
544 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
545 void AILAInitialize();
546 void AILADisable();
547 bool AILAIsActive();
548 void AILAProcess(double maxPeak);
549 void AILASetStartTime();
550 double AILAGetLastDecisionTime();
551 #endif
552
553 bool IsAvailable(AudacityProject &project) const;
554
565 double GetBestRate(bool capturing, bool playing, double sampleRate);
566
573 double GetStreamTime();
574
575 static void AudioThread(std::atomic<bool> &finish);
576
577 static void Init();
578 static void Deinit();
579
582 void DelayActions(bool recording);
583
584private:
585
586 bool DelayingActions() const;
587
590 void SetMeters();
591
602 bool StartPortAudioStream(const AudioIOStartStreamOptions &options,
603 unsigned int numPlaybackChannels,
604 unsigned int numCaptureChannels,
605 sampleFormat captureFormat);
606
607 void SetOwningProject( const std::shared_ptr<AudacityProject> &pProject );
608 void ResetOwningProject();
609
616 void TrackBufferExchange();
617
619 void FillPlayBuffers();
620 void TransformPlayBuffers(
621 std::optional<RealtimeEffects::ProcessingScope> &scope);
622 bool ProcessPlaybackSlices(
623 std::optional<RealtimeEffects::ProcessingScope> &pScope,
624 size_t available);
625
627 void DrainRecordBuffers();
628
634 size_t GetCommonlyFreePlayback();
635
642 size_t GetCommonlyAvailCapture();
643
649 bool AllocateBuffers(
650 const AudioIOStartStreamOptions &options,
651 const TransportTracks &tracks, double t0, double t1, double sampleRate );
652
656 void StartStreamCleanup(bool bOnlyBuffers = false);
657
660
661 bool mDelayingActions{ false };
662};
663
664#endif
int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Definition: AudioIO.cpp:2423
std::vector< std::shared_ptr< const SampleTrack > > SampleTrackConstArray
Definition: AudioIO.h:48
int PaError
Definition: AudioIO.h:56
bool ValidateDeviceNames()
unsigned long PaStreamCallbackFlags
Definition: AudioIO.h:54
std::vector< std::shared_ptr< SampleTrack > > SampleTrackArray
Definition: AudioIO.h:47
Acknowledge
Definition: AudioIO.h:64
std::vector< std::shared_ptr< const PlayableTrack > > PlayableTrackConstArray
Definition: AudioIO.h:43
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.
std::vector< std::shared_ptr< WritableSampleTrack > > WritableSampleTrackArray
sampleFormat
The ordering of these values with operator < agrees with the order of increasing bit width.
Definition: SampleFormat.h:30
const char * constSamplePtr
Definition: SampleFormat.h:56
bool operator!=(const WaveTrackLocation &a, const WaveTrackLocation &b)
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:90
A singleton object supporting queries of the state of any active audio streams, and audio device capa...
Definition: AudioIOBase.h:102
std::vector< std::unique_ptr< AudioIOExtBase > > mAudioIOExt
Definition: AudioIOBase.h:322
AudioIO uses the PortAudio library to play and record sound.
Definition: AudioIO.h:429
std::shared_ptr< AudacityProject > GetOwningProject() const
Definition: AudioIO.h:499
std::mutex mPostRecordingActionMutex
Definition: AudioIO.h:658
PostRecordingAction mPostRecordingAction
Definition: AudioIO.h:659
unsigned GetNumCaptureChannels() const
Definition: AudioIO.h:531
void SeekStream(double seconds)
Move the playback / recording position of the current stream by the specified amount from where it is...
Definition: AudioIO.h:487
sampleFormat GetCaptureFormat()
Definition: AudioIO.h:529
wxLongLong GetLastPlaybackTime() const
Definition: AudioIO.h:498
std::function< void()> PostRecordingAction
Definition: AudioIO.h:489
unsigned GetNumPlaybackChannels() const
Definition: AudioIO.h:530
std::vector< std::unique_ptr< AudioIOExtBase > >::const_iterator mIterator
Definition: AudioIO.h:168
AudioIOExtIterator(AudioIoCallback &audioIO, bool end)
Definition: AudioIO.h:150
std::forward_iterator_tag iterator_category
Definition: AudioIO.h:148
AudioIoCallback is a class that implements the callback required by PortAudio. The callback needs to ...
Definition: AudioIO.h:127
static int mNextStreamToken
Definition: AudioIO.h:298
std::shared_ptr< AudioIOListener > GetListener() const
Definition: AudioIO.h:185
bool mbMicroFades
Definition: AudioIO.h:302
double mSeek
Definition: AudioIO.h:304
std::unique_ptr< TransportState > mpTransportState
Holds some state for duration of playback or recording.
Definition: AudioIO.h:411
const std::vector< std::pair< double, double > > & LostCaptureIntervals()
Definition: AudioIO.h:397
wxMutex mSuspendAudioThread
Definition: AudioIO.h:373
AudioIOExtRange Extensions()
Definition: AudioIO.h:177
float GetMixerOutputVol()
Definition: AudioIO.h:354
std::array< float, 2 > OldChannelGains
Definition: AudioIO.h:201
PlaybackSchedule mPlaybackSchedule
Definition: AudioIO.h:409
std::vector< float * > mScratchPointers
pointing into mScratchBuffers
Definition: AudioIO.h:293
std::atomic< Acknowledge > mAudioThreadAcknowledge
Definition: AudioIO.h:330
WritableSampleTrackArray mCaptureTracks
Definition: AudioIO.h:284
size_t mPlaybackSamplesToCopy
Preferred batch size for replenishing the playback RingBuffer.
Definition: AudioIO.h:309
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopRunning
Definition: AudioIO.h:327
static double mCachedBestRateOut
Definition: AudioIO.h:367
std::vector< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:295
PlaybackPolicy::Duration mPlaybackRingBufferSecs
Definition: AudioIO.h:305
std::thread mAudioThread
Definition: AudioIO.h:279
int mCallbackReturn
Definition: AudioIO.h:197
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopActive
Definition: AudioIO.h:328
void ClearRecordingException()
Definition: AudioIO.h:388
long mNumPauseFrames
How many frames of zeros were output due to pauses?
Definition: AudioIO.h:260
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:323
void SetRecordingException()
Definition: AudioIO.h:386
std::atomic< bool > mAudioThreadShouldCallTrackBufferExchangeOnce
Definition: AudioIO.h:326
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:346
bool HasRecordingException() const
Definition: AudioIO.h:379
int mbHasSoloTracks
Definition: AudioIO.h:196
std::vector< OldChannelGains > mOldChannelGains
Definition: AudioIO.h:290
PaError mLastPaError
Definition: AudioIO.h:350
static bool mCachedBestRatePlaying
Definition: AudioIO.h:368
bool mSoftwarePlaythrough
Definition: AudioIO.h:315
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
Definition: AudioIO.h:283
unsigned long mMaxFramesOutput
Definition: AudioIO.h:300
double mLastRecordingOffset
Not (yet) used; should perhaps be atomic when it is.
Definition: AudioIO.h:349
size_t mPlaybackQueueMinimum
Occupancy of the queue we try to maintain, with bigger batches if needed.
Definition: AudioIO.h:311
std::weak_ptr< AudioIOListener > mListener
Definition: AudioIO.h:362
ArrayOf< std::unique_ptr< Resample > > mResample
Definition: AudioIO.h:282
double mCaptureRingBufferSecs
Definition: AudioIO.h:306
float mSilenceLevel
Definition: AudioIO.h:319
unsigned int mNumCaptureChannels
Definition: AudioIO.h:321
void SetMixerOutputVol(float value)
Definition: AudioIO.h:356
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:391
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:318
double mFactor
Definition: AudioIO.h:299
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
Definition: AudioIO.h:286
double mMinCaptureSecsToCopy
Definition: AudioIO.h:313
std::vector< SampleBuffer > mScratchBuffers
Definition: AudioIO.h:292
SampleTrackConstArray mPlaybackTracks
Definition: AudioIO.h:287
static bool mCachedBestRateCapturing
Definition: AudioIO.h:369
sampleFormat mCaptureFormat
Definition: AudioIO.h:324
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 flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1338
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:194
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:77
enum AudioIOEvent::Type type
AudacityProject * pProject
Definition: AudioIO.h:71
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:173
AudioIOExtIterator end() const
Definition: AudioIO.h:174
AudioIOExtIterator first
Definition: AudioIO.h:171
AudioIOExtIterator second
Definition: AudioIO.h:172
SampleTrackConstArray prerollTracks
Definition: AudioIO.h:92
PlayableTrackConstArray otherPlayableTracks
Definition: AudioIO.h:89
TransportTracks()=default
WritableSampleTrackArray captureTracks
Definition: AudioIO.h:88
SampleTrackConstArray playbackTracks
Definition: AudioIO.h:87