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 "AudioIOSequences.h"
18#include "PlaybackSchedule.h" // member variable
19
20#include <functional>
21#include <memory>
22#include <mutex>
23#include <thread>
24#include <utility>
25#include <wx/atomic.h> // member variable
26
27#include "PluginProvider.h" // for PluginID
28#include "Observer.h"
29#include "SampleCount.h"
30#include "SampleFormat.h"
31
32class wxArrayString;
33class AudioIOBase;
34class AudioIO;
35class RingBuffer;
36class Mixer;
39class Resample;
40
41class AudacityProject;
42
43struct PaStreamCallbackTimeInfo;
44typedef unsigned long PaStreamCallbackFlags;
45typedef int PaError;
46
47namespace RealtimeEffects {
48 class ProcessingScope;
49}
50
52
53enum class Acknowledge { eNone = 0, eStart, eStop };
54
61 enum Type {
67 bool on;
68};
69
70struct AUDIO_IO_API TransportSequences final {
73 std::vector<std::shared_ptr<const OtherPlayableSequence>>
75
76 // This is a subset of playbackSequences
78};
79
103 const void *inputBuffer, void *outputBuffer,
104 unsigned long framesPerBuffer,
105 const PaStreamCallbackTimeInfo *timeInfo,
106 PaStreamCallbackFlags statusFlags, void *userData );
107
108class AudioIOExt;
109
110class AUDIO_IO_API AudioIoCallback /* not final */
111 : public AudioIOBase
112{
113public:
116
117public:
118 // This function executes in a thread spawned by the PortAudio library
119 int AudioCallback(
120 constSamplePtr inputBuffer, float *outputBuffer,
121 unsigned long framesPerBuffer,
122 const PaStreamCallbackTimeInfo *timeInfo,
123 const PaStreamCallbackFlags statusFlags, void *userData);
124
127 class AUDIO_IO_API AudioIOExtIterator {
128 public:
129 using difference_type = ptrdiff_t;
133 using iterator_category = std::forward_iterator_tag;
134
135 explicit AudioIOExtIterator( AudioIoCallback &audioIO, bool end )
136 : mIterator{ end
137 ? audioIO.mAudioIOExt.end()
138 : audioIO.mAudioIOExt.begin() }
139 {}
140 AudioIOExtIterator &operator ++ () { ++mIterator; return *this; }
141 auto operator *() const -> AudioIOExt &;
142 friend inline bool operator == (
143 const AudioIOExtIterator &xx, const AudioIOExtIterator &yy)
144 {
145 return xx.mIterator == yy.mIterator;
146 }
147 friend inline bool operator != (
148 const AudioIOExtIterator &xx, const AudioIOExtIterator &yy)
149 {
150 return !(xx == yy);
151 }
152 private:
153 std::vector<std::unique_ptr<AudioIOExtBase>>::const_iterator mIterator;
154 };
158 AudioIOExtIterator begin() const { return first; }
159 AudioIOExtIterator end() const { return second; }
160 };
161
163 return {
164 AudioIOExtIterator{ *this, false },
165 AudioIOExtIterator{ *this, true }
166 };
167 }
169
170 std::shared_ptr< AudioIOListener > GetListener() const
171 { return mListener.lock(); }
172 void SetListener( const std::shared_ptr< AudioIOListener > &listener);
173
174 // Part of the callback
175 int CallbackDoSeek();
176
177 // Part of the callback
178 void CallbackCheckCompletion(
179 int &callbackReturn, unsigned long len);
180
183 // Helpers to determine if sequences have already been faded out.
184 unsigned CountSoloingSequences();
185
186 bool SequenceShouldBeSilent(const PlayableSequence &ps);
187
188 void CheckSoundActivatedRecordingLevel(
189 float *inputSamples,
190 unsigned long framesPerBuffer
191 );
192
193 bool FillOutputBuffers(
194 float *outputFloats,
195 unsigned long framesPerBuffer,
196 float *outputMeterFloats
197 );
198 void DrainInputBuffers(
199 constSamplePtr inputBuffer,
200 unsigned long framesPerBuffer,
201 const PaStreamCallbackFlags statusFlags,
202 float * tempFloats
203 );
204 void UpdateTimePosition(
205 unsigned long framesPerBuffer
206 );
207 void DoPlaythrough(
208 constSamplePtr inputBuffer,
209 float *outputBuffer,
210 unsigned long framesPerBuffer,
211 float *outputMeterFloats
212 );
213 void SendVuInputMeterData(
214 const float *inputSamples,
215 unsigned long framesPerBuffer
216 );
217 void SendVuOutputMeterData(
218 const float *outputMeterFloats,
219 unsigned long framesPerBuffer
220 );
221
227 size_t GetCommonlyReadyPlayback();
228
229 size_t GetCommonlyWrittenForPlayback();
230
233
234#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
235 bool mAILAActive;
236 bool mAILAClipped;
237 int mAILATotalAnalysis;
238 int mAILAAnalysisCounter;
239 double mAILAMax;
240 double mAILAGoalPoint;
241 double mAILAGoalDelta;
242 double mAILAAnalysisTime;
243 double mAILALastStartTime;
244 double mAILAChangeFactor;
245 double mAILATopLevel;
246 double mAILAAnalysisEndTime;
247 double mAILAAbsolutStartTime;
248 unsigned short mAILALastChangeType; //0 - no change, 1 - increase change, 2 - decrease change
249#endif
250
251 std::thread mAudioThread;
252 std::atomic<bool> mFinishAudioThread{ false };
253
254 std::vector<std::unique_ptr<Resample>> mResample;
255
256 using RingBuffers = std::vector<std::unique_ptr<RingBuffer>>;
261 std::vector<std::vector<float>> mProcessingBuffers;
264 std::vector<std::vector<float>> mMasterBuffers;
268 // Old gain is used in playback in linearly interpolating
269 // the gain.
271 // Temporary buffers, each as large as the playback buffers
272 std::vector<SampleBuffer> mScratchBuffers;
273 std::vector<float *> mScratchPointers;
274
275 std::vector<std::unique_ptr<Mixer>> mPlaybackMixers;
276
277 std::atomic<float> mMixerOutputVol{ 1.0 };
279 double mFactor;
280 unsigned long mMaxFramesOutput; // The actual number of frames output.
283
284 double mSeek;
287
291 size_t mHardwarePlaybackLatencyFrames {};
294
299
307 double mCaptureRate{};
308 unsigned long long mLostSamples{ 0 };
312
313 std::atomic<Acknowledge> mAudioThreadAcknowledge;
314
315 // Async start/stop + wait of AudioThread processing.
316 // Provided to allow more flexibility, however use with caution:
317 // never call Stop between Start and the wait for Started (and the converse)
318 void StartAudioThread();
319 void WaitForAudioThreadStarted();
320 void StopAudioThread();
321 void WaitForAudioThreadStopped();
322
323 void ProcessOnceAndWait( std::chrono::milliseconds sleepTime = std::chrono::milliseconds(50) );
324
325
326
327 std::atomic<bool> mForceFadeOut{ false };
328
330
334
335protected:
336 static size_t MinValue(
337 const RingBuffers &buffers, size_t (RingBuffer::*pmf)() const);
338
340 return mMixerOutputVol.load(std::memory_order_relaxed); }
341 void SetMixerOutputVol(float value) {
342 mMixerOutputVol.store(value, std::memory_order_relaxed); }
343
347 std::weak_ptr< AudioIOListener > mListener;
348
349 bool mUsingAlsa { false };
350 bool mUsingJack { false };
351
352 // For cacheing supported sample rates
353 static double mCachedBestRateOut;
356
357 // Serialize main thread and PortAudio thread's attempts to pause and change
358 // the state used by the third, Audio thread.
360
361public:
362 // Whether an exception (as for exhaustion of resource space) was detected
363 // in recording, and not yet cleared at the end of the procedure to stop
364 // recording.
366 { return mRecordingException; }
367
368protected:
369 // A flag tested and set in one thread, cleared in another. Perhaps
370 // this guarantee of atomicity is more cautious than necessary.
371 wxAtomicInt mRecordingException {};
373 { wxAtomicInc( mRecordingException ); }
375 { if (mRecordingException) wxAtomicDec( mRecordingException ); }
376
377 std::vector< std::pair<double, double> > mLostCaptureIntervals;
379 bool mDetectDropouts{ true };
380
381public:
382 // Pairs of starting time and duration
383 const std::vector< std::pair<double, double> > &LostCaptureIntervals()
384 { return mLostCaptureIntervals; }
385
386 // Used only for testing purposes in alpha builds
387 bool mSimulateRecordingErrors{ false };
388
389 // Whether to check the error code passed to audacityAudioCallback to
390 // detect more dropouts
391 std::atomic<bool> mDetectUpstreamDropouts{ true };
392
393protected:
394 RecordingSchedule mRecordingSchedule{};
396
397 struct TransportState;
399 std::unique_ptr<TransportState> mpTransportState;
400
401private:
408};
409
410struct PaStreamInfo;
411
412class AUDIO_IO_API AudioIO final
413 : public AudioIoCallback
414 , public Observer::Publisher<AudioIOEvent>
415{
416
417 AudioIO();
418 ~AudioIO();
419 void StartThread();
420
421public:
422 // This might return null during application startup or shutdown
423 static AudioIO *Get();
424
426
429 std::shared_ptr<RealtimeEffectState>
430 AddState(AudacityProject &project,
431 ChannelGroup *pGroup, const PluginID & id);
432
434
437 std::shared_ptr<RealtimeEffectState>
438 ReplaceState(AudacityProject &project,
439 ChannelGroup *pGroup, size_t index, const PluginID & id);
440
442 void RemoveState(AudacityProject &project,
443 ChannelGroup *pGroup,
444 std::shared_ptr<RealtimeEffectState> pState);
445
453 void StartMonitoring( const AudioIOStartStreamOptions &options );
454
468 int StartStream(const TransportSequences &sequences,
469 double t0, double t1,
470 double mixerLimit,
471 const AudioIOStartStreamOptions &options);
472
478 void StopStream() override;
481 void SeekStream(double seconds) { mSeek = seconds; }
482
483 using PostRecordingAction = std::function<void()>;
484
486
487 void CallAfterRecording(PostRecordingAction action);
488
489public:
490 wxString LastPaErrorString();
491
492 wxLongLong GetLastPlaybackTime() const { return mLastPlaybackTimeMillis; }
493 std::shared_ptr<AudacityProject> GetOwningProject() const
494 { return mOwningProject.lock(); }
495
497 void SetPaused(bool state, bool publish = false);
498
499 /* Mixer services are always available. If no stream is running, these
500 * methods use whatever device is specified by the preferences. If a
501 * stream *is* running, naturally they manipulate the mixer associated
502 * with that stream. If no mixer is available, output is emulated and
503 * input is stuck at 1.0f (a gain is applied to output samples).
504 */
505 void SetMixer(int inputSource, float inputVolume,
506 float playbackVolume);
507 void GetMixer(int *inputSource, float *inputVolume,
508 float *playbackVolume);
515 bool InputMixerWorks();
516
521 wxArrayString GetInputSourceNames();
522
523 sampleFormat GetCaptureFormat() { return mCaptureFormat; }
524 size_t GetNumPlaybackChannels() const { return mNumPlaybackChannels; }
525 size_t GetNumCaptureChannels() const { return mNumCaptureChannels; }
526
527 // Meaning really capturing, not just pre-rolling
528 bool IsCapturing() const;
529
533 static bool ValidateDeviceNames(const wxString &play, const wxString &rec);
534
538 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
539 void AILAInitialize();
540 void AILADisable();
541 bool AILAIsActive();
542 void AILAProcess(double maxPeak);
543 void AILASetStartTime();
544 double AILAGetLastDecisionTime();
545 #endif
546
547 bool IsAvailable(AudacityProject &project) const;
548
559 double GetBestRate(bool capturing, bool playing, double sampleRate);
560
567 double GetStreamTime();
568
569 static void AudioThread(std::atomic<bool> &finish);
570
571 static void Init();
572 static void Deinit();
573
576 void DelayActions(bool recording);
577
578private:
579
580 bool DelayingActions() const;
581
584 void SetMeters();
585
596 bool StartPortAudioStream(const AudioIOStartStreamOptions &options,
597 unsigned int numPlaybackChannels, unsigned int numCaptureChannels);
598
599 void SetOwningProject( const std::shared_ptr<AudacityProject> &pProject );
600 void ResetOwningProject();
601
608 void SequenceBufferExchange();
609
611 void FillPlayBuffers();
612
613 bool ProcessPlaybackSlices(
614 std::optional<RealtimeEffects::ProcessingScope> &pScope,
615 size_t available);
616
618 void DrainRecordBuffers();
619
625 size_t GetCommonlyFreePlayback();
626
633 size_t GetCommonlyAvailCapture();
634
640 bool AllocateBuffers(
641 const AudioIOStartStreamOptions &options,
642 const TransportSequences &sequences,
643 double t0, double t1, double sampleRate);
644
648 void StartStreamCleanup(bool bOnlyBuffers = false);
649
652
653 bool mDelayingActions{ false };
654};
655
656AUDIO_IO_API extern BoolSetting SoundActivatedRecord;
657
658#endif
int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
Definition: AudioIO.cpp:2654
AUDIO_IO_API BoolSetting SoundActivatedRecord
Definition: AudioIO.cpp:3408
int PaError
Definition: AudioIO.h:45
bool ValidateDeviceNames()
unsigned long PaStreamCallbackFlags
Definition: AudioIO.h:43
Acknowledge
Definition: AudioIO.h:53
std::vector< std::shared_ptr< RecordableSequence > > RecordableSequences
std::vector< std::shared_ptr< const PlayableSequence > > ConstPlayableSequences
wxString PluginID
Generalized interface for discovery of plug-ins for one protocol.
auto operator*(PffftAlignedCount x, Integral y) -> std::enable_if_t< std::is_unsigned_v< Integral > &&sizeof(Integral)<=sizeof(size_t), PffftAlignedCount >
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:58
const auto project
bool operator!=(const WaveTrackLocation &a, const WaveTrackLocation &b)
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:415
std::shared_ptr< AudacityProject > GetOwningProject() const
Definition: AudioIO.h:493
std::mutex mPostRecordingActionMutex
Definition: AudioIO.h:650
PostRecordingAction mPostRecordingAction
Definition: AudioIO.h:651
size_t GetNumPlaybackChannels() const
Definition: AudioIO.h:524
void SeekStream(double seconds)
Move the playback / recording position of the current stream by the specified amount from where it is...
Definition: AudioIO.h:481
sampleFormat GetCaptureFormat()
Definition: AudioIO.h:523
wxLongLong GetLastPlaybackTime() const
Definition: AudioIO.h:492
std::function< void()> PostRecordingAction
Definition: AudioIO.h:483
size_t GetNumCaptureChannels() const
Definition: AudioIO.h:525
std::vector< std::unique_ptr< AudioIOExtBase > >::const_iterator mIterator
Definition: AudioIO.h:153
AudioIOExtIterator(AudioIoCallback &audioIO, bool end)
Definition: AudioIO.h:135
std::forward_iterator_tag iterator_category
Definition: AudioIO.h:133
AudioIoCallback is a class that implements the callback required by PortAudio. The callback needs to ...
Definition: AudioIO.h:112
std::atomic< bool > mAudioThreadSequenceBufferExchangeLoopRunning
Definition: AudioIO.h:310
static int mNextStreamToken
Definition: AudioIO.h:278
std::shared_ptr< AudioIOListener > GetListener() const
Definition: AudioIO.h:170
size_t mNumPlaybackChannels
Definition: AudioIO.h:305
bool mbMicroFades
Definition: AudioIO.h:282
double mSeek
Definition: AudioIO.h:284
std::unique_ptr< TransportState > mpTransportState
Holds some state for duration of playback or recording.
Definition: AudioIO.h:397
const std::vector< std::pair< double, double > > & LostCaptureIntervals()
Definition: AudioIO.h:383
wxMutex mSuspendAudioThread
Definition: AudioIO.h:359
AudioIOExtRange Extensions()
Definition: AudioIO.h:162
std::atomic< bool > mAudioThreadShouldCallSequenceBufferExchangeOnce
Definition: AudioIO.h:309
std::vector< std::unique_ptr< Resample > > mResample
Definition: AudioIO.h:254
float GetMixerOutputVol()
Definition: AudioIO.h:339
PlaybackSchedule mPlaybackSchedule
Definition: AudioIO.h:395
std::vector< float * > mScratchPointers
pointing into mScratchBuffers
Definition: AudioIO.h:273
std::atomic< Acknowledge > mAudioThreadAcknowledge
Definition: AudioIO.h:313
int mbHasSoloSequences
Definition: AudioIO.h:181
size_t mPlaybackSamplesToCopy
Preferred batch size for replenishing the playback RingBuffer.
Definition: AudioIO.h:289
static double mCachedBestRateOut
Definition: AudioIO.h:353
std::vector< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:275
PlaybackPolicy::Duration mPlaybackRingBufferSecs
Definition: AudioIO.h:285
std::vector< std::vector< float > > mProcessingBuffers
Definition: AudioIO.h:261
std::thread mAudioThread
Definition: AudioIO.h:251
int mCallbackReturn
Definition: AudioIO.h:182
std::atomic< bool > mAudioThreadSequenceBufferExchangeLoopActive
Definition: AudioIO.h:311
void ClearRecordingException()
Definition: AudioIO.h:374
long mNumPauseFrames
How many frames of zeros were output due to pauses?
Definition: AudioIO.h:232
void SetRecordingException()
Definition: AudioIO.h:372
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:329
bool HasRecordingException() const
Definition: AudioIO.h:365
RingBuffers mCaptureBuffers
Definition: AudioIO.h:257
PaError mLastPaError
Definition: AudioIO.h:333
static bool mCachedBestRatePlaying
Definition: AudioIO.h:354
bool mSoftwarePlaythrough
Definition: AudioIO.h:297
RecordableSequences mCaptureSequences
Definition: AudioIO.h:258
RingBuffers mPlaybackBuffers
Definition: AudioIO.h:266
float mOldPlaybackGain
Definition: AudioIO.h:270
std::vector< std::unique_ptr< RingBuffer > > RingBuffers
Definition: AudioIO.h:256
unsigned long mMaxFramesOutput
Definition: AudioIO.h:280
ConstPlayableSequences mPlaybackSequences
Definition: AudioIO.h:267
double mLastRecordingOffset
Not (yet) used; should perhaps be atomic when it is.
Definition: AudioIO.h:332
size_t mPlaybackQueueMinimum
Occupancy of the queue we try to maintain, with bigger batches if needed.
Definition: AudioIO.h:293
std::weak_ptr< AudioIOListener > mListener
Definition: AudioIO.h:347
double mCaptureRingBufferSecs
Definition: AudioIO.h:286
float mSilenceLevel
Definition: AudioIO.h:301
size_t mNumCaptureChannels
Definition: AudioIO.h:303
void SetMixerOutputVol(float value)
Definition: AudioIO.h:341
std::vector< std::vector< float > > mMasterBuffers
Definition: AudioIO.h:264
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:377
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:300
double mFactor
Definition: AudioIO.h:279
double mMinCaptureSecsToCopy
Definition: AudioIO.h:295
std::vector< SampleBuffer > mScratchBuffers
Definition: AudioIO.h:272
static bool mCachedBestRateCapturing
Definition: AudioIO.h:355
sampleFormat mCaptureFormat
Definition: AudioIO.h:306
This specialization of Setting for bool adds a Toggle method to negate the saved value.
Definition: Prefs.h:346
Functions for doing the mixdown of the tracks.
Definition: Mix.h:29
An object that sends messages to an open-ended list of subscribed callbacks.
Definition: Observer.h:108
This is defined just to enable dynamic_cast on it.
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
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:202
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
const char * begin(const char *str) noexcept
Definition: StringUtils.h:101
bool on
Definition: AudioIO.h:67
enum AudioIOEvent::Type type
AudacityProject * pProject
Definition: AudioIO.h:60
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:158
AudioIOExtIterator end() const
Definition: AudioIO.h:159
AudioIOExtIterator first
Definition: AudioIO.h:156
AudioIOExtIterator second
Definition: AudioIO.h:157
RecordableSequences captureSequences
Definition: AudioIO.h:72
ConstPlayableSequences prerollSequences
Definition: AudioIO.h:77
std::vector< std::shared_ptr< const OtherPlayableSequence > > otherPlayableSequences
Definition: AudioIO.h:74
ConstPlayableSequences playbackSequences
Definition: AudioIO.h:71