20 #include "JackPortAudioDevices.h"
21 #include "JackError.h"
26 PortAudioDevices::PortAudioDevices()
30 jack_log(
"Initializing PortAudio...");
35 for (
id = 0;
id < fNumDevice;
id++) {
38 fHostName =
new string[fNumHostApi];
39 for (
id = 0;
id < fNumHostApi;
id++) {
47 PortAudioDevices::~PortAudioDevices()
62 return fDeviceInfo[id];
67 return string(fDeviceInfo[
id]->name);
70 string PortAudioDevices::GetHostFromDevice(
PaDeviceInfo* device)
72 return fHostName[device->hostApi];
77 return fHostName[fDeviceInfo[id]->hostApi];
82 string hostname = GetHostFromDevice(
id);
83 string devicename = GetDeviceName(
id);
85 if (hostname.compare(
"Windows DirectSound") == 0) {
86 hostname = string(
"DirectSound");
88 return (hostname +
"::" + devicename);
91 string PortAudioDevices::GetFullName(std::string hostname, std::string devicename)
94 if (hostname.compare(
"Windows DirectSound") == 0) {
95 hostname = string(
"DirectSound");
97 return (hostname +
"::" + devicename);
104 if (fullname.size() == 0) {
108 string::size_type separator = fullname.find(
"::", 0);
110 if (separator == string::npos) {
114 char* hostname = (
char*)malloc(separator + 9);
115 fill_n(hostname, separator + 9, 0);
116 fullname.copy(hostname, separator);
119 if (strcmp(hostname,
"DirectSound") == 0) {
120 strcpy(hostname,
"Windows DirectSound");
122 string devicename = fullname.substr(separator + 2);
124 for (
PaDeviceIndex dev_id = 0; dev_id < fNumDevice; dev_id++) {
125 bool flag = (isInput) ? (fDeviceInfo[dev_id]->maxInputChannels > 0) : (fDeviceInfo[dev_id]->maxOutputChannels > 0);
126 if ((GetHostFromDevice(dev_id).compare(hostname) == 0)
127 && (GetDeviceName(dev_id).compare(devicename) == 0)
130 ret = fDeviceInfo[dev_id];
139 static double standardSampleRates[] =
141 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
142 44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1
148 for (i = 0; standardSampleRates[i] > 0; i++) {
151 if (printCount == 0) {
152 jack_info(
"\t%8.2f", standardSampleRates[i]);
154 }
else if (printCount == 4) {
155 jack_info(
",\n\t%8.2f", standardSampleRates[i]);
158 jack_info(
", %8.2f", standardSampleRates[i]);
170 int PortAudioDevices::GetInputDeviceFromName(
const char* devicename,
PaDeviceIndex&
id,
int& max_input)
172 string fullname = string(devicename);
173 PaDeviceInfo* device = GetDeviceFromFullName(fullname,
id,
true);
175 max_input = device->maxInputChannels;
178 if (fullname.size()) {
179 jack_error(
"Can't open %s, PortAudio will use default input device.", devicename);
184 max_input = GetDeviceInfo(
id)->maxInputChannels;
189 int PortAudioDevices::GetOutputDeviceFromName(
const char* devicename,
PaDeviceIndex&
id,
int& max_output)
191 string fullname = string(devicename);
192 PaDeviceInfo* device = GetDeviceFromFullName(fullname,
id,
false);
194 max_output = device->maxOutputChannels;
197 if (fullname.size()) {
198 jack_error(
"Can't open %s, PortAudio will use default output device.", devicename);
203 max_output = GetDeviceInfo(
id)->maxOutputChannels;
208 int PortAudioDevices::GetPreferredBufferSize(
PaDeviceIndex id)
213 long minLatency, maxLatency, preferredLatency, granularity;
217 jack_info(
"ASIO minimum buffer size = %ld", minLatency);
218 jack_info(
"ASIO maximum buffer size = %ld", maxLatency);
219 jack_info(
"ASIO preferred buffer size = %ld", preferredLatency);
221 if (granularity == -1) {
222 jack_info(
"ASIO buffer granularity = power of 2");
224 jack_info(
"ASIO buffer granularity = %ld", granularity);
227 return preferredLatency;
235 void PortAudioDevices::DisplayDevicesNames()
239 jack_info(
"********************** Devices list, %d detected **********************", fNumDevice);
241 for (
id = 0;
id < fNumDevice;
id++) {
242 jack_info(
"-------- device #%d ------------------------------------------------",
id);
246 }
else if (
id ==
Pa_GetHostApiInfo(fDeviceInfo[
id]->hostApi)->defaultInputDevice) {
253 }
else if (
id ==
Pa_GetHostApiInfo(fDeviceInfo[
id]->hostApi)->defaultOutputDevice) {
259 jack_info(
"Name = %s", GetFullName(
id).c_str());
260 jack_info(
"Max inputs = %d", fDeviceInfo[
id]->maxInputChannels);
261 jack_info(
"Max outputs = %d", fDeviceInfo[
id]->maxOutputChannels);
266 long minLatency, maxLatency, preferredLatency, granularity;
270 jack_info(
"ASIO minimum buffer size = %ld", minLatency);
271 jack_info(
"ASIO maximum buffer size = %ld", maxLatency);
272 jack_info(
"ASIO preferred buffer size = %ld", preferredLatency);
274 if (granularity == -1) {
275 jack_info(
"ASIO buffer granularity = power of 2");
277 jack_info(
"ASIO buffer granularity = %ld", granularity);
281 jack_info(
"Default sample rate = %8.2f", fDeviceInfo[
id]->defaultSampleRate);
284 inputParameters.
device = id;
285 inputParameters.
channelCount = fDeviceInfo[id]->maxInputChannels;
290 outputParameters.
device = id;
291 outputParameters.
channelCount = fDeviceInfo[id]->maxOutputChannels;
296 jack_info(
"**************************** End of list ****************************");
302 if (fDeviceInfo[
id]->maxInputChannels && fDeviceInfo[
id]->maxOutputChannels) {
307 if ((i !=
id) && (GetDeviceName(i) == GetDeviceName(
id))) {
308 if ((fDeviceInfo[i]->maxInputChannels && fDeviceInfo[
id]->maxOutputChannels)
309 || (fDeviceInfo[i]->maxOutputChannels && fDeviceInfo[
id]->maxInputChannels)) {
PaError Pa_Initialize(void)
PaDeviceIndex Pa_GetDefaultInputDevice(void)
PaDeviceIndex Pa_GetDeviceCount(void)
SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)
PaError Pa_IsFormatSupported(const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate)
void * hostApiSpecificStreamInfo
PaError PaAsio_GetAvailableBufferSizes(PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames, long *preferredBufferSizeFrames, long *granularity)
PaSampleFormat sampleFormat
const PaHostApiInfo * Pa_GetHostApiInfo(PaHostApiIndex hostApi)
PaHostApiIndex Pa_GetHostApiCount(void)
const PaDeviceInfo * Pa_GetDeviceInfo(PaDeviceIndex device)
PaDeviceIndex Pa_GetDefaultOutputDevice(void)
#define paFormatIsSupported
const char * Pa_GetErrorText(PaError errorCode)
SERVER_EXPORT void jack_log(const char *fmt,...)
PaError Pa_Terminate(void)