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