globally remove all trailing whitespace from .cpp and .hpp files missed by previous...
[ardour.git] / libs / backends / wavesaudio / wavesapi / devicemanager / WCMRPortAudioDeviceManager.cpp
index 2d9081830c30c96d766b725db9144ab875ac7c5d..c039b49c0b23c2eecb555fb7725dea9a2d73db6a 100644 (file)
@@ -25,7 +25,7 @@ using namespace wvNS;
 #define PROPERTY_CHANGE_TIMEOUT_SECONDS 2
 #define PROPERTY_CHANGE_RETRIES 3
 
-///< Supported Sample rates                                                                                                  
+///< Supported Sample rates
 static const double gAllSampleRates[] =
        {
                44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, -1 /* negative terminated  list */
@@ -64,7 +64,7 @@ DWORD WINAPI WCMRPortAudioDevice::__DoIdle__(LPVOID lpThreadParameter)
 }
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::WCMRPortAudioDevice 
+// WCMRPortAudioDevice::WCMRPortAudioDevice
 //
 //! Constructor for the audio device. Opens the PA device
 //! and gets information about the device.
@@ -74,9 +74,9 @@ DWORD WINAPI WCMRPortAudioDevice::__DoIdle__(LPVOID lpThreadParameter)
 //! \param *pManager   : The audio device manager that's managing this device.
 //! \param deviceID            : The port audio device ID.
 //! \param useMultithreading : Whether to use multi-threading for audio processing. Default is true.
-//! 
+//!
 //! \return Nothing.
-//! 
+//!
 //**********************************************************************************************
 WCMRPortAudioDevice::WCMRPortAudioDevice (WCMRPortAudioDeviceManager *pManager, unsigned int deviceID, bool useMultithreading, bool bNoCopy) :
        WCMRNativeAudioDevice (pManager, useMultithreading, bNoCopy)
@@ -118,7 +118,6 @@ WCMRPortAudioDevice::WCMRPortAudioDevice (WCMRPortAudioDeviceManager *pManager,
        m_PortAudioStream = NULL;
        m_CurrentSamplingRate = DEFAULT_SR;
        m_CurrentBufferSize = DEFAULT_BUFFERSIZE;
-       m_DefaultBufferSize = DEFAULT_BUFFERSIZE;
        m_StopRequested = true;
        m_pInputData = NULL;
 
@@ -231,16 +230,16 @@ void WCMRPortAudioDevice::terminateDevice()
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::~WCMRPortAudioDevice 
+// WCMRPortAudioDevice::~WCMRPortAudioDevice
 //
 //! Destructor for the audio device. The base release all the connections that were created, if
 //!            they have not been already destroyed! Here we simply stop streaming, and close device
 //!            handles if necessary.
 //!
 //! \param none
-//! 
+//!
 //! \return Nothing.
-//! 
+//!
 //**********************************************************************************************
 WCMRPortAudioDevice::~WCMRPortAudioDevice ()
 {
@@ -294,13 +293,13 @@ WTErr WCMRPortAudioDevice::UpdateDeviceInfo ()
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::updateDeviceInfo 
+// WCMRPortAudioDevice::updateDeviceInfo
 //
 //! Must be called be device processing thread
 //! Updates Device Information about channels, sampling rates, buffer sizes.
 //!
 //! \return Nothing.
-//! 
+//!
 //**********************************************************************************************
 void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
 {
@@ -354,7 +353,7 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
        m_BufferSizes.clear();
        bool useDefaultBuffers = true;
 
-       // In ASIO Windows, the buffer size is set from the sound device manufacturer's control panel 
+       // In ASIO Windows, the buffer size is set from the sound device manufacturer's control panel
        long minSize, maxSize, preferredSize, granularity;
        PaError err = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
        
@@ -362,7 +361,6 @@ void WCMRPortAudioDevice::updateDeviceInfo (bool callerIsWaiting/*=false*/)
        {
                std::cout << "API::Device " << m_DeviceName << " Buffers: " << minSize << " " << maxSize << " " << preferredSize << std::endl;
                        
-               m_DefaultBufferSize = preferredSize;
                m_BufferSizes.push_back (preferredSize);
                useDefaultBuffers = false;
        }
@@ -488,15 +486,15 @@ PaError WCMRPortAudioDevice::testStateValidness(int sampleRate, int bufferSize)
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::CurrentSamplingRate 
+// WCMRPortAudioDevice::CurrentSamplingRate
 //
-//! The device's current sampling rate. This may be overridden, if the device needs to 
+//! The device's current sampling rate. This may be overridden, if the device needs to
 //!            query the driver for the current rate.
 //!
 //! \param none
-//! 
+//!
 //! \return The device's current sampling rate. -1 on error.
-//! 
+//!
 //**********************************************************************************************
 int WCMRPortAudioDevice::CurrentSamplingRate ()
 {
@@ -563,14 +561,14 @@ WTErr WCMRPortAudioDevice::ResetDevice()
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::SetCurrentSamplingRate 
+// WCMRPortAudioDevice::SetCurrentSamplingRate
 //
-//! Change the sampling rate to be used by the device. 
+//! Change the sampling rate to be used by the device.
 //!
 //! \param newRate : The rate to use (samples per sec).
-//! 
+//!
 //! \return eNoErr always. The derived classes may return error codes.
-//! 
+//!
 //**********************************************************************************************
 WTErr WCMRPortAudioDevice::SetCurrentSamplingRate (int newRate)
 {
@@ -605,7 +603,7 @@ WTErr WCMRPortAudioDevice::SetCurrentSamplingRate (int newRate)
        
        //make the change...
        m_CurrentSamplingRate = newRate;
-       PaError paErr = PaAsio_SetStreamSampleRate (m_PortAudioStream, m_CurrentSamplingRate);  
+       PaError paErr = PaAsio_SetStreamSampleRate (m_PortAudioStream, m_CurrentSamplingRate);
        Pa_Sleep(PROPERTY_CHANGE_SLEEP_TIME_MILLISECONDS); // sleep some time to make sure the change has place
 
        if (paErr != paNoError)
@@ -624,13 +622,13 @@ WTErr WCMRPortAudioDevice::SetCurrentSamplingRate (int newRate)
 //**********************************************************************************************
 // WCMRPortAudioDevice::CurrentBufferSize
 //
-//! The device's current buffer size in use. This may be overridden, if the device needs to 
+//! The device's current buffer size in use. This may be overridden, if the device needs to
 //!            query the driver for the current size.
 //!
 //! \param none
-//! 
+//!
 //! \return The device's current buffer size. 0 on error.
-//! 
+//!
 //**********************************************************************************************
 int WCMRPortAudioDevice::CurrentBufferSize ()
 {
@@ -641,13 +639,13 @@ int WCMRPortAudioDevice::CurrentBufferSize ()
 //**********************************************************************************************
 // WCMRPortAudioDevice::SetCurrentBufferSize
 //
-//! Change the buffer size to be used by the device. This will most likely be overridden, 
+//! Change the buffer size to be used by the device. This will most likely be overridden,
 //!            the base class simply updates the member variable.
 //!
 //! \param newSize : The buffer size to use (in sample-frames)
-//! 
+//!
 //! \return eNoErr always. The derived classes may return error codes.
-//! 
+//!
 //**********************************************************************************************
 WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
 {
@@ -655,14 +653,6 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
        WTErr retVal = eNoErr;
        std::vector<int>::iterator intIter;
 
-       //changes the status.
-       int oldSize = CurrentBufferSize();
-       bool oldActive = Active();
-
-       //same size, nothing to do.
-       if (oldSize == newSize)
-               return (retVal);
-       
        if (Streaming())
        {
                //Can't change, perhaps use an "in use" type of error
@@ -670,44 +660,17 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
                return (retVal);
        }
 
-       std::cout << "Setting buffer: " << newSize << std::endl;
-
-       //see if this is one of our supported rates...
-       intIter = find(m_BufferSizes.begin(), m_BufferSizes.end(), newSize);
-       if (intIter == m_BufferSizes.end())
-       {
-               //Sample rate proposed by client is not supported any more
-               if (m_BufferSizes.size() == 1)
-               {
-                       // we have only one aloved buffer size which is preffered by PA
-                       // this is the only value which could be set
-                       newSize = m_BufferSizes[0];
-                       int bufferSize = newSize;
-                       // notify client to update sample rate after us
-                       m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
-                       return retVal;
-               
-               } else {
-                       // more then one buffer size value is available
-                       //Can't change, perhaps use an "invalid param" type of error
-                       retVal = eCommandLineParameter;
-                       return (retVal);
-               }
-       }
-       
-       if (oldActive)
-       {
-               //Deactivate it for the change...
-               SetActive (false);
-       }
-       
-       //make the change...
-       m_CurrentBufferSize = newSize;
-
-       //reactivate it.        
-       if (oldActive)
+       // Buffer size for ASIO devices can be changed from the control panel only
+       // We have driver driven logi here
+       if (m_CurrentBufferSize != newSize )
        {
-               retVal = SetActive (true);
+               // we have only one aloved buffer size which is preffered by PA
+               // this is the only value which could be set
+               newSize = m_BufferSizes[0];
+               int bufferSize = newSize;
+               // notify client to update buffer size
+               m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::BufferSizeChanged, (void *)&bufferSize);
+               return retVal;
        }
 
        return (retVal);
@@ -715,15 +678,15 @@ WTErr WCMRPortAudioDevice::SetCurrentBufferSize (int newSize)
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::ConnectionStatus 
+// WCMRPortAudioDevice::ConnectionStatus
 //
 //! Retrieves the device's current connection status. This will most likely be overridden,
 //!            in case some driver communication is required to query the status.
 //!
 //! \param none
-//! 
+//!
 //! \return A ConnectionStates value.
-//! 
+//!
 //**********************************************************************************************
 WCMRPortAudioDevice::ConnectionStates WCMRPortAudioDevice::ConnectionStatus ()
 {
@@ -738,7 +701,7 @@ WCMRPortAudioDevice::ConnectionStates WCMRPortAudioDevice::ConnectionStatus ()
 // WCMRPortAudioDevice::activateDevice
 //
 //!    IS CALLED BY PROCESS THREAD
-//! Sets the device into "active" state. Essentially, opens the PA device. 
+//! Sets the device into "active" state. Essentially, opens the PA device.
 //!            If it's an ASIO device it may result in buffer size change in some cases.
 //!
 //**********************************************************************************************
@@ -751,17 +714,6 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
        // if device is not active activate it
        if (!Active() )
        {
-               std::list<long> buffersSizes;
-               buffersSizes.push_back(m_CurrentBufferSize);
-               
-               long minSize, maxSize, preferredSize, granularity;
-               PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
-
-               if (paErr == paNoError)
-               {
-                       buffersSizes.push_front(preferredSize);
-               }
-
                PaStreamParameters inputParameters, outputParameters;
                PaStreamParameters *pInS = NULL, *pOutS = NULL;
 
@@ -786,27 +738,20 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
                if (outputParameters.channelCount)
                        pOutS = &outputParameters;
 
-               // try opening stream with current buffer and the rest if not successful
-               std::list<long>::const_iterator bufferIter = buffersSizes.begin();
-               for (; bufferIter != buffersSizes.end(); ++bufferIter) {
-
-                       std::cout << "API::Device" << m_DeviceName << " Opening device stream " << std::endl;
-                       std::cout << "Sample rate: " << m_CurrentSamplingRate << " buffer size: " << *bufferIter << std::endl;
-                       paErr = Pa_OpenStream(&m_PortAudioStream, 
-                                                                 pInS,
-                                                                 pOutS,
-                                                                 m_CurrentSamplingRate,
-                                                                 m_CurrentBufferSize,
-                                                                 paDitherOff,
-                                                                 WCMRPortAudioDevice::TheCallback,
-                                                                 this);
+               std::cout << "API::Device " << m_DeviceName << " Opening device stream " << std::endl;
+               std::cout << "Sample rate: " << m_CurrentSamplingRate << " buffer size: " << m_CurrentBufferSize << std::endl;
+               paErr = Pa_OpenStream(&m_PortAudioStream,
+                                                               pInS,
+                                                               pOutS,
+                                                               m_CurrentSamplingRate,
+                                                               m_CurrentBufferSize,
+                                                               paDitherOff,
+                                                               WCMRPortAudioDevice::TheCallback,
+                                                               this);
                        
-                       if(paErr == paNoError)
-                       {
-                               break;
-                       }
-
-                       std::cout << "Cannot open streamm with buffer: "<< *bufferIter << " Error: " << Pa_GetErrorText (paErr) << std::endl;
+               if(paErr != paNoError)
+               {
+                       std::cout << "Cannot open streamm with buffer: "<< m_CurrentBufferSize << " Error: " << Pa_GetErrorText (paErr) << std::endl;
                        
                        if (paErr ==  paUnanticipatedHostError)
                                std::cout << "Error details: "<< Pa_GetLastHostErrorInfo ()->errorText << "; code: " << Pa_GetLastHostErrorInfo ()->errorCode << std::endl;
@@ -814,11 +759,16 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
 
                if(paErr == paNoError)
                {
+                       std::cout << "Stream has been opened! "<< std::endl;
+
+                       // check for possible changes
                        long minSize, maxSize, preferredSize, granularity;
                        PaError paErr = PaAsio_GetAvailableBufferSizes(m_DeviceID, &minSize, &maxSize, &preferredSize, &granularity);
 
+                       std::cout << "Checked if buffer size changed "<< std::endl;
                        if (paErr == paNoError && m_CurrentBufferSize != preferredSize)
                        {
+                               std::cout << "Buffer size has changed "<< std::endl;
                                m_CurrentBufferSize = preferredSize;
                                m_BufferSizes.clear();
                                m_BufferSizes.push_back(preferredSize);
@@ -837,6 +787,7 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
                                m_ResetReported = 0;
                                m_ResyncRequested = 0;
                                m_ResyncReported = 0;
+                               std::cout << "Installing new mesage hook "<< std::endl;
                                PaAsio_SetMessageHook (StaticASIOMessageHook, this);
                        }
                        m_IsActive = true;
@@ -855,6 +806,8 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
        
        }
 
+       std::cout << "Activation is DONE "<< std::endl;
+
        if (callerIsWaiting)
                SetEvent(m_hActivationDone);
 }
@@ -864,7 +817,7 @@ void WCMRPortAudioDevice::activateDevice (bool callerIsWaiting/*=false*/)
 // WCMRPortAudioDevice::deactivateDevice
 //
 //!    IS CALLED BY PROCESS THREAD
-//! Sets the device into "inactive" state. Essentially, closes the PA device. 
+//! Sets the device into "inactive" state. Essentially, closes the PA device.
 //!
 //**********************************************************************************************
 void WCMRPortAudioDevice::deactivateDevice (bool callerIsWaiting/*=false*/)
@@ -925,7 +878,7 @@ void WCMRPortAudioDevice::deactivateDevice (bool callerIsWaiting/*=false*/)
 //
 //! Sets the devices into "streaming" state. Calls PA's Start stream routines.
 //! This roughly corresponds to calling Start on the lower level interface.
-//! 
+//!
 //**********************************************************************************************
 void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/)
 {
@@ -946,6 +899,9 @@ void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/)
                unsigned int inChannelCount = pDeviceInfo->maxInputChannels;
                unsigned int outChannelCount = pDeviceInfo->maxOutputChannels;
                
+               // Prepare for streaming - tell Engine to do the initialization for process callback
+               m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
+
                paErr = Pa_StartStream( m_PortAudioStream );
 
                if(paErr == paNoError)
@@ -972,7 +928,7 @@ void WCMRPortAudioDevice::startStreaming (bool callerIsWaiting/*=false*/)
 //
 //! Sets the devices into "not streaming" state. Calls PA's Stop stream routines.
 //! This roughly corresponds to calling Stop on the lower level interface.
-//! 
+//!
 //**********************************************************************************************
 void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
 {
@@ -987,7 +943,7 @@ void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
                std::cout << "API::Device " << m_DeviceName << " Stopping device stream" << std::endl;
                paErr = Pa_StopStream( m_PortAudioStream );
 
-               if(paErr == paNoError)
+               if(paErr == paNoError || paErr == paStreamIsStopped)
                {
                        // if the stream was stopped successfully
                        m_IsStreaming = false;
@@ -995,8 +951,8 @@ void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
                }
                else
                {
-                       std::cout << "Failed to stop PA stream" <<  Pa_GetErrorText (paErr) << std::endl;
-                       DEBUG_MSG( "Failed to stop PA stream " << Pa_GetErrorText (paErr) );
+                       std::cout << "Failed to stop PA stream normaly! Error:" <<  Pa_GetErrorText (paErr) << std::endl;
+                       DEBUG_MSG( "Failed to stop PA stream normaly! Error:" << Pa_GetErrorText (paErr) );
                        m_lastErr = eGenericErr;
                }
        }
@@ -1007,20 +963,18 @@ void WCMRPortAudioDevice::stopStreaming (bool callerIsWaiting/*=false*/)
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::resetDevice 
+// WCMRPortAudioDevice::resetDevice
 //
 //! Resets the device, updates device info. Importnat: does PA reinitialization calling
 //! Pa_terminate/Pa_initialize functions.
 //!
 //! \param none
-//! 
+//!
 //! \return nothing
-//! 
+//!
 //**********************************************************************************************
 void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
 {
-       std::cout << "API::Device" << m_DeviceName << "Reseting device" << std::endl;
-
        PaError paErr = paNoError;
 
        // Keep device sates
@@ -1053,7 +1007,7 @@ void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
                if (paErr != paNoError)
                {
                        continue;
-               } 
+               }
                m_CurrentBufferSize = preferredSize;
 
                paErr = testStateValidness(m_CurrentSamplingRate, m_CurrentBufferSize);
@@ -1090,8 +1044,7 @@ void WCMRPortAudioDevice::resetDevice (bool callerIsWaiting /*=false*/ )
                // Resume streaming if the device was streaming before
                if(wasStreaming && m_lastErr == eNoErr && m_ConnectionStatus == DeviceAvailable)
                {
-                       // Notify the Application to prepare for the stream start
-                       m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
+                       // start streaming
                        startStreaming();
                }
        } else {
@@ -1123,24 +1076,29 @@ long WCMRPortAudioDevice::ASIOMessageHook (long selector, long WCUNUSEDPARAM(val
                case kAsioResyncRequest:
                        m_ResyncRequested++;
                        std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioResyncRequest" << std::endl;
-                       m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
                        break;
 
                case kAsioLatenciesChanged:
                        m_BufferSizeChangeRequested++;
                        std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioLatenciesChanged" << std::endl;
-                       m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+                       if (m_ResetRequested == 0) {
+                               m_ResetRequested++;
+                               m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+                       }
                        break;
 
                case kAsioBufferSizeChange:
                        m_BufferSizeChangeRequested++;
                        std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- m_BufferSizeChangeRequested" << std::endl;
-                       m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+                       if (m_ResetRequested == 0) {
+                               m_ResetRequested++;
+                               m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
+                       }
                        break;
 
                case kAsioResetRequest:
-                       m_ResetRequested++;
                        std::cout << "\t\t\tWCMRPortAudioDevice::ASIOMessageHook -- kAsioResetRequest" << std::endl;
+                       m_ResetRequested++;
                        m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::RequestReset);
                        break;
 
@@ -1157,22 +1115,22 @@ long WCMRPortAudioDevice::ASIOMessageHook (long selector, long WCUNUSEDPARAM(val
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::DoIdle 
+// WCMRPortAudioDevice::DoIdle
 //
 //! A place for doing idle time processing. The other derived classes will probably do something
 //!            meaningful.
 //!
 //! \param none
-//! 
+//!
 //! \return eNoErr always.
-//! 
+//!
 //**********************************************************************************************
 WTErr WCMRPortAudioDevice::DoIdle ()
 {
        WTErr retVal = eNoErr;
 
        std::cout << "WCMRPortAudioDevice::DoIdle ()" << std::endl;
-       HANDLE hEvents[] = 
+       HANDLE hEvents[] =
        {
                m_hUpdateDeviceInfoRequestedEvent,
                m_hActivateRequestedEvent,
@@ -1260,15 +1218,15 @@ WTErr WCMRPortAudioDevice::DoIdle ()
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::SetMonitorChannels 
+// WCMRPortAudioDevice::SetMonitorChannels
 //
 //! Used to set the channels to be used for monitoring.
 //!
 //! \param leftChannel : Left monitor channel index.
 //! \param rightChannel : Right monitor channel index.
-//! 
+//!
 //! \return eNoErr always, the derived classes may return appropriate errors.
-//! 
+//!
 //**********************************************************************************************
 WTErr WCMRPortAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel)
 {
@@ -1283,14 +1241,14 @@ WTErr WCMRPortAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::SetMonitorGain 
+// WCMRPortAudioDevice::SetMonitorGain
 //
 //! Used to set monitor gain (or atten).
 //!
-//! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB) 
-//! 
+//! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB)
+//!
 //! \return eNoErr always, the derived classes may return appropriate errors.
-//! 
+//!
 //**********************************************************************************************
 WTErr WCMRPortAudioDevice::SetMonitorGain (float newGain)
 {
@@ -1306,15 +1264,15 @@ WTErr WCMRPortAudioDevice::SetMonitorGain (float newGain)
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::ShowConfigPanel 
+// WCMRPortAudioDevice::ShowConfigPanel
 //
 //! Used to show device specific config/control panel. Some interfaces may not support it.
 //!            Some interfaces may require the device to be active before it can display a panel.
 //!
 //! \param pParam : A device/interface specific parameter, should be the app window handle for ASIO.
-//! 
+//!
 //! \return eNoErr always, the derived classes may return errors.
-//! 
+//!
 //**********************************************************************************************
 WTErr WCMRPortAudioDevice::ShowConfigPanel (void *pParam)
 {
@@ -1357,7 +1315,7 @@ WTErr WCMRPortAudioDevice::ShowConfigPanel (void *pParam)
 //*****************************************************************************************************
 // WCMRPortAudioDevice::TheCallback
 //
-//! The (static) Port Audio Callback function. This is a static member. It calls on the AudioCallback in the 
+//! The (static) Port Audio Callback function. This is a static member. It calls on the AudioCallback in the
 //!            WCMRPortAudioDevice to do the real work.
 //!
 //! \param pInputBuffer: pointer to input buffer.
@@ -1366,10 +1324,10 @@ WTErr WCMRPortAudioDevice::ShowConfigPanel (void *pParam)
 //! \param pTimeInfo: time info for PaStream callback.
 //! \param statusFlags:
 //! \param pUserData: pointer to user data, in our case the WCMRPortAudioDevice object.
-//! 
+//!
 //! \return true to stop streaming else returns false.
 //******************************************************************************************************
-int WCMRPortAudioDevice::TheCallback (const void *pInputBuffer, void *pOutputBuffer, unsigned long framesPerBuffer, 
+int WCMRPortAudioDevice::TheCallback (const void *pInputBuffer, void *pOutputBuffer, unsigned long framesPerBuffer,
        const PaStreamCallbackTimeInfo* /*pTimeInfo*/, PaStreamCallbackFlags statusFlags, void *pUserData )
 {
        WCMRPortAudioDevice *pMyDevice = (WCMRPortAudioDevice *)pUserData;
@@ -1384,10 +1342,10 @@ int WCMRPortAudioDevice::TheCallback (const void *pInputBuffer, void *pOutputBuf
 
 
 //**********************************************************************************************
-// WCMRPortAudioDevice::AudoiCallback 
+// WCMRPortAudioDevice::AudoiCallback
 //
-//! Here's where the actual audio processing happens. We call upon all the active connections' 
-//!            sinks to provide data to us which can be put/mixed in the output buffer! Also, we make the 
+//! Here's where the actual audio processing happens. We call upon all the active connections'
+//!            sinks to provide data to us which can be put/mixed in the output buffer! Also, we make the
 //!            input data available to any sources     that may call upon us during this time!
 //!
 //! \param *pInputBuffer : Points to a buffer with recorded data.
@@ -1396,9 +1354,9 @@ int WCMRPortAudioDevice::TheCallback (const void *pInputBuffer, void *pOutputBuf
 //!            which are interleaved, is fixed at Device Open (Active) time. In this implementation,
 //!            the number of channels are fixed to use the maximum available.
 //!    \param dropsDetected : True if dropouts were detected in input or output. Can be used to signal the GUI.
-//! 
+//!
 //! \return true
-//! 
+//!
 //**********************************************************************************************
 int WCMRPortAudioDevice::AudioCallback( const float *pInputBuffer, float *pOutputBuffer, unsigned long framesPerBuffer, bool dropsDetected )
 {
@@ -1424,7 +1382,7 @@ int WCMRPortAudioDevice::AudioCallback( const float *pInputBuffer, float *pOutpu
                m_SampleCounter,
                theStartTime.MicroSeconds()*1000
     };
-    
+
     m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::AudioCallback, (void *)&audioCallbackData );
 
        //Don't try to  access after this call returns!
@@ -1446,11 +1404,11 @@ int WCMRPortAudioDevice::AudioCallback( const float *pInputBuffer, float *pOutpu
 //! \param *pTheClient : The manager's client object (which receives notifications).
 //! \param interfaceType : The PortAudio interface type to use for this manager - acts as a filter.
 //! \param useMultithreading : Whether to use multi-threading for audio processing. Default is true.
-//! 
+//!
 //! \return Nothing.
-//! 
+//!
 //**********************************************************************************************
-WCMRPortAudioDeviceManager::WCMRPortAudioDeviceManager (WCMRAudioDeviceManagerClient *pTheClient, 
+WCMRPortAudioDeviceManager::WCMRPortAudioDeviceManager (WCMRAudioDeviceManagerClient *pTheClient,
                                                                                                                eAudioDeviceFilter eCurAudioDeviceFilter, bool useMultithreading, bool bNocopy)
        : WCMRAudioDeviceManager (pTheClient, eCurAudioDeviceFilter)
        , m_NoneDevice(0)
@@ -1478,9 +1436,9 @@ WCMRPortAudioDeviceManager::WCMRPortAudioDeviceManager (WCMRAudioDeviceManagerCl
 //! It clears the device list, releasing each of the device.
 //!
 //! \param none
-//! 
+//!
 //! \return Nothing.
-//! 
+//!
 //**********************************************************************************************
 WCMRPortAudioDeviceManager::~WCMRPortAudioDeviceManager()
 {
@@ -1505,7 +1463,7 @@ WCMRPortAudioDeviceManager::~WCMRPortAudioDeviceManager()
 WCMRAudioDevice* WCMRPortAudioDeviceManager::initNewCurrentDeviceImpl(const std::string & deviceName)
 {
     destroyCurrentDeviceImpl();
-    
+
        std::cout << "API::PortAudioDeviceManager::initNewCurrentDevice " << deviceName << std::endl;
        if (deviceName == m_NoneDevice->DeviceName() )
        {
@@ -1587,6 +1545,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()
 {
        std::cout << "API::PortAudioDeviceManager::Generating device list" << std::endl;
@@ -1633,6 +1617,7 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
                                DeviceInfo *pDevInfo = new DeviceInfo(thisDeviceID, pPaDeviceInfo->name);
                                if (pDevInfo)
                                {
+                                       //Get available sample rates
                                        std::vector<int> availableSampleRates;
                                        WTErr wErr = WCMRPortAudioDeviceManager::getDeviceAvailableSampleRates(thisDeviceID, availableSampleRates);
 
@@ -1647,6 +1632,19 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
                                        pDevInfo->m_MaxInputChannels = pPaDeviceInfo->maxInputChannels;
                                        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
                                        bool bRejectDevice = false;
                                        switch(m_eAudioDeviceFilter)
@@ -1689,7 +1687,7 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
                                                        m_DeviceInfoVec.push_back(pDevInfo);
                                                        break;
                                        }
-                
+
                                        if(bRejectDevice)
                                        {
                                                TRACE_MSG ("API::PortAudioDeviceManager::Device " << pDevInfo->m_DeviceName << "Rejected. \
@@ -1723,21 +1721,21 @@ WTErr WCMRPortAudioDeviceManager::generateDeviceListImpl()
 WTErr WCMRPortAudioDeviceManager::getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const
 {
     sampleRates.clear ();
-    
+
     WTErr retVal = eNoErr;
-    
+
        if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
        {
-               sampleRates.assign(m_CurrentDevice->SamplingRates().begin(), m_CurrentDevice->SamplingRates().end() );
+               sampleRates=m_CurrentDevice->SamplingRates();
                return retVal;
        }
 
     DeviceInfo devInfo;
        retVal = GetDeviceInfoByName(deviceName, devInfo);
-    
+
        if (eNoErr == retVal)
        {
-               sampleRates.assign(devInfo.m_AvailableSampleRates.begin(), devInfo.m_AvailableSampleRates.end() );
+               sampleRates=devInfo.m_AvailableSampleRates;
        }
        else
        {
@@ -1757,44 +1755,28 @@ WTErr WCMRPortAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & d
        //first check if the request has been made for None device
        if (deviceName == m_NoneDevice->DeviceName() )
        {
-               buffers.assign(m_NoneDevice->BufferSizes().begin(), m_NoneDevice->BufferSizes().end() );
+               buffers=m_NoneDevice->BufferSizes();
                return retVal;
        }
        
        if (m_CurrentDevice && deviceName == m_CurrentDevice->DeviceName() )
        {
-               buffers.assign(m_CurrentDevice->BufferSizes().begin(), m_CurrentDevice->BufferSizes().end() );
+               buffers=m_CurrentDevice->BufferSizes();
                return retVal;
        }
 
-       Pa_Initialize();
-
-       DeviceInfo devInfo; 
+       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;
 }