summaryrefslogtreecommitdiff
path: root/RtAudio.h
diff options
context:
space:
mode:
Diffstat (limited to 'RtAudio.h')
-rw-r--r--RtAudio.h824
1 files changed, 507 insertions, 317 deletions
diff --git a/RtAudio.h b/RtAudio.h
index a9a2a9a..cf39ab4 100644
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -1,16 +1,16 @@
/************************************************************************/
/*! \class RtAudio
- \brief Realtime audio i/o C++ class.
+ \brief Realtime audio i/o C++ classes.
RtAudio provides a common API (Application Programming Interface)
- for realtime audio input/output across Linux (native ALSA and
- OSS), SGI, Macintosh OS X (CoreAudio), and Windows (DirectSound
- and ASIO) operating systems.
+ for realtime audio input/output across Linux (native ALSA, Jack,
+ and OSS), SGI, Macintosh OS X (CoreAudio), and Windows
+ (DirectSound and ASIO) operating systems.
- RtAudio WWW site: http://www-ccrma.stanford.edu/~gary/rtaudio/
+ RtAudio WWW site: http://music.mcgill.ca/~gary/rtaudio/
RtAudio: a realtime audio i/o C++ class
- Copyright (c) 2001-2002 Gary P. Scavone
+ Copyright (c) 2001-2004 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
@@ -37,206 +37,302 @@
*/
/************************************************************************/
-#if !defined(__RTAUDIO_H)
+// RtAudio: Version 3.0, 11 March 2004
+
+#ifndef __RTAUDIO_H
#define __RTAUDIO_H
-#include <map>
+#include "RtError.h"
+#include <string>
+#include <vector>
-#if defined(__LINUX_ALSA__)
- #include <alsa/asoundlib.h>
- #include <pthread.h>
- #include <unistd.h>
+// Operating system dependent thread functionality.
+#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
+ #include <windows.h>
+ #include <process.h>
- typedef snd_pcm_t *AUDIO_HANDLE;
- typedef int DEVICE_ID;
- typedef pthread_t THREAD_HANDLE;
- typedef pthread_mutex_t MUTEX;
+ typedef unsigned long ThreadHandle;
+ typedef CRITICAL_SECTION StreamMutex;
-#elif defined(__LINUX_OSS__)
+#else // Various unix flavors with pthread support.
#include <pthread.h>
- #include <unistd.h>
- typedef int AUDIO_HANDLE;
- typedef int DEVICE_ID;
- typedef pthread_t THREAD_HANDLE;
- typedef pthread_mutex_t MUTEX;
+ typedef pthread_t ThreadHandle;
+ typedef pthread_mutex_t StreamMutex;
-#elif defined(__WINDOWS_DS__)
- #include <windows.h>
- #include <process.h>
+#endif
- // The following struct is used to hold the extra variables
- // specific to the DirectSound implementation.
- typedef struct {
- void * object;
- void * buffer;
- UINT bufferPointer;
- } AUDIO_HANDLE;
+// This global structure type is used to pass callback information
+// between the private RtAudio stream structure and global callback
+// handling functions.
+struct CallbackInfo {
+ void *object; // Used as a "this" pointer.
+ ThreadHandle thread;
+ bool usingCallback;
+ void *callback;
+ void *userData;
+ void *apiInfo; // void pointer for API specific callback information
- typedef LPGUID DEVICE_ID;
- typedef unsigned long THREAD_HANDLE;
- typedef CRITICAL_SECTION MUTEX;
+ // Default constructor.
+ CallbackInfo()
+ :object(0), usingCallback(false), callback(0),
+ userData(0), apiInfo(0) {}
+};
-#elif defined(__WINDOWS_ASIO__)
- #include <windows.h>
- #include <process.h>
+// Support for signed integers and floats. Audio data fed to/from
+// the tickStream() routine 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.
+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; /*!< Upper 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 int (*RtAudioCallback)(char *buffer, int bufferSize, void *userData);
+
+//! The public device information structure for returning queried values.
+struct RtAudioDeviceInfo {
+ std::string name; /*!< Character string device identifier. */
+ bool probed; /*!< true if the device capabilities were successfully probed. */
+ int outputChannels; /*!< Maximum output channels supported by device. */
+ int inputChannels; /*!< Maximum input channels supported by device. */
+ int duplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
+ bool isDefault; /*!< true if this is the default output or input device. */
+ std::vector<int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
+ RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
+
+ // Default constructor.
+ RtAudioDeviceInfo()
+ :probed(false), outputChannels(0), inputChannels(0),
+ duplexChannels(0), isDefault(false), nativeFormats(0) {}
+};
- typedef int AUDIO_HANDLE;
- typedef int DEVICE_ID;
- typedef unsigned long THREAD_HANDLE;
- typedef CRITICAL_SECTION MUTEX;
+// **************************************************************** //
+//
+// RtApi class declaration.
+//
+// Note that RtApi is an abstract base class and cannot be
+// explicitly instantiated. The class RtAudio will create an
+// instance of an RtApi subclass (RtApiOss, RtApiAlsa,
+// RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio).
+//
+// **************************************************************** //
-#elif defined(__IRIX_AL__)
- #include <dmedia/audio.h>
- #include <pthread.h>
- #include <unistd.h>
+class RtApi
+{
+public:
- typedef ALport AUDIO_HANDLE;
- typedef long DEVICE_ID;
- typedef pthread_t THREAD_HANDLE;
- typedef pthread_mutex_t MUTEX;
+ RtApi();
+ virtual ~RtApi();
+ void openStream( int outputDevice, int outputChannels,
+ int inputDevice, int inputChannels,
+ RtAudioFormat format, int sampleRate,
+ int *bufferSize, int numberOfBuffers );
+ virtual void setStreamCallback( RtAudioCallback callback, void *userData ) = 0;
+ virtual void cancelStreamCallback() = 0;
+ int getDeviceCount(void);
+ RtAudioDeviceInfo getDeviceInfo( int device );
+ char * const getStreamBuffer();
+ virtual void tickStream() = 0;
+ virtual void closeStream();
+ virtual void startStream() = 0;
+ virtual void stopStream() = 0;
+ virtual void abortStream() = 0;
-#elif defined(__MACOSX_CORE__)
+protected:
- #include <CoreAudio/AudioHardware.h>
- #include <pthread.h>
+ static const unsigned int MAX_SAMPLE_RATES;
+ static const unsigned int SAMPLE_RATES[];
- typedef unsigned int AUDIO_HANDLE;
- typedef AudioDeviceID DEVICE_ID;
- typedef pthread_t THREAD_HANDLE;
- typedef pthread_mutex_t MUTEX;
+ enum { FAILURE, SUCCESS };
-#endif
+ enum StreamMode {
+ OUTPUT,
+ INPUT,
+ DUPLEX,
+ UNINITIALIZED = -75
+ };
+ enum StreamState {
+ STREAM_STOPPED,
+ STREAM_RUNNING
+ };
-/************************************************************************/
-/*! \class RtError
- \brief Exception handling class for RtAudio.
-
- The RtError class is quite simple but it does allow errors to be
- "caught" by RtError::TYPE. Almost all RtAudio methods can "throw"
- an RtError, most typically if an invalid stream identifier is
- supplied to a method or a driver error occurs. There are a number
- of cases within RtAudio where warning messages may be displayed
- but an exception is not thrown. There is a private RtAudio method,
- error(), which can be modified to globally control how these
- messages are handled and reported.
-*/
-/************************************************************************/
+ // A protected structure for audio streams.
+ struct RtApiStream {
+ int device[2]; // Playback and record, respectively.
+ void *apiHandle; // void pointer for API specific stream handle information
+ StreamMode mode; // OUTPUT, INPUT, or DUPLEX.
+ StreamState state; // STOPPED or RUNNING
+ char *userBuffer;
+ char *deviceBuffer;
+ bool doConvertBuffer[2]; // Playback and record, respectively.
+ bool deInterleave[2]; // Playback and record, respectively.
+ bool doByteSwap[2]; // Playback and record, respectively.
+ int sampleRate;
+ int bufferSize;
+ int nBuffers;
+ int nUserChannels[2]; // Playback and record, respectively.
+ int nDeviceChannels[2]; // Playback and record channels, respectively.
+ RtAudioFormat userFormat;
+ RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
+ StreamMutex mutex;
+ CallbackInfo callbackInfo;
+
+ RtApiStream()
+ :apiHandle(0), userBuffer(0), deviceBuffer(0) {}
+ // :apiHandle(0), mode(UNINITIALIZED), state(STREAM_STOPPED),
+ // userBuffer(0), deviceBuffer(0) {}
+ };
-class RtError
-{
-public:
- //! Defined RtError types.
- enum TYPE {
- WARNING,
- DEBUG_WARNING,
- UNSPECIFIED,
- NO_DEVICES_FOUND,
- INVALID_DEVICE,
- INVALID_STREAM,
- MEMORY_ERROR,
- INVALID_PARAMETER,
- DRIVER_ERROR,
- SYSTEM_ERROR,
- THREAD_ERROR
+ // A protected device structure for audio devices.
+ struct RtApiDevice {
+ std::string name; /*!< Character string device identifier. */
+ bool probed; /*!< true if the device capabilities were successfully probed. */
+ void *apiDeviceId; // void pointer for API specific device information
+ int maxOutputChannels; /*!< Maximum output channels supported by device. */
+ int maxInputChannels; /*!< Maximum input channels supported by device. */
+ int maxDuplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
+ int minOutputChannels; /*!< Minimum output channels supported by device. */
+ int minInputChannels; /*!< Minimum input channels supported by device. */
+ int minDuplexChannels; /*!< Minimum simultaneous input/output channels supported by device. */
+ bool hasDuplexSupport; /*!< true if device supports duplex mode. */
+ bool isDefault; /*!< true if this is the default output or input device. */
+ std::vector<int> sampleRates; /*!< Supported sample rates. */
+ RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
+
+ // Default constructor.
+ RtApiDevice()
+ :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
+ maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
+ minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
};
-protected:
- char error_message[256];
- TYPE type;
+ typedef signed short Int16;
+ typedef signed int Int32;
+ typedef float Float32;
+ typedef double Float64;
-public:
- //! The constructor.
- RtError(const char *p, TYPE tipe = RtError::UNSPECIFIED);
+ char message_[256];
+ int nDevices_;
+ std::vector<RtApiDevice> devices_;
+ RtApiStream stream_;
- //! The destructor.
- virtual ~RtError(void);
+ /*!
+ Protected, api-specific method to count and identify the system
+ audio devices. This function MUST be implemented by all subclasses.
+ */
+ virtual void initialize(void) = 0;
- //! Prints "thrown" error message to stdout.
- virtual void printMessage(void);
+ /*!
+ Protected, api-specific method which attempts to fill an
+ RtAudioDevice structure for a given device. This function MUST be
+ implemented by all subclasses. If an error is encountered during
+ the probe, a "warning" message is reported and the value of
+ "probed" remains false (no exception is thrown). A successful
+ probe is indicated by probed = true.
+ */
+ virtual void probeDeviceInfo( RtApiDevice *info );
- //! Returns the "thrown" error message TYPE.
- virtual const TYPE& getType(void) { return type; }
+ /*!
+ Protected, api-specific method which attempts to open a device
+ with the given parameters. This function MUST be implemented by
+ all subclasses. If an error is encountered during the probe, a
+ "warning" message is reported and FAILURE is returned (no
+ exception is thrown). A successful probe is indicated by a return
+ value of SUCCESS.
+ */
+ virtual bool probeDeviceOpen( int device, StreamMode mode, int channels,
+ int sampleRate, RtAudioFormat format,
+ int *bufferSize, int numberOfBuffers );
- //! Returns the "thrown" error message string.
- virtual const char *getMessage(void) { return error_message; }
-};
+ /*!
+ Protected method which returns the index in the devices array to
+ the default input device.
+ */
+ virtual int getDefaultInputDevice(void);
+
+ /*!
+ Protected method which returns the index in the devices array to
+ the default output device.
+ */
+ virtual int getDefaultOutputDevice(void);
+ //! Protected common method to clear an RtApiDevice structure.
+ void clearDeviceInfo( RtApiDevice *info );
-// This public structure type is used to pass callback information
-// between the private RtAudio stream structure and global callback
-// handling functions.
-typedef struct {
- void *object; // Used as a "this" pointer.
- int streamId;
- DEVICE_ID device[2];
- THREAD_HANDLE thread;
- void *callback;
- void *buffers;
- unsigned long waitTime;
- bool blockTick;
- bool stopStream;
- bool usingCallback;
- void *userData;
-} CALLBACK_INFO;
+ //! Protected common method to clear an RtApiStream structure.
+ void clearStreamInfo();
+ //! Protected common error method to allow global control over error handling.
+ void error( RtError::Type type );
-// *************************************************** //
+ /*!
+ Protected common method used to check whether a stream is open.
+ If not, an "invalid identifier" exception is thrown.
+ */
+ void verifyStream();
+
+ /*!
+ Protected method used to perform format, channel number, and/or interleaving
+ conversions between the user and device buffers.
+ */
+ void convertStreamBuffer( StreamMode mode );
+
+ //! Protected common method used to perform byte-swapping on buffers.
+ void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format );
+
+ //! Protected common method which returns the number of bytes for a given format.
+ int formatBytes( RtAudioFormat format );
+};
+
+
+// **************************************************************** //
//
// 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 RtAudioApi and its
+// subclasses. RtAudio creates an instance of an RtAudioApi subclass
+// based on the user's API choice. If no choice is made, RtAudio
+// attempts to make a "logical" API selection.
+//
+// **************************************************************** //
class RtAudio
{
public:
- // Support for signed integers and floats. Audio data fed to/from
- // the tickStream() routine 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.
- typedef unsigned long RTAUDIO_FORMAT;
- static const RTAUDIO_FORMAT RTAUDIO_SINT8; /*!< 8-bit signed integer. */
- static const RTAUDIO_FORMAT RTAUDIO_SINT16; /*!< 16-bit signed integer. */
- static const RTAUDIO_FORMAT RTAUDIO_SINT24; /*!< Upper 3 bytes of 32-bit signed integer. */
- static const RTAUDIO_FORMAT RTAUDIO_SINT32; /*!< 32-bit signed integer. */
- static const RTAUDIO_FORMAT RTAUDIO_FLOAT32; /*!< Normalized between plus/minus 1.0. */
- static const RTAUDIO_FORMAT RTAUDIO_FLOAT64; /*!< Normalized between plus/minus 1.0. */
-
- //static const int MAX_SAMPLE_RATES = 14;
- enum { MAX_SAMPLE_RATES = 14 };
-
- typedef int (*RTAUDIO_CALLBACK)(char *buffer, int bufferSize, void *userData);
-
- //! The public device information structure for passing queried values.
- typedef struct {
- char name[128]; /*!< Character string device identifier. */
- DEVICE_ID id[2]; /* No value reported by getDeviceInfo(). */
- bool probed; /*!< true if the device capabilities were successfully probed. */
- int maxOutputChannels; /*!< Maximum output channels supported by device. */
- int maxInputChannels; /*!< Maximum input channels supported by device. */
- int maxDuplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
- int minOutputChannels; /*!< Minimum output channels supported by device. */
- int minInputChannels; /*!< Minimum input channels supported by device. */
- int minDuplexChannels; /*!< Minimum simultaneous input/output channels supported by device. */
- bool hasDuplexSupport; /*!< true if device supports duplex mode. */
- bool isDefault; /*!< true if this is the default output or input device. */
- int nSampleRates; /*!< Number of discrete rates or -1 if range supported. */
- int sampleRates[MAX_SAMPLE_RATES]; /*!< Supported rates or (min, max) if range. */
- RTAUDIO_FORMAT nativeFormats; /*!< Bit mask of supported data formats. */
- } RTAUDIO_DEVICE;
+ //! Audio API specifier arguments.
+ enum RtAudioApi {
+ UNSPECIFIED, /*!< Search for a working compiled API. */
+ LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
+ LINUX_OSS, /*!< The Linux Open Sound System API. */
+ LINUX_JACK, /*!< The Linux Jack Low-Latency Audio Server API. */
+ MACOSX_CORE, /*!< Macintosh OS-X Core Audio API. */
+ IRIX_AL, /*!< The Irix Audio Library API. */
+ WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */
+ WINDOWS_DS /*!< The Microsoft Direct Sound API. */
+ };
- //! The default constructor.
+ //! The default class constructor.
/*!
Probes the system to make sure at least one audio input/output
device is available and determines the api-specific identifier for
each device found. An RtError error can be thrown if no devices
are found or if a memory allocation error occurs.
+
+ 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( RtAudioApi api=UNSPECIFIED );
//! A constructor which can be used to open a stream during instantiation.
/*!
@@ -250,23 +346,21 @@ public:
for the given parameters, if a memory allocation error occurs, or
if a driver error occurs. \sa openStream()
*/
- RtAudio(int *streamId,
- int outputDevice, int outputChannels,
- int inputDevice, int inputChannels,
- RTAUDIO_FORMAT format, int sampleRate,
- int *bufferSize, int numberOfBuffers);
+ RtAudio( int outputDevice, int outputChannels,
+ int inputDevice, int inputChannels,
+ RtAudioFormat format, int sampleRate,
+ int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED );
//! The destructor.
/*!
- Stops and closes any open streams and devices and deallocates
+ Stops and closes an open stream and devices and deallocates
buffer and structure memory.
*/
~RtAudio();
//! A public method for opening a stream with the specified parameters.
/*!
- If successful, the opened stream ID is returned. Otherwise, an
- RtError is thrown.
+ An RtError is thrown if a stream cannot be opened.
\param outputDevice: If equal to 0, the default or first device
found meeting the given parameters is opened. Otherwise, the
@@ -280,7 +374,7 @@ public:
the getDeviceInfo() method.
\param inputChannels: The desired number of input channels. If
equal to zero, the inputDevice identifier is ignored.
- \param format: An RTAUDIO_FORMAT specifying the desired sample data format.
+ \param format: An RtAudioFormat specifying the desired sample data format.
\param sampleRate: The desired sample rate (sample frames per second).
\param *bufferSize: A pointer value indicating the desired internal buffer
size in sample frames. The actual value used by the device is
@@ -291,47 +385,47 @@ public:
though at a cost of greater latency. A value of zero can be
specified, in which case the lowest allowable value is used.
*/
- int openStream(int outputDevice, int outputChannels,
- int inputDevice, int inputChannels,
- RTAUDIO_FORMAT format, int sampleRate,
- int *bufferSize, int numberOfBuffers);
+ void openStream( int outputDevice, int outputChannels,
+ int inputDevice, int inputChannels,
+ RtAudioFormat format, int sampleRate,
+ int *bufferSize, int numberOfBuffers );
//! A public method which sets a user-defined callback function for a given stream.
/*!
- This method assigns a callback function to a specific,
- previously opened stream for non-blocking stream functionality. A
- separate process is initiated, though the user function is called
- only when the stream is "running" (between calls to the
- startStream() and stopStream() methods, respectively). The
- callback process remains active for the duration of the stream and
- is automatically shutdown when the stream is closed (via the
- closeStream() method or by object destruction). The callback
- process can also be shutdown and the user function de-referenced
- through an explicit call to the cancelStreamCallback() method.
- Note that a single stream can use only blocking or callback
- functionality at the same time, though it is possible to alternate
- modes on the same stream through the use of the
- setStreamCallback() and cancelStreamCallback() methods (the
- blocking tickStream() method can be used before a callback is set
- and/or after a callback is cancelled). An RtError will be thrown
- for an invalid device argument.
+ This method assigns a callback function to a previously opened
+ stream for non-blocking stream functionality. A separate process
+ is initiated, though the user function is called only when the
+ stream is "running" (between calls to the startStream() and
+ stopStream() methods, respectively). The callback process remains
+ active for the duration of the stream and is automatically
+ shutdown when the stream is closed (via the closeStream() method
+ or by object destruction). The callback process can also be
+ shutdown and the user function de-referenced through an explicit
+ call to the cancelStreamCallback() method. Note that the stream
+ can use only blocking or callback functionality at a particular
+ time, though it is possible to alternate modes on the same stream
+ through the use of the setStreamCallback() and
+ cancelStreamCallback() methods (the blocking tickStream() method
+ can be used before a callback is set and/or after a callback is
+ cancelled). An RtError will be thrown if called when no stream is
+ open or a thread errors occurs.
*/
- void setStreamCallback(int streamId, RTAUDIO_CALLBACK callback, void *userData);
+ void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); };
- //! A public method which cancels a callback process and function for a given stream.
+ //! A public method which cancels a callback process and function for the stream.
/*!
This method shuts down a callback process and de-references the
- user function for a specific stream. Callback functionality can
+ user function for the stream. Callback functionality can
subsequently be restarted on the stream via the
- setStreamCallback() method. An RtError will be thrown for an
- invalid device argument.
+ setStreamCallback() method. An RtError will be thrown if called
+ when no stream is open.
*/
- void cancelStreamCallback(int streamId);
+ void cancelStreamCallback() { rtapi_->cancelStreamCallback(); };
//! A public method which returns the number of audio devices found.
- int getDeviceCount(void);
+ int getDeviceCount(void) { return rtapi_->getDeviceCount(); };
- //! Fill a user-supplied RTAUDIO_DEVICE structure for a specified device number.
+ //! Return an RtAudioDeviceInfo structure for a specified device number.
/*!
Any device integer between 1 and getDeviceCount() is valid. If
a device is busy or otherwise unavailable, the structure member
@@ -340,185 +434,281 @@ public:
or output device, the "isDefault" member will have a value of
"true". An RtError will be thrown for an invalid device argument.
*/
- void getDeviceInfo(int device, RTAUDIO_DEVICE *info);
+ RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); };
//! A public method which returns a pointer to the buffer for an open stream.
/*!
The user should fill and/or read the buffer data in interleaved format
and then call the tickStream() method. An RtError will be
- thrown for an invalid stream identifier.
+ thrown if called when no stream is open.
*/
- char * const getStreamBuffer(int streamId);
+ char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); };
//! Public method used to trigger processing of input/output data for a stream.
/*!
This method blocks until all buffer data is read/written. An
- RtError will be thrown for an invalid stream identifier or if
- a driver error occurs.
+ RtError will be thrown if a driver error occurs or if called when
+ no stream is open.
*/
- void tickStream(int streamId);
+ void tickStream() { rtapi_->tickStream(); };
//! Public method which closes a stream and frees any associated buffers.
/*!
- If an invalid stream identifier is specified, this method
- issues a warning and returns (an RtError is not thrown).
+ If a stream is not open, this method issues a warning and
+ returns (an RtError is not thrown).
*/
- void closeStream(int streamId);
+ void closeStream() { rtapi_->closeStream(); };
//! Public method which starts a stream.
/*!
- An RtError will be thrown for an invalid stream identifier
- or if a driver error occurs.
+ An RtError will be thrown if a driver error occurs or if called
+ when no stream is open.
*/
- void startStream(int streamId);
+ void startStream() { rtapi_->startStream(); };
//! Stop a stream, allowing any samples remaining in the queue to be played out and/or read in.
/*!
- An RtError will be thrown for an invalid stream identifier
- or if a driver error occurs.
+ An RtError will be thrown if a driver error occurs or if called
+ when no stream is open.
*/
- void stopStream(int streamId);
+ void stopStream() { rtapi_->stopStream(); };
//! Stop a stream, discarding any samples remaining in the input/output queue.
/*!
- An RtError will be thrown for an invalid stream identifier
- or if a driver error occurs.
+ An RtError will be thrown if a driver error occurs or if called
+ when no stream is open.
*/
- void abortStream(int streamId);
+ void abortStream() { rtapi_->abortStream(); };
- //! Queries a stream to determine whether a call to the tickStream() method will block.
- /*!
- A return value of 0 indicates that the stream will NOT block. A positive
- return value indicates the number of sample frames that cannot yet be
- processed without blocking.
- */
- int streamWillBlock(int streamId);
-#if (defined(__MACOSX_CORE__) || defined(__WINDOWS_ASIO__))
+ protected:
+
+ void initialize( RtAudioApi api );
+
+ RtApi *rtapi_;
+};
+
+
+// RtApi Subclass prototypes.
+
+#if defined(__LINUX_ALSA__)
+
+class RtApiAlsa: public RtApi
+{
+public:
+
+ RtApiAlsa();
+ ~RtApiAlsa();
+ void tickStream();
+ void closeStream();
+ void startStream();
+ void stopStream();
+ void abortStream();
+ int streamWillBlock();
+ void setStreamCallback( RtAudioCallback callback, void *userData );
+ void cancelStreamCallback();
+
+ private:
+
+ void initialize(void);
+ void probeDeviceInfo( RtApiDevice *info );
+ bool probeDeviceOpen( int device, StreamMode mode, int channels,
+ int sampleRate, RtAudioFormat format,
+ int *bufferSize, int numberOfBuffers );
+};
+
+#endif
+
+#if defined(__LINUX_JACK__)
+
+class RtApiJack: public RtApi
+{
+public:
+
+ RtApiJack();
+ ~RtApiJack();
+ void tickStream();
+ void closeStream();
+ void startStream();
+ void stopStream();
+ void abortStream();
+ void setStreamCallback( RtAudioCallback callback, void *userData );
+ void cancelStreamCallback();
// This function is intended for internal use only. It must be
// public because it is called by the internal callback handler,
// which is not a member of RtAudio. External use of this function
// will most likely produce highly undesireable results!
- void callbackEvent(int streamId, DEVICE_ID deviceId, void *inData, void *outData);
+ void callbackEvent( unsigned long nframes );
+
+ private:
+
+ void initialize(void);
+ void probeDeviceInfo( RtApiDevice *info );
+ bool probeDeviceOpen( int device, StreamMode mode, int channels,
+ int sampleRate, RtAudioFormat format,
+ int *bufferSize, int numberOfBuffers );
+};
+
#endif
-protected:
+#if defined(__LINUX_OSS__)
-private:
+class RtApiOss: public RtApi
+{
+public:
- static const unsigned int SAMPLE_RATES[MAX_SAMPLE_RATES];
+ RtApiOss();
+ ~RtApiOss();
+ void tickStream();
+ void closeStream();
+ void startStream();
+ void stopStream();
+ void abortStream();
+ int streamWillBlock();
+ void setStreamCallback( RtAudioCallback callback, void *userData );
+ void cancelStreamCallback();
- enum { FAILURE, SUCCESS };
+ private:
- enum STREAM_MODE {
- OUTPUT,
- INPUT,
- DUPLEX,
- UNINITIALIZED = -75
- };
+ void initialize(void);
+ void probeDeviceInfo( RtApiDevice *info );
+ bool probeDeviceOpen( int device, StreamMode mode, int channels,
+ int sampleRate, RtAudioFormat format,
+ int *bufferSize, int numberOfBuffers );
+};
- enum STREAM_STATE {
- STREAM_STOPPED,
- STREAM_RUNNING
- };
+#endif
- typedef struct {
- int device[2]; // Playback and record, respectively.
- STREAM_MODE mode; // OUTPUT, INPUT, or DUPLEX.
- AUDIO_HANDLE handle[2]; // Playback and record handles, respectively.
- STREAM_STATE state; // STOPPED or RUNNING
- char *userBuffer;
- char *deviceBuffer;
- bool doConvertBuffer[2]; // Playback and record, respectively.
- bool deInterleave[2]; // Playback and record, respectively.
- bool doByteSwap[2]; // Playback and record, respectively.
- int sampleRate;
- int bufferSize;
- int nBuffers;
- int nUserChannels[2]; // Playback and record, respectively.
- int nDeviceChannels[2]; // Playback and record channels, respectively.
- RTAUDIO_FORMAT userFormat;
- RTAUDIO_FORMAT deviceFormat[2]; // Playback and record, respectively.
- MUTEX mutex;
- CALLBACK_INFO callbackInfo;
- } RTAUDIO_STREAM;
+#if defined(__MACOSX_CORE__)
- typedef signed short INT16;
- typedef signed int INT32;
- typedef float FLOAT32;
- typedef double FLOAT64;
+#include <CoreAudio/AudioHardware.h>
- char message[256];
- int nDevices;
- RTAUDIO_DEVICE *devices;
+class RtApiCore: public RtApi
+{
+public:
- std::map<int, void *> streams;
+ RtApiCore();
+ ~RtApiCore();
+ int getDefaultOutputDevice(void);
+ int getDefaultInputDevice(void);
+ void tickStream();
+ void closeStream();
+ void startStream();
+ void stopStream();
+ void abortStream();
+ void setStreamCallback( RtAudioCallback callback, void *userData );
+ void cancelStreamCallback();
+
+ // This function is intended for internal use only. It must be
+ // public because it is called by the internal callback handler,
+ // which is not a member of RtAudio. External use of this function
+ // will most likely produce highly undesireable results!
+ void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData );
- //! Private error method to allow global control over error handling.
- void error(RtError::TYPE type);
+ private:
- /*!
- Private method to count the system audio devices, allocate the
- RTAUDIO_DEVICE structures, and probe the device capabilities.
- */
void initialize(void);
+ void probeDeviceInfo( RtApiDevice *info );
+ bool probeDeviceOpen( int device, StreamMode mode, int channels,
+ int sampleRate, RtAudioFormat format,
+ int *bufferSize, int numberOfBuffers );
+};
- /*!
- Private method which returns the index in the devices array to
- the default input device.
- */
- int getDefaultInputDevice(void);
+#endif
- /*!
- Private method which returns the index in the devices array to
- the default output device.
- */
+#if defined(__WINDOWS_DS__)
+
+class RtApiDs: public RtApi
+{
+public:
+
+ RtApiDs();
+ ~RtApiDs();
int getDefaultOutputDevice(void);
+ int getDefaultInputDevice(void);
+ void tickStream();
+ void closeStream();
+ void startStream();
+ void stopStream();
+ void abortStream();
+ int streamWillBlock();
+ void setStreamCallback( RtAudioCallback callback, void *userData );
+ void cancelStreamCallback();
- //! Private method to clear an RTAUDIO_DEVICE structure.
- void clearDeviceInfo(RTAUDIO_DEVICE *info);
+ private:
- /*!
- Private method which attempts to fill an RTAUDIO_DEVICE
- structure for a given device. If an error is encountered during
- the probe, a "warning" message is reported and the value of
- "probed" remains false (no exception is thrown). A successful
- probe is indicated by probed = true.
- */
- void probeDeviceInfo(RTAUDIO_DEVICE *info);
+ void initialize(void);
+ void probeDeviceInfo( RtApiDevice *info );
+ bool probeDeviceOpen( int device, StreamMode mode, int channels,
+ int sampleRate, RtAudioFormat format,
+ int *bufferSize, int numberOfBuffers );
+};
- /*!
- Private method which attempts to open a device with the given parameters.
- If an error is encountered during the probe, a "warning" message is
- reported and FAILURE is returned (no exception is thrown). A
- successful probe is indicated by a return value of SUCCESS.
- */
- bool probeDeviceOpen(int device, RTAUDIO_STREAM *stream,
- STREAM_MODE mode, int channels,
- int sampleRate, RTAUDIO_FORMAT format,
- int *bufferSize, int numberOfBuffers);
+#endif
- /*!
- Private common method used to check validity of a user-passed
- stream ID. When the ID is valid, this method returns a pointer to
- an RTAUDIO_STREAM structure (in the form of a void pointer).
- Otherwise, an "invalid identifier" exception is thrown.
- */
- void *verifyStream(int streamId);
+#if defined(__WINDOWS_ASIO__)
- /*!
- Private method used to perform format, channel number, and/or interleaving
- conversions between the user and device buffers.
- */
- void convertStreamBuffer(RTAUDIO_STREAM *stream, STREAM_MODE mode);
+class RtApiAsio: public RtApi
+{
+public:
+
+ RtApiAsio();
+ ~RtApiAsio();
+ void tickStream();
+ void closeStream();
+ void startStream();
+ void stopStream();
+ void abortStream();
+ void setStreamCallback( RtAudioCallback callback, void *userData );
+ void cancelStreamCallback();
+
+ // This function is intended for internal use only. It must be
+ // public because it is called by the internal callback handler,
+ // which is not a member of RtAudio. External use of this function
+ // will most likely produce highly undesireable results!
+ void callbackEvent( long bufferIndex );
+
+ private:
+
+ void initialize(void);
+ void probeDeviceInfo( RtApiDevice *info );
+ bool probeDeviceOpen( int device, StreamMode mode, int channels,
+ int sampleRate, RtAudioFormat format,
+ int *bufferSize, int numberOfBuffers );
+};
+
+#endif
+
+#if defined(__IRIX_AL__)
+
+class RtApiAl: public RtApi
+{
+public:
+
+ RtApiAl();
+ ~RtApiAl();
+ int getDefaultOutputDevice(void);
+ int getDefaultInputDevice(void);
+ void tickStream();
+ void closeStream();
+ void startStream();
+ void stopStream();
+ void abortStream();
+ int streamWillBlock();
+ void setStreamCallback( RtAudioCallback callback, void *userData );
+ void cancelStreamCallback();
- //! Private method used to perform byte-swapping on buffers.
- void byteSwapBuffer(char *buffer, int samples, RTAUDIO_FORMAT format);
+ private:
- //! Private method which returns the number of bytes for a given format.
- int formatBytes(RTAUDIO_FORMAT format);
+ void initialize(void);
+ void probeDeviceInfo( RtApiDevice *info );
+ bool probeDeviceOpen( int device, StreamMode mode, int channels,
+ int sampleRate, RtAudioFormat format,
+ int *bufferSize, int numberOfBuffers );
};
+#endif
+
// Define the following flag to have extra information spewed to stderr.
//#define __RTAUDIO_DEBUG__