diff --git a/windows/portaudio/JackPortAudioDevices.cpp b/windows/portaudio/JackPortAudioDevices.cpp index e98dfc7c..3158c491 100644 --- a/windows/portaudio/JackPortAudioDevices.cpp +++ b/windows/portaudio/JackPortAudioDevices.cpp @@ -37,7 +37,7 @@ PortAudioDevices::PortAudioDevices() } fHostName = new string[fNumHostApi]; for (id = 0; id < fNumHostApi; id++) { - fHostName[id] = string (Pa_GetHostApiInfo(id)->name); + fHostName[id] = string(Pa_GetHostApiInfo(id)->name); } } else { jack_error("JackPortAudioDriver::Pa_Initialize error = %s", Pa_GetErrorText(err)); @@ -97,7 +97,7 @@ string PortAudioDevices::GetFullName(std::string hostname, std::string devicenam return (hostname + "::" + devicename); } -PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName (string fullname, PaDeviceIndex& id, bool isInput) +PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName(string fullname, PaDeviceIndex& id, bool isInput) { PaDeviceInfo* ret = NULL; //no driver to find @@ -112,14 +112,14 @@ PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName (string fullname, PaDevice } char* hostname = (char*)malloc(separator + 9); - fill_n (hostname, separator + 9, 0); - fullname.copy (hostname, separator); + fill_n(hostname, separator + 9, 0); + fullname.copy(hostname, separator); //we need the entire hostname, replace shortcuts - if (strcmp (hostname, "DirectSound") == 0) { - strcpy (hostname, "Windows DirectSound"); + if (strcmp(hostname, "DirectSound") == 0) { + strcpy(hostname, "Windows DirectSound"); } - string devicename = fullname.substr (separator + 2); + string devicename = fullname.substr(separator + 2); //then find the corresponding device for (PaDeviceIndex dev_id = 0; dev_id < fNumDevice; dev_id++) { bool flag = (isInput) ? (fDeviceInfo[dev_id]->maxInputChannels > 0) : (fDeviceInfo[dev_id]->maxOutputChannels > 0); @@ -170,7 +170,7 @@ void PortAudioDevices::PrintSupportedStandardSampleRates(const PaStreamParameter int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_input) { string fullname = string(devicename); - PaDeviceInfo* device = GetDeviceFromFullName (fullname, id, true); + PaDeviceInfo* device = GetDeviceFromFullName(fullname, id, true); if (device) { max_input = device->maxInputChannels; } else { @@ -189,7 +189,7 @@ int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceInd int PortAudioDevices::GetOutputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_output) { string fullname = string(devicename); - PaDeviceInfo* device = GetDeviceFromFullName (fullname, id, false); + PaDeviceInfo* device = GetDeviceFromFullName(fullname, id, false); if (device) { max_output = device->maxOutputChannels; } else { @@ -205,54 +205,80 @@ int PortAudioDevices::GetOutputDeviceFromName(const char* devicename, PaDeviceIn return id; } +int PortAudioDevices::GetPreferredBufferSize(PaDeviceIndex id) +{ +#ifdef WIN32 + /* ASIO specific latency information */ + if (Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO) { + long minLatency, maxLatency, preferredLatency, granularity; + + PaAsio_GetAvailableBufferSizes(id, &minLatency, &maxLatency, &preferredLatency, &granularity); + + jack_info("ASIO minimum buffer size = %ld", minLatency); + jack_info("ASIO maximum buffer size = %ld", maxLatency); + jack_info("ASIO preferred buffer size = %ld", preferredLatency); + + if (granularity == -1) { + jack_info("ASIO buffer granularity = power of 2"); + } else { + jack_info("ASIO buffer granularity = %ld", granularity); + } + + return preferredLatency; + } else +#endif + { + return 512; // Non ASIO driver, returns generic value + } +} + void PortAudioDevices::DisplayDevicesNames() { PaDeviceIndex id; PaStreamParameters inputParameters, outputParameters; - jack_info ("********************** Devices list, %d detected **********************", fNumDevice); + jack_info("********************** Devices list, %d detected **********************", fNumDevice); for (id = 0; id < fNumDevice; id++) { - jack_info ("-------- device #%d ------------------------------------------------", id); + jack_info("-------- device #%d ------------------------------------------------", id); if (id == Pa_GetDefaultInputDevice()) { jack_info("[ Default Input ]"); - } else if (id == Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi)->defaultInputDevice) { - const PaHostApiInfo *host_info = Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi); + } else if (id == Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->defaultInputDevice) { + const PaHostApiInfo *host_info = Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi); jack_info("[ Default %s Input ]", host_info->name); } if (id == Pa_GetDefaultOutputDevice()) { - jack_info ("[ Default Output ]"); - } else if (id == Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi)->defaultOutputDevice) { - const PaHostApiInfo *host_info = Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi); + jack_info("[ Default Output ]"); + } else if (id == Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->defaultOutputDevice) { + const PaHostApiInfo *host_info = Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi); jack_info("[ Default %s Output ]", host_info->name); } /* print device info fields */ - jack_info ("Name = %s", GetFullName(id).c_str()); - jack_info ("Max inputs = %d", fDeviceInfo[id]->maxInputChannels); - jack_info ("Max outputs = %d", fDeviceInfo[id]->maxOutputChannels); - -#ifdef WIN32 + jack_info("Name = %s", GetFullName(id).c_str()); + jack_info("Max inputs = %d", fDeviceInfo[id]->maxInputChannels); + jack_info("Max outputs = %d", fDeviceInfo[id]->maxOutputChannels); + + #ifdef WIN32 /* ASIO specific latency information */ if (Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO) { long minLatency, maxLatency, preferredLatency, granularity; - PaAsio_GetAvailableBufferSizes (id, &minLatency, &maxLatency, &preferredLatency, &granularity); + PaAsio_GetAvailableBufferSizes(id, &minLatency, &maxLatency, &preferredLatency, &granularity); - jack_info ("ASIO minimum buffer size = %ld", minLatency); - jack_info ("ASIO maximum buffer size = %ld", maxLatency); - jack_info ("ASIO preferred buffer size = %ld", preferredLatency); + jack_info("ASIO minimum buffer size = %ld", minLatency); + jack_info("ASIO maximum buffer size = %ld", maxLatency); + jack_info("ASIO preferred buffer size = %ld", preferredLatency); if (granularity == -1) { - jack_info ("ASIO buffer granularity = power of 2"); + jack_info("ASIO buffer granularity = power of 2"); } else { - jack_info ("ASIO buffer granularity = %ld", granularity); + jack_info("ASIO buffer granularity = %ld", granularity); } } -#endif - - jack_info ("Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate); + #endif + jack_info("Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate); /* poll for standard sample rates */ inputParameters.device = id; diff --git a/windows/portaudio/JackPortAudioDevices.h b/windows/portaudio/JackPortAudioDevices.h index 61b280d4..0acb104b 100644 --- a/windows/portaudio/JackPortAudioDevices.h +++ b/windows/portaudio/JackPortAudioDevices.h @@ -55,6 +55,7 @@ class PortAudioDevices void PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters); int GetInputDeviceFromName(const char* name, PaDeviceIndex& device, int& in_max); int GetOutputDeviceFromName(const char* name, PaDeviceIndex& device, int& out_max); + int GetPreferredBufferSize(PaDeviceIndex id); void DisplayDevicesNames(); bool IsDuplex(PaDeviceIndex id); diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index f97c4787..a84a0bcc 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -167,17 +167,11 @@ int JackPortAudioDriver::Open(jack_nframes_t buffer_size, fCaptureLatency = capture_latency; fPlaybackLatency = playback_latency; - + jack_log("JackPortAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s samplerate = %ld", buffer_size, inchannels, outchannels, capture_driver_uid, playback_driver_uid, samplerate); - // Generic JackAudioDriver Open - if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, - capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { - return -1; - } - - //get devices + // Get devices if (capturing) { if (fPaDevices->GetInputDeviceFromName(capture_driver_uid, fInputDevice, in_max) < 0) { goto error; @@ -188,10 +182,21 @@ int JackPortAudioDriver::Open(jack_nframes_t buffer_size, goto error; } } + + // If ASIO, request for preferred size (assuming fInputDevice and fOutputDevice are the same) + if (buffer_size == -1) { + buffer_size = fPaDevices->GetPreferredBufferSize(fInputDevice); + } + + // Generic JackAudioDriver Open + if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, + capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { + return -1; + } jack_log("JackPortAudioDriver::Open fInputDevice = %d, fOutputDevice %d", fInputDevice, fOutputDevice); - //default channels number required + // Default channels number required if (inchannels == 0) { jack_log("JackPortAudioDriver::Open setup max in channels = %ld", in_max); inchannels = in_max; @@ -201,7 +206,7 @@ int JackPortAudioDriver::Open(jack_nframes_t buffer_size, outchannels = out_max; } - //too many channels required, take max available + // Too many channels required, take max available if (inchannels > in_max) { jack_error("This device has only %d available input channels.", in_max); inchannels = in_max; @@ -362,7 +367,7 @@ extern "C" jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); value.ui = 512U; - jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", "Frames per period. If -1 and ASIO drver, will take preferred value"); jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "PortAudio device name", NULL);