Removed unnecessary semicolons from function definitions (gps).
[rtaudio-cdist.git] / RtAudio.h
1 /************************************************************************/
2 /*! \class RtAudio
3     \brief Realtime audio i/o C++ classes.
4
5     RtAudio provides a common API (Application Programming Interface)
6     for realtime audio input/output across Linux (native ALSA, Jack,
7     and OSS), SGI, Macintosh OS X (CoreAudio and Jack), and Windows
8     (DirectSound and ASIO) operating systems.
9
10     RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
11
12     RtAudio: realtime audio i/o C++ classes
13     Copyright (c) 2001-2007 Gary P. Scavone
14
15     Permission is hereby granted, free of charge, to any person
16     obtaining a copy of this software and associated documentation files
17     (the "Software"), to deal in the Software without restriction,
18     including without limitation the rights to use, copy, modify, merge,
19     publish, distribute, sublicense, and/or sell copies of the Software,
20     and to permit persons to whom the Software is furnished to do so,
21     subject to the following conditions:
22
23     The above copyright notice and this permission notice shall be
24     included in all copies or substantial portions of the Software.
25
26     Any person wishing to distribute modifications to the Software is
27     asked to send the modifications to the original developer so that
28     they can be incorporated into the canonical version.  This is,
29     however, not a binding provision of this license.
30
31     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
34     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
35     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
36     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 */
39 /************************************************************************/
40
41 /*!
42   \file RtAudio.h
43  */
44
45 // RtAudio: Version 4.0
46
47 #ifndef __RTAUDIO_H
48 #define __RTAUDIO_H
49
50 #include <string>
51 #include <vector>
52 #include "RtError.h"
53
54 /*! \typedef typedef unsigned long RtAudioFormat;
55     \brief RtAudio data format type.
56
57     Support for signed integers and floats.  Audio data fed to/from an
58     RtAudio stream is assumed to ALWAYS be in host byte order.  The
59     internal routines will automatically take care of any necessary
60     byte-swapping between the host format and the soundcard.  Thus,
61     endian-ness is not a concern in the following format definitions.
62
63     - \e RTAUDIO_SINT8:   8-bit signed integer.
64     - \e RTAUDIO_SINT16:  16-bit signed integer.
65     - \e RTAUDIO_SINT24:  Upper 3 bytes of 32-bit signed integer.
66     - \e RTAUDIO_SINT32:  32-bit signed integer.
67     - \e RTAUDIO_FLOAT32: Normalized between plus/minus 1.0.
68     - \e RTAUDIO_FLOAT64: Normalized between plus/minus 1.0.
69 */
70 typedef unsigned long RtAudioFormat;
71 static const RtAudioFormat RTAUDIO_SINT8 = 0x1;    // 8-bit signed integer.
72 static const RtAudioFormat RTAUDIO_SINT16 = 0x2;   // 16-bit signed integer.
73 static const RtAudioFormat RTAUDIO_SINT24 = 0x4;   // Lower 3 bytes of 32-bit signed integer.
74 static const RtAudioFormat RTAUDIO_SINT32 = 0x8;   // 32-bit signed integer.
75 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
76 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
77
78 /*! \typedef typedef unsigned long RtAudioStreamFlags;
79     \brief RtAudio stream option flags.
80
81     The following flags can be OR'ed together to allow a client to
82     make changes to the default stream behavior:
83
84     - \e RTAUDIO_NONINTERLEAVED:   Use non-interleaved buffers (default = interleaved).
85     - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
86     - \e RTAUDIO_HOG_DEVICE:       Attempt grab device for exclusive use.
87
88     By default, RtAudio streams pass and receive audio data from the
89     client in an interleaved format.  By passing the
90     RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
91     data will instead be presented in non-interleaved buffers.  In
92     this case, each buffer argument in the RtAudioCallback function
93     will point to a single array of data, with \c nFrames samples for
94     each channel concatenated back-to-back.  For example, the first
95     sample of data for the second channel would be located at index \c
96     nFrames (assuming the \c buffer pointer was recast to the correct
97     data type for the stream).
98
99     Certain audio APIs offer a number of parameters that influence the
100     I/O latency of a stream.  By default, RtAudio will attempt to set
101     these parameters internally for robust (glitch-free) performance
102     (though some APIs, like Windows Direct Sound, make this difficult).
103     By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
104     function, internal stream settings will be influenced in an attempt
105     to minimize stream latency, though possibly at the expense of stream
106     performance.
107
108     If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
109     open the input and/or output stream device(s) for exclusive use.
110     Note that this is not possible with all supported audio APIs.
111 */
112 typedef unsigned int RtAudioStreamFlags;
113 static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1;    // Use non-interleaved buffers (default = interleaved).
114 static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2;  // Attempt to set stream parameters for lowest possible latency.
115 static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4;        // Attempt grab device and prevent use by others.
116
117 /*! \typedef typedef unsigned long RtAudioStreamStatus;
118     \brief RtAudio stream status (over- or underflow) flags.
119
120     Notification of a stream over- or underflow is indicated by a
121     non-zero stream \c status argument in the RtAudioCallback function.
122     The stream status can be one of the following two options,
123     depending on whether the stream is open for output and/or input:
124
125     - \e RTAUDIO_INPUT_OVERFLOW:   Input data was discarded because of an overflow condition at the driver.
126     - \e RTAUDIO_OUTPUT_UNDERFLOW: The output buffer ran low, likely producing a break in the output sound.
127 */
128 typedef unsigned int RtAudioStreamStatus;
129 static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1;    // Input data was discarded because of an overflow condition at the driver.
130 static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2;  // The output buffer ran low, likely causing a gap in the output sound.
131
132 //! RtAudio callback function prototype.
133 /*!
134    All RtAudio clients must create a function of type RtAudioCallback
135    to read and/or write data from/to the audio stream.  When the
136    underlying audio system is ready for new input or output data, this
137    function will be invoked.
138
139    \param outputBuffer For output (or duplex) streams, the client
140           should write \c nFrames of audio sample frames into this
141           buffer.  This argument should be recast to the datatype
142           specified when the stream was opened.  For input-only
143           streams, this argument will be NULL.
144
145    \param inputBuffer For input (or duplex) streams, this buffer will
146           hold \c nFrames of input audio sample frames.  This
147           argument should be recast to the datatype specified when the
148           stream was opened.  For output-only streams, this argument
149           will be NULL.
150
151    \param nFrames The number of sample frames of input or output
152           data in the buffers.  The actual buffer size in bytes is
153           dependent on the data type and number of channels in use.
154
155    \param streamTime The number of seconds that have elapsed since the
156           stream was started.
157
158    \param status If non-zero, this argument indicates a data overflow
159           or underflow condition for the stream.  The particular
160           condition can be determined by comparison with the
161           RtAudioStreamStatus flags.
162
163    \param userData A pointer to optional data provided by the client
164           when opening the stream (default = NULL).
165
166    To continue normal stream operation, the RtAudioCallback function
167    should return a value of zero.  To stop the stream and drain the
168    output buffer, the function should return a value of one.  To abort
169    the stream immediately, the client should return a value of two.
170  */
171 typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
172                                 unsigned int nFrames,
173                                 double streamTime,
174                                 RtAudioStreamStatus status,
175                                 void *userData );
176
177
178 // **************************************************************** //
179 //
180 // RtAudio class declaration.
181 //
182 // RtAudio is a "controller" used to select an available audio i/o
183 // interface.  It presents a common API for the user to call but all
184 // functionality is implemented by the class RtApi and its
185 // subclasses.  RtAudio creates an instance of an RtApi subclass
186 // based on the user's API choice.  If no choice is made, RtAudio
187 // attempts to make a "logical" API selection.
188 //
189 // **************************************************************** //
190
191 class RtApi;
192
193 class RtAudio
194 {
195  public:
196
197   //! Audio API specifier arguments.
198   enum Api {
199     UNSPECIFIED,    /*!< Search for a working compiled API. */
200     LINUX_ALSA,     /*!< The Advanced Linux Sound Architecture API. */
201     LINUX_OSS,      /*!< The Linux Open Sound System API. */
202     UNIX_JACK,      /*!< The Jack Low-Latency Audio Server API. */
203     MACOSX_CORE,    /*!< Macintosh OS-X Core Audio API. */
204     WINDOWS_ASIO,   /*!< The Steinberg Audio Stream I/O API. */
205     WINDOWS_DS,     /*!< The Microsoft Direct Sound API. */
206     RTAUDIO_DUMMY   /*!< A compilable but non-functional API. */
207   };
208
209   //! The public device information structure for returning queried values.
210   struct DeviceInfo {
211     bool probed;                  /*!< true if the device capabilities were successfully probed. */
212     std::string name;             /*!< Character string device identifier. */
213     unsigned int outputChannels;  /*!< Maximum output channels supported by device. */
214     unsigned int inputChannels;   /*!< Maximum input channels supported by device. */
215     unsigned int duplexChannels;  /*!< Maximum simultaneous input/output channels supported by device. */
216     bool isDefaultOutput;         /*!< true if this is the default output device. */
217     bool isDefaultInput;          /*!< true if this is the default input device. */
218     std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
219     RtAudioFormat nativeFormats;  /*!< Bit mask of supported data formats. */
220
221     // Default constructor.
222     DeviceInfo()
223       :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0),
224        isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {}
225   };
226
227   //! The structure for specifying input or ouput stream parameters.
228   struct StreamParameters {
229     unsigned int deviceId;     /*!< Device index (0 to getDeviceCount() - 1). */
230     unsigned int nChannels;    /*!< Number of channels. */
231     unsigned int firstChannel; /*!< First channel index on device (default = 0). */
232
233     // Default constructor.
234     StreamParameters()
235       : deviceId(0), nChannels(0), firstChannel(0) {}
236   };
237
238   //! The structure for specifying stream options.
239   /*!
240     The following flags can be OR'ed together to allow a client to
241     make changes to the default stream behavior:
242
243     - \e RTAUDIO_NONINTERLEAVED:   Use non-interleaved buffers (default = interleaved).
244     - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
245     - \e RTAUDIO_HOG_DEVICE:       Attempt grab device for exclusive use.
246
247     By default, RtAudio streams pass and receive audio data from the
248     client in an interleaved format.  By passing the
249     RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
250     data will instead be presented in non-interleaved buffers.  In
251     this case, each buffer argument in the RtAudioCallback function
252     will point to a single array of data, with \c nFrames samples for
253     each channel concatenated back-to-back.  For example, the first
254     sample of data for the second channel would be located at index \c
255     nFrames (assuming the \c buffer pointer was recast to the correct
256     data type for the stream).
257
258     Certain audio APIs offer a number of parameters that influence the
259     I/O latency of a stream.  By default, RtAudio will attempt to set
260     these parameters internally for robust (glitch-free) performance
261     (though some APIs, like Windows Direct Sound, make this difficult).
262     By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
263     function, internal stream settings will be influenced in an attempt
264     to minimize stream latency, though possibly at the expense of stream
265     performance.
266
267     If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
268     open the input and/or output stream device(s) for exclusive use.
269     Note that this is not possible with all supported audio APIs.
270
271     The \c numberOfBuffers parameter can be used to control stream
272     latency in the Windows DirectSound, Linux OSS, and Linux Alsa APIs
273     only.  A value of two is usually the smallest allowed.  Larger
274     numbers can potentially result in more robust stream performance,
275     though likely at the cost of stream latency.  The value set by the
276     user is replaced during execution of the RtAudio::openStream()
277     function by the value actually used by the system.
278
279     The \c streamName parameter can be used to set the client name
280     when using the Jack API.  By default, the client name is set to
281     RtApiJack.  However, if you wish to create multiple instances of
282     RtAudio with Jack, each instance must have a unique client name.
283   */
284   struct StreamOptions {
285     RtAudioStreamFlags flags;      /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE). */
286     unsigned int numberOfBuffers;  /*!< Number of stream buffers. */
287     std::string streamName;        /*!< A stream name (currently used only in Jack). */
288
289     // Default constructor.
290     StreamOptions()
291       : flags(0), numberOfBuffers(0) {}
292   };
293
294   //! A static function to determine the available compiled audio APIs.
295   /*!
296     The values returned in the std::vector can be compared against
297     the enumerated list values.  Note that there can be more than one
298     API compiled for certain operating systems.
299   */
300   static void getCompiledApi( std::vector<RtAudio::Api> &apis ) throw();
301
302   //! The class constructor.
303   /*!
304     The constructor performs minor initialization tasks.  No exceptions
305     can be thrown.
306
307     If no API argument is specified and multiple API support has been
308     compiled, the default order of use is JACK, ALSA, OSS (Linux
309     systems) and ASIO, DS (Windows systems).
310   */
311   RtAudio( RtAudio::Api api=UNSPECIFIED ) throw();
312
313   //! The destructor.
314   /*!
315     If a stream is running or open, it will be stopped and closed
316     automatically.
317   */
318   ~RtAudio() throw();
319
320   //! Returns the audio API specifier for the current instance of RtAudio.
321   RtAudio::Api getCurrentApi( void ) throw();
322
323   //! A public function that queries for the number of audio devices available.
324   /*!
325     This function performs a system query of available devices each time it
326     is called, thus supporting devices connected \e after instantiation. If
327     a system error occurs during processing, a warning will be issued. 
328   */
329   unsigned int getDeviceCount( void ) throw();
330
331   //! Return an RtAudio::DeviceInfo structure for a specified device number.
332   /*!
333
334     Any device integer between 0 and getDeviceCount() - 1 is valid.
335     If an invalid argument is provided, an RtError (type = INVALID_USE)
336     will be thrown.  If a device is busy or otherwise unavailable, the
337     structure member "probed" will have a value of "false" and all
338     other members are undefined.  If the specified device is the
339     current default input or output device, the corresponding
340     "isDefault" member will have a value of "true".
341   */
342   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
343
344   //! A function that returns the index of the default output device.
345   /*!
346     If the underlying audio API does not provide a "default
347     device", or if no devices are available, the return value will be
348     0.  Note that this is a valid device identifier and it is the
349     client's responsibility to verify that a device is available
350     before attempting to open a stream.
351   */
352   unsigned int getDefaultOutputDevice( void ) throw();
353
354   //! A function that returns the index of the default input device.
355   /*!
356     If the underlying audio API does not provide a "default
357     device", or if no devices are available, the return value will be
358     0.  Note that this is a valid device identifier and it is the
359     client's responsibility to verify that a device is available
360     before attempting to open a stream.
361   */
362   unsigned int getDefaultInputDevice( void ) throw();
363
364   //! A public function for opening a stream with the specified parameters.
365   /*!
366     An RtError (type = SYSTEM_ERROR) is thrown if a stream cannot be
367     opened with the specified parameters or an error occurs during
368     processing.  An RtError (type = INVALID_USE) is thrown if any
369     invalid device ID or channel number parameters are specified.
370
371     \param outputParameters Specifies output stream parameters to use
372            when opening a stream, including a device ID, number of channels,
373            and starting channel number.  For input-only streams, this
374            argument should be NULL.  The device ID is an index value between
375            0 and getDeviceCount() - 1.
376     \param inputParameters Specifies input stream parameters to use
377            when opening a stream, including a device ID, number of channels,
378            and starting channel number.  For output-only streams, this
379            argument should be NULL.  The device ID is an index value between
380            0 and getDeviceCount() - 1.
381     \param format An RtAudioFormat specifying the desired sample data format.
382     \param sampleRate The desired sample rate (sample frames per second).
383     \param *bufferFrames A pointer to a value indicating the desired
384            internal buffer size in sample frames.  The actual value
385            used by the device is returned via the same pointer.  A
386            value of zero can be specified, in which case the lowest
387            allowable value is determined.
388     \param callback A client-defined function that will be invoked
389            when input data is available and/or output data is needed.
390     \param userData An optional pointer to data that can be accessed
391            from within the callback function.
392     \param options An optional pointer to a structure containing various
393            global stream options, including a list of OR'ed RtAudioStreamFlags
394            and a suggested number of stream buffers that can be used to 
395            control stream latency.  More buffers typically result in more
396            robust performance, though at a cost of greater latency.  If a
397            value of zero is specified, a system-specific median value is
398            chosen.  If the RTAUDIO_MINIMIZE_LATENCY flag bit is set, the
399            lowest allowable value is used.  The actual value used is
400            returned via the structure argument.  The parameter is API dependent.
401   */
402   void openStream( RtAudio::StreamParameters *outputParameters,
403                    RtAudio::StreamParameters *inputParameters,
404                    RtAudioFormat format, unsigned int sampleRate,
405                    unsigned int *bufferFrames, RtAudioCallback callback,
406                    void *userData = NULL, RtAudio::StreamOptions *options = NULL );
407
408   //! A function that closes a stream and frees any associated stream memory.
409   /*!
410     If a stream is not open, this function issues a warning and
411     returns (no exception is thrown).
412   */
413   void closeStream( void ) throw();
414
415   //! A function that starts a stream.
416   /*!
417     An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
418     during processing.  An RtError (type = INVALID_USE) is thrown if a
419     stream is not open.  A warning is issued if the stream is already
420     running.
421   */
422   void startStream( void );
423
424   //! Stop a stream, allowing any samples remaining in the output queue to be played.
425   /*!
426     An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
427     during processing.  An RtError (type = INVALID_USE) is thrown if a
428     stream is not open.  A warning is issued if the stream is already
429     stopped.
430   */
431   void stopStream( void );
432
433   //! Stop a stream, discarding any samples remaining in the input/output queue.
434   /*!
435     An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
436     during processing.  An RtError (type = INVALID_USE) is thrown if a
437     stream is not open.  A warning is issued if the stream is already
438     stopped.
439   */
440   void abortStream( void );
441
442   //! Returns true if a stream is open and false if not.
443   bool isStreamOpen( void ) throw();
444
445   //! Returns true if the stream is running and false if it is stopped or not open.
446   bool isStreamRunning( void ) throw();
447
448   //! Returns the number of elapsed seconds since the stream was started.
449   /*!
450     If a stream is not open, an RtError (type = INVALID_USE) will be thrown.
451   */
452   double getStreamTime( void );
453
454   //! Returns the internal stream latency in sample frames.
455   /*!
456     The stream latency refers to delay in audio input and/or output
457     caused by internal buffering by the audio system and/or hardware.
458     For duplex streams, the returned value will represent the sum of
459     the input and output latencies.  If a stream is not open, an
460     RtError (type = INVALID_USE) will be thrown.  If the API does not
461     report latency, the return value will be zero.
462   */
463   long getStreamLatency( void );
464
465   //! Specify whether warning messages should be printed to stderr.
466   void showWarnings( bool value = true ) throw();
467
468  protected:
469
470   void openRtApi( RtAudio::Api api );
471   RtApi *rtapi_;
472 };
473
474 // Operating system dependent thread functionality.
475 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
476   #include <windows.h>
477   #include <process.h>
478
479   typedef unsigned long ThreadHandle;
480   typedef CRITICAL_SECTION StreamMutex;
481
482 #elif defined(__LINUX_ALSA__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
483   // Using pthread library for various flavors of unix.
484   #include <pthread.h>
485
486   typedef pthread_t ThreadHandle;
487   typedef pthread_mutex_t StreamMutex;
488
489 #else // Setup for "dummy" behavior
490
491   #define __RTAUDIO_DUMMY__
492   typedef int ThreadHandle;
493   typedef int StreamMutex;
494
495 #endif
496
497 // This global structure type is used to pass callback information
498 // between the private RtAudio stream structure and global callback
499 // handling functions.
500 struct CallbackInfo {
501   void *object;    // Used as a "this" pointer.
502   ThreadHandle thread;
503   void *callback;
504   void *userData;
505   void *apiInfo;   // void pointer for API specific callback information
506   bool isRunning;
507
508   // Default constructor.
509   CallbackInfo()
510     :object(0), callback(0), userData(0), apiInfo(0), isRunning(false) {}
511 };
512
513 // **************************************************************** //
514 //
515 // RtApi class declaration.
516 //
517 // Subclasses of RtApi contain all API- and OS-specific code necessary
518 // to fully implement the RtAudio API.
519 //
520 // Note that RtApi is an abstract base class and cannot be
521 // explicitly instantiated.  The class RtAudio will create an
522 // instance of an RtApi subclass (RtApiOss, RtApiAlsa,
523 // RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio).
524 //
525 // **************************************************************** //
526
527 #if defined( HAVE_GETTIMEOFDAY )
528   #include <sys/time.h>
529 #endif
530
531 #include <sstream>
532
533 class RtApi
534 {
535 public:
536
537   RtApi();
538   virtual ~RtApi();
539   virtual RtAudio::Api getCurrentApi( void ) = 0;
540   virtual unsigned int getDeviceCount( void ) = 0;
541   virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
542   virtual unsigned int getDefaultInputDevice( void );
543   virtual unsigned int getDefaultOutputDevice( void );
544   void openStream( RtAudio::StreamParameters *outputParameters,
545                    RtAudio::StreamParameters *inputParameters,
546                    RtAudioFormat format, unsigned int sampleRate,
547                    unsigned int *bufferFrames, RtAudioCallback callback,
548                    void *userData, RtAudio::StreamOptions *options );
549   virtual void closeStream( void );
550   virtual void startStream( void ) = 0;
551   virtual void stopStream( void ) = 0;
552   virtual void abortStream( void ) = 0;
553   long getStreamLatency( void );
554   virtual double getStreamTime( void );
555   bool isStreamOpen( void ) { return stream_.state != STREAM_CLOSED; };
556   bool isStreamRunning( void ) { return stream_.state == STREAM_RUNNING; };
557   void showWarnings( bool value ) { showWarnings_ = value; };
558
559
560 protected:
561
562   static const unsigned int MAX_SAMPLE_RATES;
563   static const unsigned int SAMPLE_RATES[];
564
565   enum { FAILURE, SUCCESS };
566
567   enum StreamState {
568     STREAM_STOPPED,
569     STREAM_RUNNING,
570     STREAM_CLOSED = -50
571   };
572
573   enum StreamMode {
574     OUTPUT,
575     INPUT,
576     DUPLEX,
577     UNINITIALIZED = -75
578   };
579
580   // A protected structure used for buffer conversion.
581   struct ConvertInfo {
582     int channels;
583     int inJump, outJump;
584     RtAudioFormat inFormat, outFormat;
585     std::vector<int> inOffset;
586     std::vector<int> outOffset;
587   };
588
589   // A protected structure for audio streams.
590   struct RtApiStream {
591     unsigned int device[2];    // Playback and record, respectively.
592     void *apiHandle;           // void pointer for API specific stream handle information
593     StreamMode mode;           // OUTPUT, INPUT, or DUPLEX.
594     StreamState state;         // STOPPED, RUNNING, or CLOSED
595     char *userBuffer[2];       // Playback and record, respectively.
596     char *deviceBuffer;
597     bool doConvertBuffer[2];   // Playback and record, respectively.
598     bool userInterleaved;
599     bool deviceInterleaved[2]; // Playback and record, respectively.
600     bool doByteSwap[2];        // Playback and record, respectively.
601     unsigned int sampleRate;
602     unsigned int bufferSize;
603     unsigned int nBuffers;
604     unsigned int nUserChannels[2];    // Playback and record, respectively.
605     unsigned int nDeviceChannels[2];  // Playback and record channels, respectively.
606     unsigned int channelOffset[2];    // Playback and record, respectively.
607     unsigned long latency[2];         // Playback and record, respectively.
608     RtAudioFormat userFormat;
609     RtAudioFormat deviceFormat[2];    // Playback and record, respectively.
610     StreamMutex mutex;
611     CallbackInfo callbackInfo;
612     ConvertInfo convertInfo[2];
613     double streamTime;         // Number of elapsed seconds since the stream started.
614
615 #if defined(HAVE_GETTIMEOFDAY)
616     struct timeval lastTickTimestamp;
617 #endif
618
619     RtApiStream()
620       :apiHandle(0), deviceBuffer(0) {}
621   };
622
623   typedef signed short Int16;
624   typedef signed int Int32;
625   typedef float Float32;
626   typedef double Float64;
627
628   std::ostringstream errorStream_;
629   std::string errorText_;
630   bool showWarnings_;
631   RtApiStream stream_;
632
633   /*!
634     Protected, api-specific method that attempts to open a device
635     with the given parameters.  This function MUST be implemented by
636     all subclasses.  If an error is encountered during the probe, a
637     "warning" message is reported and FAILURE is returned. A
638     successful probe is indicated by a return value of SUCCESS.
639   */
640   virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
641                                 unsigned int firstChannel, unsigned int sampleRate,
642                                 RtAudioFormat format, unsigned int *bufferSize,
643                                 RtAudio::StreamOptions *options );
644
645   //! A protected function used to increment the stream time.
646   void tickStreamTime( void );
647
648   //! Protected common method to clear an RtApiStream structure.
649   void clearStreamInfo();
650
651   /*!
652     Protected common method that throws an RtError (type =
653     INVALID_USE) if a stream is not open.
654   */
655   void verifyStream( void );
656
657   //! Protected common error method to allow global control over error handling.
658   void error( RtError::Type type );
659
660   /*!
661     Protected method used to perform format, channel number, and/or interleaving
662     conversions between the user and device buffers.
663   */
664   void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
665
666   //! Protected common method used to perform byte-swapping on buffers.
667   void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
668
669   //! Protected common method that returns the number of bytes for a given format.
670   unsigned int formatBytes( RtAudioFormat format );
671
672   //! Protected common method that sets up the parameters for buffer conversion.
673   void setConvertInfo( StreamMode mode, unsigned int firstChannel );
674 };
675
676 // **************************************************************** //
677 //
678 // Inline RtAudio definitions.
679 //
680 // **************************************************************** //
681
682 inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
683 inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); }
684 inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); }
685 inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); }
686 inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); }
687 inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); }
688 inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
689 inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
690 inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
691 inline bool RtAudio :: isStreamOpen( void ) throw() { return rtapi_->isStreamOpen(); }
692 inline bool RtAudio :: isStreamRunning( void ) throw() { return rtapi_->isStreamRunning(); }
693 inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
694 inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
695 inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); }
696
697 // RtApi Subclass prototypes.
698
699 #if defined(__MACOSX_CORE__)
700
701 #include <CoreAudio/AudioHardware.h>
702
703 class RtApiCore: public RtApi
704 {
705 public:
706
707   RtApiCore();
708   ~RtApiCore();
709   RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; };
710   unsigned int getDeviceCount( void );
711   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
712   unsigned int getDefaultOutputDevice( void );
713   unsigned int getDefaultInputDevice( void );
714   void closeStream( void );
715   void startStream( void );
716   void stopStream( void );
717   void abortStream( void );
718   long getStreamLatency( void );
719
720   // This function is intended for internal use only.  It must be
721   // public because it is called by the internal callback handler,
722   // which is not a member of RtAudio.  External use of this function
723   // will most likely produce highly undesireable results!
724   bool callbackEvent( AudioDeviceID deviceId,
725                       const AudioBufferList *inBufferList,
726                       const AudioBufferList *outBufferList );
727
728   private:
729
730   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
731                         unsigned int firstChannel, unsigned int sampleRate,
732                         RtAudioFormat format, unsigned int *bufferSize,
733                         RtAudio::StreamOptions *options );
734   static const char* getErrorCode( OSStatus code );
735 };
736
737 #endif
738
739 #if defined(__UNIX_JACK__)
740
741 class RtApiJack: public RtApi
742 {
743 public:
744
745   RtApiJack();
746   ~RtApiJack();
747   RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; };
748   unsigned int getDeviceCount( void );
749   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
750   void closeStream( void );
751   void startStream( void );
752   void stopStream( void );
753   void abortStream( void );
754   long getStreamLatency( void );
755
756   // This function is intended for internal use only.  It must be
757   // public because it is called by the internal callback handler,
758   // which is not a member of RtAudio.  External use of this function
759   // will most likely produce highly undesireable results!
760   bool callbackEvent( unsigned long nframes );
761
762   private:
763
764   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
765                         unsigned int firstChannel, unsigned int sampleRate,
766                         RtAudioFormat format, unsigned int *bufferSize,
767                         RtAudio::StreamOptions *options );
768 };
769
770 #endif
771
772 #if defined(__WINDOWS_ASIO__)
773
774 class RtApiAsio: public RtApi
775 {
776 public:
777
778   RtApiAsio();
779   ~RtApiAsio();
780   RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; };
781   unsigned int getDeviceCount( void );
782   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
783   void closeStream( void );
784   void startStream( void );
785   void stopStream( void );
786   void abortStream( void );
787   long getStreamLatency( void );
788
789   // This function is intended for internal use only.  It must be
790   // public because it is called by the internal callback handler,
791   // which is not a member of RtAudio.  External use of this function
792   // will most likely produce highly undesireable results!
793   bool callbackEvent( long bufferIndex );
794
795   private:
796
797   bool coInitialized_;
798   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
799                         unsigned int firstChannel, unsigned int sampleRate,
800                         RtAudioFormat format, unsigned int *bufferSize,
801                         RtAudio::StreamOptions *options );
802 };
803
804 #endif
805
806 #if defined(__WINDOWS_DS__)
807
808 class RtApiDs: public RtApi
809 {
810 public:
811
812   RtApiDs();
813   ~RtApiDs();
814   RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; };
815   unsigned int getDeviceCount( void );
816   unsigned int getDefaultOutputDevice( void );
817   unsigned int getDefaultInputDevice( void );
818   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
819   void closeStream( void );
820   void startStream( void );
821   void stopStream( void );
822   void abortStream( void );
823   long getStreamLatency( void );
824
825   // This function is intended for internal use only.  It must be
826   // public because it is called by the internal callback handler,
827   // which is not a member of RtAudio.  External use of this function
828   // will most likely produce highly undesireable results!
829   void callbackEvent( void );
830
831   private:
832
833   bool coInitialized_;
834   bool buffersRolling;
835   long duplexPrerollBytes;
836   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
837                         unsigned int firstChannel, unsigned int sampleRate,
838                         RtAudioFormat format, unsigned int *bufferSize,
839                         RtAudio::StreamOptions *options );
840 };
841
842 #endif
843
844 #if defined(__LINUX_ALSA__)
845
846 class RtApiAlsa: public RtApi
847 {
848 public:
849
850   RtApiAlsa();
851   ~RtApiAlsa();
852   RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; };
853   unsigned int getDeviceCount( void );
854   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
855   void closeStream( void );
856   void startStream( void );
857   void stopStream( void );
858   void abortStream( void );
859
860   // This function is intended for internal use only.  It must be
861   // public because it is called by the internal callback handler,
862   // which is not a member of RtAudio.  External use of this function
863   // will most likely produce highly undesireable results!
864   void callbackEvent( void );
865
866   private:
867
868   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
869                         unsigned int firstChannel, unsigned int sampleRate,
870                         RtAudioFormat format, unsigned int *bufferSize,
871                         RtAudio::StreamOptions *options );
872 };
873
874 #endif
875
876 #if defined(__LINUX_OSS__)
877
878 class RtApiOss: public RtApi
879 {
880 public:
881
882   RtApiOss();
883   ~RtApiOss();
884   RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; };
885   unsigned int getDeviceCount( void );
886   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
887   void closeStream( void );
888   void startStream( void );
889   void stopStream( void );
890   void abortStream( void );
891
892   // This function is intended for internal use only.  It must be
893   // public because it is called by the internal callback handler,
894   // which is not a member of RtAudio.  External use of this function
895   // will most likely produce highly undesireable results!
896   void callbackEvent( void );
897
898   private:
899
900   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
901                         unsigned int firstChannel, unsigned int sampleRate,
902                         RtAudioFormat format, unsigned int *bufferSize,
903                         RtAudio::StreamOptions *options );
904 };
905
906 #endif
907
908 #if defined(__RTAUDIO_DUMMY__)
909
910 class RtApiDummy: public RtApi
911 {
912 public:
913
914   RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtError::WARNING ); };
915   RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; };
916   unsigned int getDeviceCount( void ) { return 0; };
917   RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) { RtAudio::DeviceInfo info; return info; };
918   void closeStream( void ) {};
919   void startStream( void ) {};
920   void stopStream( void ) {};
921   void abortStream( void ) {};
922
923   private:
924
925   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
926                         unsigned int firstChannel, unsigned int sampleRate,
927                         RtAudioFormat format, unsigned int *bufferSize,
928                         RtAudio::StreamOptions *options ) { return false; };
929 };
930
931 #endif
932
933 #endif
934
935 // Indentation settings for Vim and Emacs
936 //
937 // Local Variables:
938 // c-basic-offset: 2
939 // indent-tabs-mode: nil
940 // End:
941 //
942 // vim: et sts=2 sw=2