Audacity  2.2.2
Functions
DeviceManager.cpp File Reference
#include "portaudio.h"
#include "Audacity.h"
#include <wx/wxprec.h>
#include <wx/choice.h>
#include <wx/event.h>
#include <wx/intl.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/statbmp.h>
#include <wx/tooltip.h>
#include "Project.h"
#include "AudioIO.h"
#include "DeviceChange.h"
#include "DeviceManager.h"
#include "toolbars/DeviceToolBar.h"
#include "Experimental.h"

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

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

Definition at line 192 of file DeviceManager.cpp.

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

Referenced by DeviceManager::Rescan().

193 {
194  int error = 0;
195  DeviceSourceMap map;
196  const PaDeviceInfo *info = Pa_GetDeviceInfo(deviceIndex);
197 
198  // This tries to open the device with the samplerate worked out above, which
199  // will be the highest available for play and record on the device, or
200  // 44.1kHz if the info cannot be fetched.
201 
202  PaStream *stream = NULL;
203 
204  PaStreamParameters parameters;
205 
206  parameters.device = deviceIndex;
207  parameters.sampleFormat = paFloat32;
208  parameters.hostApiSpecificStreamInfo = NULL;
209  parameters.channelCount = 1;
210 
211  // If the device is for input, open a stream so we can use portmixer to query
212  // the number of inputs. We skip this for outputs because there are no 'sources'
213  // and some platforms (e.g. XP) have the same device for input and output, (while
214  // Vista/Win7 seperate these into two devices with the same names (but different
215  // portaudio indecies)
216  // Also, for mapper devices we don't want to keep any sources, so check for it here
217  if (isInput && !IsInputDeviceAMapperDevice(info)) {
218  if (info)
219  parameters.suggestedLatency = info->defaultLowInputLatency;
220  else
221  parameters.suggestedLatency = 10.0;
222 
223  error = Pa_OpenStream(&stream,
224  &parameters,
225  NULL,
226  rate, paFramesPerBufferUnspecified,
227  paClipOff | paDitherOff,
228  DummyPaStreamCallback, NULL);
229  }
230 
231  if (stream && !error) {
232  AddSourcesFromStream(deviceIndex, info, maps, stream);
233  Pa_CloseStream(stream);
234  } else {
235  map.sourceIndex = -1;
236  map.totalSources = 0;
237  FillHostDeviceInfo(&map, info, deviceIndex, isInput);
238  maps->push_back(map);
239  }
240 
241  if(error) {
242  wxLogDebug(wxT("PortAudio stream error creating device list: ") +
243  map.hostString + wxT(":") + map.deviceString + wxT(": ") +
244  wxString(wxSafeConvertMB2WX(Pa_GetErrorText((PaError)error))));
245  }
246 }
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 deviceString
Definition: DeviceManager.h:37
wxString hostString
Definition: DeviceManager.h:38
static void AddSourcesFromStream(int deviceIndex, const PaDeviceInfo *info, std::vector< DeviceSourceMap > *maps, PaStream *stream)
static bool IsInputDeviceAMapperDevice(const PaDeviceInfo *info)
static void AddSourcesFromStream ( int  deviceIndex,
const PaDeviceInfo *  info,
std::vector< DeviceSourceMap > *  maps,
PaStream *  stream 
)
static

Definition at line 129 of file DeviceManager.cpp.

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

Referenced by AddSources().

130 {
131 #ifdef USE_PORTMIXER
132  int i;
133 #endif
134  DeviceSourceMap map;
135 
136  map.sourceIndex = -1;
137  map.totalSources = 0;
138  // Only inputs have sources, so we call FillHostDeviceInfo with a 1 to indicate this
139  FillHostDeviceInfo(&map, info, deviceIndex, 1);
140 
141 #ifdef USE_PORTMIXER
142  PxMixer *portMixer = Px_OpenMixer(stream, 0);
143  if (!portMixer) {
144  maps->push_back(map);
145  return;
146  }
147 
148  //if there is only one source, we don't need to concatenate the source
149  //or enumerate, because it is something meaningless like 'master'
150  //(as opposed to 'mic in' or 'line in'), and the user doesn't have any choice.
151  //note that some devices have no input sources at all but are still valid.
152  //the behavior we do is the same for 0 and 1 source cases.
153  map.totalSources = Px_GetNumInputSources(portMixer);
154 #endif
155 
156  if (map.totalSources <= 1) {
157  map.sourceIndex = 0;
158  maps->push_back(map);
159  }
160 #ifdef USE_PORTMIXER
161  else {
162  //open up a stream with the device so portmixer can get the info out of it.
163  for (i = 0; i < map.totalSources; i++) {
164  map.sourceIndex = i;
165  map.sourceString = wxString(wxSafeConvertMB2WX(Px_GetInputSourceName(portMixer, i)));
166  maps->push_back(map);
167  }
168  }
169  Px_CloseMixer(portMixer);
170 #endif
171 }
static void FillHostDeviceInfo(DeviceSourceMap *map, const PaDeviceInfo *info, int deviceIndex, int isInput)
wxString sourceString
Definition: DeviceManager.h:36
static int DummyPaStreamCallback ( const void *  WXUNUSEDinput,
void *  WXUNUSEDoutput,
unsigned long   WXUNUSEDframeCount,
const PaStreamCallbackTimeInfo *  WXUNUSEDtimeInfo,
PaStreamCallbackFlags   WXUNUSEDstatusFlags,
void *  WXUNUSEDuserData 
)
static

Definition at line 107 of file DeviceManager.cpp.

Referenced by AddSources().

113 {
114  return 0;
115 }
static void FillHostDeviceInfo ( DeviceSourceMap map,
const PaDeviceInfo *  info,
int  deviceIndex,
int  isInput 
)
static

Definition at line 117 of file DeviceManager.cpp.

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

Referenced by AddSources(), and AddSourcesFromStream().

118 {
119  wxString hostapiName = wxSafeConvertMB2WX(Pa_GetHostApiInfo(info->hostApi)->name);
120  wxString infoName = wxSafeConvertMB2WX(info->name);
121 
122  map->deviceIndex = deviceIndex;
123  map->hostIndex = info->hostApi;
124  map->deviceString = infoName;
125  map->hostString = hostapiName;
126  map->numChannels = isInput ? info->maxInputChannels : info->maxOutputChannels;
127 }
wxString deviceString
Definition: DeviceManager.h:37
wxString hostString
Definition: DeviceManager.h:38
static bool IsInputDeviceAMapperDevice ( const PaDeviceInfo *  info)
static

Definition at line 173 of file DeviceManager.cpp.

Referenced by AddSources().

174 {
175  // For Windows only, portaudio returns the default mapper object
176  // as the first index after a NEW hostApi index is detected (true for MME and DS)
177  // this is a bit of a hack, but there's no other way to find out which device is a mapper,
178  // I've looked at string comparisons, but if the system is in a different language this breaks.
179 #ifdef __WXMSW__
180  static int lastHostApiTypeId = -1;
181  int hostApiTypeId = Pa_GetHostApiInfo(info->hostApi)->type;
182  if(hostApiTypeId != lastHostApiTypeId &&
183  (hostApiTypeId == paMME || hostApiTypeId == paDirectSound)) {
184  lastHostApiTypeId = hostApiTypeId;
185  return true;
186  }
187 #endif
188 
189  return false;
190 }
wxString MakeDeviceSourceString ( const DeviceSourceMap map)

Definition at line 64 of file DeviceManager.cpp.

References DeviceSourceMap::deviceString, DeviceSourceMap::sourceString, and DeviceSourceMap::totalSources.

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

65 {
66  wxString ret;
67  ret = map->deviceString;
68  if (map->totalSources > 1)
69  ret += wxT(": ") + map->sourceString;
70 
71  return ret;
72 }
wxString sourceString
Definition: DeviceManager.h:36
wxString deviceString
Definition: DeviceManager.h:37