X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=RtAudio.h;h=39d0e12576923e8f6172744c9245ff9516408063;hb=bf0fc2388b444797c79031946fd0f41735e8c820;hp=bc99bd934e23ed027709369a0ea48ab7559b357b;hpb=17613bf3d55a9424c4971b766db1edf6d2cc90bf;p=rtaudio-cdist.git diff --git a/RtAudio.h b/RtAudio.h index bc99bd9..39d0e12 100644 --- a/RtAudio.h +++ b/RtAudio.h @@ -10,7 +10,7 @@ RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/ RtAudio: realtime audio i/o C++ classes - Copyright (c) 2001-2014 Gary P. Scavone + Copyright (c) 2001-2017 Gary P. Scavone Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -45,11 +45,25 @@ #ifndef __RTAUDIO_H #define __RTAUDIO_H -#define RTAUDIO_VERSION "4.1.0" +#define RTAUDIO_VERSION "5.0.0" + +#if defined _WIN32 || defined __CYGWIN__ + #if defined(RTAUDIO_EXPORT) + #define RTAUDIO_DLL_PUBLIC __declspec(dllexport) + #else + #define RTAUDIO_DLL_PUBLIC + #endif +#else + #if __GNUC__ >= 4 + #define RTAUDIO_DLL_PUBLIC __attribute__( (visibility( "default" )) ) + #else + #define RTAUDIO_DLL_PUBLIC + #endif +#endif #include #include -#include +#include #include /*! \typedef typedef unsigned long RtAudioFormat; @@ -86,6 +100,7 @@ static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/mi - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency. - \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use. - \e RTAUDIO_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only). + - \e RTAUDIO_JACK_DONT_CONNECT: Do not automatically connect ports (JACK only). By default, RtAudio streams pass and receive audio data from the client in an interleaved format. By passing the @@ -101,7 +116,7 @@ static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/mi Certain audio APIs offer a number of parameters that influence the I/O latency of a stream. By default, RtAudio will attempt to set these parameters internally for robust (glitch-free) performance - (though some APIs, like Windows Direct Sound, make this difficult). + (though some APIs, like Windows DirectSound, make this difficult). By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream() function, internal stream settings will be influenced in an attempt to minimize stream latency, though possibly at the expense of stream @@ -111,12 +126,15 @@ static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/mi open the input and/or output stream device(s) for exclusive use. Note that this is not possible with all supported audio APIs. - If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt + If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt to select realtime scheduling (round-robin) for the callback thread. If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to open the "default" PCM device when using the ALSA API. Note that this will override any specified input or output device id. + + If the RTAUDIO_JACK_DONT_CONNECT flag is set, RtAudio will not attempt + to automatically connect the ports of the client to the audio device. */ typedef unsigned int RtAudioStreamFlags; static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1; // Use non-interleaved buffers (default = interleaved). @@ -124,6 +142,7 @@ static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2; // Attempt to s static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4; // Attempt grab device and prevent use by others. static const RtAudioStreamFlags RTAUDIO_SCHEDULE_REALTIME = 0x8; // Try to select realtime scheduling for callback thread. static const RtAudioStreamFlags RTAUDIO_ALSA_USE_DEFAULT = 0x10; // Use the "default" PCM device (ALSA only). +static const RtAudioStreamFlags RTAUDIO_JACK_DONT_CONNECT = 0x20; // Do not automatically connect ports (JACK only). /*! \typedef typedef unsigned long RtAudioStreamStatus; \brief RtAudio stream status (over- or underflow) flags. @@ -195,7 +214,7 @@ typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer, */ /************************************************************************/ -class RtAudioError : public std::exception +class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error { public: //! Defined RtAudioError types. @@ -214,25 +233,22 @@ class RtAudioError : public std::exception }; //! The constructor. - RtAudioError( const std::string& message, Type type = RtAudioError::UNSPECIFIED ) throw() : message_(message), type_(type) {} - - //! The destructor. - virtual ~RtAudioError( void ) throw() {} + RtAudioError( const std::string& message, + Type type = RtAudioError::UNSPECIFIED ) + : std::runtime_error(message), type_(type) {} //! Prints thrown error message to stderr. - virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; } + virtual void printMessage( void ) const + { std::cerr << '\n' << what() << "\n\n"; } //! Returns the thrown error message type. - virtual const Type& getType(void) const throw() { return type_; } + virtual const Type& getType(void) const { return type_; } //! Returns the thrown error message string. - virtual const std::string& getMessage(void) const throw() { return message_; } - - //! Returns the thrown error message as a c-style string. - virtual const char* what( void ) const throw() { return message_.c_str(); } + virtual const std::string getMessage(void) const + { return std::string(what()); } protected: - std::string message_; Type type_; }; @@ -258,7 +274,7 @@ typedef void (*RtAudioErrorCallback)( RtAudioError::Type type, const std::string class RtApi; -class RtAudio +class RTAUDIO_DLL_PUBLIC RtAudio { public: @@ -272,8 +288,9 @@ class RtAudio MACOSX_CORE, /*!< Macintosh OS-X Core Audio API. */ WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */ WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */ - WINDOWS_DS, /*!< The Microsoft Direct Sound API. */ - RTAUDIO_DUMMY /*!< A compilable but non-functional API. */ + WINDOWS_DS, /*!< The Microsoft DirectSound API. */ + RTAUDIO_DUMMY, /*!< A compilable but non-functional API. */ + NUM_APIS /*!< Number of values in this enum. */ }; //! The public device information structure for returning queried values. @@ -286,12 +303,13 @@ class RtAudio bool isDefaultOutput; /*!< true if this is the default output device. */ bool isDefaultInput; /*!< true if this is the default input device. */ std::vector sampleRates; /*!< Supported sample rates (queried from list of standard rates). */ + unsigned int preferredSampleRate; /*!< Preferred sample rate, e.g. for WASAPI the system sample rate. */ RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */ // Default constructor. DeviceInfo() :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0), - isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {} + isDefaultOutput(false), isDefaultInput(false), preferredSampleRate(0), nativeFormats(0) {} }; //! The structure for specifying input or ouput stream parameters. @@ -330,7 +348,7 @@ class RtAudio Certain audio APIs offer a number of parameters that influence the I/O latency of a stream. By default, RtAudio will attempt to set these parameters internally for robust (glitch-free) performance - (though some APIs, like Windows Direct Sound, make this difficult). + (though some APIs, like Windows DirectSound, make this difficult). By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream() function, internal stream settings will be influenced in an attempt to minimize stream latency, though possibly at the expense of stream @@ -340,7 +358,7 @@ class RtAudio open the input and/or output stream device(s) for exclusive use. Note that this is not possible with all supported audio APIs. - If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt + If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt to select realtime scheduling (round-robin) for the callback thread. The \c priority parameter will only be used if the RTAUDIO_SCHEDULE_REALTIME flag is set. It defines the thread's realtime priority. @@ -374,7 +392,7 @@ class RtAudio }; //! A static function to determine the current RtAudio version. - static std::string getVersion( void ) throw(); + static std::string getVersion( void ); //! A static function to determine the available compiled audio APIs. /*! @@ -382,7 +400,30 @@ class RtAudio the enumerated list values. Note that there can be more than one API compiled for certain operating systems. */ - static void getCompiledApi( std::vector &apis ) throw(); + static void getCompiledApi( std::vector &apis ); + + //! Return the name of a specified compiled audio API. + /*! + This obtains a short lower-case name used for identification purposes. + This value is guaranteed to remain identical across library versions. + If the API is unknown, this function will return the empty string. + */ + static std::string getApiName( RtAudio::Api api ); + + //! Return the display name of a specified compiled audio API. + /*! + This obtains a long name used for display purposes. + If the API is unknown, this function will return the empty string. + */ + static std::string getApiDisplayName( RtAudio::Api api ); + + //! Return the compiled audio API having the given name. + /*! + A case insensitive comparison will check the specified name + against the list of compiled APIs, and return the one which + matches. On failure, the function returns UNSPECIFIED. + */ + static RtAudio::Api getCompiledApiByName( const std::string &name ); //! The class constructor. /*! @@ -400,18 +441,18 @@ class RtAudio If a stream is running or open, it will be stopped and closed automatically. */ - ~RtAudio() throw(); + ~RtAudio(); //! Returns the audio API specifier for the current instance of RtAudio. - RtAudio::Api getCurrentApi( void ) throw(); + RtAudio::Api getCurrentApi( void ); //! A public function that queries for the number of audio devices available. /*! This function performs a system query of available devices each time it is called, thus supporting devices connected \e after instantiation. If - a system error occurs during processing, a warning will be issued. + a system error occurs during processing, a warning will be issued. */ - unsigned int getDeviceCount( void ) throw(); + unsigned int getDeviceCount( void ); //! Return an RtAudio::DeviceInfo structure for a specified device number. /*! @@ -434,7 +475,7 @@ class RtAudio client's responsibility to verify that a device is available before attempting to open a stream. */ - unsigned int getDefaultOutputDevice( void ) throw(); + unsigned int getDefaultOutputDevice( void ); //! A function that returns the index of the default input device. /*! @@ -444,7 +485,7 @@ class RtAudio client's responsibility to verify that a device is available before attempting to open a stream. */ - unsigned int getDefaultInputDevice( void ) throw(); + unsigned int getDefaultInputDevice( void ); //! A public function for opening a stream with the specified parameters. /*! @@ -476,7 +517,7 @@ class RtAudio from within the callback function. \param options An optional pointer to a structure containing various global stream options, including a list of OR'ed RtAudioStreamFlags - and a suggested number of stream buffers that can be used to + and a suggested number of stream buffers that can be used to control stream latency. More buffers typically result in more robust performance, though at a cost of greater latency. If a value of zero is specified, a system-specific median value is @@ -497,7 +538,7 @@ class RtAudio If a stream is not open, this function issues a warning and returns (no exception is thrown). */ - void closeStream( void ) throw(); + void closeStream( void ); //! A function that starts a stream. /*! @@ -527,10 +568,10 @@ class RtAudio void abortStream( void ); //! Returns true if a stream is open and false if not. - bool isStreamOpen( void ) const throw(); + bool isStreamOpen( void ) const; //! Returns true if the stream is running and false if it is stopped or not open. - bool isStreamRunning( void ) const throw(); + bool isStreamRunning( void ) const; //! Returns the number of elapsed seconds since the stream was started. /*! @@ -538,6 +579,12 @@ class RtAudio */ double getStreamTime( void ); + //! Set the stream time to a time in seconds greater than or equal to 0.0. + /*! + If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown. + */ + void setStreamTime( double time ); + //! Returns the internal stream latency in sample frames. /*! The stream latency refers to delay in audio input and/or output @@ -558,7 +605,7 @@ class RtAudio unsigned int getStreamSampleRate( void ); //! Specify whether warning messages should be printed to stderr. - void showWarnings( bool value = true ) throw(); + void showWarnings( bool value = true ); protected: @@ -567,11 +614,16 @@ class RtAudio }; // Operating system dependent thread functionality. -#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__) +#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__) + + #ifndef NOMINMAX + #define NOMINMAX + #endif #include #include + #include - typedef ULONG_PTR ThreadHandle; + typedef uintptr_t ThreadHandle; typedef CRITICAL_SECTION StreamMutex; #elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) @@ -605,7 +657,7 @@ struct CallbackInfo { // Default constructor. CallbackInfo() - :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false) {} + :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0) {} }; // **************************************************************** // @@ -638,7 +690,6 @@ class S24 { return *this; } - S24( const S24& v ) { *this = v; } S24( const double& d ) { *this = (int) d; } S24( const float& f ) { *this = (int) f; } S24( const signed short& s ) { *this = (int) s; } @@ -658,7 +709,7 @@ class S24 { #include -class RtApi +class RTAUDIO_DLL_PUBLIC RtApi { public: @@ -682,6 +733,7 @@ public: long getStreamLatency( void ); unsigned int getStreamSampleRate( void ); virtual double getStreamTime( void ); + virtual void setStreamTime( double time ); bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; } bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; } void showWarnings( bool value ) { showWarnings_ = value; } @@ -744,6 +796,9 @@ protected: double streamTime; // Number of elapsed seconds since the stream started. #if defined(HAVE_GETTIMEOFDAY) + // The gettimeofday() when tickStreamTime was last called, or both + // fields at 0 if tickStreamTime has not been called since the last + // startStream(). struct timeval lastTickTimestamp; #endif @@ -770,7 +825,7 @@ protected: "warning" message is reported and FAILURE is returned. A successful probe is indicated by a return value of SUCCESS. */ - virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -812,21 +867,22 @@ protected: // // **************************************************************** // -inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } -inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); } +inline RtAudio::Api RtAudio :: getCurrentApi( void ) { return rtapi_->getCurrentApi(); } +inline unsigned int RtAudio :: getDeviceCount( void ) { return rtapi_->getDeviceCount(); } inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); } -inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); } -inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); } -inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); } +inline unsigned int RtAudio :: getDefaultInputDevice( void ) { return rtapi_->getDefaultInputDevice(); } +inline unsigned int RtAudio :: getDefaultOutputDevice( void ) { return rtapi_->getDefaultOutputDevice(); } +inline void RtAudio :: closeStream( void ) { return rtapi_->closeStream(); } inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); } inline void RtAudio :: stopStream( void ) { return rtapi_->stopStream(); } inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); } -inline bool RtAudio :: isStreamOpen( void ) const throw() { return rtapi_->isStreamOpen(); } -inline bool RtAudio :: isStreamRunning( void ) const throw() { return rtapi_->isStreamRunning(); } +inline bool RtAudio :: isStreamOpen( void ) const { return rtapi_->isStreamOpen(); } +inline bool RtAudio :: isStreamRunning( void ) const { return rtapi_->isStreamRunning(); } inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); } inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); } inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); } -inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); } +inline void RtAudio :: setStreamTime( double time ) { return rtapi_->setStreamTime( time ); } +inline void RtAudio :: showWarnings( bool value ) { rtapi_->showWarnings( value ); } // RtApi Subclass prototypes. @@ -849,7 +905,6 @@ public: void startStream( void ); void stopStream( void ); void abortStream( void ); - long getStreamLatency( void ); // This function is intended for internal use only. It must be // public because it is called by the internal callback handler, @@ -861,7 +916,7 @@ public: private: - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -885,7 +940,6 @@ public: void startStream( void ); void stopStream( void ); void abortStream( void ); - long getStreamLatency( void ); // This function is intended for internal use only. It must be // public because it is called by the internal callback handler, @@ -895,10 +949,12 @@ public: private: - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); + + bool shouldAutoconnect_; }; #endif @@ -918,7 +974,6 @@ public: void startStream( void ); void stopStream( void ); void abortStream( void ); - long getStreamLatency( void ); // This function is intended for internal use only. It must be // public because it is called by the internal callback handler, @@ -931,7 +986,7 @@ public: std::vector devices_; void saveDeviceInfo( void ); bool coInitialized_; - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -956,7 +1011,6 @@ public: void startStream( void ); void stopStream( void ); void abortStream( void ); - long getStreamLatency( void ); // This function is intended for internal use only. It must be // public because it is called by the internal callback handler, @@ -970,7 +1024,7 @@ public: bool buffersRolling; long duplexPrerollBytes; std::vector dsDevices; - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -986,7 +1040,7 @@ class RtApiWasapi : public RtApi { public: RtApiWasapi(); - ~RtApiWasapi(); + virtual ~RtApiWasapi(); RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; } unsigned int getDeviceCount( void ); @@ -1041,7 +1095,7 @@ public: std::vector devices_; void saveDeviceInfo( void ); - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -1051,9 +1105,14 @@ public: #if defined(__LINUX_PULSE__) +struct pa_context; +struct pa_sink_info; +struct pa_threaded_mainloop; + class RtApiPulse: public RtApi { public: + RtApiPulse() : mainloop_(0), channels_(2) {} ~RtApiPulse(); RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; } unsigned int getDeviceCount( void ); @@ -1077,6 +1136,10 @@ public: unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); + static void sinkInfoCallback(pa_context* c, const pa_sink_info* info, int eol, void* arg); + static void contextStateCallback(pa_context* c, void* arg); + pa_threaded_mainloop* mainloop_; + int channels_; }; #endif @@ -1105,7 +1168,7 @@ public: private: - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, + bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, unsigned int firstChannel, unsigned int sampleRate, RtAudioFormat format, unsigned int *bufferSize, RtAudio::StreamOptions *options ); @@ -1130,7 +1193,7 @@ public: private: - bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, + bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, unsigned int /*firstChannel*/, unsigned int /*sampleRate*/, RtAudioFormat /*format*/, unsigned int * /*bufferSize*/, RtAudio::StreamOptions * /*options*/ ) { return false; }