Audacity  3.0.3
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
 
bool mPaused
 True if audio playback is paused. More...
 
volatile int mStreamToken
 
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 98 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 71 of file AudioIOBase.cpp.

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

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 922 of file AudioIOBase.cpp.

923 {
924  std::vector<AudioIODiagnostics> result;
925  result.push_back({
926  wxT("audiodev.txt"), GetDeviceInfo(), wxT("Audio Device Info") });
927  for( auto &pExt : mAudioIOExt )
928  if ( pExt )
929  result.emplace_back(pExt->Dump());
930  return result;
931 }

◆ GetDeviceInfo()

wxString AudioIOBase::GetDeviceInfo ( ) const

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

Definition at line 693 of file AudioIOBase.cpp.

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

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 547 of file AudioIOBase.cpp.

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

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 581 of file AudioIOBase.cpp.

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

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 636 of file AudioIOBase.cpp.

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

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 433 of file AudioIOBase.cpp.

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

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 368 of file AudioIOBase.cpp.

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

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 502 of file AudioIOBase.cpp.

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

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 107 of file AudioIOBase.cpp.

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

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 78 of file AudioIOBase.cpp.

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

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 358 of file AudioIOBase.cpp.

359 {
360  return ( token > 0 && token == mStreamToken );
361 }

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 332 of file AudioIOBase.cpp.

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

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 363 of file AudioIOBase.cpp.

364 {
365  return ( mPortStreamV19 && mStreamToken==0 );
366 }

References mPortStreamV19, and mStreamToken.

◆ IsPaused()

bool AudioIOBase::IsPaused ( ) const

Find out if playback / recording is currently paused.

Definition at line 327 of file AudioIOBase.cpp.

328 {
329  return mPaused;
330 }

References mPaused.

Referenced by AudioIoCallback::AudioCallback(), AudioIoCallback::CheckSoundActivatedRecordingLevel(), and PausedFlag().

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 340 of file AudioIOBase.cpp.

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

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 353 of file AudioIOBase.cpp.

354 {
355  return (this->IsStreamActive() && this->IsAudioTokenActive(token));
356 }

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 293 of file AudioIOBase.cpp.

295 {
296  if (auto pOwningProject = mOwningProject.lock();
297  ( pOwningProject ) && ( pOwningProject != project))
298  return;
299 
300  auto meter = wMeter.lock();
301  if (meter)
302  {
303  mInputMeter = meter;
304  meter->Reset(mRate, true);
305  }
306  else
307  mInputMeter.reset();
308 }

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 98 of file AudioIOBase.cpp.

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

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 310 of file AudioIOBase.cpp.

312 {
313  if (auto pOwningProject = mOwningProject.lock();
314  ( pOwningProject ) && ( pOwningProject != project))
315  return;
316 
317  auto meter = wMeter.lock();
318  if (meter)
319  {
320  mOutputMeter = meter;
321  meter->Reset(mRate, true);
322  }
323  else
324  mOutputMeter.reset();
325 }

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 318 of file AudioIOBase.h.

Referenced by IsStreamActive().

◆ mCachedBestRateIn

double AudioIOBase::mCachedBestRateIn = 0.0
staticprotected

Definition at line 278 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 276 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 274 of file AudioIOBase.h.

Referenced by GetSupportedPlaybackRates(), and HandleDeviceChange().

◆ mCachedSampleRates

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

Definition at line 277 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 270 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

bool AudioIOBase::mPaused
protected

◆ mPortStreamV19

PaStream* AudioIOBase::mPortStreamV19
protected

◆ mRate

double AudioIOBase::mRate
protected

◆ mStreamToken

volatile int AudioIOBase::mStreamToken
protected

◆ NumRatesToTry

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

How many sample rates to try.

Definition at line 313 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 189 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 311 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 187 of file AudioIOBase.h.

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

◆ ugAudioIO

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

Definition at line 239 of file AudioIOBase.h.

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


The documentation for this class was generated from the following files:
AudioIORecordingDevice
StringSetting AudioIORecordingDevice
Definition: AudioIOBase.cpp:945
AudioIOLatencyCorrection
DoubleSetting AudioIOLatencyCorrection
Definition: AudioIOBase.cpp:935
AudioIOPlaybackDevice
StringSetting AudioIOPlaybackDevice
Definition: AudioIOBase.cpp:939
AudioIOBase::DeviceName
static wxString DeviceName(const PaDeviceInfo *info)
Definition: AudioIOBase.cpp:71
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:551
AudioIOBase::mPortStreamV19
PaStream * mPortStreamV19
Definition: AudioIOBase.h:253
PaStream
void PaStream
Definition: AudioIOBase.h:23
Meter::Reset
virtual void Reset(double sampleRate, bool resetClipping)=0
AudioIOBase::mInputMixerWorks
bool mInputMixerWorks
Can we control the hardware input level?
Definition: AudioIOBase.h:270
AudioIOBase::getPlayDevIndex
static int getPlayDevIndex(const wxString &devName={})
get the index of the device selected in the preferences.
Definition: AudioIOBase.cpp:581
AudioIOBase::GetDeviceInfo
wxString GetDeviceInfo() const
Get diagnostic information on all the available audio I/O devices.
Definition: AudioIOBase.cpp:693
AudioIOBase::getRecordDevIndex
static int getRecordDevIndex(const wxString &devName={})
get the index of the supplied (named) recording device, or the device selected in the preferences if ...
Definition: AudioIOBase.cpp:636
XO
#define XO(s)
Definition: Internat.h:31
AudioIOBase::IsStreamActive
bool IsStreamActive() const
Returns true if the audio i/o is running at all, but not during cleanup.
Definition: AudioIOBase.cpp:340
AudioIOBase::GetSupportedPlaybackRates
static std::vector< long > GetSupportedPlaybackRates(int DevIndex=-1, double rate=0.0)
Get a list of sample rates the output (playback) device supports.
Definition: AudioIOBase.cpp:368
AudioIOBase::ugAudioIO
static std::unique_ptr< AudioIOBase > ugAudioIO
Definition: AudioIOBase.h:239
AudioIOBase::mCachedSampleRates
static std::vector< long > mCachedSampleRates
Definition: AudioIOBase.h:277
AudioIORecordingSourceIndex
IntSetting AudioIORecordingSourceIndex
Definition: AudioIOBase.cpp:949
Setting::Read
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:128
AudioIOBase::mAudioIOExt
std::vector< std::unique_ptr< AudioIOExtBase > > mAudioIOExt
Definition: AudioIOBase.h:318
AudioIOLatencyDuration
DoubleSetting AudioIOLatencyDuration
Definition: AudioIOBase.cpp:937
AudioIOBase::NumRatesToTry
static const int NumRatesToTry
How many sample rates to try.
Definition: AudioIOBase.h:313
AudioIOBase::mOwningProject
std::weak_ptr< AudacityProject > mOwningProject
Definition: AudioIOBase.h:243
AudioIOBase::RatesToTry
static const int RatesToTry[]
Array of audio sample rates to try to use.
Definition: AudioIOBase.h:311
AudioIOBase::mPaused
bool mPaused
True if audio playback is paused.
Definition: AudioIOBase.h:246
AudioIOBase::mCachedPlaybackRates
static std::vector< long > mCachedPlaybackRates
Definition: AudioIOBase.h:274
AudioIOBase::mInputMeter
std::weak_ptr< Meter > mInputMeter
Definition: AudioIOBase.h:255
AudioIOBase::mCachedPlaybackIndex
static int mCachedPlaybackIndex
Definition: AudioIOBase.h:273
name
const TranslatableString name
Definition: Distortion.cpp:98
Setting::GetDefault
const T & GetDefault() const
Definition: Prefs.h:120
AudioIOBase::mRate
double mRate
Audio playback rate in samples per second.
Definition: AudioIOBase.h:251
AudioIOBase::GetSupportedSampleRates
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.
Definition: AudioIOBase.cpp:502
AudioIOBase::SetMixer
void SetMixer(int inputSource)
Definition: AudioIOBase.cpp:98
AudioIOBase::HostName
static wxString HostName(const PaDeviceInfo *info)
Definition: AudioIOBase.cpp:78
AudioIOBase::mCachedCaptureIndex
static int mCachedCaptureIndex
Definition: AudioIOBase.h:275
Setting::ReadWithDefault
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:134
AudioIOBase::IsAudioTokenActive
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...
Definition: AudioIOBase.cpp:358
AudioIOBase::GetSupportedCaptureRates
static std::vector< long > GetSupportedCaptureRates(int devIndex=-1, double rate=0.0)
Get a list of sample rates the input (recording) device supports.
Definition: AudioIOBase.cpp:433
AudioIOHost
StringSetting AudioIOHost
Definition: AudioIOBase.cpp:933
AudioIOBase::mOutputMeter
std::weak_ptr< Meter > mOutputMeter
Definition: AudioIOBase.h:256
AudioIOBase::mCachedBestRateIn
static double mCachedBestRateIn
Definition: AudioIOBase.h:278
AudioIOBase::mStreamToken
volatile int mStreamToken
Definition: AudioIOBase.h:248
AudioIOBase::mCachedCaptureRates
static std::vector< long > mCachedCaptureRates
Definition: AudioIOBase.h:276
AudioIORecordChannels
IntSetting AudioIORecordChannels
Definition: AudioIOBase.cpp:943