Check in of new version 4.0.0 distribution (GS).
[rtaudio.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 ErrorType {
568     WARNING,
569     INVALID_CALL,
570     SYSTEM
571   };
572
573   enum StreamState {
574     STREAM_STOPPED,
575     STREAM_RUNNING,
576     STREAM_CLOSED = -50
577   };
578
579   enum StreamMode {
580     OUTPUT,
581     INPUT,
582     DUPLEX,
583     UNINITIALIZED = -75
584   };
585
586   // A protected structure used for buffer conversion.
587   struct ConvertInfo {
588     int channels;
589     int inJump, outJump;
590     RtAudioFormat inFormat, outFormat;
591     std::vector<int> inOffset;
592     std::vector<int> outOffset;
593   };
594
595   // A protected structure for audio streams.
596   struct RtApiStream {
597     unsigned int device[2];    // Playback and record, respectively.
598     void *apiHandle;           // void pointer for API specific stream handle information
599     StreamMode mode;           // OUTPUT, INPUT, or DUPLEX.
600     StreamState state;         // STOPPED, RUNNING, or CLOSED
601     char *userBuffer[2];       // Playback and record, respectively.
602     char *deviceBuffer;
603     bool doConvertBuffer[2];   // Playback and record, respectively.
604     bool userInterleaved;
605     bool deviceInterleaved[2]; // Playback and record, respectively.
606     bool doByteSwap[2];        // Playback and record, respectively.
607     unsigned int sampleRate;
608     unsigned int bufferSize;
609     unsigned int nBuffers;
610     unsigned int nUserChannels[2];    // Playback and record, respectively.
611     unsigned int nDeviceChannels[2];  // Playback and record channels, respectively.
612     unsigned int channelOffset[2];    // Playback and record, respectively.
613     unsigned long latency[2];         // Playback and record, respectively.
614     RtAudioFormat userFormat;
615     RtAudioFormat deviceFormat[2];    // Playback and record, respectively.
616     StreamMutex mutex;
617     CallbackInfo callbackInfo;
618     ConvertInfo convertInfo[2];
619     double streamTime;         // Number of elapsed seconds since the stream started.
620
621 #if defined(HAVE_GETTIMEOFDAY)
622     struct timeval lastTickTimestamp;
623 #endif
624
625     RtApiStream()
626       :apiHandle(0), deviceBuffer(0) {}
627   };
628
629   typedef signed short Int16;
630   typedef signed int Int32;
631   typedef float Float32;
632   typedef double Float64;
633
634   std::ostringstream errorStream_;
635   std::string errorText_;
636   bool showWarnings_;
637   RtApiStream stream_;
638
639   /*!
640     Protected, api-specific method that attempts to open a device
641     with the given parameters.  This function MUST be implemented by
642     all subclasses.  If an error is encountered during the probe, a
643     "warning" message is reported and FAILURE is returned. A
644     successful probe is indicated by a return value of SUCCESS.
645   */
646   virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
647                                 unsigned int firstChannel, unsigned int sampleRate,
648                                 RtAudioFormat format, unsigned int *bufferSize,
649                                 RtAudio::StreamOptions *options );
650
651   //! A protected function used to increment the stream time.
652   void tickStreamTime( void );
653
654   //! Protected common method to clear an RtApiStream structure.
655   void clearStreamInfo();
656
657   /*!
658     Protected common method that throws an RtError (type =
659     INVALID_USE) if a stream is not open.
660   */
661   void verifyStream( void );
662
663   //! Protected common error method to allow global control over error handling.
664   void error( ErrorType type );
665
666   /*!
667     Protected method used to perform format, channel number, and/or interleaving
668     conversions between the user and device buffers.
669   */
670   void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
671
672   //! Protected common method used to perform byte-swapping on buffers.
673   void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
674
675   //! Protected common method that returns the number of bytes for a given format.
676   unsigned int formatBytes( RtAudioFormat format );
677
678   //! Protected common method that sets up the parameters for buffer conversion.
679   void setConvertInfo( StreamMode mode, unsigned int firstChannel );
680 };
681
682 // **************************************************************** //
683 //
684 // Inline RtAudio definitions.
685 //
686 // **************************************************************** //
687
688 inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); };
689 inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); };
690 inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); };
691 inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); };
692 inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); };
693 inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); };
694 inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); };
695 inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); };
696 inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); };
697 inline bool RtAudio :: isStreamOpen( void ) throw() { return rtapi_->isStreamOpen(); };
698 inline bool RtAudio :: isStreamRunning( void ) throw() { return rtapi_->isStreamRunning(); };
699 inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); };
700 inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); };
701 inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); };
702
703 // RtApi Subclass prototypes.
704
705 #if defined(__MACOSX_CORE__)
706
707 #include <CoreAudio/AudioHardware.h>
708
709 class RtApiCore: public RtApi
710 {
711 public:
712
713   RtApiCore();
714   ~RtApiCore();
715   RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; };
716   unsigned int getDeviceCount( void );
717   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
718   unsigned int getDefaultOutputDevice( void );
719   unsigned int getDefaultInputDevice( void );
720   void closeStream( void );
721   void startStream( void );
722   void stopStream( void );
723   void abortStream( void );
724   long getStreamLatency( void );
725
726   // This function is intended for internal use only.  It must be
727   // public because it is called by the internal callback handler,
728   // which is not a member of RtAudio.  External use of this function
729   // will most likely produce highly undesireable results!
730   bool callbackEvent( AudioDeviceID deviceId,
731                       const AudioBufferList *inBufferList,
732                       const AudioBufferList *outBufferList );
733
734   private:
735
736   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
737                         unsigned int firstChannel, unsigned int sampleRate,
738                         RtAudioFormat format, unsigned int *bufferSize,
739                         RtAudio::StreamOptions *options );
740   static const char* getErrorCode( OSStatus code );
741 };
742
743 #endif
744
745 #if defined(__UNIX_JACK__)
746
747 class RtApiJack: public RtApi
748 {
749 public:
750
751   RtApiJack();
752   ~RtApiJack();
753   RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; };
754   unsigned int getDeviceCount( void );
755   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
756   void closeStream( void );
757   void startStream( void );
758   void stopStream( void );
759   void abortStream( void );
760   long getStreamLatency( void );
761
762   // This function is intended for internal use only.  It must be
763   // public because it is called by the internal callback handler,
764   // which is not a member of RtAudio.  External use of this function
765   // will most likely produce highly undesireable results!
766   bool callbackEvent( unsigned long nframes );
767
768   private:
769
770   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
771                         unsigned int firstChannel, unsigned int sampleRate,
772                         RtAudioFormat format, unsigned int *bufferSize,
773                         RtAudio::StreamOptions *options );
774 };
775
776 #endif
777
778 #if defined(__WINDOWS_ASIO__)
779
780 class RtApiAsio: public RtApi
781 {
782 public:
783
784   RtApiAsio();
785   ~RtApiAsio();
786   RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; };
787   unsigned int getDeviceCount( void );
788   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
789   void closeStream( void );
790   void startStream( void );
791   void stopStream( void );
792   void abortStream( void );
793   long getStreamLatency( void );
794
795   // This function is intended for internal use only.  It must be
796   // public because it is called by the internal callback handler,
797   // which is not a member of RtAudio.  External use of this function
798   // will most likely produce highly undesireable results!
799   bool callbackEvent( long bufferIndex );
800
801   private:
802
803   bool coInitialized_;
804   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
805                         unsigned int firstChannel, unsigned int sampleRate,
806                         RtAudioFormat format, unsigned int *bufferSize,
807                         RtAudio::StreamOptions *options );
808 };
809
810 #endif
811
812 #if defined(__WINDOWS_DS__)
813
814 class RtApiDs: public RtApi
815 {
816 public:
817
818   RtApiDs();
819   ~RtApiDs();
820   RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; };
821   unsigned int getDeviceCount( void );
822   unsigned int getDefaultOutputDevice( void );
823   unsigned int getDefaultInputDevice( void );
824   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
825   void closeStream( void );
826   void startStream( void );
827   void stopStream( void );
828   void abortStream( void );
829   long getStreamLatency( void );
830
831   // This function is intended for internal use only.  It must be
832   // public because it is called by the internal callback handler,
833   // which is not a member of RtAudio.  External use of this function
834   // will most likely produce highly undesireable results!
835   void callbackEvent( void );
836
837   private:
838
839   bool coInitialized_;
840   bool buffersRolling;
841   long duplexPrerollBytes;
842   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
843                         unsigned int firstChannel, unsigned int sampleRate,
844                         RtAudioFormat format, unsigned int *bufferSize,
845                         RtAudio::StreamOptions *options );
846 };
847
848 #endif
849
850 #if defined(__LINUX_ALSA__)
851
852 class RtApiAlsa: public RtApi
853 {
854 public:
855
856   RtApiAlsa();
857   ~RtApiAlsa();
858   RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; };
859   unsigned int getDeviceCount( void );
860   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
861   void closeStream( void );
862   void startStream( void );
863   void stopStream( void );
864   void abortStream( void );
865
866   // This function is intended for internal use only.  It must be
867   // public because it is called by the internal callback handler,
868   // which is not a member of RtAudio.  External use of this function
869   // will most likely produce highly undesireable results!
870   void callbackEvent( void );
871
872   private:
873
874   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
875                         unsigned int firstChannel, unsigned int sampleRate,
876                         RtAudioFormat format, unsigned int *bufferSize,
877                         RtAudio::StreamOptions *options );
878 };
879
880 #endif
881
882 #if defined(__LINUX_OSS__)
883
884 class RtApiOss: public RtApi
885 {
886 public:
887
888   RtApiOss();
889   ~RtApiOss();
890   RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; };
891   unsigned int getDeviceCount( void );
892   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
893   void closeStream( void );
894   void startStream( void );
895   void stopStream( void );
896   void abortStream( void );
897
898   // This function is intended for internal use only.  It must be
899   // public because it is called by the internal callback handler,
900   // which is not a member of RtAudio.  External use of this function
901   // will most likely produce highly undesireable results!
902   void callbackEvent( void );
903
904   private:
905
906   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
907                         unsigned int firstChannel, unsigned int sampleRate,
908                         RtAudioFormat format, unsigned int *bufferSize,
909                         RtAudio::StreamOptions *options );
910 };
911
912 #endif
913
914 #if defined(__RTAUDIO_DUMMY__)
915
916 class RtApiDummy: public RtApi
917 {
918 public:
919
920   RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( WARNING ); };
921   RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; };
922   unsigned int getDeviceCount( void ) { return 0; };
923   RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) { RtAudio::DeviceInfo info; return info; };
924   void closeStream( void ) {};
925   void startStream( void ) {};
926   void stopStream( void ) {};
927   void abortStream( void ) {};
928
929   private:
930
931   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
932                         unsigned int firstChannel, unsigned int sampleRate,
933                         RtAudioFormat format, unsigned int *bufferSize,
934                         RtAudio::StreamOptions *options ) { return false; };
935 };
936
937 #endif
938
939 #endif
940
941 // Indentation settings for Vim and Emacs
942 //
943 // Local Variables:
944 // c-basic-offset: 2
945 // indent-tabs-mode: nil
946 // End:
947 //
948 // vim: et sts=2 sw=2