Paul Davis
000609901b
This follows the letter sent from Waves Audio Ltd. to Paul Davis dated February 20th 2014 agreeing to release this code under the GNU Public License, version 2, with copyright owned by Waves Audio Ltd
180 lines
7.0 KiB
C++
180 lines
7.0 KiB
C++
/*
|
|
Copyright (C) 2014 Waves Audio Ltd.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
//----------------------------------------------------------------------------------
|
|
//
|
|
//
|
|
//! \file WCMRPortAudioDeviceManager.h
|
|
//!
|
|
//! WCMRPortAudioDeviceManager and related class declarations
|
|
//!
|
|
//---------------------------------------------------------------------------------*/
|
|
#ifndef __WCMRPortAudioDeviceManager_h_
|
|
#define __WCMRPortAudioDeviceManager_h_
|
|
|
|
#include "WCMRAudioDeviceManager.h"
|
|
#include "WCMRNativeAudio.h"
|
|
#include "portaudio.h"
|
|
|
|
//forward decl.
|
|
class WCMRPortAudioDeviceManager;
|
|
|
|
//! Manages a port audio device, providing information
|
|
//! about the device, and managing audio callbacks.
|
|
class WCMRPortAudioDevice : public WCMRNativeAudioDevice
|
|
{
|
|
public:
|
|
|
|
WCMRPortAudioDevice (WCMRPortAudioDeviceManager *pManager, unsigned int deviceID, bool useMultiThreading = true, bool bNoCopy = false);///<Constructor
|
|
virtual ~WCMRPortAudioDevice ();///<Destructor
|
|
|
|
virtual int CurrentSamplingRate(); ///<Current Sampling rate.?
|
|
virtual WTErr SetCurrentSamplingRate(int newRate);///<Change Current Sampling Rate : This is a requset, might not be successful at run time!
|
|
|
|
virtual int CurrentBufferSize();///<Current Buffer Size.? - note that this may change with change in sampling rate.
|
|
virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
|
|
|
|
virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected
|
|
|
|
virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
|
|
|
|
virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
|
|
|
|
virtual WTErr SetMonitorChannels (int leftChannel, int rightChannel);///<Set monitor channels. - optional, will not be available with AG
|
|
virtual WTErr SetMonitorGain (float newGain);///<Set monitor gain. - optional, will not be available with AG
|
|
|
|
virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!
|
|
|
|
virtual int AudioCallback (const float *pInputBuffer, float *pOutputBuffer, unsigned long framesPerBuffe, bool dropsDetectedr);
|
|
|
|
virtual WTErr UpdateDeviceInfo ();
|
|
|
|
virtual WTErr ResetDevice();
|
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
static long StaticASIOMessageHook (void *pRefCon, long selector, long value, void* message, double* opt);
|
|
long ASIOMessageHook (long selector, long value, void* message, double* opt);
|
|
#endif //PLATFORM_WINDOWS
|
|
|
|
protected:
|
|
static DWORD WINAPI __DoIdle__(LPVOID lpThreadParameter);
|
|
|
|
// Methods which are executed by device processing thread
|
|
WTErr DoIdle();///<Do Idle Processing
|
|
void initDevice();
|
|
void terminateDevice();
|
|
void updateDeviceInfo(bool callerIsWaiting = false);
|
|
void activateDevice(bool callerIsWaiting = false);
|
|
void deactivateDevice(bool callerIsWaiting = false);
|
|
void startStreaming(bool callerIsWaiting = false);
|
|
void stopStreaming(bool callerIsWaiting = false);
|
|
void resetDevice (bool callerIsWaiting = false);///<Reset device - close and reopen stream, update device information!
|
|
|
|
PaError testStateValidness(int sampleRate, int bufferSize);
|
|
///////////////////////////////////////////////////////////
|
|
|
|
static int TheCallback (const void *pInputBuffer, void *pOutputBuffer, unsigned long framesPerBuffer,
|
|
const PaStreamCallbackTimeInfo* /*pTimeInfo*/, PaStreamCallbackFlags /*statusFlags*/, void *pUserData );
|
|
|
|
unsigned int m_DeviceID; ///< The PA device id
|
|
PaStream* m_PortAudioStream; ///< Port audio stream, when the device is active!
|
|
bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
|
|
const float *m_pInputData; ///< This is what came in with the most recent callback.
|
|
int m_SampleCounter; ///< The current running sample counter, updated by the audio callback.
|
|
int m_SampleCountAtLastIdle;
|
|
|
|
int m_DropsDetected; ///< Number of times audio drops have been detected so far.
|
|
int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
|
|
bool m_IgnoreThisDrop; ///< Allows disregarding the first drop
|
|
|
|
int m_BufferSizeChangeRequested;
|
|
int m_BufferSizeChangeReported;
|
|
int m_ResetRequested;
|
|
int m_ResetReported;
|
|
int m_ResyncRequested;
|
|
int m_ResyncReported;
|
|
|
|
HANDLE m_hDeviceProcessingThread;
|
|
DWORD m_DeviceProcessingThreadID;
|
|
|
|
///< Backend request events
|
|
HANDLE m_hResetRequestedEvent;
|
|
HANDLE m_hResetDone;
|
|
|
|
HANDLE m_hUpdateDeviceInfoRequestedEvent;
|
|
HANDLE m_hUpdateDeviceInfoDone;
|
|
|
|
HANDLE m_hActivateRequestedEvent;
|
|
HANDLE m_hActivationDone;
|
|
|
|
HANDLE m_hDeActivateRequestedEvent;
|
|
HANDLE m_hDeActivationDone;
|
|
|
|
HANDLE m_hStartStreamingRequestedEvent;
|
|
HANDLE m_hStartStreamingDone;
|
|
|
|
HANDLE m_hStopStreamingRequestedEvent;
|
|
HANDLE m_hStopStreamingDone;
|
|
/////////////////////////
|
|
|
|
///< Device request events
|
|
HANDLE m_hResetFromDevRequestedEvent;
|
|
HANDLE m_hBufferSizeChangedEvent;
|
|
HANDLE m_hSampleRateChangedEvent;
|
|
/////////////////////////////
|
|
|
|
///< Sync events
|
|
HANDLE m_hDeviceInitialized;
|
|
HANDLE m_hExitIdleThread;
|
|
|
|
//Should be set if the device connection status is "DeviceErrors"
|
|
WTErr m_lastErr;
|
|
};
|
|
|
|
//! WCMRPortAudioDeviceManager
|
|
/*! The PortAudio Device Manager class */
|
|
class WCMRPortAudioDeviceManager : public WCMRAudioDeviceManager
|
|
{
|
|
public:
|
|
WCMRPortAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
|
|
bool useMultithreading = true, bool bNocopy = false); ///< constructor
|
|
|
|
virtual ~WCMRPortAudioDeviceManager(void); ///< destructor
|
|
|
|
protected:
|
|
|
|
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName);
|
|
virtual void destroyCurrentDeviceImpl();
|
|
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;
|
|
|
|
private:
|
|
// helper functions for this class only
|
|
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
|
|
|
|
WCMRAudioDevice* m_NoneDevice;
|
|
};
|
|
|
|
#endif //#ifndef __WCMRPortAudioDeviceManager_h_
|