From 0cf788ef12cf8258d5c9c351a58e483e7a75e939 Mon Sep 17 00:00:00 2001 From: GZharun Date: Tue, 8 Jul 2014 12:27:20 +0300 Subject: [PATCH] [Summary] Added possibility to update sample rate list for devices on the fly on MAC --- .../backends/wavesaudio/waves_audiobackend.cc | 14 ++-- .../devicemanager/WCMRAudioDeviceManager.cpp | 7 ++ .../devicemanager/WCMRAudioDeviceManager.h | 2 + .../WCMRCoreAudioDeviceManager.cpp | 73 +++++++++++++++++++ .../WCMRCoreAudioDeviceManager.h | 1 + .../WCMRPortAudioDeviceManager.cpp | 13 ++++ .../WCMRPortAudioDeviceManager.h | 1 + 7 files changed, 103 insertions(+), 8 deletions(-) diff --git a/libs/backends/wavesaudio/waves_audiobackend.cc b/libs/backends/wavesaudio/waves_audiobackend.cc index 07d786239f..6ceacd2b3c 100644 --- a/libs/backends/wavesaudio/waves_audiobackend.cc +++ b/libs/backends/wavesaudio/waves_audiobackend.cc @@ -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 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 (); } // COMMENTED DBG LOGS */ std::cout << "\tFound " << devInfo.m_AvailableSampleRates.size () << " sample rates for " << device_name << ":"; - std::vector sample_rates (devInfo.m_AvailableSampleRates.begin (), devInfo.m_AvailableSampleRates.end ()); + std::vector sample_rates (sr.begin (), sr.end ()); // COMMENTED DBG LOGS */ for (std::vector::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 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; diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp index 00ee1c247f..6565237215 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.cpp @@ -631,6 +631,13 @@ WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatc } +WTErr WCMRAudioDeviceManager::GetDeviceSampleRates(const std::string & nameToMatch, std::vector& sampleRates) const +{ + return getDeviceSampleRatesImpl(nameToMatch, sampleRates); +} + + + WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector& bufferSizes) const { return getDeviceBufferSizesImpl(nameToMatch, bufferSizes); diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h index a3b1baa784..e364439602 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRAudioDeviceManager.h @@ -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& sampleRates) const; WTErr GetDeviceBufferSizes(const std::string & nameToMatch, std::vector& 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& sampleRates) const = 0; virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector& bufferSizes) const = 0; virtual WTErr generateDeviceListImpl() = 0; virtual WTErr updateDeviceListImpl() = 0; diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp index bad6807c9a..6567360c1d 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp @@ -2870,6 +2870,79 @@ WTErr WCMRCoreAudioDeviceManager::updateDeviceListImpl() } +WTErr WCMRCoreAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& 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& bufferSizes) const { AUTO_FUNC_DEBUG; diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h index 143c4eaf9c..913b4af5cb 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h @@ -173,6 +173,7 @@ protected: virtual void destroyCurrentDeviceImpl(); virtual WTErr generateDeviceListImpl(); virtual WTErr updateDeviceListImpl(); + virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& sampleRates) const; virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector& bufferSizes) const; bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing. diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp index ca8bc170f3..017da5069f 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp @@ -1656,6 +1656,19 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl() } +WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& 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& buffers) const { WTErr retVal = eNoErr; diff --git a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h index acbed161e2..f9a1300d7e 100644 --- a/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h +++ b/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h @@ -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& buffers) const; + virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector& sampleRates) const; bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing. bool m_bNoCopyAudioBuffer;