ITAPortaudioInterface.h 10.2 KB
Newer Older
Jonas Stienen's avatar
Jonas Stienen committed
1 2 3 4 5
/*
* ----------------------------------------------------------------
*
*		ITA core libs
*		(c) Copyright Institute of Technical Acoustics (ITA)
6
*		RWTH Aachen University, Germany, 2015-2017
Jonas Stienen's avatar
Jonas Stienen committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
*
* ----------------------------------------------------------------
*				    ____  __________  _______
*				   //  / //__   ___/ //  _   |
*				  //  /    //  /    //  /_|  |
*				 //  /    //  /    //  ___   |
*				//__/    //__/    //__/   |__|
*
* ----------------------------------------------------------------
*
*/
// $Id: ITAPortaudioInterface.h 2900 2012-09-17 08:42:42Z stienen $

#ifndef INCLUDE_WATCHER_ITA_PORTAUDIO_INTERFACE
#define INCLUDE_WATCHER_ITA_PORTAUDIO_INTERFACE

#include <ITADataSourcesDefinitions.h>

#include <string>
#include <vector>

// Forward declaration of ITADatasource
class ITADatasource;

/*! ITAPortaudioInterface
 *
 * This class provides an eays-to-use connection and configuration to Portaudio. It
 * gives opportunity to playback and record ITADatasources.
 *
 * see also \ITADatasources
 *
 */
class ITA_DATA_SOURCES_API ITAPortaudioInterface
{
public:
	//! ITAPortaudio error code table
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
43
	enum ITA_PA_ERRORCODE
44
	{
Jonas Stienen's avatar
Jonas Stienen committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
		//! Portaudio/ITAPortaudio no error
		ITA_PA_NO_ERROR=0,

		//! ITAPortaudio invalid configuration (deprecated)
		ITA_PA_INVALID_CONFIGURATION = -10,

		//! ITAPortaudio already initialized
		ITA_PA_IS_INITIALIZED,

		//! ITAPortaudio stream is open
		ITA_PA_IS_OPEN,

		//! ITAPortaudio stream is not open
		ITA_PA_IS_NOT_OPEN,

		//! ITAPortaudio no playback data source provided
		ITA_PA_NO_PLAYBACK_DATASOURCE,

		//! ITAPortaudio no playback data source provided
		ITA_PA_NO_RECORD_DATASOURCE,

		//! ITAPortaudio buffer size is not matching
		ITA_PA_UNMATCHED_BUFFER_SIZE,

		//! ITAPortaudio sample rate is not matching
		ITA_PA_UNMATCHED_SAMPLE_RATE,

		//! ITAPortaudio channels are not matching
		ITA_PA_UNMATCHED_CHANNELS,

		//! Portaudio not initialized
		ITA_PA_NOT_INITIALIZED = -10000,

		//! Portaudio unanticipated host error
		ITA_PA_UNANTICIPATED_HOST_ERROR,

		//! Portaudio invalid channel count
		ITA_PA_INVALID_CHANNEL_COUNT,

		//! Portaudio invalid sample rate
		ITA_PA_INVALID_SAMPLE_RATE,

		//! Portaudio invalid device
		ITA_PA_INVALID_DEVICE,

		//! Portaudio invalid flag
		ITA_PA_INVALID_FLAG,

		//! Portaudio invalid sample format
		ITA_PA_SAMPLE_FORMAT_NOT_SUPPORTED,

		//! Portaudio bad input output device combination
		ITA_PA_BAD_IO_DEVICE_COMBINATION,

		//! Portaudio insufficient memobry
		ITA_PA_INSUFFICIENT_MEMORY,

		//! Portaudio buffer too big
		ITA_PA_BUFFER_TOO_BIG,

		//! Portaudio buffer too small
		ITA_PA_BUFFER_TOO_SMALL,

		//! Portaudio null callback
		ITA_PA_NULL_CALLBACK,

		//! Portaudio bad stream pointer
		ITA_PA_BAD_STREAM_POINTER,

		//! Portaudio timeout
		ITA_PA_TIMED_OUT,

		//! Portaudio/ITAPortaudio internal error
		ITA_PA_INTERNAL_ERROR,

		//! Portaudio device unavailable
		ITA_PA_DEVICE_UNAVAILABLE,

		//! Portaudio incompatible host api specific stream info
		ITA_PA_INCOMPATOBLE_HOST_API_SPECIFIC_STREAM_INFO,

		//! Portaudio stream is stopped
		ITA_PA_STREAM_IS_STOPPED,

		//! Portaudio stream is started
		ITA_PA_IS_STARTED,

		//! Portaudio input overflowed
		ITA_PA_INPUT_OVERFLOWED,

		//! Portaudio output underflowed
		ITA_PA_OUTPUT_UNDERFLOWED,

		//! Portaudio host api not found
		ITA_PA_HOST_API_NOT_FOUND,

		//! Portaudio invalid host api
		ITA_PA_INVALID_HOST_API,

		//! Portaudio can not read from a callback stream
		ITA_PA_CAN_NOT_READ_FROM_A_CALLBACK_STREAM,

		//! Portaudio can not write to a callback stream
		ITA_PA_CAN_NOT_WRITE_TO_A_CALLBACK_STREAM,

		//! Portaudio can not read from an output only stream
		ITA_PA_CAN_NOT_READ_FROM_AN_OUTPUT_ONLY_STREAM,

		//! Portaudio can not write to an input only stream
		ITA_PA_CAN_NOT_WRITE_TO_AN_INPUT_ONLY_STREAM,

		//! Portaudio incompatible stream host api
		ITA_PA_INCOMPATIBLE_STREAM_HOST_API,

		//! Portaudio bad buffer pointer
		ITA_PA_BAD_BUFFER_PTR
	};

	//! Portaudio available host APIs
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
164
	enum ITA_PA_HOST_APIS
165 166 167 168 169 170 171 172 173 174 175 176 177
	{
		ITA_PA_DIRECT_SOUND = 1,	//!< Windows DirectSound
		ITA_PA_MME = 2,				//!< Windows MME
		ITA_PA_ASIO = 3,			//!< Windows Steinberg ASIO (recommended: use ITAsioInterface instead)
		ITA_PA_SOUND_MANAGER = 4,	//!< Macintosh Sound Manager
		ITA_PA_CORE_AUDIO = 5,		//!< MacOS CoreAudio
		ITA_PA_OSS = 7,				//!< Linux/Unix OSS
		ITA_PA_ALSA = 8,			//!< Linux/Unix ALSA
		ITA_PA_AL = 9,				//!< Silicon Graphics Irix using AL
		ITA_PA_BE_OS = 10,			//!< BeOS
		ITA_PA_WDMKS = 11,			//!< Windows Driver Model Kernel Streaming driver
		ITA_PA_JACK = 12,			//!< MacOS/Linux/Unix Jack Audio
		ITA_PA_WASAPI = 13,			//!< Windows Audio Session API
Jonas Stienen's avatar
Jonas Stienen committed
178 179 180 181 182 183 184 185
		ITA_PA_AUDIO_SCIENCE_HPI=14	//!< AudioScience Hardware Programming Interface
	};


	//! Constructor with sample rate and buffer size
	/**
	  * Set up internal variables of ITAPortaudio. No exception will be
	  * thrown here.
186
	  * @note Next do initialization
Jonas Stienen's avatar
Jonas Stienen committed
187
	  *
188
	  * @see Initialize()
Jonas Stienen's avatar
Jonas Stienen committed
189
	  */
190
	ITAPortaudioInterface( double dSampleRate, int iBufferSize );
Jonas Stienen's avatar
Jonas Stienen committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205

	//! Destructor
	~ITAPortaudioInterface();

	//! Initialize Portaudio using default hardware and default host/driver
	/**
	  * Initializes Portaudio with the current driver. If no driver has been set,
	  * the default output device will be used, while the input device will be
	  * deactivated (playback mode on, recording mode off).
	  * 
	  * \return Will return error code if Portaudio could not be initialized with the current configuration, ITA_PA_NO_ERROR otherwise
	  */
	ITA_PA_ERRORCODE Initialize();

	//! Initialize Portaudio using specified host/driver by id
206
	ITA_PA_ERRORCODE Initialize( int iDriverID );
Jonas Stienen's avatar
Jonas Stienen committed
207 208

	//! Initialize Portaudio using specified driver by name
209
	ITA_PA_ERRORCODE Initialize( const std::string& sDriverName );
Jonas Stienen's avatar
Jonas Stienen committed
210 211

	//! Use Portaudio with specific input device
212
	ITA_PA_ERRORCODE SetOutputDevice( int iOutputDevice );
Jonas Stienen's avatar
Jonas Stienen committed
213 214 215 216 217

	//! Returns true if playback is enabled, false otherwise
	bool IsPlaybackEnabled() const;

	//! Set playback enabled/disabled
218
	void SetPlaybackEnabled( bool bEnabled);
Jonas Stienen's avatar
Jonas Stienen committed
219 220 221 222 223

	//! Returns true if record is enabled, false otherwise
	bool IsRecordEnabled() const;

	//! Set record enabled/disabled
224
	void SetRecordEnabled( bool bEnabled);
Jonas Stienen's avatar
Jonas Stienen committed
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247

	//! Finalize Portaudio
	/**
	  * This also deletes the record datasource.
	  */
	ITA_PA_ERRORCODE Finalize();

	//! Opens a Portaudio stream
	ITA_PA_ERRORCODE Open();

	//! Closes the Portaudio stream
	ITA_PA_ERRORCODE Close();

	//! Start Portaudio streaming
	ITA_PA_ERRORCODE Start();

	//! Stop Portaudio streaming
	ITA_PA_ERRORCODE Stop();

	//! Returns the number of drivers found by Portaudio
	int GetNumDevices() const;

	//! Returns the name of the driver avaiable in Portaudio
248
	std::string GetDeviceName( int iDriverID ) const;
Jonas Stienen's avatar
Jonas Stienen committed
249 250 251 252 253 254 255 256

	static int GetPreferredBufferSize();

	//! Returns the interactive low latency capability of the driver
	/**
	  * \param iDriverID Identifier of driver
	  * \return Latency in seconds, -1 if any error with the driver occurs
	  */
257
	float GetDeviceLatency( int iDriverID ) const;
Jonas Stienen's avatar
Jonas Stienen committed
258

259
	ITA_PA_ERRORCODE GetDriverSampleRate( int iDeviceID, double& dSampleRate ) const;
Jonas Stienen's avatar
Jonas Stienen committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279

	//! Returns the name of the current devices in Portaudio
	std::string GetInputDeviceName() const;

	//! Returns the name of the current devices in Portaudio
	std::string GetOutputDeviceName() const;

	//! Get default input device index
	int GetDefaultInputDevice() const;

	//! Get default output device index
	int GetDefaultOutputDevice() const;

	//! Get current input device index
	int GetInputDevice() const;

	//! Get current output device index
	int GetOutputDevice() const;

	//! Returns the number of input and output channels
280
	void GetNumChannels( int iDeviceID, int& iNumInputChannels, int& iNumOutputChannels ) const;
Jonas Stienen's avatar
Jonas Stienen committed
281 282 283 284 285

	//! Returns the number of input channels
	/**
	  * \return Number of input channels (>=0) or #ITA_PA_ERRORCODE (<0)
	  */
286
	int GetNumInputChannels( int iDeviceID ) const;
Jonas Stienen's avatar
Jonas Stienen committed
287 288 289 290 291

	//! Returns the number of output channels
	/**
	  * \return Number of output channels (>=0) or #ITA_PA_ERRORCODE (<0)
	  */
292
	int GetNumOutputChannels( int iDeviceID ) const;
Jonas Stienen's avatar
Jonas Stienen committed
293 294 295 296 297

	//! Returns the sample rate
	double GetSampleRate() const;

	//! Sets the sample rate
298
	ITA_PA_ERRORCODE SetSampleRate( double dSampleRate );
Jonas Stienen's avatar
Jonas Stienen committed
299 300 301 302 303
	
	//! Set the playback data source
	/**
	  * \note Enables playback, see IsPlaybackEnabled() and SetPlaybackEnabled()
	  */
304
	ITA_PA_ERRORCODE SetPlaybackDatasource( ITADatasource* pidsDatasource );
Jonas Stienen's avatar
Jonas Stienen committed
305 306 307 308 309 310 311 312 313 314 315 316

	//! Get the recording data source
	/**
	  * This also creates the record datasource if not already present.
	  
	  * \note Enables recording, see IsRecordingEnabled() and SetRecordingEnabled()
	  *
	  * \see Finalize()
	  */
	ITADatasource* GetRecordDatasource();

	//! Uses the Portaudio sleep function
317
	void Sleep( float fSeconds ) const;
Jonas Stienen's avatar
Jonas Stienen committed
318 319

	//! Returns a human readable error code string
320
	static std::string GetErrorCodeString( ITA_PA_ERRORCODE err );
Jonas Stienen's avatar
Jonas Stienen committed
321 322 323
	

	//! Internal user data class for information exchange with callback function
324 325
	class ITAPortaudioUserData
	{
Jonas Stienen's avatar
Jonas Stienen committed
326 327 328 329 330 331
	public:
		ITADatasource* pdsPlaybackDatasource; //!< ITADatasource playback datasource
		ITADatasource* pdsRecordDatasource;   //!< ITADatasource record datasource
		bool bPlayback;	//!< Playback enabled
		bool bRecord;   //!< Record enabled

332 333
		inline ITAPortaudioUserData()
		{
Jonas Stienen's avatar
Jonas Stienen committed
334 335 336 337 338 339 340 341
			pdsPlaybackDatasource = NULL;
			pdsRecordDatasource = NULL;
			bPlayback = false;
			bRecord = false;
		}
	};

private:
342
	//! Standard constructor deactivated
Jonas Stienen's avatar
Jonas Stienen committed
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
	ITAPortaudioInterface();
	
	std::string m_sConfigFile;	//!< Configuration file path
	double m_dSampleRate;		//!< Internal sampling rate
	int m_iBufferSize;			//!< Internal buffer size

	void* m_vpPaStream;			//!< Portaudio stream pointer

	ITAPortaudioUserData m_oUserData;		//!< ITAPortaudioDatasource user data
	
	bool m_bInitialized;		//!< Portaudio initialization status
	bool m_bOpen;				//!< Portaudio open status
	bool m_bStreaming;			//!< Portaudio streaming status
		
	bool m_bRecord;				//!< Portaudio recording mode
	bool m_bPlayback;			//!< Portaudio playback mode
	
	int m_iNumInputChannels;	//!< Number of input channels
	int m_iNumOutputChannels;	//!< Number of output channels

	int m_iDriverID;			//!< Portaudio driver identifier
	/*
	int m_iInputDevice;			//!< Identifier of input device
	int m_iOutputDevice;		//!< Identifier of output device
	*/

	ITA_PA_ERRORCODE m_iError;	//!< Last ITAPortaudio error

};

#endif // INCLUDE_WATCHER_ITA_PORTAUDIO_INTERFACE