From 88810bc7beaa7338e20f5229345b8053dc193c36 Mon Sep 17 00:00:00 2001 From: Greg Zharun Date: Tue, 10 Feb 2015 23:16:56 +0200 Subject: [PATCH] [Summary] Changed buffer sizes retrieving [Details] There is no need to Initialize/Deinitialize PA and each time take buffers from the device. Buffer size will be assigned on device activation and application will be notified about buffer changes when it's required. This appears to be the correct workflow with buffer size on ASIO devices. --- .../devicemanager/WCMRAudioDeviceManager.h | 1 + .../WCMRPortAudioDeviceManager.cpp | 60 +++++++++++++------ .../WCMRPortAudioDeviceManager.h | 1 + 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h index da5be82b4f..f12ca636c8 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h @@ -57,6 +57,7 @@ struct DeviceInfo DeviceID m_DeviceId; std::string m_DeviceName; std::vector m_AvailableSampleRates; + std::vector m_AvailableBufferSizes; unsigned int m_MaxInputChannels; unsigned int m_MaxOutputChannels; diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp index 2c34c10e0e..e41d879061 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp @@ -1581,6 +1581,32 @@ WTErr WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceI } +WTErr WCMRPortAudioDeviceManager::getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector& buffers) +{ + WTErr retVal = eNoErr; + + buffers.clear(); + + //make PA request to get actual device buffer sizes + long minSize, maxSize, preferredSize, granularity; + + PaError paErr = PaAsio_GetAvailableBufferSizes(deviceId, &minSize, &maxSize, &preferredSize, &granularity); + + //for Windows ASIO devices we always use prefferes buffer size ONLY + if (paNoError == paErr ) + { + buffers.push_back(preferredSize); + } + else + { + retVal = eAsioFailed; + std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << Pa_GetErrorText (paErr) << " getting buffer sizes for device: "<< deviceId << std::endl; + } + + return retVal; +} + + WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl() { std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl; @@ -1627,6 +1653,7 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl() DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name); if (pDevInfo) { + //Get available sample rates std::vector availableSampleRates; WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates); @@ -1641,6 +1668,19 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl() pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels; pDevInfo->m_MaxOutputChannels = pPaDeviceInfo->maxOutputChannels; + //Get available buffer sizes + std::vector availableBuffers; + wErr = getDeviceAvailableBufferSizes(thisDeviceID, availableBuffers); + + if (wErr != eNoErr) + { + DEBUG_MSG ("Failed to get device available buffer sizes. Device ID: " << m_DeviceID); + delete pDevInfo; + continue; //proceed to the next device + } + + pDevInfo->m_AvailableBufferSizes = availableBuffers; + //Now check if this device is acceptable according to current input/output settings bool bRejectDevice = false; switch(m_eAudioDeviceFilter) @@ -1761,34 +1801,18 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d return retVal; } - Pa_Initialize(); - DeviceInfo devInfo; retVal = GetDeviceInfoByName(deviceName, devInfo); if (eNoErr == retVal) { - //make PA request to get actual device buffer sizes - long minSize, maxSize, preferredSize, granularity; - PaError paErr = PaAsio_GetAvailableBufferSizes(devInfo.m_DeviceId, &minSize, &maxSize, &preferredSize, &granularity); - - //for Windows ASIO devices we always use prefferes buffer size ONLY - if (paNoError == paErr ) - { - buffers.push_back(preferredSize); - } - else - { - retVal = eAsioFailed; - std::cout << "API::PortAudioDeviceManager::GetBufferSizes: error: " << Pa_GetErrorText (paErr) << " getting buffer sizes for device: "<< deviceName << std::endl; - } + std::cout << "API::PortAudioDeviceManager::GetBufferSizes: got buffer :"<< devInfo.m_AvailableBufferSizes.front() << std::endl; + buffers = devInfo.m_AvailableBufferSizes; } else { std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl; } - Pa_Terminate(); - return retVal; } diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h index 2202c4fed5..9172c34b43 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h @@ -172,6 +172,7 @@ protected: private: // helper functions for this class only WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector& sampleRates); + WTErr getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector& buffers); WCMRAudioDevice* m_NoneDevice; };