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