[Summary] Added possibility to update sample rate list for devices on the fly on MAC

This commit is contained in:
GZharun 2014-07-08 12:27:20 +03:00
parent 9958f084e5
commit 0cf788ef12
7 changed files with 103 additions and 8 deletions

View file

@ -34,10 +34,8 @@ void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reaso
_buffer_size_change(*(uint32_t*)parameter);
break;
case WCMRAudioDeviceManagerClient::RequestReset:
{
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestReset" << std::endl;
engine.request_backend_reset();
}
break;
case WCMRAudioDeviceManagerClient::RequestResync:
std::cout << "------------------------------- WCMRAudioDeviceManagerClient::RequestResync" << std::endl;
@ -188,17 +186,18 @@ WavesAudioBackend::available_sample_rates (const std::string& device_name) const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_sample_rates (): [" << device_name << "]" << std::endl;
DeviceInfo devInfo;
WTErr err = _audio_device_manager.GetDeviceInfoByName(device_name, devInfo);
std::vector<int> sr;
if (eNoErr != err) {
WTErr retVal = _audio_device_manager.GetDeviceSampleRates(device_name, sr);
if (eNoErr != retVal) {
std::cerr << "WavesAudioBackend::available_sample_rates (): Failed to find device [" << device_name << "]" << std::endl;
return std::vector<float> ();
}
// COMMENTED DBG LOGS */ std::cout << "\tFound " << devInfo.m_AvailableSampleRates.size () << " sample rates for " << device_name << ":";
std::vector<float> sample_rates (devInfo.m_AvailableSampleRates.begin (), devInfo.m_AvailableSampleRates.end ());
std::vector<float> sample_rates (sr.begin (), sr.end ());
// COMMENTED DBG LOGS */ for (std::vector<float>::iterator i = sample_rates.begin (); i != sample_rates.end (); ++i) std::cout << " " << *i; std::cout << std::endl;
@ -220,8 +219,7 @@ WavesAudioBackend::available_buffer_sizes (const std::string& device_name) const
std::vector<int> bs;
WTErr retVal;
retVal = _audio_device_manager.GetDeviceBufferSizes(device_name, bs);
WTErr retVal = _audio_device_manager.GetDeviceBufferSizes(device_name, bs);
if (retVal != eNoErr) {
std::cerr << "WavesAudioBackend::available_buffer_sizes (): Failed to get buffer size for device [" << device_name << "]" << std::endl;

View file

@ -631,6 +631,13 @@ WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatc
}
WTErr WCMRAudioDeviceManager::GetDeviceSampleRates(const std::string & nameToMatch, std::vector<int>& sampleRates) const
{
return getDeviceSampleRatesImpl(nameToMatch, sampleRates);
}
WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const
{
return getDeviceBufferSizesImpl(nameToMatch, bufferSizes);

View file

@ -218,6 +218,7 @@ public://< Public functions for the class.
void DestroyCurrentDevice();
const DeviceInfoVec DeviceInfoList () const;
WTErr GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const;
WTErr GetDeviceSampleRates(const std::string & nameToMatch, std::vector<int>& sampleRates) const;
WTErr GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const;
//virtual void EnableVerboseLogging(bool /*bEnable*/, const std::string& /*logFilePath*/) { };
@ -238,6 +239,7 @@ private:
// made private to avoid pure virtual function call
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName) = 0;
virtual void destroyCurrentDeviceImpl() = 0;
virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const = 0;
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const = 0;
virtual WTErr generateDeviceListImpl() = 0;
virtual WTErr updateDeviceListImpl() = 0;

View file

@ -2870,6 +2870,79 @@ WTErr WCMRCoreAudioDeviceManager::updateDeviceListImpl()
}
WTErr WCMRCoreAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const
{
AUTO_FUNC_DEBUG;
WTErr retVal = eNoErr;
OSStatus err = kAudioHardwareNoError;
UInt32 propSize = 0;
sampleRates.clear();
//first check if the request has been made for None device
if (deviceName == m_NoneDevice->DeviceName() )
{
sampleRates = m_NoneDevice->SamplingRates();
return retVal;
}
DeviceInfo devInfo;
retVal = GetDeviceInfoByName(deviceName, devInfo);
//! 1. Get sample rate property size.
err = AudioDeviceGetPropertyInfo(devInfo.m_DeviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, NULL);
if (err == kAudioHardwareNoError)
{
//! 2. Get property: cannels output.
// Allocate size accrding to the number of audio values
int numRates = propSize / sizeof(AudioValueRange);
AudioValueRange* supportedRates = new AudioValueRange[numRates];
// Get sampling rates from Audio device
err = AudioDeviceGetProperty(devInfo.m_DeviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, supportedRates);
if (err == kAudioHardwareNoError)
{
//! 3. Update sample rates
// now iterate through our standard SRs
for(int ourSR=0; gAllSampleRates[ourSR] > 0; ourSR++)
{
//check to see if our SR is in the supported rates...
for (int deviceSR = 0; deviceSR < numRates; deviceSR++)
{
if ((supportedRates[deviceSR].mMinimum <= gAllSampleRates[ourSR]) &&
(supportedRates[deviceSR].mMaximum >= gAllSampleRates[ourSR]))
{
sampleRates.push_back ((int)gAllSampleRates[ourSR]);
break;
}
}
}
}
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device Sample rates. Device Name: " << m_DeviceName.c_str());
}
delete [] supportedRates;
}
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device Sample rates property size. Device Name: " << m_DeviceName.c_str());
}
devInfo.m_AvailableSampleRates.assign(sampleRates.begin(), sampleRates.end() );
return retVal;
}
WTErr WCMRCoreAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const
{
AUTO_FUNC_DEBUG;

View file

@ -173,6 +173,7 @@ protected:
virtual void destroyCurrentDeviceImpl();
virtual WTErr generateDeviceListImpl();
virtual WTErr updateDeviceListImpl();
virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const;
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const;
bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.

View file

@ -1656,6 +1656,19 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
}
WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const
{
sampleRates.clear ();
WTErr retVal = eNoErr;
DeviceInfo devInfo;
retVal = GetDeviceInfoByName(deviceName, devInfo);
sampleRates.assign(devInfo.m_AvailableSampleRates.begin(), devInfo.m_AvailableSampleRates.end() );
}
WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& buffers) const
{
WTErr retVal = eNoErr;

View file

@ -146,6 +146,7 @@ protected:
virtual WTErr generateDeviceListImpl(); // use this in derived class to fill device list
virtual WTErr updateDeviceListImpl() {return eNoErr; } // not supported
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& buffers) const;
virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const;
bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
bool m_bNoCopyAudioBuffer;