Audacity 3.2.0
Classes | Public Types | Public Member Functions | Public Attributes | Static Public Attributes | 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 >
 

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 CountSoloingTracks ()
 
bool TrackShouldBeSilent (const SampleTrack &wt)
 
bool TrackHasBeenFadedOut (const SampleTrack &wt, const OldChannelGains &gains)
 
bool AllTracksAlreadySilent ()
 
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 SampleTrack *vt, OldChannelGains &gains)
 
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 mbHasSoloTracks
 
int mCallbackReturn
 
long mNumPauseFrames
 How many frames of zeros were output due to pauses? More...
 
std::thread mAudioThread
 
std::atomic< bool > mFinishAudioThread { false }
 
ArrayOf< std::unique_ptr< Resample > > mResample
 
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
 
WritableSampleTrackArray mCaptureTracks
 
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
 
SampleTrackConstArray mPlaybackTracks
 
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
 
unsigned int mNumCaptureChannels
 
unsigned int mNumPlaybackChannels
 
sampleFormat mCaptureFormat
 
unsigned long long mLostSamples { 0 }
 
std::atomic< bool > mAudioThreadShouldCallTrackBufferExchangeOnce
 
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopRunning
 
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopActive
 
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 ()
 

Protected Attributes

std::weak_ptr< AudioIOListenermListener
 
bool mUsingAlsa { 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...
 
- 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...
 

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 125 of file AudioIO.h.

Member Typedef Documentation

◆ OldChannelGains

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

Definition at line 201 of file AudioIO.h.

Constructor & Destructor Documentation

◆ AudioIoCallback()

AudioIoCallback::AudioIoCallback ( )

Definition at line 3063 of file AudioIO.cpp.

3064{
3065 auto &factories = AudioIOExt::GetFactories();
3066 for (auto &factory: factories)
3067 if (auto pExt = factory(mPlaybackSchedule))
3068 mAudioIOExt.push_back( move(pExt) );
3069}
static Factories & GetFactories()
Definition: AudioIOExt.cpp:15
PlaybackSchedule mPlaybackSchedule
Definition: AudioIO.h:411
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 3072 of file AudioIO.cpp.

3073{
3074}

Member Function Documentation

◆ AddToOutputChannel()

void AudioIoCallback::AddToOutputChannel ( unsigned int  chan,
float *  outputMeterFloats,
float *  outputFloats,
const float *  tempBuf,
bool  drop,
unsigned long  len,
const SampleTrack vt,
OldChannelGains gains 
)

Definition at line 2502 of file AudioIO.cpp.

2511{
2512 const auto numPlaybackChannels = mNumPlaybackChannels;
2513
2514 float gain = vt->GetChannelGain(chan);
2515 if (drop || mForceFadeOut.load(std::memory_order_relaxed) || IsPaused())
2516 gain = 0.0;
2517
2518 // Output volume emulation: possibly copy meter samples, then
2519 // apply volume, then copy to the output buffer
2520 if (outputMeterFloats != outputFloats)
2521 for ( unsigned i = 0; i < len; ++i)
2522 outputMeterFloats[numPlaybackChannels*i+chan] +=
2523 gain*tempBuf[i];
2524
2525 // DV: We use gain to emulate panning.
2526 // Let's keep the old behavior for panning.
2527 gain *= ExpGain(GetMixerOutputVol());
2528
2529 float oldGain = gains[chan];
2530 if( gain != oldGain )
2531 gains[chan] = gain;
2532 // if no microfades, jump in volume.
2533 if( !mbMicroFades )
2534 oldGain =gain;
2535 wxASSERT(len > 0);
2536
2537 // Linear interpolate.
2538 float deltaGain = (gain - oldGain) / len;
2539 for (unsigned i = 0; i < len; i++)
2540 outputFloats[numPlaybackChannels*i+chan] += (oldGain + deltaGain * i) *tempBuf[i];
2541};
Type ExpGain(Type gain) noexcept
Definition: Gain.h:19
bool IsPaused() const
Find out if playback / recording is currently paused.
bool mbMicroFades
Definition: AudioIO.h:302
float GetMixerOutputVol()
Definition: AudioIO.h:356
unsigned int mNumPlaybackChannels
Definition: AudioIO.h:325
std::atomic< bool > mForceFadeOut
Definition: AudioIO.h:346
virtual float GetChannelGain(int channel) const =0
Takes gain and pan into account.

References ExpGain(), SampleTrack::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:

◆ AllTracksAlreadySilent()

bool AudioIoCallback::AllTracksAlreadySilent ( )

Definition at line 3052 of file AudioIO.cpp.

3053{
3054 for (size_t ii = 0, nn = mPlaybackTracks.size(); ii < nn; ++ii) {
3055 auto vt = mPlaybackTracks[ii];
3056 const auto &oldGains = mOldChannelGains[ii];
3057 if (!(TrackShouldBeSilent(*vt) && TrackHasBeenFadedOut(*vt, oldGains)))
3058 return false;
3059 }
3060 return true;
3061}
bool TrackShouldBeSilent(const SampleTrack &wt)
Definition: AudioIO.cpp:3028
std::vector< OldChannelGains > mOldChannelGains
Definition: AudioIO.h:290
bool TrackHasBeenFadedOut(const SampleTrack &wt, const OldChannelGains &gains)
Definition: AudioIO.cpp:3039
SampleTrackConstArray mPlaybackTracks
Definition: AudioIO.h:287

References mOldChannelGains, mPlaybackTracks, TrackHasBeenFadedOut(), and TrackShouldBeSilent().

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

3082{
3083 // Poll tracks for change of state. User might click mute and solo buttons.
3085 mCallbackReturn = paContinue;
3086
3087 if (IsPaused()
3088 // PRL: Why was this added? Was it only because of the mysterious
3089 // initial leading zeroes, now solved by setting mStreamToken early?
3090 // JKC: I think it's used for the MIDI time cursor. See comments
3091 // at head of file about AudioTime().
3092 || mStreamToken <= 0
3093 )
3094 mNumPauseFrames += framesPerBuffer;
3095
3096 for( auto &ext : Extensions() ) {
3097 ext.ComputeOtherTimings(mRate, IsPaused(),
3098 timeInfo,
3099 framesPerBuffer);
3100 ext.FillOtherBuffers(
3102 }
3103
3104 // ------ MEMORY ALLOCATIONS -----------------------------------------------
3105 // tempFloats will be a reusable scratch pad for (possibly format converted)
3106 // audio data. One temporary use is for the InputMeter data.
3107 const auto numPlaybackChannels = mNumPlaybackChannels;
3108 const auto numCaptureChannels = mNumCaptureChannels;
3109 float *tempFloats = (float *)alloca(framesPerBuffer*sizeof(float)*
3110 MAX(numCaptureChannels,numPlaybackChannels));
3111
3112 bool bVolEmulationActive =
3113 (outputBuffer && GetMixerOutputVol() != 1.0);
3114 // outputMeterFloats is the scratch pad for the output meter.
3115 // we can often reuse the existing outputBuffer and save on allocating
3116 // something new.
3117 float *outputMeterFloats = bVolEmulationActive ?
3118 (float *)alloca(framesPerBuffer*numPlaybackChannels * sizeof(float)) :
3119 outputBuffer;
3120 // ----- END of MEMORY ALLOCATIONS ------------------------------------------
3121
3122 if (inputBuffer && numCaptureChannels) {
3123 float *inputSamples;
3124
3125 if (mCaptureFormat == floatSample) {
3126 inputSamples = (float *) inputBuffer;
3127 }
3128 else {
3129 SamplesToFloats(reinterpret_cast<constSamplePtr>(inputBuffer),
3130 mCaptureFormat, tempFloats, framesPerBuffer * numCaptureChannels);
3131 inputSamples = tempFloats;
3132 }
3133
3135 inputSamples,
3136 framesPerBuffer);
3137
3138 // This function may queue up a pause or resume.
3139 // TODO this is a bit dodgy as it toggles the Pause, and
3140 // relies on an idle event to have handled that, so could
3141 // queue up multiple toggle requests and so do nothing.
3142 // Eventually it will sort itself out by random luck, but
3143 // the net effect is a delay in starting/stopping sound activated
3144 // recording.
3146 inputSamples,
3147 framesPerBuffer);
3148 }
3149
3150 // Even when paused, we do playthrough.
3151 // Initialise output buffer to zero or to playthrough data.
3152 // Initialise output meter values.
3154 inputBuffer,
3155 outputBuffer,
3156 framesPerBuffer,
3157 outputMeterFloats);
3158
3159 // Test for no track audio to play (because we are paused and have faded out)
3160 if( IsPaused() && (( !mbMicroFades ) || AllTracksAlreadySilent() ))
3161 return mCallbackReturn;
3162
3163 // To add track output to output (to play sound on speaker)
3164 // possible exit, if we were seeking.
3166 outputBuffer,
3167 framesPerBuffer,
3168 outputMeterFloats))
3169 return mCallbackReturn;
3170
3171 // To move the cursor onwards. (uses mMaxFramesOutput)
3172 UpdateTimePosition(framesPerBuffer);
3173
3174 // To capture input into track (sound from microphone)
3176 inputBuffer,
3177 framesPerBuffer,
3178 statusFlags,
3179 tempFloats);
3180
3181 SendVuOutputMeterData( outputMeterFloats, framesPerBuffer);
3182
3183 return mCallbackReturn;
3184}
#define MAX(a, b)
Definition: AudioIO.cpp:2434
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:56
double mRate
Audio playback rate in samples per second.
Definition: AudioIOBase.h:255
int mStreamToken
Definition: AudioIOBase.h:251
AudioIOExtRange Extensions()
Definition: AudioIO.h:177
bool AllTracksAlreadySilent()
Definition: AudioIO.cpp:3052
void CheckSoundActivatedRecordingLevel(float *inputSamples, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2474
void UpdateTimePosition(unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2753
unsigned CountSoloingTracks()
Definition: AudioIO.cpp:3007
int mCallbackReturn
Definition: AudioIO.h:197
long mNumPauseFrames
How many frames of zeros were output due to pauses?
Definition: AudioIO.h:260
void DrainInputBuffers(constSamplePtr inputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackFlags statusFlags, float *tempFloats)
Definition: AudioIO.cpp:2768
void SendVuInputMeterData(const float *inputSamples, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2963
void SendVuOutputMeterData(const float *outputMeterFloats, unsigned long framesPerBuffer)
Definition: AudioIO.cpp:2979
void DoPlaythrough(constSamplePtr inputBuffer, float *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
Definition: AudioIO.cpp:2927
int mbHasSoloTracks
Definition: AudioIO.h:196
bool FillOutputBuffers(float *outputBuffer, unsigned long framesPerBuffer, float *outputMeterFloats)
Definition: AudioIO.cpp:2555
unsigned int mNumCaptureChannels
Definition: AudioIO.h:323
sampleFormat mCaptureFormat
Definition: AudioIO.h:326

References AllTracksAlreadySilent(), CheckSoundActivatedRecordingLevel(), CountSoloingTracks(), DoPlaythrough(), DrainInputBuffers(), Extensions(), FillOutputBuffers(), floatSample, GetMixerOutputVol(), AudioIOBase::IsPaused(), MAX, mbHasSoloTracks, mbMicroFades, mCallbackReturn, mCaptureFormat, mNumCaptureChannels, mNumPauseFrames, mNumPlaybackChannels, AudioIOBase::mRate, AudioIOBase::mStreamToken, SamplesToFloats(), SendVuInputMeterData(), SendVuOutputMeterData(), and UpdateTimePosition().

Here is the call graph for this function:

◆ CallbackCheckCompletion()

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

Definition at line 3255 of file AudioIO.cpp.

3257{
3258 if (IsPaused())
3259 return;
3260
3261 bool done =
3263 if (!done)
3264 return;
3265
3266 for( auto &ext : Extensions() )
3267 ext.SignalOtherCompletion();
3268 callbackReturn = paComplete;
3269}
virtual bool Done(PlaybackSchedule &schedule, unsigned long outputFrames)
Returns true if schedule.GetTrackTime() 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 3190 of file AudioIO.cpp.

3191{
3192 const int token = mStreamToken;
3193 wxMutexLocker locker(mSuspendAudioThread);
3194 if (token != mStreamToken)
3195 // This stream got destroyed while we waited for it
3196 return paAbort;
3197
3198 const auto numPlaybackTracks = mPlaybackTracks.size();
3199
3200 // Pause audio thread and wait for it to finish
3201 //
3202 // [PM] the following 8 lines of code could be probably replaced by
3203 // a single call to StopAudioThreadAndWait()
3204 //
3205 // CAUTION: when trying the above, you must also replace the setting of the
3206 // atomic before the return, with a call to StartAudioThread()
3207 //
3208 // If that works, then we can remove mAudioThreadTrackBufferExchangeLoopActive,
3209 // as it will become unused; consequently, the AudioThread loop would get simpler too.
3210 //
3212 .store(false, std::memory_order_relaxed);
3213
3215 .load(std::memory_order_relaxed ) )
3216 {
3217 using namespace std::chrono;
3218 std::this_thread::sleep_for(50ms);
3219 }
3220
3221 // Calculate the NEW time position, in the PortAudio callback
3222 const auto time =
3224
3226 mSeek = 0.0;
3227
3228
3229 // Reset mixer positions and flush buffers for all tracks
3230 for (auto &mixer : mPlaybackMixers)
3231 mixer->Reposition( time, true );
3232 for (size_t i = 0; i < numPlaybackTracks; i++)
3233 {
3234 const auto toDiscard =
3235 mPlaybackBuffers[i]->AvailForGet();
3236 const auto discarded =
3237 mPlaybackBuffers[i]->Discard( toDiscard );
3238 // wxASSERT( discarded == toDiscard );
3239 // but we can't assert in this thread
3240 wxUnusedVar(discarded);
3241 }
3242
3244
3245 // Reload the ring buffers
3247
3248 // Reenable the audio thread
3250 .store(true, std::memory_order_relaxed);
3251
3252 return paContinue;
3253}
double mSeek
Definition: AudioIO.h:304
wxMutex mSuspendAudioThread
Definition: AudioIO.h:375
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopRunning
Definition: AudioIO.h:329
std::vector< std::unique_ptr< Mixer > > mPlaybackMixers
Definition: AudioIO.h:295
std::atomic< bool > mAudioThreadTrackBufferExchangeLoopActive
Definition: AudioIO.h:330
void ProcessOnceAndWait(std::chrono::milliseconds sleepTime=std::chrono::milliseconds(50))
Definition: AudioIO.cpp:3309
ArrayOf< std::unique_ptr< RingBuffer > > mPlaybackBuffers
Definition: AudioIO.h:286
virtual double OffsetTrackTime(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 SetTrackTime(double time)
Set current track time value, unadjusted.
class AUDIO_IO_API PlaybackSchedule::TimeQueue mTimeQueue

References PlaybackSchedule::GetPolicy(), mAudioThreadTrackBufferExchangeLoopActive, mAudioThreadTrackBufferExchangeLoopRunning, mPlaybackBuffers, mPlaybackMixers, mPlaybackSchedule, mPlaybackTracks, mSeek, AudioIOBase::mStreamToken, mSuspendAudioThread, PlaybackSchedule::mTimeQueue, PlaybackPolicy::OffsetTrackTime(), PlaybackSchedule::TimeQueue::Prime(), ProcessOnceAndWait(), and PlaybackSchedule::SetTrackTime().

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

2478{
2479 // Quick returns if next to nothing to do.
2480 if( !mPauseRec )
2481 return;
2482
2483 float maxPeak = 0.;
2484 for( unsigned long i = 0, cnt = framesPerBuffer * mNumCaptureChannels; i < cnt; ++i ) {
2485 float sample = fabs(*(inputSamples++));
2486 if (sample > maxPeak) {
2487 maxPeak = sample;
2488 }
2489 }
2490
2491 bool bShouldBePaused = maxPeak < mSilenceLevel;
2492 if( bShouldBePaused != IsPaused() )
2493 {
2494 auto pListener = GetListener();
2495 if ( pListener )
2496 pListener->OnSoundActivationThreshold();
2497 }
2498}
std::shared_ptr< AudioIOListener > GetListener() const
Definition: AudioIO.h:185
float mSilenceLevel
Definition: AudioIO.h:321
bool mPauseRec
True if Sound Activated Recording is enabled.
Definition: AudioIO.h:320

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 390 of file AudioIO.h.

391 { if (mRecordingException) wxAtomicDec( mRecordingException ); }
wxAtomicInt mRecordingException
Definition: AudioIO.h:387

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

Here is the caller graph for this function:

◆ CountSoloingTracks()

unsigned AudioIoCallback::CountSoloingTracks ( )

Definition at line 3007 of file AudioIO.cpp.

3007 {
3008 const auto numPlaybackTracks = mPlaybackTracks.size();
3009
3010 // MOVE_TO: CountSoloedTracks() function
3011 unsigned numSolo = 0;
3012 for(unsigned t = 0; t < numPlaybackTracks; t++ )
3013 if( mPlaybackTracks[t]->GetSolo() )
3014 numSolo++;
3015 auto range = Extensions();
3016 numSolo += std::accumulate(range.begin(), range.end(), 0,
3017 [](unsigned sum, auto &ext){
3018 return sum + ext.CountOtherSoloTracks(); });
3019 return numSolo;
3020}

References Extensions(), and mPlaybackTracks.

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

2933{
2934 const auto numCaptureChannels = mNumCaptureChannels;
2935 const auto numPlaybackChannels = mNumPlaybackChannels;
2936
2937 // Quick returns if next to nothing to do.
2938 if( !outputBuffer )
2939 return;
2940 if( numPlaybackChannels <= 0 )
2941 return;
2942
2943 float *outputFloats = outputBuffer;
2944 for(unsigned i = 0; i < framesPerBuffer*numPlaybackChannels; i++)
2945 outputFloats[i] = 0.0;
2946
2947 if (inputBuffer && mSoftwarePlaythrough) {
2949 numCaptureChannels,
2950 outputBuffer, framesPerBuffer);
2951 }
2952
2953 // Copy the results to outputMeterFloats if necessary
2954 if (outputMeterFloats != outputFloats) {
2955 for (unsigned i = 0; i < framesPerBuffer*numPlaybackChannels; ++i) {
2956 outputMeterFloats[i] = outputFloats[i];
2957 }
2958 }
2959}
static void DoSoftwarePlaythrough(constSamplePtr inputBuffer, sampleFormat inputFormat, unsigned inputChannels, float *outputBuffer, unsigned long len)
Definition: AudioIO.cpp:2436
bool mSoftwarePlaythrough
Definition: AudioIO.h:317

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

2774{
2775 const auto numPlaybackTracks = mPlaybackTracks.size();
2776 const auto numPlaybackChannels = mNumPlaybackChannels;
2777 const auto numCaptureChannels = mNumCaptureChannels;
2778
2779 // Quick returns if next to nothing to do.
2780 if (mStreamToken <= 0)
2781 return;
2782 if( !inputBuffer )
2783 return;
2784 if( numCaptureChannels <= 0 )
2785 return;
2786
2787 // If there are no playback tracks, and we are recording, then the
2788 // earlier checks for being past the end won't happen, so do it here.
2790 mCallbackReturn = paComplete;
2791 }
2792
2793 // The error likely from a too-busy CPU falling behind real-time data
2794 // is paInputOverflow
2795 bool inputError =
2796 (statusFlags & (paInputOverflow))
2797 && !(statusFlags & paPrimingOutput);
2798
2799 // But it seems it's easy to get false positives, at least on Mac
2800 // So we have not decided to enable this extra detection yet in
2801 // production
2802
2803 size_t len = framesPerBuffer;
2804 for(unsigned t = 0; t < numCaptureChannels; t++)
2805 len = std::min( len, mCaptureBuffers[t]->AvailForPut() );
2806
2807 if (mSimulateRecordingErrors && 100LL * rand() < RAND_MAX)
2808 // Make spurious errors for purposes of testing the error
2809 // reporting
2810 len = 0;
2811
2812 // A different symptom is that len < framesPerBuffer because
2813 // the other thread, executing TrackBufferExchange, isn't consuming fast
2814 // enough from mCaptureBuffers; maybe it's CPU-bound, or maybe the
2815 // storage device it writes is too slow
2816 if (mDetectDropouts &&
2817 ((mDetectUpstreamDropouts.load(std::memory_order_relaxed)
2818 && inputError) ||
2819 len < framesPerBuffer) ) {
2820 // Assume that any good partial buffer should be written leftmost
2821 // and zeroes will be padded after; label the zeroes.
2822 auto start = mPlaybackSchedule.GetTrackTime() +
2824 auto duration = (framesPerBuffer - len) / mRate;
2825 auto pLast = mLostCaptureIntervals.empty()
2826 ? nullptr : &mLostCaptureIntervals.back();
2827 if (pLast &&
2828 fabs(pLast->first + pLast->second - start) < 0.5/mRate)
2829 // Make one bigger interval, not two butting intervals
2830 pLast->second = start + duration - pLast->first;
2831 else
2832 mLostCaptureIntervals.emplace_back( start, duration );
2833 }
2834
2835 if (len < framesPerBuffer)
2836 {
2837 mLostSamples += (framesPerBuffer - len);
2838 wxPrintf(wxT("lost %d samples\n"), (int)(framesPerBuffer - len));
2839 }
2840
2841 if (len <= 0)
2842 return;
2843
2844 // We have an ASSERT in the AudioIO constructor to alert us to
2845 // possible issues with the (short*) cast. We'd have a problem if
2846 // sizeof(short) > sizeof(float) since our buffers are sized for floats.
2847 for(unsigned t = 0; t < numCaptureChannels; t++) {
2848
2849 // dmazzoni:
2850 // Un-interleave. Ugly special-case code required because the
2851 // capture channels could be in three different sample formats;
2852 // it'd be nice to be able to call CopySamples, but it can't
2853 // handle multiplying by the gain and then clipping. Bummer.
2854
2855 switch(mCaptureFormat) {
2856 case floatSample: {
2857 auto inputFloats = (const float *)inputBuffer;
2858 for(unsigned i = 0; i < len; i++)
2859 tempFloats[i] =
2860 inputFloats[numCaptureChannels*i+t];
2861 } break;
2862 case int24Sample:
2863 // We should never get here. Audacity's int24Sample format
2864 // is different from PortAudio's sample format and so we
2865 // make PortAudio return float samples when recording in
2866 // 24-bit samples.
2867 wxASSERT(false);
2868 break;
2869 case int16Sample: {
2870 auto inputShorts = (const short *)inputBuffer;
2871 short *tempShorts = (short *)tempFloats;
2872 for( unsigned i = 0; i < len; i++) {
2873 float tmp = inputShorts[numCaptureChannels*i+t];
2874 tmp = std::clamp(tmp, -32768.0f, 32767.0f);
2875 tempShorts[i] = (short)(tmp);
2876 }
2877 } break;
2878 } // switch
2879
2880 // JKC: mCaptureFormat must be for samples with sizeof(float) or
2881 // fewer bytes (because tempFloats is sized for floats). All
2882 // formats are 2 or 4 bytes, so we are OK.
2883 const auto put =
2884 mCaptureBuffers[t]->Put(
2885 (samplePtr)tempFloats, mCaptureFormat, len);
2886 // wxASSERT(put == len);
2887 // but we can't assert in this thread
2888 wxUnusedVar(put);
2889 mCaptureBuffers[t]->Flush();
2890 }
2891}
wxT("CloseDown"))
int min(int a, int b)
char * samplePtr
Definition: SampleFormat.h:55
RecordingSchedule mRecordingSchedule
Definition: AudioIO.h:410
bool mDetectDropouts
Definition: AudioIO.h:395
bool mSimulateRecordingErrors
Definition: AudioIO.h:403
ArrayOf< std::unique_ptr< RingBuffer > > mCaptureBuffers
Definition: AudioIO.h:283
std::atomic< bool > mDetectUpstreamDropouts
Definition: AudioIO.h:407
std::vector< std::pair< double, double > > mLostCaptureIntervals
Definition: AudioIO.h:393
unsigned long long mLostSamples
Definition: AudioIO.h:327
double GetTrackTime() const
Get current track time value, unadjusted.

References PlaybackPolicy::Done(), floatSample, PlaybackSchedule::GetPolicy(), PlaybackSchedule::GetTrackTime(), int16Sample, int24Sample, mCallbackReturn, mCaptureBuffers, mCaptureFormat, mDetectDropouts, mDetectUpstreamDropouts, min(), RecordingSchedule::mLatencyCorrection, mLostCaptureIntervals, mLostSamples, mNumCaptureChannels, mNumPlaybackChannels, mPlaybackSchedule, mPlaybackTracks, 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 177 of file AudioIO.h.

177 {
178 return {
179 AudioIOExtIterator{ *this, false },
180 AudioIOExtIterator{ *this, true }
181 };
182 }

Referenced by AudioCallback(), CallbackCheckCompletion(), CountSoloingTracks(), 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 2555 of file AudioIO.cpp.

2560{
2561 const auto numPlaybackTracks = mPlaybackTracks.size();
2562 const auto numPlaybackChannels = mNumPlaybackChannels;
2563 const auto numCaptureChannels = mNumCaptureChannels;
2564
2565 mMaxFramesOutput = 0;
2566
2567 // Quick returns if next to nothing to do.
2568 if (mStreamToken <= 0 ||
2569 !outputBuffer ||
2570 numPlaybackChannels <= 0) {
2571 // So that UpdateTimePosition() will be correct, in case of MIDI play with
2572 // no audio output channels
2573 mMaxFramesOutput = framesPerBuffer;
2574 return false;
2575 }
2576
2577 float *outputFloats = outputBuffer;
2578
2580 mSeek = 0.0;
2581
2582 if (mSeek){
2584 return true;
2585 }
2586
2587 // ------ MEMORY ALLOCATION ----------------------
2588 // These are small structures.
2589 const auto chans = (const SampleTrack **) alloca(
2590 numPlaybackChannels * sizeof(const SampleTrack *));
2591 const auto oldgains = (OldChannelGains **) alloca(
2592 numPlaybackChannels * sizeof(OldChannelGains *));
2593 float **tempBufs = (float **) alloca(numPlaybackChannels * sizeof(float *));
2594
2595 // And these are larger structures....
2596 for (unsigned int c = 0; c < numPlaybackChannels; c++)
2597 tempBufs[c] = (float *) alloca(framesPerBuffer * sizeof(float));
2598 // ------ End of MEMORY ALLOCATION ---------------
2599
2600 int chanCnt = 0;
2601
2602 // Choose a common size to take from all ring buffers
2603 const auto toGet =
2604 std::min<size_t>(framesPerBuffer, GetCommonlyReadyPlayback());
2605
2606 // The drop and dropQuickly booleans are so named for historical reasons.
2607 // JKC: The original code attempted to be faster by doing nothing on silenced audio.
2608 // This, IMHO, is 'premature optimisation'. Instead clearer and cleaner code would
2609 // simply use a gain of 0.0 for silent audio and go on through to the stage of
2610 // applying that 0.0 gain to the data mixed into the buffer.
2611 // Then (and only then) we would have if needed fast paths for:
2612 // - Applying a uniform gain of 0.0.
2613 // - Applying a uniform gain of 1.0.
2614 // - Applying some other uniform gain.
2615 // - Applying a linearly interpolated gain.
2616 // I would expect us not to need the fast paths, since linearly interpolated gain
2617 // is very cheap to process.
2618
2619 bool drop = false; // Track should become silent.
2620 bool dropQuickly = false; // Track has already been faded to silence.
2621 for (unsigned t = 0; t < numPlaybackTracks; t++)
2622 {
2623 auto vt = mPlaybackTracks[t].get();
2624 chans[chanCnt] = vt;
2625 oldgains[chanCnt] = &mOldChannelGains[t];
2626
2627 // TODO: more-than-two-channels
2628 auto nextTrack =
2629 t + 1 < numPlaybackTracks
2630 ? mPlaybackTracks[t + 1].get()
2631 : nullptr;
2632
2633 // First and last channel in this group (for example left and right
2634 // channels of stereo).
2635 bool firstChannel = vt->IsLeader();
2636 bool lastChannel = !nextTrack || nextTrack->IsLeader();
2637
2638 if ( firstChannel )
2639 {
2640 // IF mono THEN clear 'the other' channel.
2641 if ( lastChannel && (numPlaybackChannels>1)) {
2642 // TODO: more-than-two-channels
2643 memset(tempBufs[1], 0, framesPerBuffer * sizeof(float));
2644 }
2645 drop = TrackShouldBeSilent( *vt );
2646 dropQuickly = drop;
2647 }
2648
2649 if( mbMicroFades )
2650 dropQuickly = dropQuickly &&
2652
2653 decltype(framesPerBuffer) len = 0;
2654
2655 if (dropQuickly)
2656 {
2657 len = mPlaybackBuffers[t]->Discard(toGet);
2658 // keep going here.
2659 // we may still need to issue a paComplete.
2660 }
2661 else
2662 {
2663 len = mPlaybackBuffers[t]->Get((samplePtr)tempBufs[chanCnt],
2665 toGet);
2666 // wxASSERT( len == toGet );
2667 if (len < framesPerBuffer)
2668 // This used to happen normally at the end of non-looping
2669 // plays, but it can also be an anomalous case where the
2670 // supply from TrackBufferExchange fails to keep up with the
2671 // real-time demand in this thread (see bug 1932). We
2672 // must supply something to the sound card, so pad it with
2673 // zeroes and not random garbage.
2674 memset((void*)&tempBufs[chanCnt][len], 0,
2675 (framesPerBuffer - len) * sizeof(float));
2676 chanCnt++;
2677 }
2678
2679 // PRL: Bug1104:
2680 // There can be a difference of len in different loop passes if one channel
2681 // of a stereo track ends before the other! Take a max!
2682
2683 // PRL: More recent rewrites of TrackBufferExchange should guarantee a
2684 // padding out of the ring buffers so that equal lengths are
2685 // available, so maxLen ought to increase from 0 only once
2686 mMaxFramesOutput = std::max(mMaxFramesOutput, len);
2687
2688 if ( !lastChannel )
2689 continue;
2690
2691 // Last channel of a track seen now
2692 len = mMaxFramesOutput;
2693
2694 // Realtime effect transformation of the sound used to happen here
2695 // but it is now done already on the producer side of the RingBuffer
2696
2697 // Mix the results with the existing output (software playthrough) and
2698 // apply panning. If post panning effects are desired, the panning would
2699 // need to be be split out from the mixing and applied in a separate step.
2700
2701 // Our channels aren't silent. We need to pass their data on.
2702 //
2703 // Note that there are two kinds of channel count.
2704 // c and chanCnt are counting channels in the Tracks.
2705 // chan (and numPlayBackChannels) is counting output channels on the device.
2706 // chan = 0 is left channel
2707 // chan = 1 is right channel.
2708 //
2709 // Each channel in the tracks can output to more than one channel on the device.
2710 // For example mono channels output to both left and right output channels.
2711 if (len > 0) for (int c = 0; c < chanCnt; c++)
2712 {
2713 vt = chans[c];
2714
2715 if (vt->GetChannelIgnoringPan() == Track::LeftChannel ||
2716 vt->GetChannelIgnoringPan() == Track::MonoChannel )
2717 AddToOutputChannel( 0, outputMeterFloats, outputFloats,
2718 tempBufs[c], drop, len, vt, *oldgains[c % 2]);
2719
2720 if (vt->GetChannelIgnoringPan() == Track::RightChannel ||
2721 vt->GetChannelIgnoringPan() == Track::MonoChannel )
2722 AddToOutputChannel( 1, outputMeterFloats, outputFloats,
2723 tempBufs[c], drop, len, vt, *oldgains[c % 2]);
2724 }
2725
2727 if (dropQuickly) // no samples to process, they've been discarded
2728 continue;
2729
2730 chanCnt = 0;
2731 }
2732
2733 // Poke: If there are no playback tracks, then the earlier check
2734 // about the time indicator being past the end won't happen;
2735 // do it here instead (but not if looping or scrubbing)
2736 // PRL: Also consume from the single playback ring buffer
2737 if (numPlaybackTracks == 0) {
2738 mMaxFramesOutput = mPlaybackBuffers[0]->Discard(toGet);
2740 }
2741
2742 // wxASSERT( maxLen == toGet );
2743
2744 mLastPlaybackTimeMillis = ::wxGetUTCTimeMillis();
2745
2746 ClampBuffer( outputFloats, framesPerBuffer*numPlaybackChannels );
2747 if (outputMeterFloats != outputFloats)
2748 ClampBuffer( outputMeterFloats, framesPerBuffer*numPlaybackChannels );
2749
2750 return false;
2751}
void ClampBuffer(float *pBuffer, unsigned long len)
Definition: AudioIO.cpp:2544
void CallbackCheckCompletion(int &callbackReturn, unsigned long len)
Definition: AudioIO.cpp:3255
std::array< float, 2 > OldChannelGains
Definition: AudioIO.h:201
wxLongLong mLastPlaybackTimeMillis
Definition: AudioIO.h:348
void AddToOutputChannel(unsigned int chan, float *outputMeterFloats, float *outputFloats, const float *tempBuf, bool drop, unsigned long len, const SampleTrack *vt, OldChannelGains &gains)
Definition: AudioIO.cpp:2502
int CallbackDoSeek()
Definition: AudioIO.cpp:3190
unsigned long mMaxFramesOutput
Definition: AudioIO.h:300
size_t GetCommonlyReadyPlayback()
Get the number of audio samples ready in all of the playback buffers.
Definition: AudioIO.cpp:1814
virtual bool AllowSeek(PlaybackSchedule &schedule)
Whether repositioning commands are allowed during playback.
@ LeftChannel
Definition: Track.h:283
@ RightChannel
Definition: Track.h:284
@ MonoChannel
Definition: Track.h:285

References AddToOutputChannel(), PlaybackPolicy::AllowSeek(), CallbackCheckCompletion(), CallbackDoSeek(), ClampBuffer(), floatSample, GetCommonlyReadyPlayback(), PlaybackSchedule::GetPolicy(), Track::LeftChannel, mbMicroFades, mCallbackReturn, mLastPlaybackTimeMillis, mMaxFramesOutput, mNumCaptureChannels, mNumPlaybackChannels, mOldChannelGains, Track::MonoChannel, mPlaybackBuffers, mPlaybackSchedule, mPlaybackTracks, mSeek, AudioIOBase::mStreamToken, Track::RightChannel, TrackHasBeenFadedOut(), and TrackShouldBeSilent().

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

1815{
1816 auto commonlyAvail = mPlaybackBuffers[0]->AvailForGet();
1817 for (unsigned i = 1; i < mPlaybackTracks.size(); ++i)
1818 commonlyAvail = std::min(commonlyAvail,
1819 mPlaybackBuffers[i]->AvailForGet());
1820 return commonlyAvail;
1821}

References min(), mPlaybackBuffers, and mPlaybackTracks.

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

1824{
1825 auto commonlyAvail = mPlaybackBuffers[0]->WrittenForGet();
1826 for (unsigned i = 1; i < mPlaybackTracks.size(); ++i)
1827 commonlyAvail = std::min(commonlyAvail,
1828 mPlaybackBuffers[i]->WrittenForGet());
1829 return commonlyAvail;
1830}

References min(), mPlaybackBuffers, and mPlaybackTracks.

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 185 of file AudioIO.h.

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

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 356 of file AudioIO.h.

356 {
357 return mMixerOutputVol.load(std::memory_order_relaxed); }
std::atomic< float > mMixerOutputVol
Definition: AudioIO.h:297

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

Here is the caller graph for this function:

◆ HasRecordingException()

bool AudioIoCallback::HasRecordingException ( ) const
inline

Definition at line 381 of file AudioIO.h.

382 { 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 399 of file AudioIO.h.

400 { return mLostCaptureIntervals; }

◆ ProcessOnceAndWait()

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

Definition at line 3309 of file AudioIO.cpp.

3310{
3312 .store(true, std::memory_order_release);
3313
3315 .load(std::memory_order_acquire))
3316 {
3317 using namespace std::chrono;
3318 std::this_thread::sleep_for(sleepTime);
3319 }
3320}
std::atomic< bool > mAudioThreadShouldCallTrackBufferExchangeOnce
Definition: AudioIO.h:328

References mAudioThreadShouldCallTrackBufferExchangeOnce.

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

2967{
2968 const auto numCaptureChannels = mNumCaptureChannels;
2969 auto pInputMeter = mInputMeter.lock();
2970 if ( !pInputMeter )
2971 return;
2972 if( pInputMeter->IsMeterDisabled())
2973 return;
2974 pInputMeter->UpdateDisplay(
2975 numCaptureChannels, framesPerBuffer, inputSamples);
2976}
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 2979 of file AudioIO.cpp.

2982{
2983 const auto numPlaybackChannels = mNumPlaybackChannels;
2984
2985 auto pOutputMeter = mOutputMeter.lock();
2986 if (!pOutputMeter)
2987 return;
2988 if( pOutputMeter->IsMeterDisabled() )
2989 return;
2990 if( !outputMeterFloats)
2991 return;
2992 pOutputMeter->UpdateDisplay(
2993 numPlaybackChannels, framesPerBuffer, outputMeterFloats);
2994
2995 //v Vaughan, 2011-02-25: Moved this update back to TrackPanel::OnTimer()
2996 // as it helps with playback issues reported by Bill and noted on Bug 258.
2997 // The problem there occurs if Software Playthrough is on.
2998 // Could conditionally do the update here if Software Playthrough is off,
2999 // and in TrackPanel::OnTimer() if Software Playthrough is on, but not now.
3000 // PRL 12 Jul 2015: and what was in TrackPanel::OnTimer is now handled by means of track panel timer events
3001 //MixerBoard* pMixerBoard = mOwningProject->GetMixerBoard();
3002 //if (pMixerBoard)
3003 // pMixerBoard->UpdateMeters(GetStreamTime(),
3004 // (pProj->GetControlToolBar()->GetLastPlayMode() == loopedPlay));
3005}
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:

◆ SetListener()

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

Definition at line 2255 of file AudioIO.cpp.

2257{
2258 if (IsBusy())
2259 return;
2260
2261 mListener = listener;
2262}
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 358 of file AudioIO.h.

358 {
359 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 388 of file AudioIO.h.

389 { wxAtomicInc( mRecordingException ); }

Referenced by AudioIO::DrainRecordBuffers().

Here is the caller graph for this function:

◆ StartAudioThread()

void AudioIoCallback::StartAudioThread ( )

Definition at line 3279 of file AudioIO.cpp.

3280{
3281 mAudioThreadTrackBufferExchangeLoopRunning.store(true, std::memory_order_release);
3282}

References mAudioThreadTrackBufferExchangeLoopRunning.

Referenced by AudioIO::StartStream().

Here is the caller graph for this function:

◆ StopAudioThread()

void AudioIoCallback::StopAudioThread ( )

Definition at line 3294 of file AudioIO.cpp.

3295{
3296 mAudioThreadTrackBufferExchangeLoopRunning.store(false, std::memory_order_release);
3297}

References mAudioThreadTrackBufferExchangeLoopRunning.

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

Here is the caller graph for this function:

◆ TrackHasBeenFadedOut()

bool AudioIoCallback::TrackHasBeenFadedOut ( const SampleTrack wt,
const OldChannelGains gains 
)

Definition at line 3039 of file AudioIO.cpp.

3041{
3042 const auto channel = wt.GetChannelIgnoringPan();
3043 if ((channel == Track::LeftChannel || channel == Track::MonoChannel) &&
3044 gains[0] != 0.0)
3045 return false;
3046 if ((channel == Track::RightChannel || channel == Track::MonoChannel) &&
3047 gains[1] != 0.0)
3048 return false;
3049 return true;
3050}
virtual ChannelType GetChannelIgnoringPan() const =0

References SampleTrack::GetChannelIgnoringPan(), Track::LeftChannel, Track::MonoChannel, and Track::RightChannel.

Referenced by AllTracksAlreadySilent(), and FillOutputBuffers().

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

◆ TrackShouldBeSilent()

bool AudioIoCallback::TrackShouldBeSilent ( const SampleTrack wt)

Definition at line 3028 of file AudioIO.cpp.

3029{
3030 return IsPaused() || (!wt.GetSolo() && (
3031 // Cut if somebody else is soloing
3033 // Cut if we're muted (and not soloing)
3034 wt.GetMute()
3035 ));
3036}
bool GetSolo() const
Definition: Track.h:925
bool GetMute() const
Definition: Track.h:924

References PlayableTrack::GetMute(), PlayableTrack::GetSolo(), AudioIOBase::IsPaused(), and mbHasSoloTracks.

Referenced by AllTracksAlreadySilent(), and FillOutputBuffers().

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

◆ UpdateTimePosition()

void AudioIoCallback::UpdateTimePosition ( unsigned long  framesPerBuffer)

Definition at line 2753 of file AudioIO.cpp.

2754{
2755 // Quick returns if next to nothing to do.
2756 if (mStreamToken <= 0)
2757 return;
2758
2759 // Update the position seen by drawing code
2762}
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::SetTrackTime().

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

3285{
3286 while (mAudioThreadAcknowledge.load(std::memory_order_acquire) != Acknowledge::eStart)
3287 {
3288 using namespace std::chrono;
3289 std::this_thread::sleep_for(50ms);
3290 }
3291 mAudioThreadAcknowledge.store(Acknowledge::eNone, std::memory_order_release);
3292}
std::atomic< Acknowledge > mAudioThreadAcknowledge
Definition: AudioIO.h:332

References eNone, eStart, and mAudioThreadAcknowledge.

Referenced by AudioIO::StartStream().

Here is the caller graph for this function:

◆ WaitForAudioThreadStopped()

void AudioIoCallback::WaitForAudioThreadStopped ( )

Definition at line 3299 of file AudioIO.cpp.

3300{
3301 while (mAudioThreadAcknowledge.load(std::memory_order_acquire) != Acknowledge::eStop)
3302 {
3303 using namespace std::chrono;
3304 std::this_thread::sleep_for(50ms);
3305 }
3306 mAudioThreadAcknowledge.store(Acknowledge::eNone, std::memory_order_release);
3307}

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 279 of file AudioIO.h.

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

◆ mAudioThreadAcknowledge

std::atomic<Acknowledge> AudioIoCallback::mAudioThreadAcknowledge

◆ mAudioThreadShouldCallTrackBufferExchangeOnce

std::atomic<bool> AudioIoCallback::mAudioThreadShouldCallTrackBufferExchangeOnce

◆ mAudioThreadTrackBufferExchangeLoopActive

std::atomic<bool> AudioIoCallback::mAudioThreadTrackBufferExchangeLoopActive

Definition at line 330 of file AudioIO.h.

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

◆ mAudioThreadTrackBufferExchangeLoopRunning

std::atomic<bool> AudioIoCallback::mAudioThreadTrackBufferExchangeLoopRunning

◆ mbHasSoloTracks

int AudioIoCallback::mbHasSoloTracks

Definition at line 196 of file AudioIO.h.

Referenced by AudioCallback(), and TrackShouldBeSilent().

◆ mbMicroFades

bool AudioIoCallback::mbMicroFades

Read by a worker thread but unchanging during playback

Definition at line 302 of file AudioIO.h.

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

◆ mCachedBestRateCapturing

bool AudioIoCallback::mCachedBestRateCapturing
staticprotected

Definition at line 371 of file AudioIO.h.

Referenced by AudioIO::GetBestRate().

◆ mCachedBestRateOut

double AudioIoCallback::mCachedBestRateOut
staticprotected

Definition at line 369 of file AudioIO.h.

Referenced by AudioIO::GetBestRate().

◆ mCachedBestRatePlaying

bool AudioIoCallback::mCachedBestRatePlaying
staticprotected

Definition at line 370 of file AudioIO.h.

Referenced by AudioIO::GetBestRate().

◆ mCallbackReturn

int AudioIoCallback::mCallbackReturn

Definition at line 197 of file AudioIO.h.

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

◆ mCaptureBuffers

ArrayOf<std::unique_ptr<RingBuffer> > AudioIoCallback::mCaptureBuffers

◆ mCaptureFormat

sampleFormat AudioIoCallback::mCaptureFormat

◆ mCaptureRingBufferSecs

double AudioIoCallback::mCaptureRingBufferSecs

Definition at line 306 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers().

◆ mCaptureTracks

WritableSampleTrackArray AudioIoCallback::mCaptureTracks

◆ mDetectDropouts

bool AudioIoCallback::mDetectDropouts { true }
protected

Read by a worker thread but unchanging during playback

Definition at line 395 of file AudioIO.h.

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

◆ mDetectUpstreamDropouts

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

◆ mFactor

double AudioIoCallback::mFactor

Definition at line 299 of file AudioIO.h.

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

◆ mFinishAudioThread

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

Definition at line 280 of file AudioIO.h.

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

◆ mForceFadeOut

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

Definition at line 346 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 311 of file AudioIO.h.

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

◆ mLastPaError

PaError AudioIoCallback::mLastPaError

◆ mLastPlaybackTimeMillis

wxLongLong AudioIoCallback::mLastPlaybackTimeMillis

Definition at line 348 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 351 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 364 of file AudioIO.h.

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

◆ mLostCaptureIntervals

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

Definition at line 393 of file AudioIO.h.

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

◆ mLostSamples

unsigned long long AudioIoCallback::mLostSamples { 0 }

Definition at line 327 of file AudioIO.h.

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

◆ mMaxFramesOutput

unsigned long AudioIoCallback::mMaxFramesOutput

Definition at line 300 of file AudioIO.h.

Referenced by FillOutputBuffers(), and UpdateTimePosition().

◆ mMinCaptureSecsToCopy

double AudioIoCallback::mMinCaptureSecsToCopy

Definition at line 315 of file AudioIO.h.

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

◆ mMixerOutputVol

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

Definition at line 297 of file AudioIO.h.

◆ mNextStreamToken

int AudioIoCallback::mNextStreamToken = 0
static

Definition at line 298 of file AudioIO.h.

Referenced by AudioIO::StartStream().

◆ mNumCaptureChannels

unsigned int AudioIoCallback::mNumCaptureChannels

◆ mNumPauseFrames

long AudioIoCallback::mNumPauseFrames

How many frames of zeros were output due to pauses?

Definition at line 260 of file AudioIO.h.

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

◆ mNumPlaybackChannels

unsigned int AudioIoCallback::mNumPlaybackChannels

◆ mOldChannelGains

std::vector<OldChannelGains> AudioIoCallback::mOldChannelGains

Definition at line 290 of file AudioIO.h.

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

◆ mPauseRec

bool AudioIoCallback::mPauseRec

True if Sound Activated Recording is enabled.

Read by a worker thread but unchanging during playback

Definition at line 320 of file AudioIO.h.

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

◆ mPlaybackBuffers

ArrayOf<std::unique_ptr<RingBuffer> > 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 313 of file AudioIO.h.

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

◆ mPlaybackRingBufferSecs

PlaybackPolicy::Duration AudioIoCallback::mPlaybackRingBufferSecs

Definition at line 305 of file AudioIO.h.

Referenced by AudioIO::AllocateBuffers().

◆ mPlaybackSamplesToCopy

size_t AudioIoCallback::mPlaybackSamplesToCopy

Preferred batch size for replenishing the playback RingBuffer.

Definition at line 309 of file AudioIO.h.

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

◆ mPlaybackSchedule

PlaybackSchedule AudioIoCallback::mPlaybackSchedule
protected

◆ mPlaybackTracks

SampleTrackConstArray AudioIoCallback::mPlaybackTracks

◆ mpTransportState

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

Holds some state for duration of playback or recording.

Definition at line 415 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 387 of file AudioIO.h.

Referenced by AudioIO::DrainRecordBuffers().

◆ mRecordingSchedule

RecordingSchedule AudioIoCallback::mRecordingSchedule {}
protected

◆ mResample

ArrayOf<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 304 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 317 of file AudioIO.h.

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

◆ mSuspendAudioThread

wxMutex AudioIoCallback::mSuspendAudioThread
protected

Definition at line 375 of file AudioIO.h.

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

◆ mUsingAlsa

bool AudioIoCallback::mUsingAlsa { false }
protected

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