Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Static Public Attributes | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
AudioIOBase Class Referenceabstract

A singleton object supporting queries of the state of any active audio streams, and audio device capabilities. More...

#include <AudioIOBase.h>

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

Public Member Functions

 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)
 

Static Public Member Functions

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 Public Attributes

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...
 

Static Protected Member Functions

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< 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 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...
 

Detailed Description

A singleton object supporting queries of the state of any active audio streams, and audio device capabilities.

Definition at line 101 of file AudioIOBase.h.

Constructor & Destructor Documentation

◆ AudioIOBase() [1/2]

AudioIOBase::AudioIOBase ( )
default

◆ ~AudioIOBase()

AudioIOBase::~AudioIOBase ( )
virtualdefault

◆ AudioIOBase() [2/2]

AudioIOBase::AudioIOBase ( const AudioIOBase )
delete

Member Function Documentation

◆ DeviceName()

wxString AudioIOBase::DeviceName ( const PaDeviceInfo *  info)
staticprotected

Definition at line 73 of file AudioIOBase.cpp.

74{
75 wxString infoName = wxSafeConvertMB2WX(info->name);
76
77 return infoName;
78}

Referenced by GetDeviceInfo(), getPlayDevIndex(), getRecordDevIndex(), and AudioIO::Init().

Here is the caller graph for this function:

◆ Get()

AudioIOBase * AudioIOBase::Get ( )
static

◆ GetAllDeviceInfo()

auto AudioIOBase::GetAllDeviceInfo ( )

Get diagnostic information for audio devices and also for extensions.

Definition at line 924 of file AudioIOBase.cpp.

925{
926 std::vector<AudioIODiagnostics> result;
927 result.push_back({
928 wxT("audiodev.txt"), GetDeviceInfo(), wxT("Audio Device Info") });
929 for( auto &pExt : mAudioIOExt )
930 if ( pExt )
931 result.emplace_back(pExt->Dump());
932 return result;
933}
wxString GetDeviceInfo() const
Get diagnostic information on all the available audio I/O devices.
std::vector< std::unique_ptr< AudioIOExtBase > > mAudioIOExt
Definition: AudioIOBase.h:323

◆ GetDeviceInfo()

wxString AudioIOBase::GetDeviceInfo ( ) const

Get diagnostic information on all the available audio I/O devices.

Definition at line 695 of file AudioIOBase.cpp.

696{
697 wxStringOutputStream o;
698 wxTextOutputStream s(o, wxEOL_UNIX);
699
700 if (IsStreamActive()) {
701 return XO("Stream is active ... unable to gather information.\n")
702 .Translation();
703 }
704
705
706 // FIXME: TRAP_ERR PaErrorCode not handled. 3 instances in GetDeviceInfo().
707 int recDeviceNum = Pa_GetDefaultInputDevice();
708 int playDeviceNum = Pa_GetDefaultOutputDevice();
709 int cnt = Pa_GetDeviceCount();
710
711 // PRL: why only into the log?
712 wxLogDebug(wxT("Portaudio reports %d audio devices"),cnt);
713
714 s << wxT("==============================\n");
715 s << XO("Default recording device number: %d\n").Format( recDeviceNum );
716 s << XO("Default playback device number: %d\n").Format( playDeviceNum);
717
718 auto recDevice = AudioIORecordingDevice.Read();
719 auto playDevice = AudioIOPlaybackDevice.Read();
720 int j;
721
722 // This gets info on all available audio devices (input and output)
723 if (cnt <= 0) {
724 s << XO("No devices found\n");
725 return o.GetString();
726 }
727
728 const PaDeviceInfo* info;
729
730 for (j = 0; j < cnt; j++) {
731 s << wxT("==============================\n");
732
733 info = Pa_GetDeviceInfo(j);
734 if (!info) {
735 s << XO("Device info unavailable for: %d\n").Format( j );
736 continue;
737 }
738
739 wxString name = DeviceName(info);
740 s << XO("Device ID: %d\n").Format( j );
741 s << XO("Device name: %s\n").Format( name );
742 s << XO("Host name: %s\n").Format( HostName(info) );
743 s << XO("Recording channels: %d\n").Format( info->maxInputChannels );
744 s << XO("Playback channels: %d\n").Format( info->maxOutputChannels );
745 s << XO("Low Recording Latency: %g\n").Format( info->defaultLowInputLatency );
746 s << XO("Low Playback Latency: %g\n").Format( info->defaultLowOutputLatency );
747 s << XO("High Recording Latency: %g\n").Format( info->defaultHighInputLatency );
748 s << XO("High Playback Latency: %g\n").Format( info->defaultHighOutputLatency );
749
750 auto rates = GetSupportedPlaybackRates(j, 0.0);
751
752 /* i18n-hint: Supported, meaning made available by the system */
753 s << XO("Supported Rates:\n");
754 for (int k = 0; k < (int) rates.size(); k++) {
755 s << wxT(" ") << (int)rates[k] << wxT("\n");
756 }
757
758 if (name == playDevice && info->maxOutputChannels > 0)
759 playDeviceNum = j;
760
761 if (name == recDevice && info->maxInputChannels > 0)
762 recDeviceNum = j;
763
764 // Sometimes PortAudio returns -1 if it cannot find a suitable default
765 // device, so we just use the first one available
766 if (recDeviceNum < 0 && info->maxInputChannels > 0){
767 recDeviceNum = j;
768 }
769 if (playDeviceNum < 0 && info->maxOutputChannels > 0){
770 playDeviceNum = j;
771 }
772 }
773
774 bool haveRecDevice = (recDeviceNum >= 0);
775 bool havePlayDevice = (playDeviceNum >= 0);
776
777 s << wxT("==============================\n");
778 if (haveRecDevice)
779 s << XO("Selected recording device: %d - %s\n").Format( recDeviceNum, recDevice );
780 else
781 s << XO("No recording device found for '%s'.\n").Format( recDevice );
782
783 if (havePlayDevice)
784 s << XO("Selected playback device: %d - %s\n").Format( playDeviceNum, playDevice );
785 else
786 s << XO("No playback device found for '%s'.\n").Format( playDevice );
787
788 std::vector<long> supportedSampleRates;
789
790 if (havePlayDevice && haveRecDevice) {
791 supportedSampleRates = GetSupportedSampleRates(playDeviceNum, recDeviceNum);
792
793 s << XO("Supported Rates:\n");
794 for (int k = 0; k < (int) supportedSampleRates.size(); k++) {
795 s << wxT(" ") << (int)supportedSampleRates[k] << wxT("\n");
796 }
797 }
798 else {
799 s << XO("Cannot check mutual sample rates without both devices.\n");
800 return o.GetString();
801 }
802
803#if defined(USE_PORTMIXER)
804 if (supportedSampleRates.size() > 0)
805 {
806 int highestSampleRate = supportedSampleRates.back();
807 bool EmulateMixerInputVol = true;
808 float MixerInputVol = 1.0;
809 float MixerOutputVol = 1.0;
810
811 int error;
812
813 PaStream *stream;
814
815 PaStreamParameters playbackParameters;
816
817 playbackParameters.device = playDeviceNum;
818 playbackParameters.sampleFormat = paFloat32;
819 playbackParameters.hostApiSpecificStreamInfo = NULL;
820 playbackParameters.channelCount = 1;
821 if (Pa_GetDeviceInfo(playDeviceNum)){
822 playbackParameters.suggestedLatency =
823 Pa_GetDeviceInfo(playDeviceNum)->defaultLowOutputLatency;
824 }
825 else
826 playbackParameters.suggestedLatency =
828
829 PaStreamParameters captureParameters;
830
831 captureParameters.device = recDeviceNum;
832 captureParameters.sampleFormat = paFloat32;;
833 captureParameters.hostApiSpecificStreamInfo = NULL;
834 captureParameters.channelCount = 1;
835 if (Pa_GetDeviceInfo(recDeviceNum)){
836 captureParameters.suggestedLatency =
837 Pa_GetDeviceInfo(recDeviceNum)->defaultLowInputLatency;
838 }
839 else
840 captureParameters.suggestedLatency =
842
843 // Not really doing I/O so pass nullptr for the callback function
844 error = Pa_OpenStream(&stream,
845 &captureParameters, &playbackParameters,
846 highestSampleRate, paFramesPerBufferUnspecified,
847 paClipOff | paDitherOff,
848 nullptr, NULL);
849
850 if (error) {
851 error = Pa_OpenStream(&stream,
852 &captureParameters, NULL,
853 highestSampleRate, paFramesPerBufferUnspecified,
854 paClipOff | paDitherOff,
855 nullptr, NULL);
856 }
857
858 if (error) {
859 s << XO("Received %d while opening devices\n").Format( error );
860 return o.GetString();
861 }
862
863 PxMixer *PortMixer = Px_OpenMixer(stream, recDeviceNum, playDeviceNum, 0);
864
865 if (!PortMixer) {
866 s << XO("Unable to open Portmixer\n");
867 Pa_CloseStream(stream);
868 return o.GetString();
869 }
870
871 s << wxT("==============================\n");
872 s << XO("Available mixers:\n");
873
874 // FIXME: ? PortMixer errors on query not reported in GetDeviceInfo
875 cnt = Px_GetNumMixers(stream);
876 for (int i = 0; i < cnt; i++) {
877 wxString name = wxSafeConvertMB2WX(Px_GetMixerName(stream, i));
878 s << XO("%d - %s\n").Format( i, name );
879 }
880
881 s << wxT("==============================\n");
882 s << XO("Available recording sources:\n");
883 cnt = Px_GetNumInputSources(PortMixer);
884 for (int i = 0; i < cnt; i++) {
885 wxString name = wxSafeConvertMB2WX(Px_GetInputSourceName(PortMixer, i));
886 s << XO("%d - %s\n").Format( i, name );
887 }
888
889 s << wxT("==============================\n");
890 s << XO("Available playback volumes:\n");
891 cnt = Px_GetNumOutputVolumes(PortMixer);
892 for (int i = 0; i < cnt; i++) {
893 wxString name = wxSafeConvertMB2WX(Px_GetOutputVolumeName(PortMixer, i));
894 s << XO("%d - %s\n").Format( i, name );
895 }
896
897 // Check, if PortMixer supports adjusting input levels on the interface
898
899 MixerInputVol = Px_GetInputVolume(PortMixer);
900 EmulateMixerInputVol = false;
901 Px_SetInputVolume(PortMixer, 0.0);
902 if (Px_GetInputVolume(PortMixer) > 0.1)
903 EmulateMixerInputVol = true;
904 Px_SetInputVolume(PortMixer, 0.2f);
905 if (Px_GetInputVolume(PortMixer) < 0.1 ||
906 Px_GetInputVolume(PortMixer) > 0.3)
907 EmulateMixerInputVol = true;
908 Px_SetInputVolume(PortMixer, MixerInputVol);
909
910 Pa_CloseStream(stream);
911
912 s << wxT("==============================\n");
913 s << ( EmulateMixerInputVol
914 ? XO("Recording volume is emulated\n")
915 : XO("Recording volume is native\n") );
916
917 Px_CloseMixer(PortMixer);
918
919 } //end of massive if statement if a valid sample rate has been found
920#endif
921 return o.GetString();
922}
DoubleSetting AudioIOLatencyCorrection
StringSetting AudioIOPlaybackDevice
StringSetting AudioIORecordingDevice
void PaStream
Definition: AudioIOBase.h:23
const TranslatableString name
Definition: Distortion.cpp:82
#define XO(s)
Definition: Internat.h:31
static wxString HostName(const PaDeviceInfo *info)
Definition: AudioIOBase.cpp:80
static std::vector< long > GetSupportedPlaybackRates(int DevIndex=-1, double rate=0.0)
Get a list of sample rates the output (playback) device supports.
bool IsStreamActive() const
Returns true if the audio i/o is running at all, but not during cleanup.
static wxString DeviceName(const PaDeviceInfo *info)
Definition: AudioIOBase.cpp:73
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.
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:200
const T & GetDefault() const
Definition: Prefs.h:192

References AudioIOLatencyCorrection, AudioIOPlaybackDevice, AudioIORecordingDevice, DeviceName(), Setting< T >::GetDefault(), GetSupportedPlaybackRates(), GetSupportedSampleRates(), HostName(), IsStreamActive(), name, Setting< T >::Read(), and XO.

Here is the call graph for this function:

◆ GetOptimalSupportedSampleRate()

int AudioIOBase::GetOptimalSupportedSampleRate ( )
static

Get a supported sample rate which can be used a an optimal default.

Currently, this uses the first supported rate in the list [44100, 48000, highest sample rate]. Used in Project as a default value for project rates if one cannot be retrieved from the preferences. So all in all not that useful or important really

Todo:
: should this take into account PortAudio's value for PaDeviceInfo::defaultSampleRate? In principal this should let us work out which rates are "real" and which resampled in the drivers, and so prefer the real rates.

Definition at line 549 of file AudioIOBase.cpp.

550{
551 auto rates = GetSupportedSampleRates();
552
553 if (make_iterator_range(rates).contains(44100))
554 return 44100;
555
556 if (make_iterator_range(rates).contains(48000))
557 return 48000;
558
559 // if there are no supported rates, the next bit crashes. So check first,
560 // and give them a "sensible" value if there are no valid values. They
561 // will still get an error later, but with any luck may have changed
562 // something by then. It's no worse than having an invalid default rate
563 // stored in the preferences, which we don't check for
564 if (rates.empty()) return 44100;
565
566 return rates.back();
567}
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:423

References GetSupportedSampleRates(), and make_iterator_range().

Here is the call graph for this function:

◆ getPlayDevIndex()

int AudioIOBase::getPlayDevIndex ( const wxString &  devName = {})
staticprotected

get the index of the device selected in the preferences.

If the device isn't found, returns -1

get the index of the supplied (named) playback device, or the device selected in the preferences if none given.

Pure utility function, but it comes round a number of times in the code and would be neater done once. If the device isn't found, return the default device index.

Definition at line 583 of file AudioIOBase.cpp.

584{
585 wxString devName(devNameArg);
586 // if we don't get given a device, look up the preferences
587 if (devName.empty())
588 devName = AudioIOPlaybackDevice.Read();
589
590 auto hostName = AudioIOHost.Read();
591 PaHostApiIndex hostCnt = Pa_GetHostApiCount();
592 PaHostApiIndex hostNum;
593 for (hostNum = 0; hostNum < hostCnt; hostNum++)
594 {
595 const PaHostApiInfo *hinfo = Pa_GetHostApiInfo(hostNum);
596 if (hinfo && wxString(wxSafeConvertMB2WX(hinfo->name)) == hostName)
597 {
598 for (PaDeviceIndex hostDevice = 0; hostDevice < hinfo->deviceCount; hostDevice++)
599 {
600 PaDeviceIndex deviceNum = Pa_HostApiDeviceIndexToDeviceIndex(hostNum, hostDevice);
601
602 const PaDeviceInfo *dinfo = Pa_GetDeviceInfo(deviceNum);
603 if (dinfo && DeviceName(dinfo) == devName && dinfo->maxOutputChannels > 0 )
604 {
605 // this device name matches the stored one, and works.
606 // So we say this is the answer and return it
607 return deviceNum;
608 }
609 }
610
611 // The device wasn't found so use the default for this host.
612 // LL: At this point, preferences and active no longer match.
613 return hinfo->defaultOutputDevice;
614 }
615 }
616
617 // The host wasn't found, so use the default output device.
618 // FIXME: TRAP_ERR PaErrorCode not handled well (this code is similar to input code
619 // and the input side has more comments.)
620
621 PaDeviceIndex deviceNum = Pa_GetDefaultOutputDevice();
622
623 // Sometimes PortAudio returns -1 if it cannot find a suitable default
624 // device, so we just use the first one available
625 //
626 // LL: At this point, preferences and active no longer match
627 //
628 // And I can't imagine how far we'll get specifying an "invalid" index later
629 // on...are we certain "0" even exists?
630 if (deviceNum < 0) {
631 wxASSERT(false);
632 deviceNum = 0;
633 }
634
635 return deviceNum;
636}
StringSetting AudioIOHost

References AudioIOHost, AudioIOPlaybackDevice, DeviceName(), and Setting< T >::Read().

Referenced by GetSupportedPlaybackRates(), GetSupportedSampleRates(), HandleDeviceChange(), AudioIO::Init(), AudioIO::StartPortAudioStream(), and AudioIO::ValidateDeviceNames().

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

◆ getRecordDevIndex()

int AudioIOBase::getRecordDevIndex ( const wxString &  devName = {})
staticprotected

get the index of the supplied (named) recording device, or the device selected in the preferences if none given.

Pure utility function, but it comes round a number of times in the code and would be neater done once. If the device isn't found, return the default device index.

Definition at line 638 of file AudioIOBase.cpp.

639{
640 wxString devName(devNameArg);
641 // if we don't get given a device, look up the preferences
642 if (devName.empty())
643 devName = AudioIORecordingDevice.Read();
644
645 auto hostName = AudioIOHost.Read();
646 PaHostApiIndex hostCnt = Pa_GetHostApiCount();
647 PaHostApiIndex hostNum;
648 for (hostNum = 0; hostNum < hostCnt; hostNum++)
649 {
650 const PaHostApiInfo *hinfo = Pa_GetHostApiInfo(hostNum);
651 if (hinfo && wxString(wxSafeConvertMB2WX(hinfo->name)) == hostName)
652 {
653 for (PaDeviceIndex hostDevice = 0; hostDevice < hinfo->deviceCount; hostDevice++)
654 {
655 PaDeviceIndex deviceNum = Pa_HostApiDeviceIndexToDeviceIndex(hostNum, hostDevice);
656
657 const PaDeviceInfo *dinfo = Pa_GetDeviceInfo(deviceNum);
658 if (dinfo && DeviceName(dinfo) == devName && dinfo->maxInputChannels > 0 )
659 {
660 // this device name matches the stored one, and works.
661 // So we say this is the answer and return it
662 return deviceNum;
663 }
664 }
665
666 // The device wasn't found so use the default for this host.
667 // LL: At this point, preferences and active no longer match.
668 return hinfo->defaultInputDevice;
669 }
670 }
671
672 // The host wasn't found, so use the default input device.
673 // FIXME: TRAP_ERR PaErrorCode not handled well in getRecordDevIndex()
674 PaDeviceIndex deviceNum = Pa_GetDefaultInputDevice();
675
676 // Sometimes PortAudio returns -1 if it cannot find a suitable default
677 // device, so we just use the first one available
678 // PortAudio has an error reporting function. We should log/report the error?
679 //
680 // LL: At this point, preferences and active no longer match
681 //
682 // And I can't imagine how far we'll get specifying an "invalid" index later
683 // on...are we certain "0" even exists?
684 if (deviceNum < 0) {
685 // JKC: This ASSERT will happen if you run with no config file
686 // This happens once. Config file will exist on the next run.
687 // TODO: Look into this a bit more. Could be relevant to blank Device Toolbar.
688 wxASSERT(false);
689 deviceNum = 0;
690 }
691
692 return deviceNum;
693}

References AudioIOHost, AudioIORecordingDevice, DeviceName(), and Setting< T >::Read().

Referenced by GetSupportedCaptureRates(), GetSupportedSampleRates(), HandleDeviceChange(), AudioIO::Init(), AudioIO::StartPortAudioStream(), and AudioIO::ValidateDeviceNames().

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

◆ GetSupportedCaptureRates()

std::vector< long > AudioIOBase::GetSupportedCaptureRates ( int  devIndex = -1,
double  rate = 0.0 
)
static

Get a list of sample rates the input (recording) device supports.

If no information about available sample rates can be fetched, an empty list is returned.

You can explicitly give the index of the device. If you don't give it, the currently selected device from the preferences will be used.

You may also specify a rate for which to check in addition to the standard rates.

Definition at line 435 of file AudioIOBase.cpp.

436{
437 if (devIndex == -1)
438 { // not given a device, look up in prefs / default
439 devIndex = getRecordDevIndex();
440 }
441
442 // Check if we can use the cached rates
443 if (mCachedCaptureIndex != -1 && devIndex == mCachedCaptureIndex
444 && (rate == 0.0 || make_iterator_range(mCachedCaptureRates).contains(rate)))
445 {
446 return mCachedCaptureRates;
447 }
448
449 std::vector<long> supported;
450 int irate = (int)rate;
451 const PaDeviceInfo* devInfo = NULL;
452 int i;
453
454 devInfo = Pa_GetDeviceInfo(devIndex);
455
456 if (!devInfo)
457 {
458 wxLogDebug(wxT("GetSupportedCaptureRates() Could not get device info!"));
459 return supported;
460 }
461
462 auto latencyDuration = AudioIOLatencyDuration.Read();
463 // Why not defaulting to 2 as elsewhere?
464 auto recordChannels = AudioIORecordChannels.ReadWithDefault(1);
465
466 // LLL: Remove when a proper method of determining actual supported
467 // DirectSound rate is devised.
468 const PaHostApiInfo* hostInfo = Pa_GetHostApiInfo(devInfo->hostApi);
469 bool isDirectSound = (hostInfo && hostInfo->type == paDirectSound);
470
471 PaStreamParameters pars;
472
473 pars.device = devIndex;
474 pars.channelCount = recordChannels;
475 pars.sampleFormat = paFloat32;
476 pars.suggestedLatency = latencyDuration / 1000.0;
477 pars.hostApiSpecificStreamInfo = NULL;
478
479 for (i = 0; i < NumRatesToTry; i++)
480 {
481 // LLL: Remove when a proper method of determining actual supported
482 // DirectSound rate is devised.
483 if (!(isDirectSound && RatesToTry[i] > 200000))
484 {
485 if (Pa_IsFormatSupported(&pars, NULL, RatesToTry[i]) == 0)
486 supported.push_back(RatesToTry[i]);
487 Pa_Sleep( 10 );// There are ALSA drivers that don't like being probed
488 // too quickly.
489 }
490 }
491
492 if (irate != 0 && !make_iterator_range(supported).contains(irate))
493 {
494 // LLL: Remove when a proper method of determining actual supported
495 // DirectSound rate is devised.
496 if (!(isDirectSound && RatesToTry[i] > 200000))
497 if (Pa_IsFormatSupported(&pars, NULL, irate) == 0)
498 supported.push_back(irate);
499 }
500
501 return supported;
502}
DoubleSetting AudioIOLatencyDuration
IntSetting AudioIORecordChannels
static int mCachedCaptureIndex
Definition: AudioIOBase.h:280
static std::vector< long > mCachedCaptureRates
Definition: AudioIOBase.h:281
static const int NumRatesToTry
How many sample rates to try.
Definition: AudioIOBase.h:318
static int getRecordDevIndex(const wxString &devName={})
get the index of the supplied (named) recording device, or the device selected in the preferences if ...
static const int RatesToTry[]
Array of audio sample rates to try to use.
Definition: AudioIOBase.h:316
bool ReadWithDefault(T *pVar, const T &defaultValue) const
overload of ReadWithDefault returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:206

References AudioIOLatencyDuration, AudioIORecordChannels, getRecordDevIndex(), make_iterator_range(), mCachedCaptureIndex, mCachedCaptureRates, NumRatesToTry, RatesToTry, Setting< T >::Read(), and Setting< T >::ReadWithDefault().

Referenced by AudioIO::GetBestRate(), GetSupportedSampleRates(), and HandleDeviceChange().

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

◆ GetSupportedPlaybackRates()

std::vector< long > AudioIOBase::GetSupportedPlaybackRates ( int  DevIndex = -1,
double  rate = 0.0 
)
static

Get a list of sample rates the output (playback) device supports.

If no information about available sample rates can be fetched, an empty list is returned.

You can explicitly give the index of the device. If you don't give it, the currently selected device from the preferences will be used.

You may also specify a rate for which to check in addition to the standard rates.

Definition at line 370 of file AudioIOBase.cpp.

371{
372 if (devIndex == -1)
373 { // weren't given a device index, get the prefs / default one
374 devIndex = getPlayDevIndex();
375 }
376
377 // Check if we can use the cached rates
378 if (mCachedPlaybackIndex != -1 && devIndex == mCachedPlaybackIndex
379 && (rate == 0.0 || make_iterator_range(mCachedPlaybackRates).contains(rate)))
380 {
382 }
383
384 std::vector<long> supported;
385 int irate = (int)rate;
386 const PaDeviceInfo* devInfo = NULL;
387 int i;
388
389 devInfo = Pa_GetDeviceInfo(devIndex);
390
391 if (!devInfo)
392 {
393 wxLogDebug(wxT("GetSupportedPlaybackRates() Could not get device info!"));
394 return supported;
395 }
396
397 // LLL: Remove when a proper method of determining actual supported
398 // DirectSound rate is devised.
399 const PaHostApiInfo* hostInfo = Pa_GetHostApiInfo(devInfo->hostApi);
400 bool isDirectSound = (hostInfo && hostInfo->type == paDirectSound);
401
402 PaStreamParameters pars;
403
404 pars.device = devIndex;
405 pars.channelCount = 1;
406 pars.sampleFormat = paFloat32;
407 pars.suggestedLatency = devInfo->defaultHighOutputLatency;
408 pars.hostApiSpecificStreamInfo = NULL;
409
410 // JKC: PortAudio Errors handled OK here. No need to report them
411 for (i = 0; i < NumRatesToTry; i++)
412 {
413 // LLL: Remove when a proper method of determining actual supported
414 // DirectSound rate is devised.
415 if (!(isDirectSound && RatesToTry[i] > 200000)){
416 if (Pa_IsFormatSupported(NULL, &pars, RatesToTry[i]) == 0)
417 supported.push_back(RatesToTry[i]);
418 Pa_Sleep( 10 );// There are ALSA drivers that don't like being probed
419 // too quickly.
420 }
421 }
422
423 if (irate != 0 && !make_iterator_range(supported).contains(irate))
424 {
425 // LLL: Remove when a proper method of determining actual supported
426 // DirectSound rate is devised.
427 if (!(isDirectSound && RatesToTry[i] > 200000))
428 if (Pa_IsFormatSupported(NULL, &pars, irate) == 0)
429 supported.push_back(irate);
430 }
431
432 return supported;
433}
static int getPlayDevIndex(const wxString &devName={})
get the index of the device selected in the preferences.
static std::vector< long > mCachedPlaybackRates
Definition: AudioIOBase.h:279
static int mCachedPlaybackIndex
Definition: AudioIOBase.h:278

References getPlayDevIndex(), make_iterator_range(), mCachedPlaybackIndex, mCachedPlaybackRates, NumRatesToTry, and RatesToTry.

Referenced by AudioIO::GetBestRate(), GetDeviceInfo(), GetSupportedSampleRates(), and HandleDeviceChange().

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

◆ GetSupportedSampleRates()

std::vector< long > AudioIOBase::GetSupportedSampleRates ( int  playDevice = -1,
int  recDevice = -1,
double  rate = 0.0 
)
static

Get a list of sample rates the current input/output device combination supports.

Since there is no concept (yet) for different input/output sample rates, this currently returns only sample rates that are supported on both the output and input device. If no information about available sample rates can be fetched, it returns a default list. You can explicitly give the indexes of the playDevice/recDevice. If you don't give them, the selected devices from the preferences will be used. You may also specify a rate for which to check in addition to the standard rates.

Definition at line 504 of file AudioIOBase.cpp.

506{
507 // Not given device indices, look up prefs
508 if (playDevice == -1) {
509 playDevice = getPlayDevIndex();
510 }
511 if (recDevice == -1) {
512 recDevice = getRecordDevIndex();
513 }
514
515 // Check if we can use the cached rates
516 if (mCachedPlaybackIndex != -1 && mCachedCaptureIndex != -1 &&
517 playDevice == mCachedPlaybackIndex &&
518 recDevice == mCachedCaptureIndex &&
519 (rate == 0.0 || make_iterator_range(mCachedSampleRates).contains(rate)))
520 {
521 return mCachedSampleRates;
522 }
523
524 auto playback = GetSupportedPlaybackRates(playDevice, rate);
525 auto capture = GetSupportedCaptureRates(recDevice, rate);
526 int i;
527
528 // Return only sample rates which are in both arrays
529 std::vector<long> result;
530
531 for (i = 0; i < (int)playback.size(); i++)
532 if (make_iterator_range(capture).contains(playback[i]))
533 result.push_back(playback[i]);
534
535 // If this yields no results, use the default sample rates nevertheless
536/* if (result.empty())
537 {
538 for (i = 0; i < NumStandardRates; i++)
539 result.push_back(StandardRates[i]);
540 }*/
541
542 return result;
543}
static std::vector< long > mCachedSampleRates
Definition: AudioIOBase.h:282
static std::vector< long > GetSupportedCaptureRates(int devIndex=-1, double rate=0.0)
Get a list of sample rates the input (recording) device supports.

References getPlayDevIndex(), getRecordDevIndex(), GetSupportedCaptureRates(), GetSupportedPlaybackRates(), make_iterator_range(), mCachedCaptureIndex, mCachedPlaybackIndex, and mCachedSampleRates.

Referenced by AudioIO::GetBestRate(), GetDeviceInfo(), GetOptimalSupportedSampleRate(), and HandleDeviceChange().

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

◆ HandleDeviceChange()

void AudioIOBase::HandleDeviceChange ( )

update state after changing what audio devices are selected

Called when the devices stored in the preferences are changed to update the audio mixer capabilities

Todo:
: Make this do a sample rate query and store the result in the AudioIO object to avoid doing it later? Would simplify the GetSupported*Rate functions considerably

Definition at line 109 of file AudioIOBase.cpp.

110{
111 // This should not happen, but it would screw things up if it did.
112 // Vaughan, 2010-10-08: But it *did* happen, due to a bug, and nobody
113 // caught it because this method just returned. Added wxASSERT().
114 wxASSERT(!IsStreamActive());
115 if (IsStreamActive())
116 return;
117
118 // get the selected record and playback devices
119 const int playDeviceNum = getPlayDevIndex();
120 const int recDeviceNum = getRecordDevIndex();
121
122 // If no change needed, return
123 if (mCachedPlaybackIndex == playDeviceNum &&
124 mCachedCaptureIndex == recDeviceNum)
125 return;
126
127 // cache playback/capture rates
130 mCachedSampleRates = GetSupportedSampleRates(playDeviceNum, recDeviceNum);
131 mCachedPlaybackIndex = playDeviceNum;
132 mCachedCaptureIndex = recDeviceNum;
133 mCachedBestRateIn = 0.0;
134
135#if defined(USE_PORTMIXER)
136
137 // if we have a PortMixer object, close it down
138 if (mPortMixer) {
139 #if __WXMAC__
140 // on the Mac we must make sure that we restore the hardware playthrough
141 // state of the sound device to what it was before, because there isn't
142 // a UI for this (!)
143 if (Px_SupportsPlaythrough(mPortMixer) && mPreviousHWPlaythrough >= 0.0)
144 Px_SetPlaythrough(mPortMixer, mPreviousHWPlaythrough);
145 mPreviousHWPlaythrough = -1.0;
146 #endif
147 Px_CloseMixer(mPortMixer);
148 mPortMixer = NULL;
149 }
150
151 // that might have given us no rates whatsoever, so we have to guess an
152 // answer to do the next bit
153 int numrates = mCachedSampleRates.size();
154 int highestSampleRate;
155 if (numrates > 0)
156 {
157 highestSampleRate = mCachedSampleRates[numrates - 1];
158 }
159 else
160 { // we don't actually have any rates that work for Rec and Play. Guess one
161 // to use for messing with the mixer, which doesn't actually do either
162 highestSampleRate = 44100;
163 // mCachedSampleRates is still empty, but it's not used again, so
164 // can ignore
165 }
166
167 mInputMixerWorks = false;
168
169 int error;
170 // This tries to open the device with the samplerate worked out above, which
171 // will be the highest available for play and record on the device, or
172 // 44.1kHz if the info cannot be fetched.
173
174 PaStream *stream;
175
176 PaStreamParameters playbackParameters;
177
178 playbackParameters.device = playDeviceNum;
179 playbackParameters.sampleFormat = paFloat32;
180 playbackParameters.hostApiSpecificStreamInfo = NULL;
181 playbackParameters.channelCount = 1;
182 if (Pa_GetDeviceInfo(playDeviceNum))
183 playbackParameters.suggestedLatency =
184 Pa_GetDeviceInfo(playDeviceNum)->defaultLowOutputLatency;
185 else
186 playbackParameters.suggestedLatency =
188
189 PaStreamParameters captureParameters;
190
191 captureParameters.device = recDeviceNum;
192 captureParameters.sampleFormat = paFloat32;;
193 captureParameters.hostApiSpecificStreamInfo = NULL;
194 captureParameters.channelCount = 1;
195 if (Pa_GetDeviceInfo(recDeviceNum))
196 captureParameters.suggestedLatency =
197 Pa_GetDeviceInfo(recDeviceNum)->defaultLowInputLatency;
198 else
199 captureParameters.suggestedLatency =
201
202 // try opening for record and playback
203 // Not really doing I/O so pass nullptr for the callback function
204 error = Pa_OpenStream(&stream,
205 &captureParameters, &playbackParameters,
206 highestSampleRate, paFramesPerBufferUnspecified,
207 paClipOff | paDitherOff,
208 nullptr, NULL);
209
210 if (!error) {
211 // Try portmixer for this stream
212 mPortMixer = Px_OpenMixer(stream, recDeviceNum, playDeviceNum, 0);
213 if (!mPortMixer) {
214 Pa_CloseStream(stream);
215 error = true;
216 }
217 }
218
219 // if that failed, try just for record
220 if( error ) {
221 error = Pa_OpenStream(&stream,
222 &captureParameters, NULL,
223 highestSampleRate, paFramesPerBufferUnspecified,
224 paClipOff | paDitherOff,
225 nullptr, NULL);
226
227 if (!error) {
228 mPortMixer = Px_OpenMixer(stream, recDeviceNum, playDeviceNum, 0);
229 if (!mPortMixer) {
230 Pa_CloseStream(stream);
231 error = true;
232 }
233 }
234 }
235
236 // finally, try just for playback
237 if ( error ) {
238 error = Pa_OpenStream(&stream,
239 NULL, &playbackParameters,
240 highestSampleRate, paFramesPerBufferUnspecified,
241 paClipOff | paDitherOff,
242 nullptr, NULL);
243
244 if (!error) {
245 mPortMixer = Px_OpenMixer(stream, recDeviceNum, playDeviceNum, 0);
246 if (!mPortMixer) {
247 Pa_CloseStream(stream);
248 error = true;
249 }
250 }
251 }
252
253 // FIXME: TRAP_ERR errors in HandleDeviceChange not reported.
254 // if it's still not working, give up
255 if( error )
256 return;
257
258 // Set input source
259#if USE_PORTMIXER
260 auto sourceIndex = AudioIORecordingSourceIndex.Read(); // defaults to -1
261 if (sourceIndex >= 0) {
262 //the current index of our source may be different because the stream
263 //is a combination of two devices, so update it.
264 sourceIndex = getRecordSourceIndex(mPortMixer);
265 if (sourceIndex >= 0)
266 SetMixer(sourceIndex);
267 }
268#endif
269
270 // Determine mixer capabilities - if it doesn't support control of output
271 // signal level, we emulate it (by multiplying this value by all outgoing
272 // samples)
273
274 float inputVol = Px_GetInputVolume(mPortMixer);
275 mInputMixerWorks = true; // assume it works unless proved wrong
276 Px_SetInputVolume(mPortMixer, 0.0);
277 if (Px_GetInputVolume(mPortMixer) > 0.1)
278 mInputMixerWorks = false; // can't set to zero
279 Px_SetInputVolume(mPortMixer, 0.2f);
280 if (Px_GetInputVolume(mPortMixer) < 0.1 ||
281 Px_GetInputVolume(mPortMixer) > 0.3)
282 mInputMixerWorks = false; // can't set level accurately
283 Px_SetInputVolume(mPortMixer, inputVol);
284
285 Pa_CloseStream(stream);
286
287
288 #if 0
289 wxPrintf("PortMixer: Recording: %s\n"
290 mInputMixerWorks? "hardware": "no control");
291 #endif
292#endif // USE_PORTMIXER
293}
IntSetting AudioIORecordingSourceIndex
static double mCachedBestRateIn
Definition: AudioIOBase.h:283
void SetMixer(int inputSource)
bool mInputMixerWorks
Can we control the hardware input level?
Definition: AudioIOBase.h:275

References AudioIOLatencyCorrection, AudioIORecordingSourceIndex, Setting< T >::GetDefault(), getPlayDevIndex(), getRecordDevIndex(), GetSupportedCaptureRates(), GetSupportedPlaybackRates(), GetSupportedSampleRates(), IsStreamActive(), mCachedBestRateIn, mCachedCaptureIndex, mCachedCaptureRates, mCachedPlaybackIndex, mCachedPlaybackRates, mCachedSampleRates, mInputMixerWorks, Setting< T >::Read(), and SetMixer().

Referenced by AudioIO::AudioIO().

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

◆ HostName()

wxString AudioIOBase::HostName ( const PaDeviceInfo *  info)
staticprotected

Definition at line 80 of file AudioIOBase.cpp.

81{
82 wxString hostapiName = wxSafeConvertMB2WX(Pa_GetHostApiInfo(info->hostApi)->name);
83
84 return hostapiName;
85}

Referenced by GetDeviceInfo(), and AudioIO::Init().

Here is the caller graph for this function:

◆ IsAudioTokenActive()

bool AudioIOBase::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.

This is used by TrackPanel to determine when a track has been completely recorded, and it's safe to flush to disk.

Definition at line 360 of file AudioIOBase.cpp.

361{
362 return ( token > 0 && token == mStreamToken );
363}
int mStreamToken
Definition: AudioIOBase.h:252

References mStreamToken.

Referenced by AudioIOBusyPred(), and IsStreamActive().

Here is the caller graph for this function:

◆ IsBusy()

bool AudioIOBase::IsBusy ( ) const

Returns true if audio i/o is busy starting, stopping, playing, or recording.

When this is false, it's safe to start playing or recording

Definition at line 334 of file AudioIOBase.cpp.

335{
336 if (mStreamToken != 0)
337 return true;
338
339 return false;
340}

References mStreamToken.

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

Here is the caller graph for this function:

◆ IsMonitoring()

bool AudioIOBase::IsMonitoring ( ) const

Returns true if we're monitoring input (but not recording or playing actual audio)

Definition at line 365 of file AudioIOBase.cpp.

366{
367 return ( mPortStreamV19 && mStreamToken==0 );
368}
PaStream * mPortStreamV19
Definition: AudioIOBase.h:258

References mPortStreamV19, and mStreamToken.

Referenced by AudioIO::AudioThread().

Here is the caller graph for this function:

◆ IsPaused()

bool AudioIOBase::IsPaused ( ) const

Find out if playback / recording is currently paused.

Definition at line 329 of file AudioIOBase.cpp.

330{
331 return mPaused.load(std::memory_order_relaxed);
332}
std::atomic< bool > mPaused
True if audio playback is paused.
Definition: AudioIOBase.h:249

References mPaused.

Referenced by AudioIoCallback::AddToOutputChannel(), AudioIoCallback::AudioCallback(), AudioIoCallback::CallbackCheckCompletion(), AudioIoCallback::CheckSoundActivatedRecordingLevel(), PausedFlag(), AudioIO::SetPaused(), and AudioIoCallback::TrackShouldBeSilent().

Here is the caller graph for this function:

◆ IsStreamActive() [1/2]

bool AudioIOBase::IsStreamActive ( ) const

Returns true if the audio i/o is running at all, but not during cleanup.

Doesn't return true if the device has been closed but some disk i/o or cleanup is still going on. If you want to know if it's safe to start a NEW stream, use IsBusy()

Definition at line 342 of file AudioIOBase.cpp.

343{
344 bool isActive = false;
345 // JKC: Not reporting any Pa error, but that looks OK.
346 if( mPortStreamV19 )
347 isActive = (Pa_IsStreamActive( mPortStreamV19 ) > 0);
348
349 isActive = isActive ||
350 std::any_of(mAudioIOExt.begin(), mAudioIOExt.end(),
351 [](auto &pExt){ return pExt && pExt->IsOtherStreamActive(); });
352 return isActive;
353}

References mAudioIOExt, and mPortStreamV19.

Referenced by AudioIO::DrainRecordBuffers(), GetDeviceInfo(), AudioIO::GetStreamTime(), HandleDeviceChange(), AudioIO::IsCapturing(), and IsStreamActive().

Here is the caller graph for this function:

◆ IsStreamActive() [2/2]

bool AudioIOBase::IsStreamActive ( int  token) const

Definition at line 355 of file AudioIOBase.cpp.

356{
357 return (this->IsStreamActive() && this->IsAudioTokenActive(token));
358}
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...

References IsAudioTokenActive(), and IsStreamActive().

Here is the call graph for this function:

◆ operator=()

AudioIOBase & AudioIOBase::operator= ( const AudioIOBase )
delete

◆ SetCaptureMeter()

void AudioIOBase::SetCaptureMeter ( const std::shared_ptr< AudacityProject > &  project,
const std::weak_ptr< Meter > &  meter 
)

Definition at line 295 of file AudioIOBase.cpp.

297{
298 if (auto pOwningProject = mOwningProject.lock();
299 ( pOwningProject ) && ( pOwningProject != project))
300 return;
301
302 auto meter = wMeter.lock();
303 if (meter)
304 {
305 mInputMeter = meter;
306 meter->Reset(mRate, true);
307 }
308 else
309 mInputMeter.reset();
310}
double mRate
Audio playback rate in samples per second.
Definition: AudioIOBase.h:256
std::weak_ptr< AudacityProject > mOwningProject
Definition: AudioIOBase.h:246
std::weak_ptr< Meter > mInputMeter
Definition: AudioIOBase.h:260

References mInputMeter, mOwningProject, and mRate.

Referenced by AudioIO::StartPortAudioStream().

Here is the caller graph for this function:

◆ SetMixer()

void AudioIOBase::SetMixer ( int  inputSource)

Definition at line 100 of file AudioIOBase.cpp.

101{
102#if defined(USE_PORTMIXER)
103 int oldRecordSource = Px_GetCurrentInputSource(mPortMixer);
104 if ( inputSource != oldRecordSource )
105 Px_SetCurrentInputSource(mPortMixer, inputSource);
106#endif
107}

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

Here is the caller graph for this function:

◆ SetPlaybackMeter()

void AudioIOBase::SetPlaybackMeter ( const std::shared_ptr< AudacityProject > &  project,
const std::weak_ptr< Meter > &  meter 
)

Definition at line 312 of file AudioIOBase.cpp.

314{
315 if (auto pOwningProject = mOwningProject.lock();
316 ( pOwningProject ) && ( pOwningProject != project))
317 return;
318
319 auto meter = wMeter.lock();
320 if (meter)
321 {
322 mOutputMeter = meter;
323 meter->Reset(mRate, true);
324 }
325 else
326 mOutputMeter.reset();
327}
std::weak_ptr< Meter > mOutputMeter
Definition: AudioIOBase.h:261

References mOutputMeter, mOwningProject, and mRate.

◆ StopStream()

virtual void AudioIOBase::StopStream ( )
pure virtual

Implemented in AudioIO.

Member Data Documentation

◆ mAudioIOExt

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

This class needs to iterate this array for one limited purpose but does not populate it and does not give access to it except to subclasses

Definition at line 323 of file AudioIOBase.h.

Referenced by IsStreamActive().

◆ mCachedBestRateIn

double AudioIOBase::mCachedBestRateIn = 0.0
staticprotected

Definition at line 283 of file AudioIOBase.h.

Referenced by AudioIO::GetBestRate(), and HandleDeviceChange().

◆ mCachedCaptureIndex

int AudioIOBase::mCachedCaptureIndex = -1
staticprotected

◆ mCachedCaptureRates

std::vector< long > AudioIOBase::mCachedCaptureRates
staticprotected

Definition at line 281 of file AudioIOBase.h.

Referenced by GetSupportedCaptureRates(), and HandleDeviceChange().

◆ mCachedPlaybackIndex

int AudioIOBase::mCachedPlaybackIndex = -1
staticprotected

◆ mCachedPlaybackRates

std::vector< long > AudioIOBase::mCachedPlaybackRates
staticprotected

Definition at line 279 of file AudioIOBase.h.

Referenced by GetSupportedPlaybackRates(), and HandleDeviceChange().

◆ mCachedSampleRates

std::vector< long > AudioIOBase::mCachedSampleRates
staticprotected

Definition at line 282 of file AudioIOBase.h.

Referenced by GetSupportedSampleRates(), and HandleDeviceChange().

◆ mInputMeter

std::weak_ptr<Meter> AudioIOBase::mInputMeter {}
protected

◆ mInputMixerWorks

bool AudioIOBase::mInputMixerWorks
protected

Can we control the hardware input level?

This flag is set to true if using portmixer to control the input volume seems to be working (and so we offer the user the control), and to false (locking the control out) otherwise. This avoids stupid scaled clipping problems when trying to do software emulated input volume control

Definition at line 275 of file AudioIOBase.h.

Referenced by AudioIO::AudioIO(), AudioIO::GetMixer(), HandleDeviceChange(), and AudioIO::InputMixerWorks().

◆ mOutputMeter

std::weak_ptr<Meter> AudioIOBase::mOutputMeter {}
protected

◆ mOwningProject

std::weak_ptr<AudacityProject> AudioIOBase::mOwningProject
protected

◆ mPaused

std::atomic<bool> AudioIOBase::mPaused { false }
protected

True if audio playback is paused.

Definition at line 249 of file AudioIOBase.h.

Referenced by IsPaused(), and AudioIO::SetPaused().

◆ mPortStreamV19

PaStream* AudioIOBase::mPortStreamV19
protected

◆ mRate

double AudioIOBase::mRate
protected

◆ mStreamToken

int AudioIOBase::mStreamToken { 0 }
protected

◆ NumRatesToTry

const int AudioIOBase::NumRatesToTry = WXSIZEOF(AudioIOBase::RatesToTry)
staticprotected

How many sample rates to try.

Definition at line 318 of file AudioIOBase.h.

Referenced by GetSupportedCaptureRates(), and GetSupportedPlaybackRates().

◆ NumStandardRates

const int AudioIOBase::NumStandardRates = WXSIZEOF(AudioIOBase::StandardRates)
static

How many standard sample rates there are.

Definition at line 192 of file AudioIOBase.h.

Referenced by QualityPrefs::GetNamesAndLabels(), ImportRawDialog::ImportRawDialog(), and SelectionBar::UpdateRates().

◆ RatesToTry

const int AudioIOBase::RatesToTry
staticprotected
Initial value:
= {
8000,
9600,
11025,
12000,
15000,
16000,
22050,
24000,
32000,
44100,
48000,
88200,
96000,
176400,
192000,
352800,
384000
}

Array of audio sample rates to try to use.

These are the rates we will check if a device supports, and is as long as I can think of (to try and work out what the card can do)

Definition at line 316 of file AudioIOBase.h.

Referenced by GetSupportedCaptureRates(), and GetSupportedPlaybackRates().

◆ StandardRates

const int AudioIOBase::StandardRates
static
Initial value:
= {
8000,
11025,
16000,
22050,
32000,
44100,
48000,
88200,
96000,
176400,
192000,
352800,
384000
}

Array of common audio sample rates.

These are the rates we will always support, regardless of hardware support for them (by resampling in audacity if needed)

Definition at line 190 of file AudioIOBase.h.

Referenced by QualityPrefs::GetNamesAndLabels(), ImportRawDialog::ImportRawDialog(), and SelectionBar::UpdateRates().

◆ ugAudioIO

std::unique_ptr< AudioIOBase > AudioIOBase::ugAudioIO
staticprotected

Definition at line 242 of file AudioIOBase.h.

Referenced by AudioIO::Deinit(), Get(), and AudioIO::Init().


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