Audacity 3.2.0
Classes | Public Types | Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Attributes | List of all members
AudioIoCallback Class Reference

AudioIoCallback is a class that implements the callback required by PortAudio. The callback needs to be responsive, has no GUI, and copies data into and out of the sound card buffers. It also sends data to the meters. More...

#include <AudioIO.h>

Inheritance diagram for AudioIoCallback:
[legend]
Collaboration diagram for AudioIoCallback:
[legend]

Classes

class  AudioIOExtIterator
 
struct  AudioIOExtRange
 
struct  TransportState
 

Public Types

using OldChannelGains = std::array< float, 2 >
 
using RingBuffers = std::vector< std::unique_ptr< RingBuffer > >
 

Public Member Functions

 AudioIoCallback ()
 
 ~AudioIoCallback ()
 
int AudioCallback (constSamplePtr inputBuffer, float *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, const PaStreamCallbackFlags statusFlags, void *userData)
 
std::shared_ptr< AudioIOListenerGetListener () const
 
void SetListener (const std::shared_ptr< AudioIOListener > &listener)
 
int CallbackDoSeek ()
 
void CallbackCheckCompletion (int &callbackReturn, unsigned long len)
 
unsigned CountSoloingSequences ()
 
bool SequenceShouldBeSilent (const PlayableSequence &ps)
 
bool SequenceHasBeenFadedOut (const OldChannelGains &gains)
 Returns true when playback buffer data from both channels is discardable. More...
 
bool AllSequencesAlreadySilent ()
 
void CheckSoundActivatedRecordingLevel (float *inputSamples, unsigned long framesPerBuffer)
 
void AddToOutputChannel (unsigned int chan, float *outputMeterFloats, float *outputFloats, const float *tempBuf, bool drop, unsigned long len, const PlayableSequence &ps, float &channelGain)
 
bool FillOutputBuffers (float *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
 
void DrainInputBuffers (constSamplePtr inputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackFlags statusFlags, float *tempFloats)
 
void UpdateTimePosition (unsigned long framesPerBuffer)
 
void DoPlaythrough (constSamplePtr inputBuffer, float *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
 
void SendVuInputMeterData (const float *inputSamples, unsigned long framesPerBuffer)
 
void SendVuOutputMeterData (const float *outputMeterFloats, unsigned long framesPerBuffer)
 
size_t GetCommonlyReadyPlayback ()
 Get the number of audio samples ready in all of the playback buffers. More...
 
size_t GetCommonlyWrittenForPlayback ()
 
void StartAudioThread ()
 
void WaitForAudioThreadStarted ()
 
void StopAudioThread ()
 
void WaitForAudioThreadStopped ()
 
void ProcessOnceAndWait (std::chrono::milliseconds sleepTime=std::chrono::milliseconds(50))
 
bool HasRecordingException () const
 
const std::vector< std::pair< double, double > > & LostCaptureIntervals ()
 
iteration over extensions, supporting range-for syntax
AudioIOExtRange Extensions ()
 
- Public Member Functions inherited from AudioIOBase
 AudioIOBase ()
 
virtual ~AudioIOBase ()
 
 AudioIOBase (const AudioIOBase &)=delete
 
AudioIOBaseoperator= (const AudioIOBase &)=delete
 
void SetCaptureMeter (const std::shared_ptr< AudacityProject > &project, const std::weak_ptr< Meter > &meter)
 
void SetPlaybackMeter (const std::shared_ptr< AudacityProject > &project, const std::weak_ptr< Meter > &meter)
 
void HandleDeviceChange ()
 update state after changing what audio devices are selected More...
 
wxString GetDeviceInfo () const
 Get diagnostic information on all the available audio I/O devices. More...
 
std::vector< AudioIODiagnosticsGetAllDeviceInfo ()
 Get diagnostic information for audio devices and also for extensions. More...
 
bool IsPaused () const
 Find out if playback / recording is currently paused. More...
 
virtual void StopStream ()=0
 
bool IsBusy () const
 Returns true if audio i/o is busy starting, stopping, playing, or recording. More...
 
bool IsStreamActive () const
 Returns true if the audio i/o is running at all, but not during cleanup. More...
 
bool IsStreamActive (int token) const
 
bool IsAudioTokenActive (int token) const
 Returns true if the stream is active, or even if audio I/O is busy cleaning up its data or writing to disk. More...
 
bool IsMonitoring () const
 Returns true if we're monitoring input (but not recording or playing actual audio) More...
 
void SetMixer (int inputSource)
 

Public Attributes

int mbHasSoloSequences
 
int mCallbackReturn
 
long mNumPauseFrames
 How many frames of zeros were output due to pauses? More...
 
std::thread mAudioThread
 
std::atomic< bool > mFinishAudioThread { false }
 
std::vector< std::unique_ptr< Resample > > mResample
 
RingBuffers mCaptureBuffers
 
RecordableSequences mCaptureSequences
 
RingBuffers mPlaybackBuffers
 
ConstPlayableSequences mPlaybackSequences
 
std::vector< OldChannelGainsmOldChannelGains
 
std::vector< SampleBuffermScratchBuffers
 
std::vector< float * > mScratchPointers
 pointing into mScratchBuffers More...
 
std::vector< std::unique_ptr< Mixer > > mPlaybackMixers
 
std::atomic< float > mMixerOutputVol { 1.0 }
 
double mFactor
 
unsigned long mMaxFramesOutput
 
bool mbMicroFades
 
double mSeek
 
PlaybackPolicy::Duration mPlaybackRingBufferSecs
 
double mCaptureRingBufferSecs
 
size_t mPlaybackSamplesToCopy
 Preferred batch size for replenishing the playback RingBuffer. More...
 
size_t mHardwarePlaybackLatencyFrames {}
 Hardware output latency in frames. More...
 
size_t mPlaybackQueueMinimum
 Occupancy of the queue we try to maintain, with bigger batches if needed. More...
 
double mMinCaptureSecsToCopy
 
bool mSoftwarePlaythrough
 
bool mPauseRec
 True if Sound Activated Recording is enabled. More...
 
float mSilenceLevel
 
size_t mNumCaptureChannels
 
size_t mNumPlaybackChannels
 
sampleFormat mCaptureFormat
 
double mCaptureRate {}
 
unsigned long long mLostSamples { 0 }
 
std::atomic< bool > mAudioThreadShouldCallSequenceBufferExchangeOnce
 
std::atomic< bool > mAudioThreadSequenceBufferExchangeLoopRunning
 
std::atomic< bool > mAudioThreadSequenceBufferExchangeLoopActive
 
std::atomic< AcknowledgemAudioThreadAcknowledge
 
std::atomic< bool > mForceFadeOut { false }
 
wxLongLong mLastPlaybackTimeMillis
 
double mLastRecordingOffset
 Not (yet) used; should perhaps be atomic when it is. More...
 
PaError mLastPaError
 
bool mSimulateRecordingErrors { false }
 
std::atomic< bool > mDetectUpstreamDropouts { true }
 

Static Public Attributes

static int mNextStreamToken = 0
 
- Static Public Attributes inherited from AudioIOBase
static const int StandardRates []
 Array of common audio sample rates. More...
 
static const int NumStandardRates = WXSIZEOF(AudioIOBase::StandardRates)
 How many standard sample rates there are. More...
 

Protected Member Functions

float GetMixerOutputVol ()
 
void SetMixerOutputVol (float value)
 
void SetRecordingException ()
 
void ClearRecordingException ()
 

Static Protected Member Functions

static size_t MinValue (const RingBuffers &buffers, size_t(RingBuffer::*pmf)() const)
 
- Static Protected Member Functions inherited from AudioIOBase
static wxString DeviceName (const PaDeviceInfo *info)
 
static wxString HostName (const PaDeviceInfo *info)
 
static int getRecordDevIndex (const wxString &devName={})
 get the index of the supplied (named) recording device, or the device selected in the preferences if none given. More...
 
static int getPlayDevIndex (const wxString &devName={})
 get the index of the device selected in the preferences. More...
 

Protected Attributes

std::weak_ptr< AudioIOListenermListener
 
bool mUsingAlsa { false }
 
bool mUsingJack { false }
 
wxMutex mSuspendAudioThread
 
wxAtomicInt mRecordingException {}
 
std::vector< std::pair< double, double > > mLostCaptureIntervals
 
bool mDetectDropouts { true }
 
RecordingSchedule mRecordingSchedule {}
 
PlaybackSchedule mPlaybackSchedule
 
std::unique_ptr< TransportStatempTransportState
 Holds some state for duration of playback or recording. More...
 
- Protected Attributes inherited from AudioIOBase
std::weak_ptr< AudacityProjectmOwningProject
 
std::atomic< bool > mPaused { false }
 True if audio playback is paused. More...
 
int mStreamToken { 0 }
 
double mRate
 Audio playback rate in samples per second. More...
 
PaStreammPortStreamV19
 
std::weak_ptr< MetermInputMeter {}
 
std::weak_ptr< MetermOutputMeter {}
 
bool mInputMixerWorks
 Can we control the hardware input level? More...
 
std::vector< std::unique_ptr< AudioIOExtBase > > mAudioIOExt
 

Static Protected Attributes

static double mCachedBestRateOut
 
static bool mCachedBestRatePlaying
 
static bool mCachedBestRateCapturing
 
- Static Protected Attributes inherited from AudioIOBase
static std::unique_ptr< AudioIOBaseugAudioIO
 
static int mCachedPlaybackIndex = -1
 
static std::vector< long > mCachedPlaybackRates
 
static int mCachedCaptureIndex = -1
 
static std::vector< long > mCachedCaptureRates
 
static std::vector< long > mCachedSampleRates
 
static double mCachedBestRateIn = 0.0
 
static const int RatesToTry []
 Array of audio sample rates to try to use. More...
 
static const int NumRatesToTry = WXSIZEOF(AudioIOBase::RatesToTry)
 How many sample rates to try. More...
 

Private Attributes

std::vector< std::unique_ptr< AudioIOExtBase > > mAudioIOExt
 

Additional Inherited Members

- Static Public Member Functions inherited from AudioIOBase
static AudioIOBaseGet ()
 
static std::vector< long > GetSupportedPlaybackRates (int DevIndex=-1, double rate=0.0)
 Get a list of sample rates the output (playback) device supports. More...
 
static std::vector< long > GetSupportedCaptureRates (int devIndex=-1, double rate=0.0)
 Get a list of sample rates the input (recording) device supports. More...
 
static std::vector< long > GetSupportedSampleRates (int playDevice=-1, int recDevice=-1, double rate=0.0)
 Get a list of sample rates the current input/output device combination supports. More...
 
static int GetOptimalSupportedSampleRate ()
 Get a supported sample rate which can be used a an optimal default. More...
 

Detailed Description

AudioIoCallback is a class that implements the callback required by PortAudio. The callback needs to be responsive, has no GUI, and copies data into and out of the sound card buffers. It also sends data to the meters.

Definition at line 109 of file AudioIO.h.

Member Typedef Documentation

◆ OldChannelGains

using AudioIoCallback::OldChannelGains = std::array<float, 2>

Definition at line 185 of file AudioIO.h.

◆ RingBuffers

using AudioIoCallback::RingBuffers = std::vector<std::unique_ptr<RingBuffer> >

Definition at line 271 of file AudioIO.h.

Constructor & Destructor Documentation

◆ AudioIoCallback()

AudioIoCallback::AudioIoCallback ( )

Definition at line 3089 of file AudioIO.cpp.

3090{
3091 auto &factories = AudioIOExt::GetFactories();
3092 for (auto &factory: factories)
3093 if (auto pExt = factory(mPlaybackSchedule))
3094 mAudioIOExt.push_back( move(pExt) );
3095}
static Factories & GetFactories()
Definition: AudioIOExt.cpp:15
PlaybackSchedule mPlaybackSchedule
Definition: AudioIO.h:404
std::vector< std::unique_ptr< AudioIOExtBase > > mAudioIOExt
Definition: AudioIOBase.h:322
static RegisteredToolbarFactory factory

References cloud::factory, AudioIOExt::GetFactories(), mAudioIOExt, and mPlaybackSchedule.

Here is the call graph for this function:

◆ ~AudioIoCallback()

AudioIoCallback::~AudioIoCallback ( )

Definition at line 3098 of file AudioIO.cpp.

3099{
3100}

Member Function Documentation

◆ AddToOutputChannel()

void AudioIoCallback::AddToOutputChannel ( unsigned int  chan,
float *  outputMeterFloats,
float *  outputFloats,
const float *  tempBuf,
bool  drop,
unsigned long  len,
const PlayableSequence ps,
float &  channelGain 
)
Parameters
[in,out]channelGain

Definition at line 2571 of file AudioIO.cpp.

2579{
2580 const auto numPlaybackChannels = mNumPlaybackChannels;
2581
2582 float gain = ps.GetChannelGain(chan);
2583 if (drop || mForceFadeOut.load(std::memory_order_relaxed) || IsPaused())
2584 gain = 0.0;
2585
2586 // Output volume emulation: possibly copy meter samples, then
2587 // apply volume, then copy to the output buffer
2588 if (outputMeterFloats != outputFloats)
2589 for ( unsigned i = 0; i < len; ++i)
2590 outputMeterFloats[numPlaybackChannels*i+chan] +=
2591 gain*tempBuf[i];
2592
2593 // DV: We use gain to emulate panning.
2594 // Let's keep the old behavior for panning.
2595 gain *= ExpGain(GetMixerOutputVol());
2596
2597 float oldGain = channelGain;
2598 channelGain = gain;
2599 // if no microfades, jump in volume.
2600 if (!mbMicroFades)
2601 oldGain = gain;
2602 wxASSERT(len > 0);
2603
2604 // Linear interpolate.
2605 // PRL todo: choose denominator differently, so it doesn't depend on
2606 // framesPerBuffer, which is influenced by the portAudio implementation in
2607 // opaque ways
2608 float deltaGain = (gain - oldGain) / len;
2609 for (unsigned i = 0; i < len; i++)
2610 outputFloats[numPlaybackChannels*i+chan] += (oldGain + deltaGain * i) *tempBuf[i];
2611};
Type ExpGain(Type gain) noexcept
Definition: Gain.h:19
bool IsPaused() const
Find out if playback / recording is currently paused.
size_t mNumPlaybackChannels
Definition: AudioIO.h:314
bool mbMicroFades
Definition: AudioIO.h:291
float GetMixerOutputVol()
Definition: AudioIO.h:348
std::atomic< bool > mForceFadeOut
Definition: AudioIO.h:336
virtual float GetChannelGain(int channel) const =0

References ExpGain(), WideSampleSequence::GetChannelGain(), GetMixerOutputVol(), AudioIOBase::IsPaused(), mbMicroFades, mForceFadeOut, and mNumPlaybackChannels.

Referenced by FillOutputBuffers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AllSequencesAlreadySilent()

bool AudioIoCallback::AllSequencesAlreadySilent ( )

Definition at line 3078 of file AudioIO.cpp.

3079{
3080 for (size_t ii = 0, nn = mPlaybackSequences.size(); ii < nn; ++ii) {
3081 auto vt = mPlaybackSequences[ii];
3082 const auto &oldGains = mOldChannelGains[ii];
3083 if (!(SequenceShouldBeSilent(*vt) && SequenceHasBeenFadedOut(oldGains)))
3084 return false;
3085 }
3086 return true;
3087}
bool SequenceShouldBeSilent(const PlayableSequence &ps)
Definition: AudioIO.cpp:3062
bool SequenceHasBeenFadedOut(const OldChannelGains &gains)
Returns true when playback buffer data from both channels is discardable.
Definition: AudioIO.cpp:3073
std::vector< OldChannelGains > mOldChannelGains
Definition: AudioIO.h:279
ConstPlayableSequences mPlaybackSequences
Definition: AudioIO.h:276

References mOldChannelGains, mPlaybackSequences, SequenceHasBeenFadedOut(), and SequenceShouldBeSilent().

Referenced by AudioCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AudioCallback()

int AudioIoCallback::AudioCallback ( constSamplePtr  inputBuffer,
float *  outputBuffer,
unsigned long  framesPerBuffer,
const PaStreamCallbackTimeInfo *  timeInfo,
const PaStreamCallbackFlags  statusFlags,
void *  userData 
)

Definition at line 3103 of file AudioIO.cpp.

3108{
3109 // Poll sequences for change of state.
3110 // (User might click mute and solo buttons.)
3112 mCallbackReturn = paContinue;
3113
3114 if (IsPaused()
3115 // PRL: Why was this added? Was it only because of the mysterious
3116 // initial leading zeroes, now solved by setting mStreamToken early?
3117 // JKC: I think it's used for the MIDI time cursor. See comments
3118 // at head of file about AudioTime().
3119 || mStreamToken <= 0
3120 )
3121 mNumPauseFrames += framesPerBuffer;
3122
3123 for( auto &ext : Extensions() ) {
3124 ext.ComputeOtherTimings(mRate, IsPaused(),
3125 timeInfo,
3126 framesPerBuffer);
3127 ext.FillOtherBuffers(
3129 }
3130
3131 // ------ MEMORY ALLOCATIONS -----------------------------------------------
3132 // tempFloats will be a reusable scratch pad for (possibly format converted)
3133 // audio data. One temporary use is for the InputMeter data.
3134 const auto numPlaybackChannels = mNumPlaybackChannels;
3135 const auto numCaptureChannels = mNumCaptureChannels;
3136 const auto tempFloats = stackAllocate(float,
3137 framesPerBuffer * std::max(numCaptureChannels, numPlaybackChannels));
3138
3139 bool bVolEmulationActive =
3140 (outputBuffer && GetMixerOutputVol() != 1.0);
3141 // outputMeterFloats is the scratch pad for the output meter.
3142 // we can often reuse the existing outputBuffer and save on allocating
3143 // something new.
3144 const auto outputMeterFloats = bVolEmulationActive
3145 ? stackAllocate(float, framesPerBuffer * numPlaybackChannels)
3146 : outputBuffer;
3147 // ----- END of MEMORY ALLOCATIONS ------------------------------------------
3148
3149 if (inputBuffer && numCaptureChannels) {
3150 float *inputSamples;
3151
3152 if (mCaptureFormat == floatSample) {
3153 inputSamples = (float *) inputBuffer;
3154 }
3155 else {
3156 SamplesToFloats(reinterpret_cast<constSamplePtr>(inputBuffer),
3157 mCaptureFormat, tempFloats, framesPerBuffer * numCaptureChannels);
3158 inputSamples = tempFloats;
3159 }
3160
3162 inputSamples,
3163 framesPerBuffer);
3164
3165 // This function may queue up a pause or resume.
3166 // TODO this is a bit dodgy as it toggles the Pause, and
3167 // relies on an idle event to have handled that, so could
3168 // queue up multiple toggle requests and so do nothing.
3169 // Eventually it will sort itself out by random luck, but
3170 // the net effect is a delay in starting/stopping sound activated
3171 // recording.
3173 inputSamples,
3174 framesPerBuffer);
3175 }
3176
3177 // Even when paused, we do playthrough.
3178 // Initialise output buffer to zero or to playthrough data.
3179 // Initialise output meter values.
3181 inputBuffer,
3182 outputBuffer,
3183 framesPerBuffer,
3184 outputMeterFloats);
3185
3186 // Test for no sequence audio to play (because we are paused and have faded
3187 // out)
3188 if( IsPaused() && (( !mbMicroFades ) || AllSequencesAlreadySilent() ))
3189 return mCallbackReturn;
3190
3191 // To add sequence output to output (to play sound on speaker)
3192 // possible exit, if we were seeking.
3194 outputBuffer,
3195 framesPerBuffer,
3196 outputMeterFloats))
3197 return mCallbackReturn;
3198
3199 // To move the cursor onwards. (uses mMaxFramesOutput)
3200 UpdateTimePosition(framesPerBuffer);
3201
3202 // To capture input into sequence (sound from microphone)
3204 inputBuffer,
3205 framesPerBuffer,
3206 statusFlags,
3207 tempFloats);
3208
3209 SendVuOutputMeterData( outputMeterFloats, framesPerBuffer);
3210
3211 return mCallbackReturn;
3212}
#define stackAllocate(T, count)
Definition: AudioIO.cpp:2055
void SamplesToFloats(constSamplePtr src, sampleFormat srcFormat, float *dst, size_t len, size_t srcStride, size_t dstStride)
Copy samples from any format into the widest format, which is 32 bit float, with no dithering.
const char * constSamplePtr
Definition: SampleFormat.h:58
double mRate
Audio playback rate in samples per second.
Definition: AudioIOBase.h:255
int mStreamToken
Definition: AudioIOBase.h:251
unsigned CountSoloingSequences()
Definition: AudioIO.cpp:3041
bool AllSequencesAlreadySilent()
Definition: AudioIO.cpp:3078
AudioIOExtRange Extensions()
Definition: AudioIO.h:161
void CheckSoundActivatedRecordingLevel(float *inputSamples, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2543
void UpdateTimePosition(unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2788
int mbHasSoloSequences
Definition: AudioIO.h:180
int mCallbackReturn
Definition: AudioIO.h:181
long mNumPauseFrames
How many frames of zeros were output due to pauses?
Definition: AudioIO.h:247
void DrainInputBuffers(constSamplePtr inputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackFlags statusFlags, float *tempFloats)
Definition: AudioIO.cpp:2803
void SendVuInputMeterData(const float *inputSamples, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2997
void SendVuOutputMeterData(const float *outputMeterFloats, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:3013
void DoPlaythrough(constSamplePtr inputBuffer, float *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
Definition: AudioIO.cpp:2961
bool FillOutputBuffers(float *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
Definition: AudioIO.cpp:2625
size_t mNumCaptureChannels
Definition: AudioIO.h:312
sampleFormat mCaptureFormat
Definition: AudioIO.h:315

References AllSequencesAlreadySilent(), CheckSoundActivatedRecordingLevel(), CountSoloingSequences(), DoPlaythrough(), DrainInputBuffers(), Extensions(), FillOutputBuffers(), floatSample, GetMixerOutputVol(), AudioIOBase::IsPaused(), mbHasSoloSequences, mbMicroFades, mCallbackReturn, mCaptureFormat, mNumCaptureChannels, mNumPauseFrames, mNumPlaybackChannels, AudioIOBase::mRate, AudioIOBase::mStreamToken, SamplesToFloats(), SendVuInputMeterData(), SendVuOutputMeterData(), stackAllocate, and UpdateTimePosition().

Here is the call graph for this function:

◆ CallbackCheckCompletion()

void AudioIoCallback::CallbackCheckCompletion ( int &  callbackReturn,
unsigned long  len 
)

Definition at line 3278 of file AudioIO.cpp.

3280{
3281 if (IsPaused())
3282 return;
3283
3284 bool done =
3286 if (!done)
3287 return;
3288
3289 for( auto &ext : Extensions() )
3290 ext.SignalOtherCompletion();
3291 callbackReturn = paComplete;
3292}
virtual bool Done(PlaybackSchedule &schedule, unsigned long outputFrames)
Returns true if schedule.GetSequenceTime() has reached the end of playback.
PlaybackPolicy & GetPolicy()

References PlaybackPolicy::Done(), Extensions(), PlaybackSchedule::GetPolicy(), AudioIOBase::IsPaused(), and mPlaybackSchedule.

Referenced by FillOutputBuffers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CallbackDoSeek()

int AudioIoCallback::CallbackDoSeek ( )

Definition at line 3218 of file AudioIO.cpp.

3219{
3220 const int token = mStreamToken;
3221 wxMutexLocker locker(mSuspendAudioThread);
3222 if (token != mStreamToken)
3223 // This stream got destroyed while we waited for it
3224 return paAbort;
3225
3226 // Pause audio thread and wait for it to finish
3227 //
3228 // [PM] the following 8 lines of code could be probably replaced by
3229 // a single call to StopAudioThreadAndWait()
3230 //
3231 // CAUTION: when trying the above, you must also replace the setting of the
3232 // atomic before the return, with a call to StartAudioThread()
3233 //
3234 // If that works, then we can remove mAudioThreadSequenceBufferExchangeLoopActive,
3235 // as it will become unused; consequently, the AudioThread loop would get simpler too.
3236 //
3238 .store(false, std::memory_order_relaxed);
3239
3241 .load(std::memory_order_relaxed ) )
3242 {
3243 using namespace std::chrono;
3244 std::this_thread::sleep_for(50ms);
3245 }
3246
3247 // Calculate the NEW time position, in the PortAudio callback
3248 const auto time =
3250
3252 mSeek = 0.0;
3253
3254
3255 // Reset mixer positions and flush buffers for all sequences
3256 for (auto &mixer : mPlaybackMixers)
3257 mixer->Reposition( time, true );
3258 for (auto &buffer : mPlaybackBuffers) {
3259 const auto toDiscard = buffer->AvailForGet();
3260 const auto discarded = buffer->Discard( toDiscard );
3261 // wxASSERT( discarded == toDiscard );
3262 // but we can't assert in this thread
3263 wxUnusedVar(discarded);
3264 }
3265
3267
3268 // Reload the ring buffers
3270
3271 // Reenable the audio thread
3273 .store(true, std::memory_order_relaxed);
3274
3275 return paContinue;
3276}
std::atomic< bool > mAudioThreadSequenceBufferExchangeLoopRunning
Definition: AudioIO.h:319
double mSeek
Definition: AudioIO.h:293
wxMutex mSuspendAudioThread
Definition: AudioIO.h:368
std::vector< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:284
std::atomic< bool > mAudioThreadSequenceBufferExchangeLoopActive
Definition: AudioIO.h:320
RingBuffers mPlaybackBuffers
Definition: AudioIO.h:275
void ProcessOnceAndWait(std::chrono::milliseconds sleepTime=std::chrono::milliseconds(50))
Definition: AudioIO.cpp:3332
virtual double OffsetSequenceTime(PlaybackSchedule &schedule, double offset)
Called when the play head needs to jump a certain distance.
void Prime(double time)
Empty the queue and reassign the last produced time.
void SetSequenceTime(double time)
Set current track time value, unadjusted.
class AUDIO_IO_API PlaybackSchedule::TimeQueue mTimeQueue

References PlaybackSchedule::GetPolicy(), mAudioThreadSequenceBufferExchangeLoopActive, mAudioThreadSequenceBufferExchangeLoopRunning, mPlaybackBuffers, mPlaybackMixers, mPlaybackSchedule, mSeek, AudioIOBase::mStreamToken, mSuspendAudioThread, PlaybackSchedule::mTimeQueue, PlaybackPolicy::OffsetSequenceTime(), PlaybackSchedule::TimeQueue::Prime(), ProcessOnceAndWait(), and PlaybackSchedule::SetSequenceTime().

Referenced by FillOutputBuffers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CheckSoundActivatedRecordingLevel()

void AudioIoCallback::CheckSoundActivatedRecordingLevel ( float *  inputSamples,
unsigned long  framesPerBuffer 
)

Definition at line 2543 of file AudioIO.cpp.

2547{
2548 // Quick returns if next to nothing to do.
2549 if( !mPauseRec )
2550 return;
2551
2552 float maxPeak = 0.;
2553 for( unsigned long i = 0, cnt = framesPerBuffer * mNumCaptureChannels; i < cnt; ++i ) {
2554 float sample = fabs(*(inputSamples++));
2555 if (sample > maxPeak) {
2556 maxPeak = sample;
2557 }
2558 }
2559
2560 bool bShouldBePaused = maxPeak < mSilenceLevel;
2561 if( bShouldBePaused != IsPaused() )
2562 {
2563 auto pListener = GetListener();
2564 if ( pListener )
2565 pListener->OnSoundActivationThreshold();
2566 }
2567}
std::shared_ptr< AudioIOListener > GetListener() const
Definition: AudioIO.h:169
float mSilenceLevel
Definition: AudioIO.h:310
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:309

References GetListener(), AudioIOBase::IsPaused(), mNumCaptureChannels, mPauseRec, and mSilenceLevel.

Referenced by AudioCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearRecordingException()

void AudioIoCallback::ClearRecordingException ( )
inlineprotected

Definition at line 383 of file AudioIO.h.

384 { if (mRecordingException) wxAtomicDec( mRecordingException ); }
wxAtomicInt mRecordingException
Definition: AudioIO.h:380

Referenced by AudioIO::StartStream(), and AudioIO::StopStream().

Here is the caller graph for this function:

◆ CountSoloingSequences()

unsigned AudioIoCallback::CountSoloingSequences ( )

Definition at line 3041 of file AudioIO.cpp.

3041 {
3042 const auto numPlaybackSequences = mPlaybackSequences.size();
3043
3044 // MOVE_TO: CountSoloingSequences() function
3045 unsigned numSolo = 0;
3046 for (unsigned t = 0; t < numPlaybackSequences; t++ )
3047 if (mPlaybackSequences[t]->GetSolo())
3048 numSolo++;
3049 auto range = Extensions();
3050 numSolo += std::accumulate(range.begin(), range.end(), 0,
3051 [](unsigned sum, auto &ext){
3052 return sum + ext.CountOtherSolo(); });
3053 return numSolo;
3054}

References Extensions(), and mPlaybackSequences.

Referenced by AudioCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoPlaythrough()

void AudioIoCallback::DoPlaythrough ( constSamplePtr  inputBuffer,
float *  outputBuffer,
unsigned long  framesPerBuffer,
float *  outputMeterFloats 
)

Definition at line 2961 of file AudioIO.cpp.

2967{
2968 const auto numCaptureChannels = mNumCaptureChannels;
2969 const auto numPlaybackChannels = mNumPlaybackChannels;
2970
2971 // Quick returns if next to nothing to do.
2972 if( !outputBuffer )
2973 return;
2974 if( numPlaybackChannels <= 0 )
2975 return;
2976
2977 float *outputFloats = outputBuffer;
2978 for(unsigned i = 0; i < framesPerBuffer*numPlaybackChannels; i++)
2979 outputFloats[i] = 0.0;
2980
2981 if (inputBuffer && mSoftwarePlaythrough) {
2983 numCaptureChannels,
2984 outputBuffer, framesPerBuffer);
2985 }
2986
2987 // Copy the results to outputMeterFloats if necessary
2988 if (outputMeterFloats != outputFloats) {
2989 for (unsigned i = 0; i < framesPerBuffer*numPlaybackChannels; ++i) {
2990 outputMeterFloats[i] = outputFloats[i];
2991 }
2992 }
2993}
static void DoSoftwarePlaythrough(constSamplePtr inputBuffer, sampleFormat inputFormat, unsigned inputChannels, float *outputBuffer, unsigned long len)
Definition: AudioIO.cpp:2505
bool mSoftwarePlaythrough
Definition: AudioIO.h:306

References DoSoftwarePlaythrough(), mCaptureFormat, mNumCaptureChannels, mNumPlaybackChannels, and mSoftwarePlaythrough.

Referenced by AudioCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DrainInputBuffers()

void AudioIoCallback::DrainInputBuffers ( constSamplePtr  inputBuffer,
unsigned long  framesPerBuffer,
const PaStreamCallbackFlags  statusFlags,
float *  tempFloats 
)

Definition at line 2803 of file AudioIO.cpp.

2809{
2810 const auto numPlaybackChannels = mNumPlaybackChannels;
2811 const auto numCaptureChannels = mNumCaptureChannels;
2812
2813 // Quick returns if next to nothing to do.
2814 if (mStreamToken <= 0)
2815 return;
2816 if( !inputBuffer )
2817 return;
2818 if( numCaptureChannels <= 0 )
2819 return;
2820
2821 // If there are no playback sequences, and we are recording, then the
2822 // earlier checks for being past the end won't happen, so do it here.
2824 mCallbackReturn = paComplete;
2825 }
2826
2827 // The error likely from a too-busy CPU falling behind real-time data
2828 // is paInputOverflow
2829 bool inputError =
2830 (statusFlags & (paInputOverflow))
2831 && !(statusFlags & paPrimingOutput);
2832
2833 // But it seems it's easy to get false positives, at least on Mac
2834 // So we have not decided to enable this extra detection yet in
2835 // production
2836
2837 size_t len = framesPerBuffer;
2838 for(unsigned t = 0; t < numCaptureChannels; t++)
2839 len = std::min( len, mCaptureBuffers[t]->AvailForPut() );
2840
2841 if (mSimulateRecordingErrors && 100LL * rand() < RAND_MAX)
2842 // Make spurious errors for purposes of testing the error
2843 // reporting
2844 len = 0;
2845
2846 // A different symptom is that len < framesPerBuffer because
2847 // the other thread, executing SequenceBufferExchange, isn't consuming fast
2848 // enough from mCaptureBuffers; maybe it's CPU-bound, or maybe the
2849 // storage device it writes is too slow
2850 if (mDetectDropouts &&
2851 ((mDetectUpstreamDropouts.load(std::memory_order_relaxed)
2852 && inputError) ||
2853 len < framesPerBuffer) ) {
2854 // Assume that any good partial buffer should be written leftmost
2855 // and zeroes will be padded after; label the zeroes.
2856 auto start = mPlaybackSchedule.GetSequenceTime() +
2858 auto duration = (framesPerBuffer - len) / mRate;
2859 auto pLast = mLostCaptureIntervals.empty()
2860 ? nullptr : &mLostCaptureIntervals.back();
2861 if (pLast &&
2862 fabs(pLast->first + pLast->second - start) < 0.5/mRate)
2863 // Make one bigger interval, not two butting intervals
2864 pLast->second = start + duration - pLast->first;
2865 else
2866 mLostCaptureIntervals.emplace_back( start, duration );
2867 }
2868
2869 if (len < framesPerBuffer)
2870 {
2871 mLostSamples += (framesPerBuffer - len);
2872 wxPrintf(wxT("lost %d samples\n"), (int)(framesPerBuffer - len));
2873 }
2874
2875 if (len <= 0)
2876 return;
2877
2878 // We have an ASSERT in the AudioIO constructor to alert us to
2879 // possible issues with the (short*) cast. We'd have a problem if
2880 // sizeof(short) > sizeof(float) since our buffers are sized for floats.
2881 for(unsigned t = 0; t < numCaptureChannels; t++) {
2882
2883 // dmazzoni:
2884 // Un-interleave. Ugly special-case code required because the
2885 // capture channels could be in three different sample formats;
2886 // it'd be nice to be able to call CopySamples, but it can't
2887 // handle multiplying by the gain and then clipping. Bummer.
2888
2889 switch(mCaptureFormat) {
2890 case floatSample: {
2891 auto inputFloats = (const float *)inputBuffer;
2892 for(unsigned i = 0; i < len; i++)
2893 tempFloats[i] =
2894 inputFloats[numCaptureChannels*i+t];
2895 } break;
2896 case int24Sample:
2897 // We should never get here. Audacity's int24Sample format
2898 // is different from PortAudio's sample format and so we
2899 // make PortAudio return float samples when recording in
2900 // 24-bit samples.
2901 wxASSERT(false);
2902 break;
2903 case int16Sample: {
2904 auto inputShorts = (const short *)inputBuffer;
2905 short *tempShorts = (short *)tempFloats;
2906 for( unsigned i = 0; i < len; i++) {
2907 float tmp = inputShorts[numCaptureChannels*i+t];
2908 tmp = std::clamp(tmp, -32768.0f, 32767.0f);
2909 tempShorts[i] = (short)(tmp);
2910 }
2911 } break;
2912 } // switch
2913
2914 // JKC: mCaptureFormat must be for samples with sizeof(float) or
2915 // fewer bytes (because tempFloats is sized for floats). All
2916 // formats are 2 or 4 bytes, so we are OK.
2917 const auto put =
2918 mCaptureBuffers[t]->Put(
2919 (samplePtr)tempFloats, mCaptureFormat, len);
2920 // wxASSERT(put == len);
2921 // but we can't assert in this thread
2922 wxUnusedVar(put);
2923 mCaptureBuffers[t]->Flush();
2924 }
2925}
wxT("CloseDown"))
int min(int a, int b)
char * samplePtr
Definition: SampleFormat.h:57
RecordingSchedule mRecordingSchedule
Definition: AudioIO.h:403
RingBuffers mCaptureBuffers
Definition: AudioIO.h:272
bool mDetectDropouts
Definition: AudioIO.h:388
bool mSimulateRecordingErrors
Definition: AudioIO.h:396
std::atomic< bool > mDetectUpstreamDropouts
Definition: AudioIO.h:400
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:386
unsigned long long mLostSamples
Definition: AudioIO.h:317
double GetSequenceTime() const
Get current track time value, unadjusted.

References PlaybackPolicy::Done(), floatSample, PlaybackSchedule::GetPolicy(), PlaybackSchedule::GetSequenceTime(), int16Sample, int24Sample, mCallbackReturn, mCaptureBuffers, mCaptureFormat, mDetectDropouts, mDetectUpstreamDropouts, min(), RecordingSchedule::mLatencyCorrection, mLostCaptureIntervals, mLostSamples, mNumCaptureChannels, mNumPlaybackChannels, mPlaybackSchedule, AudioIOBase::mRate, mRecordingSchedule, mSimulateRecordingErrors, AudioIOBase::mStreamToken, and wxT().

Referenced by AudioCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Extensions()

AudioIOExtRange AudioIoCallback::Extensions ( )
inline

Definition at line 161 of file AudioIO.h.

161 {
162 return {
163 AudioIOExtIterator{ *this, false },
164 AudioIOExtIterator{ *this, true }
165 };
166 }

Referenced by AudioCallback(), CallbackCheckCompletion(), CountSoloingSequences(), AudioIO::StartStream(), and AudioIO::StopStream().

Here is the caller graph for this function:

◆ FillOutputBuffers()

bool AudioIoCallback::FillOutputBuffers ( float *  outputBuffer,
unsigned long  framesPerBuffer,
float *  outputMeterFloats 
)

Definition at line 2625 of file AudioIO.cpp.

2630{
2631 const auto numPlaybackSequences = mPlaybackSequences.size();
2632 const auto numPlaybackChannels = mNumPlaybackChannels;
2633 const auto numCaptureChannels = mNumCaptureChannels;
2634
2635 mMaxFramesOutput = 0;
2636
2637 // Quick returns if next to nothing to do.
2638 if (mStreamToken <= 0 ||
2639 !outputBuffer ||
2640 numPlaybackChannels <= 0) {
2641 // So that UpdateTimePosition() will be correct, in case of MIDI play with
2642 // no audio output channels
2643 mMaxFramesOutput = framesPerBuffer;
2644 return false;
2645 }
2646
2647 float *outputFloats = outputBuffer;
2648
2650 mSeek = 0.0;
2651
2652 if (mSeek){
2654 return true;
2655 }
2656
2657 // ------ MEMORY ALLOCATION ----------------------
2658 // These are small structures.
2659 const auto tempBufs = stackAllocate(float *, numPlaybackChannels);
2660
2661 // And these are larger structures....
2662 for (unsigned int c = 0; c < numPlaybackChannels; c++)
2663 tempBufs[c] = stackAllocate(float, framesPerBuffer);
2664 // ------ End of MEMORY ALLOCATION ---------------
2665
2666 // Choose a common size to take from all ring buffers
2667 const auto toGet =
2668 std::min<size_t>(framesPerBuffer, GetCommonlyReadyPlayback());
2669
2670 // The drop and dropQuickly booleans are so named for historical reasons.
2671 // JKC: The original code attempted to be faster by doing nothing on silenced audio.
2672 // This, IMHO, is 'premature optimisation'. Instead clearer and cleaner code would
2673 // simply use a gain of 0.0 for silent audio and go on through to the stage of
2674 // applying that 0.0 gain to the data mixed into the buffer.
2675 // Then (and only then) we would have if needed fast paths for:
2676 // - Applying a uniform gain of 0.0.
2677 // - Applying a uniform gain of 1.0.
2678 // - Applying some other uniform gain.
2679 // - Applying a linearly interpolated gain.
2680 // I would expect us not to need the fast paths, since linearly interpolated gain
2681 // is very cheap to process.
2682
2683 bool drop = false; // Sequence should become silent.
2684 bool discardable = false; // Sequence has already been faded to silence.
2685 // mPlaybackBuffers buffers correspond many-to-one with mPlaybackSequences
2686 size_t iBuffer = 0;
2687 for (unsigned tt = 0; tt < numPlaybackSequences; ++tt) {
2688 auto vt = mPlaybackSequences[tt].get();
2689 const auto width = vt->NChannels();
2690
2691 // IF mono THEN clear 'the other' channel.
2692 if (width < numPlaybackChannels)
2693 // TODO: more-than-two-channels
2694 memset(tempBufs[1], 0, framesPerBuffer * sizeof(float));
2695
2696 // Check for asynchronous user changes in mute, solo, pause status
2697 discardable = drop = SequenceShouldBeSilent(*vt);
2698
2699 if (mbMicroFades)
2700 // If micro fading, don't silence tracks instantaneously
2701 discardable = discardable &&
2703
2704 decltype(framesPerBuffer) len = 0;
2705
2706 for (size_t c = 0; c < width; ++c) {
2707 if (discardable) {
2708 len = mPlaybackBuffers[iBuffer]->Discard(toGet);
2709 // keep going here.
2710 // we may still need to issue a paComplete.
2711
2712 // Keep tempBufs initialized to avoid NaNs and Infs
2713 memset(tempBufs[c], 0, framesPerBuffer * sizeof(float));
2714 }
2715 else {
2716 len = mPlaybackBuffers[iBuffer]
2717 ->Get((samplePtr)tempBufs[c], floatSample, toGet);
2718 // wxASSERT( len == toGet );
2719 if (len < framesPerBuffer)
2720 // This used to happen normally at the end of non-looping
2721 // plays, but it can also be an anomalous case where the
2722 // supply from SequenceBufferExchange fails to keep up with the
2723 // real-time demand in this thread (see bug 1932). We
2724 // must supply something to the sound card, so pad it with
2725 // zeroes and not random garbage.
2726 memset((void*)&tempBufs[c][len], 0,
2727 (framesPerBuffer - len) * sizeof(float));
2728 }
2729 ++iBuffer;
2730 }
2731
2732 // PRL: More recent rewrites of SequenceBufferExchange should guarantee a
2733 // padding out of the ring buffers so that equal lengths are
2734 // available, so maxLen ought to increase from 0 only once
2735 mMaxFramesOutput = std::max(mMaxFramesOutput, len);
2736
2737 len = mMaxFramesOutput;
2738
2739 // Realtime effect transformation of the sound used to happen here
2740 // but it is now done already on the producer side of the RingBuffer
2741
2742 // Mix the results with the existing output (software playthrough) and
2743 // apply panning. If post panning effects are desired, the panning would
2744 // need to be be split out from the mixing and applied in a separate step.
2745
2746 // Our channels aren't silent. We need to pass their data on.
2747 //
2748 // Each channel in the sequences can output to more than one channel on
2749 // the device. For example mono channels output to both left and right
2750 // output channels.
2751 if (len > 0) {
2752 auto &gains = mOldChannelGains[tt];
2753 AddToOutputChannel(0, outputMeterFloats, outputFloats,
2754 tempBufs[0], drop, len, *vt, gains[0]);
2755
2756 // If one of mPlaybackSequences is mono, this replicates it in both
2757 // device channels
2758 const auto iBuffer = std::min<size_t>(1, width - 1);
2759 AddToOutputChannel(1, outputMeterFloats, outputFloats,
2760 tempBufs[iBuffer], drop, len, *vt, gains[1]);
2761 }
2762
2764 if (discardable) // no samples to process, they've been discarded
2765 continue;
2766 }
2767
2768 // Poke: If there are no playback sequences, then the earlier check
2769 // about the time indicator being past the end won't happen;
2770 // do it here instead (but not if looping or scrubbing)
2771 // PRL: Also consume from the single playback ring buffer
2772 if (numPlaybackSequences == 0) {
2773 mMaxFramesOutput = mPlaybackBuffers[0]->Discard(toGet);
2775 }
2776
2777 // wxASSERT( maxLen == toGet );
2778
2779 mLastPlaybackTimeMillis = ::wxGetUTCTimeMillis();
2780
2781 ClampBuffer( outputFloats, framesPerBuffer*numPlaybackChannels );
2782 if (outputMeterFloats != outputFloats)
2783 ClampBuffer( outputMeterFloats, framesPerBuffer*numPlaybackChannels );
2784
2785 return false;
2786}
void ClampBuffer(float *pBuffer, unsigned long len)
Definition: AudioIO.cpp:2614
void CallbackCheckCompletion(int &callbackReturn, unsigned long len)
Definition: AudioIO.cpp:3278
void AddToOutputChannel(unsigned int chan, float *outputMeterFloats, float *outputFloats, const float *tempBuf, bool drop, unsigned long len, const PlayableSequence &ps, float &channelGain)
Definition: AudioIO.cpp:2571
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:338
int CallbackDoSeek()
Definition: AudioIO.cpp:3218
unsigned long mMaxFramesOutput
Definition: AudioIO.h:289
size_t GetCommonlyReadyPlayback()
Get the number of audio samples ready in all of the playback buffers.
Definition: AudioIO.cpp:1884
virtual bool AllowSeek(PlaybackSchedule &schedule)
Whether repositioning commands are allowed during playback.

References AddToOutputChannel(), PlaybackPolicy::AllowSeek(), CallbackCheckCompletion(), CallbackDoSeek(), ClampBuffer(), floatSample, GetCommonlyReadyPlayback(), PlaybackSchedule::GetPolicy(), mbMicroFades, mCallbackReturn, mLastPlaybackTimeMillis, mMaxFramesOutput, mNumCaptureChannels, mNumPlaybackChannels, mOldChannelGains, mPlaybackBuffers, mPlaybackSchedule, mPlaybackSequences, mSeek, AudioIOBase::mStreamToken, SequenceHasBeenFadedOut(), SequenceShouldBeSilent(), and stackAllocate.

Referenced by AudioCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetCommonlyReadyPlayback()

size_t AudioIoCallback::GetCommonlyReadyPlayback ( )

Get the number of audio samples ready in all of the playback buffers.

Returns the smallest of the buffer ready space values in the event that they are different.

Definition at line 1884 of file AudioIO.cpp.

1885{
1887}
static size_t MinValue(const RingBuffers &buffers, size_t(RingBuffer::*pmf)() const)
Definition: AudioIO.cpp:1867
size_t AvailForGet() const
Definition: RingBuffer.cpp:226

References RingBuffer::AvailForGet(), MinValue(), and mPlaybackBuffers.

Referenced by FillOutputBuffers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetCommonlyWrittenForPlayback()

size_t AudioIoCallback::GetCommonlyWrittenForPlayback ( )

Definition at line 1889 of file AudioIO.cpp.

1890{
1892}
size_t WrittenForGet() const
Reader may concurrently cause a decrease of what this returns.
Definition: RingBuffer.cpp:73

References MinValue(), mPlaybackBuffers, and RingBuffer::WrittenForGet().

Referenced by AudioIO::FillPlayBuffers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetListener()

std::shared_ptr< AudioIOListener > AudioIoCallback::GetListener ( ) const
inline

Definition at line 169 of file AudioIO.h.

170 { return mListener.lock(); }
std::weak_ptr< AudioIOListener > mListener
Definition: AudioIO.h:356

Referenced by CheckSoundActivatedRecordingLevel(), AudioIO::DrainRecordBuffers(), AudioIO::StartMonitoring(), AudioIO::StartStream(), and AudioIO::StopStream().

Here is the caller graph for this function:

◆ GetMixerOutputVol()

float AudioIoCallback::GetMixerOutputVol ( )
inlineprotected

Definition at line 348 of file AudioIO.h.

348 {
349 return mMixerOutputVol.load(std::memory_order_relaxed); }
std::atomic< float > mMixerOutputVol
Definition: AudioIO.h:286

Referenced by AddToOutputChannel(), AudioCallback(), and AudioIO::GetMixer().

Here is the caller graph for this function:

◆ HasRecordingException()

bool AudioIoCallback::HasRecordingException ( ) const
inline

Definition at line 374 of file AudioIO.h.

375 { return mRecordingException; }

Referenced by ProjectAudioManager::OnAudioIOStopRecording().

Here is the caller graph for this function:

◆ LostCaptureIntervals()

const std::vector< std::pair< double, double > > & AudioIoCallback::LostCaptureIntervals ( )
inline

Definition at line 392 of file AudioIO.h.

393 { return mLostCaptureIntervals; }

◆ MinValue()

size_t AudioIoCallback::MinValue ( const RingBuffers buffers,
size_t(RingBuffer::*)() const  pmf 
)
staticprotected

Definition at line 1867 of file AudioIO.cpp.

1869{
1870 return std::accumulate(buffers.begin(), buffers.end(),
1871 std::numeric_limits<size_t>::max(),
1872 [pmf](auto value, auto &pBuffer){
1873 return std::min(value, (pBuffer.get()->*pmf)()); });
1874}

Referenced by AudioIO::GetCommonlyAvailCapture(), AudioIO::GetCommonlyFreePlayback(), GetCommonlyReadyPlayback(), and GetCommonlyWrittenForPlayback().

Here is the caller graph for this function:

◆ ProcessOnceAndWait()

void AudioIoCallback::ProcessOnceAndWait ( std::chrono::milliseconds  sleepTime = std::chrono::milliseconds(50))

Definition at line 3332 of file AudioIO.cpp.

3333{
3335 .store(true, std::memory_order_release);
3336
3338 .load(std::memory_order_acquire))
3339 {
3340 using namespace std::chrono;
3341 std::this_thread::sleep_for(sleepTime);
3342 }
3343}
std::atomic< bool > mAudioThreadShouldCallSequenceBufferExchangeOnce
Definition: AudioIO.h:318

References mAudioThreadShouldCallSequenceBufferExchangeOnce.

Referenced by CallbackDoSeek(), and AudioIO::StopStream().

Here is the caller graph for this function:

◆ SendVuInputMeterData()

void AudioIoCallback::SendVuInputMeterData ( const float *  inputSamples,
unsigned long  framesPerBuffer 
)

Definition at line 2997 of file AudioIO.cpp.

3001{
3002 const auto numCaptureChannels = mNumCaptureChannels;
3003 auto pInputMeter = mInputMeter.lock();
3004 if ( !pInputMeter )
3005 return;
3006 if( pInputMeter->IsMeterDisabled())
3007 return;
3008 pInputMeter->UpdateDisplay(
3009 numCaptureChannels, framesPerBuffer, inputSamples);
3010}
std::weak_ptr< Meter > mInputMeter
Definition: AudioIOBase.h:259

References AudioIOBase::mInputMeter, and mNumCaptureChannels.

Referenced by AudioCallback().

Here is the caller graph for this function:

◆ SendVuOutputMeterData()

void AudioIoCallback::SendVuOutputMeterData ( const float *  outputMeterFloats,
unsigned long  framesPerBuffer 
)

Definition at line 3013 of file AudioIO.cpp.

3016{
3017 const auto numPlaybackChannels = mNumPlaybackChannels;
3018
3019 auto pOutputMeter = mOutputMeter.lock();
3020 if (!pOutputMeter)
3021 return;
3022 if( pOutputMeter->IsMeterDisabled() )
3023 return;
3024 if( !outputMeterFloats)
3025 return;
3026 pOutputMeter->UpdateDisplay(
3027 numPlaybackChannels, framesPerBuffer, outputMeterFloats);
3028
3029 //v Vaughan, 2011-02-25: Moved this update back to TrackPanel::OnTimer()
3030 // as it helps with playback issues reported by Bill and noted on Bug 258.
3031 // The problem there occurs if Software Playthrough is on.
3032 // Could conditionally do the update here if Software Playthrough is off,
3033 // and in TrackPanel::OnTimer() if Software Playthrough is on, but not now.
3034 // PRL 12 Jul 2015: and what was in TrackPanel::OnTimer is now handled by means of track panel timer events
3035 //MixerBoard* pMixerBoard = mOwningProject->GetMixerBoard();
3036 //if (pMixerBoard)
3037 // pMixerBoard->UpdateMeters(GetStreamTime(),
3038 // (pProj->GetControlToolBar()->GetLastPlayMode() == loopedPlay));
3039}
std::weak_ptr< Meter > mOutputMeter
Definition: AudioIOBase.h:260

References mNumPlaybackChannels, and AudioIOBase::mOutputMeter.

Referenced by AudioCallback().

Here is the caller graph for this function:

◆ SequenceHasBeenFadedOut()

bool AudioIoCallback::SequenceHasBeenFadedOut ( const OldChannelGains gains)

Returns true when playback buffer data from both channels is discardable.

Definition at line 3073 of file AudioIO.cpp.

3074{
3075 return gains[0] == 0.0 && gains[1] == 0.0;
3076}

Referenced by AllSequencesAlreadySilent(), and FillOutputBuffers().

Here is the caller graph for this function:

◆ SequenceShouldBeSilent()

bool AudioIoCallback::SequenceShouldBeSilent ( const PlayableSequence ps)

Definition at line 3062 of file AudioIO.cpp.

3063{
3064 return IsPaused() || (!ps.GetSolo() && (
3065 // Cut if somebody else is soloing
3067 // Cut if we're muted (and not soloing)
3068 ps.GetMute()
3069 ));
3070}
virtual bool GetSolo() const =0
May vary asynchronously.
virtual bool GetMute() const =0
May vary asynchronously.

References PlayableSequence::GetMute(), PlayableSequence::GetSolo(), AudioIOBase::IsPaused(), and mbHasSoloSequences.

Referenced by AllSequencesAlreadySilent(), and FillOutputBuffers().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetListener()

void AudioIoCallback::SetListener ( const std::shared_ptr< AudioIOListener > &  listener)

Definition at line 2326 of file AudioIO.cpp.

2328{
2329 if (IsBusy())
2330 return;
2331
2332 mListener = listener;
2333}
bool IsBusy() const
Returns true if audio i/o is busy starting, stopping, playing, or recording.

References AudioIOBase::IsBusy(), and mListener.

Here is the call graph for this function:

◆ SetMixerOutputVol()

void AudioIoCallback::SetMixerOutputVol ( float  value)
inlineprotected

Definition at line 350 of file AudioIO.h.

350 {
351 mMixerOutputVol.store(value, std::memory_order_relaxed); }

Referenced by AudioIO::AudioIO(), and AudioIO::SetMixer().

Here is the caller graph for this function:

◆ SetRecordingException()

void AudioIoCallback::SetRecordingException ( )
inlineprotected

Definition at line 381 of file AudioIO.h.

382 { wxAtomicInc( mRecordingException ); }

Referenced by AudioIO::DrainRecordBuffers().

Here is the caller graph for this function:

◆ StartAudioThread()

void AudioIoCallback::StartAudioThread ( )

Definition at line 3302 of file AudioIO.cpp.

3303{
3304 mAudioThreadSequenceBufferExchangeLoopRunning.store(true, std::memory_order_release);
3305}

References mAudioThreadSequenceBufferExchangeLoopRunning.

Referenced by AudioIO::StartStream().

Here is the caller graph for this function:

◆ StopAudioThread()

void AudioIoCallback::StopAudioThread ( )

Definition at line 3317 of file AudioIO.cpp.

3318{
3319 mAudioThreadSequenceBufferExchangeLoopRunning.store(false, std::memory_order_release);
3320}

References mAudioThreadSequenceBufferExchangeLoopRunning.

Referenced by AudioIO::StartStream(), and AudioIO::StopStream().

Here is the caller graph for this function:

◆ UpdateTimePosition()

void AudioIoCallback::UpdateTimePosition ( unsigned long  framesPerBuffer)

Definition at line 2788 of file AudioIO.cpp.

2789{
2790 // Quick returns if next to nothing to do.
2791 if (mStreamToken <= 0)
2792 return;
2793
2794 // Update the position seen by drawing code
2797}
double Consumer(size_t nSamples, double rate)
Find the track time value nSamples after the last consumed sample.

References PlaybackSchedule::TimeQueue::Consumer(), mMaxFramesOutput, mPlaybackSchedule, AudioIOBase::mRate, AudioIOBase::mStreamToken, PlaybackSchedule::mTimeQueue, and PlaybackSchedule::SetSequenceTime().

Referenced by AudioCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WaitForAudioThreadStarted()

void AudioIoCallback::WaitForAudioThreadStarted ( )

Definition at line 3307 of file AudioIO.cpp.

3308{
3309 while (mAudioThreadAcknowledge.load(std::memory_order_acquire) != Acknowledge::eStart)
3310 {
3311 using namespace std::chrono;
3312 std::this_thread::sleep_for(50ms);
3313 }
3314 mAudioThreadAcknowledge.store(Acknowledge::eNone, std::memory_order_release);
3315}
std::atomic< Acknowledge > mAudioThreadAcknowledge
Definition: AudioIO.h:322

References eNone, eStart, and mAudioThreadAcknowledge.

Referenced by AudioIO::StartStream().

Here is the caller graph for this function:

◆ WaitForAudioThreadStopped()

void AudioIoCallback::WaitForAudioThreadStopped ( )

Definition at line 3322 of file AudioIO.cpp.

3323{
3324 while (mAudioThreadAcknowledge.load(std::memory_order_acquire) != Acknowledge::eStop)
3325 {
3326 using namespace std::chrono;
3327 std::this_thread::sleep_for(50ms);
3328 }
3329 mAudioThreadAcknowledge.store(Acknowledge::eNone, std::memory_order_release);
3330}

References eNone, eStop, and mAudioThreadAcknowledge.

Referenced by AudioIO::StopStream().

Here is the caller graph for this function:

Member Data Documentation

◆ mAudioIOExt

std::vector<std::unique_ptr<AudioIOExtBase> > AudioIOBase::mAudioIOExt
private

Privatize the inherited array but give access by Extensions(). This class guarantees that this array is populated only with non-null pointers to the subtype AudioIOExt

Definition at line 322 of file AudioIOBase.h.

Referenced by AudioIoCallback().

◆ mAudioThread

std::thread AudioIoCallback::mAudioThread

Definition at line 266 of file AudioIO.h.

Referenced by AudioIO::StartThread(), and AudioIO::~AudioIO().

◆ mAudioThreadAcknowledge

std::atomic<Acknowledge> AudioIoCallback::mAudioThreadAcknowledge

◆ mAudioThreadSequenceBufferExchangeLoopActive

std::atomic<bool> AudioIoCallback::mAudioThreadSequenceBufferExchangeLoopActive

Definition at line 320 of file AudioIO.h.

Referenced by AudioIO::AudioIO(), AudioIO::AudioThread(), and CallbackDoSeek().

◆ mAudioThreadSequenceBufferExchangeLoopRunning

std::atomic<bool> AudioIoCallback::mAudioThreadSequenceBufferExchangeLoopRunning

◆ mAudioThreadShouldCallSequenceBufferExchangeOnce

std::atomic<bool> AudioIoCallback::mAudioThreadShouldCallSequenceBufferExchangeOnce

◆ mbHasSoloSequences

int AudioIoCallback::mbHasSoloSequences

Definition at line 180 of file AudioIO.h.

Referenced by AudioCallback(), and SequenceShouldBeSilent().

◆ mbMicroFades

bool AudioIoCallback::mbMicroFades

Read by a worker thread but unchanging during playback

Definition at line 291 of file AudioIO.h.

Referenced by AddToOutputChannel(), AudioCallback(), FillOutputBuffers(), AudioIO::StartStream(), and AudioIO::StopStream().

◆ mCachedBestRateCapturing

bool AudioIoCallback::mCachedBestRateCapturing
staticprotected

Definition at line 364 of file AudioIO.h.

Referenced by AudioIO::GetBestRate().

◆ mCachedBestRateOut

double AudioIoCallback::mCachedBestRateOut
staticprotected

Definition at line 362 of file AudioIO.h.

Referenced by AudioIO::GetBestRate().

◆ mCachedBestRatePlaying

bool AudioIoCallback::mCachedBestRatePlaying
staticprotected

Definition at line 363 of file AudioIO.h.

Referenced by AudioIO::GetBestRate().

◆ mCallbackReturn

int AudioIoCallback::mCallbackReturn

Definition at line 181 of file AudioIO.h.

Referenced by AudioCallback(), DrainInputBuffers(), and FillOutputBuffers().

◆ mCaptureBuffers

RingBuffers AudioIoCallback::mCaptureBuffers

◆ mCaptureFormat

sampleFormat AudioIoCallback::mCaptureFormat

◆ mCaptureRate

double AudioIoCallback::mCaptureRate {}

◆ mCaptureRingBufferSecs

double AudioIoCallback::mCaptureRingBufferSecs

Definition at line 295 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers().

◆ mCaptureSequences

RecordableSequences AudioIoCallback::mCaptureSequences

◆ mDetectDropouts

bool AudioIoCallback::mDetectDropouts { true }
protected

Read by a worker thread but unchanging during playback

Definition at line 388 of file AudioIO.h.

Referenced by DrainInputBuffers(), and AudioIO::StartStream().

◆ mDetectUpstreamDropouts

std::atomic<bool> AudioIoCallback::mDetectUpstreamDropouts { true }

◆ mFactor

double AudioIoCallback::mFactor

Definition at line 288 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers(), and AudioIO::DrainRecordBuffers().

◆ mFinishAudioThread

std::atomic<bool> AudioIoCallback::mFinishAudioThread { false }

Definition at line 267 of file AudioIO.h.

Referenced by AudioIO::StartThread(), and AudioIO::~AudioIO().

◆ mForceFadeOut

std::atomic<bool> AudioIoCallback::mForceFadeOut { false }

Definition at line 336 of file AudioIO.h.

Referenced by AddToOutputChannel(), AudioIO::StartStream(), and AudioIO::StopStream().

◆ mHardwarePlaybackLatencyFrames

size_t AudioIoCallback::mHardwarePlaybackLatencyFrames {}

Hardware output latency in frames.

Definition at line 300 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers(), and AudioIO::StartPortAudioStream().

◆ mLastPaError

PaError AudioIoCallback::mLastPaError

◆ mLastPlaybackTimeMillis

wxLongLong AudioIoCallback::mLastPlaybackTimeMillis

Definition at line 338 of file AudioIO.h.

Referenced by AudioIO::AudioIO(), and FillOutputBuffers().

◆ mLastRecordingOffset

double AudioIoCallback::mLastRecordingOffset

Not (yet) used; should perhaps be atomic when it is.

Definition at line 341 of file AudioIO.h.

Referenced by AudioIO::AudioIO(), and AudioIO::StartStream().

◆ mListener

std::weak_ptr< AudioIOListener > AudioIoCallback::mListener
protected

Pointer is read by a worker thread but unchanging during playback. (Whether its overriding methods are race-free is not for AudioIO to ensure.)

Definition at line 356 of file AudioIO.h.

Referenced by SetListener(), and AudioIO::StartStream().

◆ mLostCaptureIntervals

std::vector< std::pair<double, double> > AudioIoCallback::mLostCaptureIntervals
protected

Definition at line 386 of file AudioIO.h.

Referenced by DrainInputBuffers(), AudioIO::StartStream(), and AudioIO::StopStream().

◆ mLostSamples

unsigned long long AudioIoCallback::mLostSamples { 0 }

Definition at line 317 of file AudioIO.h.

Referenced by DrainInputBuffers(), and AudioIO::StartStream().

◆ mMaxFramesOutput

unsigned long AudioIoCallback::mMaxFramesOutput

Definition at line 289 of file AudioIO.h.

Referenced by FillOutputBuffers(), and UpdateTimePosition().

◆ mMinCaptureSecsToCopy

double AudioIoCallback::mMinCaptureSecsToCopy

Definition at line 304 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers(), and AudioIO::DrainRecordBuffers().

◆ mMixerOutputVol

std::atomic<float> AudioIoCallback::mMixerOutputVol { 1.0 }

Definition at line 286 of file AudioIO.h.

◆ mNextStreamToken

int AudioIoCallback::mNextStreamToken = 0
static

Definition at line 287 of file AudioIO.h.

Referenced by AudioIO::StartStream().

◆ mNumCaptureChannels

size_t AudioIoCallback::mNumCaptureChannels

◆ mNumPauseFrames

long AudioIoCallback::mNumPauseFrames

How many frames of zeros were output due to pauses?

Definition at line 247 of file AudioIO.h.

Referenced by AudioCallback(), AudioIO::AudioIO(), and AudioIO::StartPortAudioStream().

◆ mNumPlaybackChannels

size_t AudioIoCallback::mNumPlaybackChannels

◆ mOldChannelGains

std::vector<OldChannelGains> AudioIoCallback::mOldChannelGains

◆ mPauseRec

bool AudioIoCallback::mPauseRec

True if Sound Activated Recording is enabled.

Read by a worker thread but unchanging during playback

Definition at line 309 of file AudioIO.h.

Referenced by CheckSoundActivatedRecordingLevel(), and AudioIO::StartStream().

◆ mPlaybackBuffers

RingBuffers AudioIoCallback::mPlaybackBuffers

◆ mPlaybackMixers

std::vector<std::unique_ptr<Mixer> > AudioIoCallback::mPlaybackMixers

◆ mPlaybackQueueMinimum

size_t AudioIoCallback::mPlaybackQueueMinimum

Occupancy of the queue we try to maintain, with bigger batches if needed.

Definition at line 302 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers(), and AudioIO::FillPlayBuffers().

◆ mPlaybackRingBufferSecs

PlaybackPolicy::Duration AudioIoCallback::mPlaybackRingBufferSecs

Definition at line 294 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers().

◆ mPlaybackSamplesToCopy

size_t AudioIoCallback::mPlaybackSamplesToCopy

Preferred batch size for replenishing the playback RingBuffer.

Definition at line 298 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers(), and AudioIO::FillPlayBuffers().

◆ mPlaybackSchedule

PlaybackSchedule AudioIoCallback::mPlaybackSchedule
protected

◆ mPlaybackSequences

ConstPlayableSequences AudioIoCallback::mPlaybackSequences

◆ mpTransportState

std::unique_ptr<TransportState> AudioIoCallback::mpTransportState
protected

Holds some state for duration of playback or recording.

Definition at line 408 of file AudioIO.h.

Referenced by AudioIO::AddState(), AudioIO::FillPlayBuffers(), AudioIO::RemoveState(), AudioIO::ReplaceState(), AudioIO::StartStream(), AudioIO::StartStreamCleanup(), and AudioIO::StopStream().

◆ mRecordingException

wxAtomicInt AudioIoCallback::mRecordingException {}
protected

Definition at line 380 of file AudioIO.h.

Referenced by AudioIO::DrainRecordBuffers().

◆ mRecordingSchedule

RecordingSchedule AudioIoCallback::mRecordingSchedule {}
protected

◆ mResample

std::vector<std::unique_ptr<Resample> > AudioIoCallback::mResample

◆ mScratchBuffers

std::vector<SampleBuffer> AudioIoCallback::mScratchBuffers

◆ mScratchPointers

std::vector<float *> AudioIoCallback::mScratchPointers

◆ mSeek

double AudioIoCallback::mSeek

Definition at line 293 of file AudioIO.h.

Referenced by CallbackDoSeek(), FillOutputBuffers(), and AudioIO::StartStream().

◆ mSilenceLevel

float AudioIoCallback::mSilenceLevel

◆ mSimulateRecordingErrors

bool AudioIoCallback::mSimulateRecordingErrors { false }

◆ mSoftwarePlaythrough

bool AudioIoCallback::mSoftwarePlaythrough

Read by a worker thread but unchanging during playback

Definition at line 306 of file AudioIO.h.

Referenced by DoPlaythrough(), AudioIO::StartMonitoring(), AudioIO::StartPortAudioStream(), and AudioIO::StartStream().

◆ mSuspendAudioThread

wxMutex AudioIoCallback::mSuspendAudioThread
protected

Definition at line 368 of file AudioIO.h.

Referenced by CallbackDoSeek(), and AudioIO::StopStream().

◆ mUsingAlsa

bool AudioIoCallback::mUsingAlsa { false }
protected

◆ mUsingJack

bool AudioIoCallback::mUsingJack { false }
protected

Definition at line 359 of file AudioIO.h.

Referenced by AudioIO::StartPortAudioStream().


The documentation for this class was generated from the following files: