[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.
This commit is contained in:
Greg Zharun 2015-02-10 23:16:56 +02:00
parent 37c03b4e9f
commit 88810bc7be
3 changed files with 44 additions and 18 deletions

View file

@ -57,6 +57,7 @@ struct DeviceInfo
DeviceID m_DeviceId; DeviceID m_DeviceId;
std::string m_DeviceName; std::string m_DeviceName;
std::vector<int> m_AvailableSampleRates; std::vector<int> m_AvailableSampleRates;
std::vector<int> m_AvailableBufferSizes;
unsigned int m_MaxInputChannels; unsigned int m_MaxInputChannels;
unsigned int m_MaxOutputChannels; unsigned int m_MaxOutputChannels;

View file

@ -1581,6 +1581,32 @@ WTErr WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceI
} }
WTErr WCMRPortAudioDeviceManager::getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector<int>& 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() WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
{ {
std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl; std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl;
@ -1627,6 +1653,7 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name); DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name);
if (pDevInfo) if (pDevInfo)
{ {
//Get available sample rates
std::vector<int> availableSampleRates; std::vector<int> availableSampleRates;
WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates); WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates);
@ -1641,6 +1668,19 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels; pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels;
pDevInfo->m_MaxOutputChannels = pPaDeviceInfo->maxOutputChannels; pDevInfo->m_MaxOutputChannels = pPaDeviceInfo->maxOutputChannels;
//Get available buffer sizes
std::vector<int> 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 //Now check if this device is acceptable according to current input/output settings
bool bRejectDevice = false; bool bRejectDevice = false;
switch(m_eAudioDeviceFilter) switch(m_eAudioDeviceFilter)
@ -1761,34 +1801,18 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
return retVal; return retVal;
} }
Pa_Initialize();
DeviceInfo devInfo; DeviceInfo devInfo;
retVal = GetDeviceInfoByName(deviceName, devInfo); retVal = GetDeviceInfoByName(deviceName, devInfo);
if (eNoErr == retVal) if (eNoErr == retVal)
{ {
//make PA request to get actual device buffer sizes std::cout << "API::PortAudioDeviceManager::GetBufferSizes: got buffer :"<< devInfo.m_AvailableBufferSizes.front() << std::endl;
long minSize, maxSize, preferredSize, granularity; buffers = devInfo.m_AvailableBufferSizes;
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;
}
} }
else else
{ {
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl; std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
} }
Pa_Terminate();
return retVal; return retVal;
} }

View file

@ -172,6 +172,7 @@ protected:
private: private:
// helper functions for this class only // helper functions for this class only
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates); WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
WTErr getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector<int>& buffers);
WCMRAudioDevice* m_NoneDevice; WCMRAudioDevice* m_NoneDevice;
}; };