Add missing apostrophe and parentheses
[rtaudio-cdist.git] / RtAudio.h
index fa2d494d297949d2b37b08e357895293d75cde2e..c60fbbb89ba718d6fc51cf23559ca1576fa9e988 100644 (file)
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -4,13 +4,13 @@
 
     RtAudio provides a common API (Application Programming Interface)
     for realtime audio input/output across Linux (native ALSA, Jack,
-    and OSS), SGI, Macintosh OS X (CoreAudio), and Windows
-    (DirectSound and ASIO) operating systems.
+    and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
+    (DirectSound, ASIO and WASAPI) operating systems.
 
-    RtAudio WWW site: http://music.mcgill.ca/~gary/rtaudio/
+    RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
 
-    RtAudio: a realtime audio i/o C++ class
-    Copyright (c) 2001-2004 Gary P. Scavone
+    RtAudio: realtime audio i/o C++ classes
+    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
@@ -24,8 +24,9 @@
     included in all copies or substantial portions of the Software.
 
     Any person wishing to distribute modifications to the Software is
-    requested to send the modifications to the original developer so that
-    they can be incorporated into the canonical version.
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
 
     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 */
 /************************************************************************/
 
-// RtAudio: Version 3.0.1, 22 March 2004
+/*!
+  \file RtAudio.h
+ */
 
 #ifndef __RTAUDIO_H
 #define __RTAUDIO_H
 
-#include "RtError.h"
+#define RTAUDIO_VERSION "5.0.0"
+
+#if defined _WIN32 || defined __CYGWIN__
+  #define RTAUDIO_DLL_PUBLIC
+#else
+  #if __GNUC__ >= 4
+    #define RTAUDIO_DLL_PUBLIC __attribute__( (visibility( "default" )) )
+  #else
+    #define RTAUDIO_DLL_PUBLIC
+  #endif
+#endif
+
 #include <string>
 #include <vector>
+#include <stdexcept>
+#include <iostream>
+
+/*! \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:  24-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;   // 24-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.
+    - \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
+    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.
+
+    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).
+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.
+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.
+
+    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 );
+
+/************************************************************************/
+/*! \class RtAudioError
+    \brief Exception handling class for RtAudio.
+
+    The RtAudioError class is quite simple but it does allow errors to be
+    "caught" by RtAudioError::Type. See the RtAudio documentation to know
+    which methods can throw an RtAudioError.
+*/
+/************************************************************************/
+
+class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error
+{
+ public:
+  //! Defined RtAudioError types.
+  enum Type {
+    WARNING,           /*!< A non-critical error. */
+    DEBUG_WARNING,     /*!< A non-critical error which might be useful for debugging. */
+    UNSPECIFIED,       /*!< The default, unspecified error type. */
+    NO_DEVICES_FOUND,  /*!< No devices found on system. */
+    INVALID_DEVICE,    /*!< An invalid device ID was specified. */
+    MEMORY_ERROR,      /*!< An error occured during memory allocation. */
+    INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
+    INVALID_USE,       /*!< The function was called incorrectly. */
+    DRIVER_ERROR,      /*!< A system driver error occured. */
+    SYSTEM_ERROR,      /*!< A system error occured. */
+    THREAD_ERROR       /*!< A thread error occured. */
+  };
+
+  //! The constructor.
+  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
+    { std::cerr << '\n' << what() << "\n\n"; }
+
+  //! Returns the thrown error message type.
+  virtual const Type& getType(void) const { return type_; }
+
+  //! Returns the thrown error message string.
+  virtual const std::string getMessage(void) const
+    { return std::string(what()); }
+
+ protected:
+  Type type_;
+};
+
+//! RtAudio error callback function prototype.
+/*!
+    \param type Type of error.
+    \param errorText Error description.
+ */
+typedef void (*RtAudioErrorCallback)( RtAudioError::Type type, const std::string &errorText );
+
+// **************************************************************** //
+//
+// 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_DLL_PUBLIC RtAudio
+{
+ public:
+
+  //! Audio API specifier arguments.
+  enum Api {
+    UNSPECIFIED,    /*!< Search for a working compiled API. */
+    LINUX_ALSA,     /*!< The Advanced Linux Sound Architecture API. */
+    LINUX_PULSE,    /*!< The Linux PulseAudio 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_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. */
+  };
+
+  //! 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). */
+    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), preferredSampleRate(0), 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.
+    - \e RTAUDIO_SCHEDULE_REALTIME: Attempt to select realtime scheduling for callback thread.
+    - \e RTAUDIO_ALSA_USE_DEFAULT:  Use the "default" PCM device (ALSA only).
+
+    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.
+
+    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.
+
+    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.
+
+    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, RTAUDIO_ALSA_USE_DEFAULT). */
+    unsigned int numberOfBuffers;  /*!< Number of stream buffers. */
+    std::string streamName;        /*!< A stream name (currently used only in Jack). */
+    int priority;                  /*!< Scheduling priority of callback thread (only used with flag RTAUDIO_SCHEDULE_REALTIME). */
+
+    // Default constructor.
+    StreamOptions()
+    : flags(0), numberOfBuffers(0), priority(0) {}
+  };
+
+  //! A static function to determine the current RtAudio version.
+  static std::string getVersion( void );
+
+  //! 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 );
+
+  //! The class constructor.
+  /*!
+    The constructor performs minor initialization tasks.  An exception
+    can be thrown if no API support is compiled.
+
+    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 );
+
+  //! The destructor.
+  /*!
+    If a stream is running or open, it will be stopped and closed
+    automatically.
+  */
+  ~RtAudio();
+
+  //! Returns the audio API specifier for the current instance of RtAudio.
+  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. 
+  */
+  unsigned int getDeviceCount( void );
+
+  //! 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 RtAudioError (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 );
+
+  //! 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 );
+
+  //! A public function for opening a stream with the specified parameters.
+  /*!
+    An RtAudioError (type = SYSTEM_ERROR) is thrown if a stream cannot be
+    opened with the specified parameters or an error occurs during
+    processing.  An RtAudioError (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.
+    \param errorCallback A client-defined function that will be invoked
+           when an error has occured.
+  */
+  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, RtAudioErrorCallback errorCallback = 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 );
+
+  //! A function that starts a stream.
+  /*!
+    An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
+    during processing.  An RtAudioError (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 RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
+    during processing.  An RtAudioError (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 RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs
+    during processing.  An RtAudioError (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 ) const;
+
+  //! Returns true if the stream is running and false if it is stopped or not open.
+  bool isStreamRunning( void ) const;
+
+  //! Returns the number of elapsed seconds since the stream was started.
+  /*!
+    If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown.
+  */
+  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
+    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
+    RtAudioError (type = INVALID_USE) will be thrown.  If the API does not
+    report latency, the return value will be zero.
+  */
+  long getStreamLatency( void );
+
+ //! Returns actual sample rate in use by the stream.
+ /*!
+   On some systems, the sample rate used may be slightly different
+   than that specified in the stream parameters.  If a stream is not
+   open, an RtAudioError (type = INVALID_USE) will be thrown.
+ */
+  unsigned int getStreamSampleRate( void );
+
+  //! Specify whether warning messages should be printed to stderr.
+  void showWarnings( bool value = true );
+
+ protected:
+
+  void openRtApi( RtAudio::Api api );
+  RtApi *rtapi_;
+};
 
 // Operating system dependent thread functionality.
-#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
+#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__)
+
+  #ifndef NOMINMAX
+    #define NOMINMAX
+  #endif
   #include <windows.h>
   #include <process.h>
 
-  typedef unsigned long ThreadHandle;
+  typedef uintptr_t ThreadHandle;
   typedef CRITICAL_SECTION StreamMutex;
 
-#else // Various unix flavors with pthread support.
+#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
+  // Using pthread library for various flavors of unix.
   #include <pthread.h>
 
   typedef pthread_t ThreadHandle;
   typedef pthread_mutex_t StreamMutex;
 
+#else // Setup for "dummy" behavior
+
+  #define __RTAUDIO_DUMMY__
+  typedef int ThreadHandle;
+  typedef int StreamMutex;
+
 #endif
 
 // This global structure type is used to pass callback information
 struct CallbackInfo {
   void *object;    // Used as a "this" pointer.
   ThreadHandle thread;
-  bool usingCallback;
   void *callback;
   void *userData;
+  void *errorCallback;
   void *apiInfo;   // void pointer for API specific callback information
+  bool isRunning;
+  bool doRealtime;
+  int priority;
 
   // Default constructor.
   CallbackInfo()
-    :object(0), usingCallback(false), callback(0),
-     userData(0), apiInfo(0) {}
-};
-
-// 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) {}
+  :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0) {}
 };
 
 // **************************************************************** //
 //
 // RtApi class declaration.
 //
+// Subclasses of RtApi contain all API- and OS-specific code necessary
+// to fully implement the RtAudio API.
+//
 // 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).
+// RtApiJack, RtApiCore, RtApiDs, or RtApiAsio).
 //
 // **************************************************************** //
 
-class RtApi
+#pragma pack(push, 1)
+class S24 {
+
+ protected:
+  unsigned char c3[3];
+
+ public:
+  S24() {}
+
+  S24& operator = ( const int& i ) {
+    c3[0] = (i & 0x000000ff);
+    c3[1] = (i & 0x0000ff00) >> 8;
+    c3[2] = (i & 0x00ff0000) >> 16;
+    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; }
+  S24( const char& c ) { *this = (int) c; }
+
+  int asInt() {
+    int i = c3[0] | (c3[1] << 8) | (c3[2] << 16);
+    if (i & 0x800000) i |= ~0xffffff;
+    return i;
+  }
+};
+#pragma pack(pop)
+
+#if defined( HAVE_GETTIMEOFDAY )
+  #include <sys/time.h>
+#endif
+
+#include <sstream>
+
+class RTAUDIO_DLL_PUBLIC RtApi
 {
 public:
 
   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;
+  virtual RtAudio::Api getCurrentApi( void ) = 0;
+  virtual unsigned int getDeviceCount( void ) = 0;
+  virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
+  virtual unsigned int getDefaultInputDevice( void );
+  virtual unsigned int getDefaultOutputDevice( void );
+  void openStream( RtAudio::StreamParameters *outputParameters,
+                   RtAudio::StreamParameters *inputParameters,
+                   RtAudioFormat format, unsigned int sampleRate,
+                   unsigned int *bufferFrames, RtAudioCallback callback,
+                   void *userData, RtAudio::StreamOptions *options,
+                   RtAudioErrorCallback errorCallback );
+  virtual void closeStream( void );
+  virtual void startStream( void ) = 0;
+  virtual void stopStream( void ) = 0;
+  virtual void abortStream( void ) = 0;
+  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; }
+
 
 protected:
 
@@ -151,6 +718,13 @@ protected:
 
   enum { FAILURE, SUCCESS };
 
+  enum StreamState {
+    STREAM_STOPPED,
+    STREAM_STOPPING,
+    STREAM_RUNNING,
+    STREAM_CLOSED = -50
+  };
+
   enum StreamMode {
     OUTPUT,
     INPUT,
@@ -158,557 +732,446 @@ protected:
     UNINITIALIZED = -75
   };
 
-  enum StreamState {
-    STREAM_STOPPED,
-    STREAM_RUNNING
+  // A protected structure used for buffer conversion.
+  struct ConvertInfo {
+    int channels;
+    int inJump, outJump;
+    RtAudioFormat inFormat, outFormat;
+    std::vector<int> inOffset;
+    std::vector<int> outOffset;
   };
 
   // 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;
+    unsigned 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, RUNNING, or CLOSED
+    char *userBuffer[2];       // Playback and record, respectively.
     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.
+    bool doConvertBuffer[2];   // Playback and record, respectively.
+    bool userInterleaved;
+    bool deviceInterleaved[2]; // Playback and record, respectively.
+    bool doByteSwap[2];        // Playback and record, respectively.
+    unsigned int sampleRate;
+    unsigned int bufferSize;
+    unsigned int nBuffers;
+    unsigned int nUserChannels[2];    // Playback and record, respectively.
+    unsigned int nDeviceChannels[2];  // Playback and record channels, respectively.
+    unsigned int channelOffset[2];    // Playback and record, respectively.
+    unsigned long latency[2];         // Playback and record, respectively.
     RtAudioFormat userFormat;
-    RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
+    RtAudioFormat deviceFormat[2];    // Playback and record, respectively.
     StreamMutex mutex;
     CallbackInfo callbackInfo;
+    ConvertInfo convertInfo[2];
+    double streamTime;         // Number of elapsed seconds since the stream started.
 
-    RtApiStream()
-      :apiHandle(0), userBuffer(0), deviceBuffer(0) {}
-    //      mode(UNINITIALIZED), state(STREAM_STOPPED),
-  };
-
-  // 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. */
+#if defined(HAVE_GETTIMEOFDAY)
+    struct timeval lastTickTimestamp;
+#endif
 
-    // Default constructor.
-    RtApiDevice()
-      :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
-       maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
-       minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
+    RtApiStream()
+      :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
   };
 
+  typedef S24 Int24;
   typedef signed short Int16;
   typedef signed int Int32;
   typedef float Float32;
   typedef double Float64;
 
-  char message_[256];
-  int nDevices_;
-  std::vector<RtApiDevice> devices_;
+  std::ostringstream errorStream_;
+  std::string errorText_;
+  bool showWarnings_;
   RtApiStream stream_;
+  bool firstErrorOccurred_;
 
   /*!
-    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;
-
-  /*!
-    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 );
-
-  /*!
-    Protected, api-specific method which attempts to open a device
+    Protected, api-specific method that 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 );
-
-  /*!
-    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.
+    "warning" message is reported and FAILURE is returned. A
+    successful probe is indicated by a return value of SUCCESS.
   */
-  virtual int getDefaultOutputDevice(void);
+  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 );
 
-  //! Protected common method to clear an RtApiDevice structure.
-  void clearDeviceInfo( RtApiDevice *info );
+  //! A protected function used to increment the stream time.
+  void tickStreamTime( void );
 
   //! 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.
+    Protected common method that throws an RtAudioError (type =
+    INVALID_USE) if a stream is not open.
   */
-  void verifyStream();
+  void verifyStream( void );
+
+  //! Protected common error method to allow global control over error handling.
+  void error( RtAudioError::Type type );
 
   /*!
     Protected method used to perform format, channel number, and/or interleaving
     conversions between the user and device buffers.
   */
-  void convertStreamBuffer( StreamMode mode );
+  void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
 
   //! Protected common method used to perform byte-swapping on buffers.
-  void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format );
+  void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
 
-  //! Protected common method which returns the number of bytes for a given format.
-  int formatBytes( RtAudioFormat format );
-};
+  //! Protected common method that returns the number of bytes for a given format.
+  unsigned int formatBytes( RtAudioFormat format );
 
+  //! Protected common method that sets up the parameters for buffer conversion.
+  void setConvertInfo( StreamMode mode, unsigned int firstChannel );
+};
 
 // **************************************************************** //
 //
-// 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.
+// Inline RtAudio definitions.
 //
 // **************************************************************** //
 
-class RtAudio
-{
-public:
+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 ) { 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 { 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 :: setStreamTime( double time ) { return rtapi_->setStreamTime( time ); }
+inline void RtAudio :: showWarnings( bool value ) { rtapi_->showWarnings( value ); }
 
-  //! 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 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( RtAudioApi api=UNSPECIFIED );
+// RtApi Subclass prototypes.
 
-  //! A constructor which can be used to open a stream during instantiation.
-  /*!
-    The specified output and/or input device identifiers correspond
-    to those enumerated via the getDeviceInfo() method.  If device =
-    0, the default or first available devices meeting the given
-    parameters is selected.  If an output or input channel value is
-    zero, the corresponding device value is ignored.  When a stream is
-    successfully opened, its identifier is returned via the "streamId"
-    pointer.  An RtError can be thrown if no devices are found
-    for the given parameters, if a memory allocation error occurs, or
-    if a driver error occurs. \sa openStream()
-  */
-  RtAudio( int outputDevice, int outputChannels,
-           int inputDevice, int inputChannels,
-           RtAudioFormat format, int sampleRate,
-           int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED );
+#if defined(__MACOSX_CORE__)
 
-  //! The destructor.
-  /*!
-    Stops and closes an open stream and devices and deallocates
-    buffer and structure memory.
-  */
-  ~RtAudio();
+#include <CoreAudio/AudioHardware.h>
 
-  //! A public method for opening a stream with the specified parameters.
-  /*!
-    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
-           device number should correspond to one of those enumerated via
-           the getDeviceInfo() method.
-    \param outputChannels: The desired number of output channels.  If
-           equal to zero, the outputDevice identifier is ignored.
-    \param inputDevice: If equal to 0, the default or first device
-           found meeting the given parameters is opened.  Otherwise, the
-           device number should correspond to one of those enumerated via
-           the getDeviceInfo() method.
-    \param inputChannels: The desired number of input channels.  If
-           equal to zero, the inputDevice identifier is ignored.
-    \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
-           returned via the same pointer.  A value of zero can be specified,
-           in which case the lowest allowable value is determined.
-    \param numberOfBuffers: A value which can be used to help control device
-           latency.  More buffers typically result in more robust performance,
-           though at a cost of greater latency.  A value of zero can be
-           specified, in which case the lowest allowable value is used.
-  */
-  void openStream( int outputDevice, int outputChannels,
-                   int inputDevice, int inputChannels,
-                   RtAudioFormat format, int sampleRate,
-                   int *bufferSize, int numberOfBuffers );
+class RtApiCore: public RtApi
+{
+public:
 
-  //! A public method which sets a user-defined callback function for a given stream.
-  /*!
-    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(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); };
+  RtApiCore();
+  ~RtApiCore();
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  unsigned int getDefaultOutputDevice( void );
+  unsigned int getDefaultInputDevice( void );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+  long getStreamLatency( void );
 
-  //! 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 the stream.  Callback functionality can
-    subsequently be restarted on the stream via the
-    setStreamCallback() method.  An RtError will be thrown if called
-    when no stream is open.
-   */
-  void cancelStreamCallback() { rtapi_->cancelStreamCallback(); };
-
-  //! A public method which returns the number of audio devices found.
-  int getDeviceCount(void) { return rtapi_->getDeviceCount(); };
-
-  //! 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
-    "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 "isDefault" member will have a value of
-    "true".  An RtError will be thrown for an invalid device argument.
-  */
-  RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); };
+  // 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!
+  bool callbackEvent( AudioDeviceID deviceId,
+                      const AudioBufferList *inBufferList,
+                      const AudioBufferList *outBufferList );
 
-  //! 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 if called when no stream is open.
-  */
-  char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); };
+  private:
 
-  //! 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 if a driver error occurs or if called when
-    no stream is open.
-  */
-  void tickStream() { rtapi_->tickStream(); };
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
+  static const char* getErrorCode( OSStatus code );
+};
 
-  //! Public method which closes a stream and frees any associated buffers.
-  /*!
-    If a stream is not open, this method issues a warning and
-    returns (an RtError is not thrown).
-  */
-  void closeStream()  { rtapi_->closeStream(); };
+#endif
 
-  //! Public method which starts a stream.
-  /*!
-    An RtError will be thrown if a driver error occurs or if called
-    when no stream is open.
-  */
-  void startStream() { rtapi_->startStream(); };
+#if defined(__UNIX_JACK__)
 
-  //! Stop a stream, allowing any samples remaining in the queue to be played out and/or read in.
-  /*!
-    An RtError will be thrown if a driver error occurs or if called
-    when no stream is open.
-  */
-  void stopStream() { rtapi_->stopStream(); };
+class RtApiJack: public RtApi
+{
+public:
 
-  //! Stop a stream, discarding any samples remaining in the input/output queue.
-  /*!
-    An RtError will be thrown if a driver error occurs or if called
-    when no stream is open.
-  */
-  void abortStream() { rtapi_->abortStream(); };
+  RtApiJack();
+  ~RtApiJack();
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  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,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  bool callbackEvent( unsigned long nframes );
 
protected:
 private:
 
-  void initialize( RtAudioApi api );
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
 
-  RtApi *rtapi_;
+  bool shouldAutoconnect_;
 };
 
+#endif
 
-// RtApi Subclass prototypes.
-
-#if defined(__LINUX_ALSA__)
+#if defined(__WINDOWS_ASIO__)
 
-class RtApiAlsa: public RtApi
+class RtApiAsio: 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();
+  RtApiAsio();
+  ~RtApiAsio();
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  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,
+  // which is not a member of RtAudio.  External use of this function
+  // will most likely produce highly undesireable results!
+  bool 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 );
+  std::vector<RtAudio::DeviceInfo> devices_;
+  void saveDeviceInfo( void );
+  bool coInitialized_;
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
 };
 
 #endif
 
-#if defined(__LINUX_JACK__)
+#if defined(__WINDOWS_DS__)
 
-class RtApiJack: public RtApi
+class RtApiDs: public RtApi
 {
 public:
 
-  RtApiJack();
-  ~RtApiJack();
-  void tickStream();
-  void closeStream();
-  void startStream();
-  void stopStream();
-  void abortStream();
-  void setStreamCallback( RtAudioCallback callback, void *userData );
-  void cancelStreamCallback();
+  RtApiDs();
+  ~RtApiDs();
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; }
+  unsigned int getDeviceCount( void );
+  unsigned int getDefaultOutputDevice( void );
+  unsigned int getDefaultInputDevice( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  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,
   // which is not a member of RtAudio.  External use of this function
   // will most likely produce highly undesireable results!
-  void callbackEvent( unsigned long nframes );
+  void callbackEvent( void );
 
   private:
 
-  void initialize(void);
-  void probeDeviceInfo( RtApiDevice *info );
-  bool probeDeviceOpen( int device, StreamMode mode, int channels, 
-                        int sampleRate, RtAudioFormat format,
-                        int *bufferSize, int numberOfBuffers );
+  bool coInitialized_;
+  bool buffersRolling;
+  long duplexPrerollBytes;
+  std::vector<struct DsDevice> dsDevices;
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
 };
 
 #endif
 
-#if defined(__LINUX_OSS__)
+#if defined(__WINDOWS_WASAPI__)
 
-class RtApiOss: public RtApi
+struct IMMDeviceEnumerator;
+
+class RtApiWasapi : public RtApi
 {
 public:
-
-  RtApiOss();
-  ~RtApiOss();
-  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 );
+  RtApiWasapi();
+  ~RtApiWasapi();
+
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  unsigned int getDefaultOutputDevice( void );
+  unsigned int getDefaultInputDevice( void );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
+
+private:
+  bool coInitialized_;
+  IMMDeviceEnumerator* deviceEnumerator_;
+
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int* bufferSize,
+                        RtAudio::StreamOptions* options );
+
+  static DWORD WINAPI runWasapiThread( void* wasapiPtr );
+  static DWORD WINAPI stopWasapiThread( void* wasapiPtr );
+  static DWORD WINAPI abortWasapiThread( void* wasapiPtr );
+  void wasapiThread();
 };
 
 #endif
 
-#if defined(__MACOSX_CORE__)
-
-#include <CoreAudio/AudioHardware.h>
+#if defined(__LINUX_ALSA__)
 
-class RtApiCore: public RtApi
+class RtApiAlsa: public RtApi
 {
 public:
 
-  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();
+  RtApiAlsa();
+  ~RtApiAlsa();
+  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
 
   // 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 );
+  void callbackEvent( void );
 
   private:
 
-  void initialize(void);
-  void probeDeviceInfo( RtApiDevice *info );
-  bool probeDeviceOpen( int device, StreamMode mode, int channels, 
-                        int sampleRate, RtAudioFormat format,
-                        int *bufferSize, int numberOfBuffers );
+  std::vector<RtAudio::DeviceInfo> devices_;
+  void saveDeviceInfo( void );
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
 };
 
 #endif
 
-#if defined(__WINDOWS_DS__)
+#if defined(__LINUX_PULSE__)
 
-class RtApiDs: public RtApi
+class RtApiPulse: public RtApi
 {
 public:
+  ~RtApiPulse();
+  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
 
-  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();
+  // 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( void );
 
   private:
 
-  void initialize(void);
-  void probeDeviceInfo( RtApiDevice *info );
-  bool probeDeviceOpen( int device, StreamMode mode, int channels, 
-                        int sampleRate, RtAudioFormat format,
-                        int *bufferSize, int numberOfBuffers );
+  std::vector<RtAudio::DeviceInfo> devices_;
+  void saveDeviceInfo( void );
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
 };
 
 #endif
 
-#if defined(__WINDOWS_ASIO__)
+#if defined(__LINUX_OSS__)
 
-class RtApiAsio: public RtApi
+class RtApiOss: public RtApi
 {
 public:
 
-  RtApiAsio();
-  ~RtApiAsio();
-  void tickStream();
-  void closeStream();
-  void startStream();
-  void stopStream();
-  void abortStream();
-  void setStreamCallback( RtAudioCallback callback, void *userData );
-  void cancelStreamCallback();
+  RtApiOss();
+  ~RtApiOss();
+  RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; }
+  unsigned int getDeviceCount( void );
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
+  void closeStream( void );
+  void startStream( void );
+  void stopStream( void );
+  void abortStream( void );
 
   // 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 );
+  void callbackEvent( void );
 
   private:
 
-  void initialize(void);
-  void probeDeviceInfo( RtApiDevice *info );
-  bool probeDeviceOpen( int device, StreamMode mode, int channels, 
-                        int sampleRate, RtAudioFormat format,
-                        int *bufferSize, int numberOfBuffers );
+  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
+                        unsigned int firstChannel, unsigned int sampleRate,
+                        RtAudioFormat format, unsigned int *bufferSize,
+                        RtAudio::StreamOptions *options );
 };
 
 #endif
 
-#if defined(__IRIX_AL__)
+#if defined(__RTAUDIO_DUMMY__)
 
-class RtApiAl: public RtApi
+class RtApiDummy: 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();
+  RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtAudioError::WARNING ); }
+  RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; }
+  unsigned int getDeviceCount( void ) { return 0; }
+  RtAudio::DeviceInfo getDeviceInfo( unsigned int /*device*/ ) { RtAudio::DeviceInfo info; return info; }
+  void closeStream( void ) {}
+  void startStream( void ) {}
+  void stopStream( void ) {}
+  void abortStream( void ) {}
 
   private:
 
-  void initialize(void);
-  void probeDeviceInfo( RtApiDevice *info );
-  bool probeDeviceOpen( int device, StreamMode mode, int channels, 
-                        int sampleRate, RtAudioFormat format,
-                        int *bufferSize, int numberOfBuffers );
+  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; }
 };
 
 #endif
 
-// Define the following flag to have extra information spewed to stderr.
-//#define __RTAUDIO_DEBUG__
-
 #endif
+
+// Indentation settings for Vim and Emacs
+//
+// Local Variables:
+// c-basic-offset: 2
+// indent-tabs-mode: nil
+// End:
+//
+// vim: et sts=2 sw=2