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 3087 of file AudioIO.cpp.

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

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

Here is the call graph for this function:

◆ ~AudioIoCallback()

AudioIoCallback::~AudioIoCallback ( )

Definition at line 3096 of file AudioIO.cpp.

3097{
3098}

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 2569 of file AudioIO.cpp.

2577{
2578 const auto numPlaybackChannels = mNumPlaybackChannels;
2579
2580 float gain = ps.GetChannelGain(chan);
2581 if (drop || mForceFadeOut.load(std::memory_order_relaxed) || IsPaused())
2582 gain = 0.0;
2583
2584 // Output volume emulation: possibly copy meter samples, then
2585 // apply volume, then copy to the output buffer
2586 if (outputMeterFloats != outputFloats)
2587 for ( unsigned i = 0; i < len; ++i)
2588 outputMeterFloats[numPlaybackChannels*i+chan] +=
2589 gain*tempBuf[i];
2590
2591 // DV: We use gain to emulate panning.
2592 // Let's keep the old behavior for panning.
2593 gain *= ExpGain(GetMixerOutputVol());
2594
2595 float oldGain = channelGain;
2596 channelGain = gain;
2597 // if no microfades, jump in volume.
2598 if (!mbMicroFades)
2599 oldGain = gain;
2600 wxASSERT(len > 0);
2601
2602 // Linear interpolate.
2603 // PRL todo: choose denominator differently, so it doesn't depend on
2604 // framesPerBuffer, which is influenced by the portAudio implementation in
2605 // opaque ways
2606 float deltaGain = (gain - oldGain) / len;
2607 for (unsigned i = 0; i < len; i++)
2608 outputFloats[numPlaybackChannels*i+chan] += (oldGain + deltaGain * i) *tempBuf[i];
2609};
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 3076 of file AudioIO.cpp.

3077{
3078 for (size_t ii = 0, nn = mPlaybackSequences.size(); ii < nn; ++ii) {
3079 auto vt = mPlaybackSequences[ii];
3080 const auto &oldGains = mOldChannelGains[ii];
3081 if (!(SequenceShouldBeSilent(*vt) && SequenceHasBeenFadedOut(oldGains)))
3082 return false;
3083 }
3084 return true;
3085}
bool SequenceShouldBeSilent(const PlayableSequence &ps)
Definition: AudioIO.cpp:3060
bool SequenceHasBeenFadedOut(const OldChannelGains &gains)
Returns true when playback buffer data from both channels is discardable.
Definition: AudioIO.cpp:3071
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 3101 of file AudioIO.cpp.

3106{
3107 // Poll sequences for change of state.
3108 // (User might click mute and solo buttons.)
3110 mCallbackReturn = paContinue;
3111
3112 if (IsPaused()
3113 // PRL: Why was this added? Was it only because of the mysterious
3114 // initial leading zeroes, now solved by setting mStreamToken early?
3115 // JKC: I think it's used for the MIDI time cursor. See comments
3116 // at head of file about AudioTime().
3117 || mStreamToken <= 0
3118 )
3119 mNumPauseFrames += framesPerBuffer;
3120
3121 for( auto &ext : Extensions() ) {
3122 ext.ComputeOtherTimings(mRate, IsPaused(),
3123 timeInfo,
3124 framesPerBuffer);
3125 ext.FillOtherBuffers(
3127 }
3128
3129 // ------ MEMORY ALLOCATIONS -----------------------------------------------
3130 // tempFloats will be a reusable scratch pad for (possibly format converted)
3131 // audio data. One temporary use is for the InputMeter data.
3132 const auto numPlaybackChannels = mNumPlaybackChannels;
3133 const auto numCaptureChannels = mNumCaptureChannels;
3134 const auto tempFloats = stackAllocate(float,
3135 framesPerBuffer * std::max(numCaptureChannels, numPlaybackChannels));
3136
3137 bool bVolEmulationActive =
3138 (outputBuffer && GetMixerOutputVol() != 1.0);
3139 // outputMeterFloats is the scratch pad for the output meter.
3140 // we can often reuse the existing outputBuffer and save on allocating
3141 // something new.
3142 const auto outputMeterFloats = bVolEmulationActive
3143 ? stackAllocate(float, framesPerBuffer * numPlaybackChannels)
3144 : outputBuffer;
3145 // ----- END of MEMORY ALLOCATIONS ------------------------------------------
3146
3147 if (inputBuffer && numCaptureChannels) {
3148 float *inputSamples;
3149
3150 if (mCaptureFormat == floatSample) {
3151 inputSamples = (float *) inputBuffer;
3152 }
3153 else {
3154 SamplesToFloats(reinterpret_cast<constSamplePtr>(inputBuffer),
3155 mCaptureFormat, tempFloats, framesPerBuffer * numCaptureChannels);
3156 inputSamples = tempFloats;
3157 }
3158
3160 inputSamples,
3161 framesPerBuffer);
3162
3163 // This function may queue up a pause or resume.
3164 // TODO this is a bit dodgy as it toggles the Pause, and
3165 // relies on an idle event to have handled that, so could
3166 // queue up multiple toggle requests and so do nothing.
3167 // Eventually it will sort itself out by random luck, but
3168 // the net effect is a delay in starting/stopping sound activated
3169 // recording.
3171 inputSamples,
3172 framesPerBuffer);
3173 }
3174
3175 // Even when paused, we do playthrough.
3176 // Initialise output buffer to zero or to playthrough data.
3177 // Initialise output meter values.
3179 inputBuffer,
3180 outputBuffer,
3181 framesPerBuffer,
3182 outputMeterFloats);
3183
3184 // Test for no sequence audio to play (because we are paused and have faded
3185 // out)
3186 if( IsPaused() && (( !mbMicroFades ) || AllSequencesAlreadySilent() ))
3187 return mCallbackReturn;
3188
3189 // To add sequence output to output (to play sound on speaker)
3190 // possible exit, if we were seeking.
3192 outputBuffer,
3193 framesPerBuffer,
3194 outputMeterFloats))
3195 return mCallbackReturn;
3196
3197 // To move the cursor onwards. (uses mMaxFramesOutput)
3198 UpdateTimePosition(framesPerBuffer);
3199
3200 // To capture input into sequence (sound from microphone)
3202 inputBuffer,
3203 framesPerBuffer,
3204 statusFlags,
3205 tempFloats);
3206
3207 SendVuOutputMeterData( outputMeterFloats, framesPerBuffer);
3208
3209 return mCallbackReturn;
3210}
#define stackAllocate(T, count)
Definition: AudioIO.cpp:2051
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:3039
bool AllSequencesAlreadySilent()
Definition: AudioIO.cpp:3076
AudioIOExtRange Extensions()
Definition: AudioIO.h:161
void CheckSoundActivatedRecordingLevel(float *inputSamples, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2541
void UpdateTimePosition(unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2786
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:2801
void SendVuInputMeterData(const float *inputSamples, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2995
void SendVuOutputMeterData(const float *outputMeterFloats, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:3011
void DoPlaythrough(constSamplePtr inputBuffer, float *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
Definition: AudioIO.cpp:2959
bool FillOutputBuffers(float *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
Definition: AudioIO.cpp:2623
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 3276 of file AudioIO.cpp.

3278{
3279 if (IsPaused())
3280 return;
3281
3282 bool done =
3284 if (!done)
3285 return;
3286
3287 for( auto &ext : Extensions() )
3288 ext.SignalOtherCompletion();
3289 callbackReturn = paComplete;
3290}
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 3216 of file AudioIO.cpp.

3217{
3218 const int token = mStreamToken;
3219 wxMutexLocker locker(mSuspendAudioThread);
3220 if (token != mStreamToken)
3221 // This stream got destroyed while we waited for it
3222 return paAbort;
3223
3224 // Pause audio thread and wait for it to finish
3225 //
3226 // [PM] the following 8 lines of code could be probably replaced by
3227 // a single call to StopAudioThreadAndWait()
3228 //
3229 // CAUTION: when trying the above, you must also replace the setting of the
3230 // atomic before the return, with a call to StartAudioThread()
3231 //
3232 // If that works, then we can remove mAudioThreadSequenceBufferExchangeLoopActive,
3233 // as it will become unused; consequently, the AudioThread loop would get simpler too.
3234 //
3236 .store(false, std::memory_order_relaxed);
3237
3239 .load(std::memory_order_relaxed ) )
3240 {
3241 using namespace std::chrono;
3242 std::this_thread::sleep_for(50ms);
3243 }
3244
3245 // Calculate the NEW time position, in the PortAudio callback
3246 const auto time =
3248
3250 mSeek = 0.0;
3251
3252
3253 // Reset mixer positions and flush buffers for all sequences
3254 for (auto &mixer : mPlaybackMixers)
3255 mixer->Reposition( time, true );
3256 for (auto &buffer : mPlaybackBuffers) {
3257 const auto toDiscard = buffer->AvailForGet();
3258 const auto discarded = buffer->Discard( toDiscard );
3259 // wxASSERT( discarded == toDiscard );
3260 // but we can't assert in this thread
3261 wxUnusedVar(discarded);
3262 }
3263
3265
3266 // Reload the ring buffers
3268
3269 // Reenable the audio thread
3271 .store(true, std::memory_order_relaxed);
3272
3273 return paContinue;
3274}
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:3330
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 2541 of file AudioIO.cpp.

2545{
2546 // Quick returns if next to nothing to do.
2547 if( !mPauseRec )
2548 return;
2549
2550 float maxPeak = 0.;
2551 for( unsigned long i = 0, cnt = framesPerBuffer * mNumCaptureChannels; i < cnt; ++i ) {
2552 float sample = fabs(*(inputSamples++));
2553 if (sample > maxPeak) {
2554 maxPeak = sample;
2555 }
2556 }
2557
2558 bool bShouldBePaused = maxPeak < mSilenceLevel;
2559 if( bShouldBePaused != IsPaused() )
2560 {
2561 auto pListener = GetListener();
2562 if ( pListener )
2563 pListener->OnSoundActivationThreshold();
2564 }
2565}
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 3039 of file AudioIO.cpp.

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

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 2959 of file AudioIO.cpp.

2965{
2966 const auto numCaptureChannels = mNumCaptureChannels;
2967 const auto numPlaybackChannels = mNumPlaybackChannels;
2968
2969 // Quick returns if next to nothing to do.
2970 if( !outputBuffer )
2971 return;
2972 if( numPlaybackChannels <= 0 )
2973 return;
2974
2975 float *outputFloats = outputBuffer;
2976 for(unsigned i = 0; i < framesPerBuffer*numPlaybackChannels; i++)
2977 outputFloats[i] = 0.0;
2978
2979 if (inputBuffer && mSoftwarePlaythrough) {
2981 numCaptureChannels,
2982 outputBuffer, framesPerBuffer);
2983 }
2984
2985 // Copy the results to outputMeterFloats if necessary
2986 if (outputMeterFloats != outputFloats) {
2987 for (unsigned i = 0; i < framesPerBuffer*numPlaybackChannels; ++i) {
2988 outputMeterFloats[i] = outputFloats[i];
2989 }
2990 }
2991}
static void DoSoftwarePlaythrough(constSamplePtr inputBuffer, sampleFormat inputFormat, unsigned inputChannels, float *outputBuffer, unsigned long len)
Definition: AudioIO.cpp:2503
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 2801 of file AudioIO.cpp.

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

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

1881{
1883}
static size_t MinValue(const RingBuffers &buffers, size_t(RingBuffer::*pmf)() const)
Definition: AudioIO.cpp:1863
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 1885 of file AudioIO.cpp.

1886{
1888}
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 1863 of file AudioIO.cpp.

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

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 3330 of file AudioIO.cpp.

3331{
3333 .store(true, std::memory_order_release);
3334
3336 .load(std::memory_order_acquire))
3337 {
3338 using namespace std::chrono;
3339 std::this_thread::sleep_for(sleepTime);
3340 }
3341}
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 2995 of file AudioIO.cpp.

2999{
3000 const auto numCaptureChannels = mNumCaptureChannels;
3001 auto pInputMeter = mInputMeter.lock();
3002 if ( !pInputMeter )
3003 return;
3004 if( pInputMeter->IsMeterDisabled())
3005 return;
3006 pInputMeter->UpdateDisplay(
3007 numCaptureChannels, framesPerBuffer, inputSamples);
3008}
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 3011 of file AudioIO.cpp.

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

3072{
3073 return gains[0] == 0.0 && gains[1] == 0.0;
3074}

Referenced by AllSequencesAlreadySilent(), and FillOutputBuffers().

Here is the caller graph for this function:

◆ SequenceShouldBeSilent()

bool AudioIoCallback::SequenceShouldBeSilent ( const PlayableSequence ps)

Definition at line 3060 of file AudioIO.cpp.

3061{
3062 return IsPaused() || (!ps.GetSolo() && (
3063 // Cut if somebody else is soloing
3065 // Cut if we're muted (and not soloing)
3066 ps.GetMute()
3067 ));
3068}
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 2324 of file AudioIO.cpp.

2326{
2327 if (IsBusy())
2328 return;
2329
2330 mListener = listener;
2331}
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 3300 of file AudioIO.cpp.

3301{
3302 mAudioThreadSequenceBufferExchangeLoopRunning.store(true, std::memory_order_release);
3303}

References mAudioThreadSequenceBufferExchangeLoopRunning.

Referenced by AudioIO::StartStream().

Here is the caller graph for this function:

◆ StopAudioThread()

void AudioIoCallback::StopAudioThread ( )

Definition at line 3315 of file AudioIO.cpp.

3316{
3317 mAudioThreadSequenceBufferExchangeLoopRunning.store(false, std::memory_order_release);
3318}

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 2786 of file AudioIO.cpp.

2787{
2788 // Quick returns if next to nothing to do.
2789 if (mStreamToken <= 0)
2790 return;
2791
2792 // Update the position seen by drawing code
2795}
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 3305 of file AudioIO.cpp.

3306{
3307 while (mAudioThreadAcknowledge.load(std::memory_order_acquire) != Acknowledge::eStart)
3308 {
3309 using namespace std::chrono;
3310 std::this_thread::sleep_for(50ms);
3311 }
3312 mAudioThreadAcknowledge.store(Acknowledge::eNone, std::memory_order_release);
3313}
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 3320 of file AudioIO.cpp.

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

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: