+#include "RtError.h"
+
+/*! \typedef typedef unsigned long RtAudioFormat;
+ \brief RtAudio data format type.
+
+ Support for signed integers and floats. Audio data fed to/from an
+ RtAudio stream is assumed to ALWAYS be in host byte order. The
+ internal routines will automatically take care of any necessary
+ byte-swapping between the host format and the soundcard. Thus,
+ endian-ness is not a concern in the following format definitions.
+
+ - \e RTAUDIO_SINT8: 8-bit signed integer.
+ - \e RTAUDIO_SINT16: 16-bit signed integer.
+ - \e RTAUDIO_SINT24: Upper 3 bytes of 32-bit signed integer.
+ - \e RTAUDIO_SINT32: 32-bit signed integer.
+ - \e RTAUDIO_FLOAT32: Normalized between plus/minus 1.0.
+ - \e RTAUDIO_FLOAT64: Normalized between plus/minus 1.0.
+*/
+typedef unsigned long RtAudioFormat;
+static const RtAudioFormat RTAUDIO_SINT8 = 0x1; // 8-bit signed integer.
+static const RtAudioFormat RTAUDIO_SINT16 = 0x2; // 16-bit signed integer.
+static const RtAudioFormat RTAUDIO_SINT24 = 0x4; // Lower 3 bytes of 32-bit signed integer.
+static const RtAudioFormat RTAUDIO_SINT32 = 0x8; // 32-bit signed integer.
+static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
+static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
+
+/*! \typedef typedef unsigned long RtAudioStreamFlags;
+ \brief RtAudio stream option flags.
+
+ The following flags can be OR'ed together to allow a client to
+ make changes to the default stream behavior:
+
+ - \e RTAUDIO_NONINTERLEAVED: Use non-interleaved buffers (default = interleaved).
+ - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
+ - \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use.
+
+ By default, RtAudio streams pass and receive audio data from the
+ client in an interleaved format. By passing the
+ RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
+ data will instead be presented in non-interleaved buffers. In
+ this case, each buffer argument in the RtAudioCallback function
+ will point to a single array of data, with \c nFrames samples for
+ each channel concatenated back-to-back. For example, the first
+ sample of data for the second channel would be located at index \c
+ nFrames (assuming the \c buffer pointer was recast to the correct
+ data type for the stream).
+
+ 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).
+ 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
+ performance.
+
+ If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
+ open the input and/or output stream device(s) for exclusive use.
+ Note that this is not possible with all supported audio APIs.
+*/
+typedef unsigned int RtAudioStreamFlags;
+static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1; // Use non-interleaved buffers (default = interleaved).
+static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2; // Attempt to set stream parameters for lowest possible latency.
+static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4; // Attempt grab device and prevent use by others.
+
+/*! \typedef typedef unsigned long RtAudioStreamStatus;
+ \brief RtAudio stream status (over- or underflow) flags.
+
+ Notification of a stream over- or underflow is indicated by a
+ non-zero stream \c status argument in the RtAudioCallback function.
+ The stream status can be one of the following two options,
+ depending on whether the stream is open for output and/or input:
+
+ - \e RTAUDIO_INPUT_OVERFLOW: Input data was discarded because of an overflow condition at the driver.
+ - \e RTAUDIO_OUTPUT_UNDERFLOW: The output buffer ran low, likely producing a break in the output sound.
+*/
+typedef unsigned int RtAudioStreamStatus;
+static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1; // Input data was discarded because of an overflow condition at the driver.
+static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2; // The output buffer ran low, likely causing a gap in the output sound.
+
+//! RtAudio callback function prototype.
+/*!
+ All RtAudio clients must create a function of type RtAudioCallback
+ to read and/or write data from/to the audio stream. When the
+ underlying audio system is ready for new input or output data, this
+ function will be invoked.
+
+ \param outputBuffer For output (or duplex) streams, the client
+ should write \c nFrames of audio sample frames into this
+ buffer. This argument should be recast to the datatype
+ specified when the stream was opened. For input-only
+ streams, this argument will be NULL.
+
+ \param inputBuffer For input (or duplex) streams, this buffer will
+ hold \c nFrames of input audio sample frames. This
+ argument should be recast to the datatype specified when the
+ stream was opened. For output-only streams, this argument
+ will be NULL.
+
+ \param nFrames The number of sample frames of input or output
+ data in the buffers. The actual buffer size in bytes is
+ dependent on the data type and number of channels in use.
+
+ \param streamTime The number of seconds that have elapsed since the
+ stream was started.
+
+ \param status If non-zero, this argument indicates a data overflow
+ or underflow condition for the stream. The particular
+ condition can be determined by comparison with the
+ RtAudioStreamStatus flags.
+
+ \param userData A pointer to optional data provided by the client
+ when opening the stream (default = NULL).
+
+ To continue normal stream operation, the RtAudioCallback function
+ should return a value of zero. To stop the stream and drain the
+ output buffer, the function should return a value of one. To abort
+ the stream immediately, the client should return a value of two.
+ */
+typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
+ unsigned int nFrames,
+ double streamTime,
+ RtAudioStreamStatus status,
+ void *userData );
+
+
+// **************************************************************** //
+//
+// RtAudio class declaration.
+//
+// RtAudio is a "controller" used to select an available audio i/o
+// interface. It presents a common API for the user to call but all
+// functionality is implemented by the class RtApi and its
+// subclasses. RtAudio creates an instance of an RtApi subclass
+// based on the user's API choice. If no choice is made, RtAudio
+// attempts to make a "logical" API selection.
+//
+// **************************************************************** //
+
+class RtApi;
+
+class RtAudio
+{
+ public:
+
+ //! Audio API specifier arguments.
+ enum Api {
+ UNSPECIFIED, /*!< Search for a working compiled API. */
+ LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
+ LINUX_OSS, /*!< The Linux Open Sound System API. */
+ UNIX_JACK, /*!< The Jack Low-Latency Audio Server API. */
+ MACOSX_CORE, /*!< Macintosh OS-X Core Audio 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. */
+ };
+
+ //! The public device information structure for returning queried values.
+ struct DeviceInfo {
+ bool probed; /*!< true if the device capabilities were successfully probed. */
+ std::string name; /*!< Character string device identifier. */
+ unsigned int outputChannels; /*!< Maximum output channels supported by device. */
+ unsigned int inputChannels; /*!< Maximum input channels supported by device. */
+ unsigned int duplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
+ bool isDefaultOutput; /*!< true if this is the default output device. */
+ bool isDefaultInput; /*!< true if this is the default input device. */
+ std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
+ 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) {}
+ };
+
+ //! The structure for specifying input or ouput stream parameters.
+ struct StreamParameters {
+ unsigned int deviceId; /*!< Device index (0 to getDeviceCount() - 1). */
+ unsigned int nChannels; /*!< Number of channels. */
+ unsigned int firstChannel; /*!< First channel index on device (default = 0). */
+
+ // Default constructor.
+ StreamParameters()
+ : deviceId(0), nChannels(0), firstChannel(0) {}
+ };
+
+ //! The structure for specifying stream options.
+ /*!
+ The following flags can be OR'ed together to allow a client to
+ make changes to the default stream behavior:
+
+ - \e RTAUDIO_NONINTERLEAVED: Use non-interleaved buffers (default = interleaved).
+ - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
+ - \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use.
+
+ By default, RtAudio streams pass and receive audio data from the
+ client in an interleaved format. By passing the
+ RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
+ data will instead be presented in non-interleaved buffers. In
+ this case, each buffer argument in the RtAudioCallback function
+ will point to a single array of data, with \c nFrames samples for
+ each channel concatenated back-to-back. For example, the first
+ sample of data for the second channel would be located at index \c
+ nFrames (assuming the \c buffer pointer was recast to the correct
+ data type for the stream).
+
+ 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).
+ 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
+ performance.
+
+ If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
+ open the input and/or output stream device(s) for exclusive use.
+ Note that this is not possible with all supported audio APIs.
+
+ The \c numberOfBuffers parameter can be used to control stream
+ latency in the Windows DirectSound, Linux OSS, and Linux Alsa APIs
+ only. A value of two is usually the smallest allowed. Larger
+ numbers can potentially result in more robust stream performance,
+ though likely at the cost of stream latency. The value set by the
+ user is replaced during execution of the RtAudio::openStream()
+ function by the value actually used by the system.
+
+ The \c streamName parameter can be used to set the client name
+ when using the Jack API. By default, the client name is set to
+ RtApiJack. However, if you wish to create multiple instances of
+ RtAudio with Jack, each instance must have a unique client name.
+ */
+ struct StreamOptions {
+ RtAudioStreamFlags flags; /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE). */
+ unsigned int numberOfBuffers; /*!< Number of stream buffers. */
+ std::string streamName; /*!< A stream name (currently used only in Jack). */
+
+ // Default constructor.
+ StreamOptions()
+ : flags(0), numberOfBuffers(0) {}
+ };
+
+ //! A static function to determine the available compiled audio APIs.
+ /*!
+ The values returned in the std::vector can be compared against
+ the enumerated list values. Note that there can be more than one
+ API compiled for certain operating systems.
+ */
+ static void getCompiledApi( std::vector<RtAudio::Api> &apis ) throw();
+
+ //! The class constructor.
+ /*!
+ The constructor performs minor initialization tasks. No exceptions
+ can be thrown.
+
+ If no API argument is specified and multiple API support has been
+ compiled, the default order of use is JACK, ALSA, OSS (Linux
+ systems) and ASIO, DS (Windows systems).
+ */
+ RtAudio( RtAudio::Api api=UNSPECIFIED ) throw();
+
+ //! The destructor.
+ /*!
+ If a stream is running or open, it will be stopped and closed
+ automatically.
+ */
+ ~RtAudio() throw();
+
+ //! Returns the audio API specifier for the current instance of RtAudio.
+ RtAudio::Api getCurrentApi( void ) throw();
+
+ //! 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.
+ */
+ unsigned int getDeviceCount( void ) throw();
+
+ //! Return an RtAudio::DeviceInfo structure for a specified device number.
+ /*!
+
+ Any device integer between 0 and getDeviceCount() - 1 is valid.
+ If an invalid argument is provided, an RtError (type = INVALID_USE)
+ will be thrown. If a device is busy or otherwise unavailable, the
+ structure member "probed" will have a value of "false" and all
+ other members are undefined. If the specified device is the
+ current default input or output device, the corresponding
+ "isDefault" member will have a value of "true".
+ */
+ RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+
+ //! A function that returns the index of the default output device.
+ /*!
+ If the underlying audio API does not provide a "default
+ device", or if no devices are available, the return value will be
+ 0. Note that this is a valid device identifier and it is the
+ client's responsibility to verify that a device is available
+ before attempting to open a stream.
+ */
+ unsigned int getDefaultOutputDevice( void ) throw();
+
+ //! A function that returns the index of the default input device.
+ /*!
+ If the underlying audio API does not provide a "default
+ device", or if no devices are available, the return value will be
+ 0. Note that this is a valid device identifier and it is the
+ client's responsibility to verify that a device is available
+ before attempting to open a stream.
+ */
+ unsigned int getDefaultInputDevice( void ) throw();
+
+ //! A public function for opening a stream with the specified parameters.
+ /*!
+ An RtError (type = SYSTEM_ERROR) is thrown if a stream cannot be
+ opened with the specified parameters or an error occurs during
+ processing. An RtError (type = INVALID_USE) is thrown if any
+ invalid device ID or channel number parameters are specified.
+
+ \param outputParameters Specifies output stream parameters to use
+ when opening a stream, including a device ID, number of channels,
+ and starting channel number. For input-only streams, this
+ argument should be NULL. The device ID is an index value between
+ 0 and getDeviceCount() - 1.
+ \param inputParameters Specifies input stream parameters to use
+ when opening a stream, including a device ID, number of channels,
+ and starting channel number. For output-only streams, this
+ argument should be NULL. The device ID is an index value between
+ 0 and getDeviceCount() - 1.
+ \param format An RtAudioFormat specifying the desired sample data format.
+ \param sampleRate The desired sample rate (sample frames per second).
+ \param *bufferFrames A pointer to a value indicating the desired
+ internal buffer size in sample frames. The actual value
+ used by the device is returned via the same pointer. A
+ value of zero can be specified, in which case the lowest
+ allowable value is determined.
+ \param callback A client-defined function that will be invoked
+ when input data is available and/or output data is needed.
+ \param userData An optional pointer to data that can be accessed
+ 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
+ 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
+ chosen. If the RTAUDIO_MINIMIZE_LATENCY flag bit is set, the
+ lowest allowable value is used. The actual value used is
+ returned via the structure argument. The parameter is API dependent.
+ */
+ void openStream( RtAudio::StreamParameters *outputParameters,
+ RtAudio::StreamParameters *inputParameters,
+ RtAudioFormat format, unsigned int sampleRate,
+ unsigned int *bufferFrames, RtAudioCallback callback,
+ void *userData = NULL, RtAudio::StreamOptions *options = NULL );
+
+ //! A function that closes a stream and frees any associated stream memory.
+ /*!
+ If a stream is not open, this function issues a warning and
+ returns (no exception is thrown).
+ */
+ void closeStream( void ) throw();
+
+ //! A function that starts a stream.
+ /*!
+ An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
+ during processing. An RtError (type = INVALID_USE) is thrown if a
+ stream is not open. A warning is issued if the stream is already
+ running.
+ */
+ void startStream( void );
+
+ //! Stop a stream, allowing any samples remaining in the output queue to be played.
+ /*!
+ An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
+ during processing. An RtError (type = INVALID_USE) is thrown if a
+ stream is not open. A warning is issued if the stream is already
+ stopped.
+ */
+ void stopStream( void );
+
+ //! Stop a stream, discarding any samples remaining in the input/output queue.
+ /*!
+ An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
+ during processing. An RtError (type = INVALID_USE) is thrown if a
+ stream is not open. A warning is issued if the stream is already
+ stopped.
+ */
+ void abortStream( void );
+
+ //! Returns true if a stream is open and false if not.
+ bool isStreamOpen( void ) throw();
+
+ //! Returns true if the stream is running and false if it is stopped or not open.
+ bool isStreamRunning( void ) throw();
+
+ //! Returns the number of elapsed seconds since the stream was started.
+ /*!
+ If a stream is not open, an RtError (type = INVALID_USE) will be thrown.
+ */
+ double getStreamTime( void );
+
+ //! Returns the internal stream latency in sample frames.
+ /*!
+ The stream latency refers to delay in audio input and/or output
+ caused by internal buffering by the audio system and/or hardware.
+ For duplex streams, the returned value will represent the sum of
+ the input and output latencies. If a stream is not open, an
+ RtError (type = INVALID_USE) will be thrown. If the API does not
+ report latency, the return value will be zero.
+ */
+ long getStreamLatency( void );
+
+ //! Specify whether warning messages should be printed to stderr.
+ void showWarnings( bool value = true ) throw();
+
+ protected:
+
+ void openRtApi( RtAudio::Api api );
+ RtApi *rtapi_;
+};