13
0
livetrax/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRPortAudioDeviceManager.h
Paul Davis 000609901b add correct copyright statements to all files in Waves backend except those derived from portaudio/portmidi
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
2014-10-07 16:17:34 -04:00

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_