Audacity 3.2.0
Functions
DeviceManager.cpp File Reference
#include "DeviceManager.h"
#include <wx/log.h>
#include <thread>
#include "portaudio.h"
#include "pa_win_wasapi.h"
#include "AudioIOBase.h"
#include "DeviceChange.h"
Include dependency graph for DeviceManager.cpp:

Go to the source code of this file.

Functions

wxString MakeDeviceSourceString (const DeviceSourceMap *map)
 
static int DummyPaStreamCallback (const void *WXUNUSED(input), void *WXUNUSED(output), unsigned long WXUNUSED(frameCount), const PaStreamCallbackTimeInfo *WXUNUSED(timeInfo), PaStreamCallbackFlags WXUNUSED(statusFlags), void *WXUNUSED(userData))
 
static void FillHostDeviceInfo (DeviceSourceMap *map, const PaDeviceInfo *info, int deviceIndex, int isInput)
 
static void AddSourcesFromStream (int deviceIndex, const PaDeviceInfo *info, std::vector< DeviceSourceMap > *maps, PaStream *stream)
 
static bool IsInputDeviceAMapperDevice (const PaDeviceInfo *info)
 
static void AddSources (int deviceIndex, int rate, std::vector< DeviceSourceMap > *maps, int isInput)
 

Function Documentation

◆ AddSources()

static void AddSources ( int  deviceIndex,
int  rate,
std::vector< DeviceSourceMap > *  maps,
int  isInput 
)
static

Definition at line 180 of file DeviceManager.cpp.

181{
182 int error = 0;
183 DeviceSourceMap map;
184 const PaDeviceInfo *info = Pa_GetDeviceInfo(deviceIndex);
185
186 // This tries to open the device with the samplerate worked out above, which
187 // will be the highest available for play and record on the device, or
188 // 44.1kHz if the info cannot be fetched.
189
190 PaStream *stream = NULL;
191
192 PaStreamParameters parameters;
193
194 parameters.device = deviceIndex;
195 parameters.sampleFormat = paFloat32;
196 parameters.hostApiSpecificStreamInfo = NULL;
197 parameters.channelCount = 1;
198
199 // If the device is for input, open a stream so we can use portmixer to query
200 // the number of inputs. We skip this for outputs because there are no 'sources'
201 // and some platforms (e.g. XP) have the same device for input and output, (while
202 // Vista/Win7 separate these into two devices with the same names (but different
203 // portaudio indices)
204 // Also, for mapper devices we don't want to keep any sources, so check for it here
205 if (isInput && !IsInputDeviceAMapperDevice(info)) {
206 if (info)
207 parameters.suggestedLatency = info->defaultLowInputLatency;
208 else
209 parameters.suggestedLatency = 10.0;
210
211 error = Pa_OpenStream(&stream,
212 &parameters,
213 NULL,
214 rate, paFramesPerBufferUnspecified,
215 paClipOff | paDitherOff,
217 }
218
219 if (stream && !error) {
220 AddSourcesFromStream(deviceIndex, info, maps, stream);
221 Pa_CloseStream(stream);
222 } else {
223 map.sourceIndex = -1;
224 map.totalSources = 0;
225 FillHostDeviceInfo(&map, info, deviceIndex, isInput);
226 maps->push_back(map);
227 }
228
229 if(error) {
230 wxLogDebug(wxT("PortAudio stream error creating device list: ") +
231 map.hostString + wxT(":") + map.deviceString + wxT(": ") +
232 wxString(wxSafeConvertMB2WX(Pa_GetErrorText((PaError)error))));
233 }
234}
wxT("CloseDown"))
int PaError
Definition: AudioIO.h:45
void PaStream
Definition: AudioIOBase.h:23
static bool IsInputDeviceAMapperDevice(const PaDeviceInfo *info)
static void AddSourcesFromStream(int deviceIndex, const PaDeviceInfo *info, std::vector< DeviceSourceMap > *maps, PaStream *stream)
static void FillHostDeviceInfo(DeviceSourceMap *map, const PaDeviceInfo *info, int deviceIndex, int isInput)
static int DummyPaStreamCallback(const void *WXUNUSED(input), void *WXUNUSED(output), unsigned long WXUNUSED(frameCount), const PaStreamCallbackTimeInfo *WXUNUSED(timeInfo), PaStreamCallbackFlags WXUNUSED(statusFlags), void *WXUNUSED(userData))
wxString hostString
Definition: DeviceManager.h:36
wxString deviceString
Definition: DeviceManager.h:35

References AddSourcesFromStream(), DeviceSourceMap::deviceString, DummyPaStreamCallback(), FillHostDeviceInfo(), DeviceSourceMap::hostString, IsInputDeviceAMapperDevice(), DeviceSourceMap::sourceIndex, DeviceSourceMap::totalSources, and wxT().

Referenced by DeviceManager::Rescan().

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

◆ AddSourcesFromStream()

static void AddSourcesFromStream ( int  deviceIndex,
const PaDeviceInfo *  info,
std::vector< DeviceSourceMap > *  maps,
PaStream stream 
)
static

Definition at line 117 of file DeviceManager.cpp.

118{
119#ifdef USE_PORTMIXER
120 int i;
121#endif
122 DeviceSourceMap map;
123
124 map.sourceIndex = -1;
125 map.totalSources = 0;
126 // Only inputs have sources, so we call FillHostDeviceInfo with a 1 to indicate this
127 FillHostDeviceInfo(&map, info, deviceIndex, 1);
128
129#ifdef USE_PORTMIXER
130 PxMixer *portMixer = Px_OpenMixer(stream, deviceIndex, -1, 0);
131 if (!portMixer) {
132 maps->push_back(map);
133 return;
134 }
135
136 //if there is only one source, we don't need to concatenate the source
137 //or enumerate, because it is something meaningless like 'master'
138 //(as opposed to 'mic in' or 'line in'), and the user doesn't have any choice.
139 //note that some devices have no input sources at all but are still valid.
140 //the behavior we do is the same for 0 and 1 source cases.
141 map.totalSources = Px_GetNumInputSources(portMixer);
142#endif
143
144 if (map.totalSources <= 1) {
145 map.sourceIndex = 0;
146 maps->push_back(map);
147 }
148#ifdef USE_PORTMIXER
149 else {
150 //open up a stream with the device so portmixer can get the info out of it.
151 for (i = 0; i < map.totalSources; i++) {
152 map.sourceIndex = i;
153 map.sourceString = wxString(wxSafeConvertMB2WX(Px_GetInputSourceName(portMixer, i)));
154 maps->push_back(map);
155 }
156 }
157 Px_CloseMixer(portMixer);
158#endif
159}
wxString sourceString
Definition: DeviceManager.h:34

References FillHostDeviceInfo(), DeviceSourceMap::sourceIndex, DeviceSourceMap::sourceString, and DeviceSourceMap::totalSources.

Referenced by AddSources().

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

◆ DummyPaStreamCallback()

static int DummyPaStreamCallback ( const void *  WXUNUSEDinput,
void *  WXUNUSEDoutput,
unsigned long   WXUNUSEDframeCount,
const PaStreamCallbackTimeInfo *  WXUNUSEDtimeInfo,
PaStreamCallbackFlags   WXUNUSEDstatusFlags,
void *  WXUNUSEDuserData 
)
static

Definition at line 95 of file DeviceManager.cpp.

101{
102 return 0;
103}

Referenced by AddSources().

Here is the caller graph for this function:

◆ FillHostDeviceInfo()

static void FillHostDeviceInfo ( DeviceSourceMap map,
const PaDeviceInfo *  info,
int  deviceIndex,
int  isInput 
)
static

Definition at line 105 of file DeviceManager.cpp.

106{
107 wxString hostapiName = wxSafeConvertMB2WX(Pa_GetHostApiInfo(info->hostApi)->name);
108 wxString infoName = wxSafeConvertMB2WX(info->name);
109
110 map->deviceIndex = deviceIndex;
111 map->hostIndex = info->hostApi;
112 map->deviceString = infoName;
113 map->hostString = hostapiName;
114 map->numChannels = isInput ? info->maxInputChannels : info->maxOutputChannels;
115}

References DeviceSourceMap::deviceIndex, DeviceSourceMap::deviceString, DeviceSourceMap::hostIndex, DeviceSourceMap::hostString, and DeviceSourceMap::numChannels.

Referenced by AddSources(), and AddSourcesFromStream().

Here is the caller graph for this function:

◆ IsInputDeviceAMapperDevice()

static bool IsInputDeviceAMapperDevice ( const PaDeviceInfo *  info)
static

Definition at line 161 of file DeviceManager.cpp.

162{
163 // For Windows only, portaudio returns the default mapper object
164 // as the first index after a NEW hostApi index is detected (true for MME and DS)
165 // this is a bit of a hack, but there's no other way to find out which device is a mapper,
166 // I've looked at string comparisons, but if the system is in a different language this breaks.
167#ifdef __WXMSW__
168 static int lastHostApiTypeId = -1;
169 int hostApiTypeId = Pa_GetHostApiInfo(info->hostApi)->type;
170 if(hostApiTypeId != lastHostApiTypeId &&
171 (hostApiTypeId == paMME || hostApiTypeId == paDirectSound)) {
172 lastHostApiTypeId = hostApiTypeId;
173 return true;
174 }
175#endif
176
177 return false;
178}

Referenced by AddSources().

Here is the caller graph for this function:

◆ MakeDeviceSourceString()

wxString MakeDeviceSourceString ( const DeviceSourceMap map)

Definition at line 52 of file DeviceManager.cpp.

53{
54 wxString ret;
55 ret = map->deviceString;
56 if (map->totalSources > 1)
57 ret += wxT(": ") + map->sourceString;
58
59 return ret;
60}

References DeviceSourceMap::deviceString, DeviceSourceMap::sourceString, DeviceSourceMap::totalSources, and wxT().

Referenced by DeviceToolBar::ChangeDevice(), AudioSetupToolBar::ChangeDeviceLabel(), AudioSetupToolBar::FillHostDevices(), DeviceToolBar::FillHostDevices(), DevicePrefs::OnHost(), AudioSetupToolBar::UpdatePrefs(), and DeviceToolBar::UpdatePrefs().

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