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