Version 3.0.2
[rtaudio-cdist.git] / RtAudio.h
1 /************************************************************************/
2 /*! \class RtAudio
3     \brief Realtime audio i/o C++ classes.
4
5     RtAudio provides a common API (Application Programming Interface)
6     for realtime audio input/output across Linux (native ALSA, Jack,
7     and OSS), SGI, Macintosh OS X (CoreAudio), and Windows
8     (DirectSound and ASIO) operating systems.
9
10     RtAudio WWW site: http://music.mcgill.ca/~gary/rtaudio/
11
12     RtAudio: realtime audio i/o C++ classes
13     Copyright (c) 2001-2005 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     requested to send the modifications to the original developer so that
28     they can be incorporated into the canonical version.
29
30     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
34     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
35     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 */
38 /************************************************************************/
39
40 // RtAudio: Version 3.0.2 (14 October 2005)
41
42 #ifndef __RTAUDIO_H
43 #define __RTAUDIO_H
44
45 #include "RtError.h"
46 #include <string>
47 #include <vector>
48
49 // Operating system dependent thread functionality.
50 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
51   #include <windows.h>
52   #include <process.h>
53
54   typedef unsigned long ThreadHandle;
55   typedef CRITICAL_SECTION StreamMutex;
56
57 #else // Various unix flavors with pthread support.
58   #include <pthread.h>
59
60   typedef pthread_t ThreadHandle;
61   typedef pthread_mutex_t StreamMutex;
62
63 #endif
64
65 // This global structure type is used to pass callback information
66 // between the private RtAudio stream structure and global callback
67 // handling functions.
68 struct CallbackInfo {
69   void *object;    // Used as a "this" pointer.
70   ThreadHandle thread;
71   bool usingCallback;
72   void *callback;
73   void *userData;
74   void *apiInfo;   // void pointer for API specific callback information
75
76   // Default constructor.
77   CallbackInfo()
78     :object(0), usingCallback(false), callback(0),
79      userData(0), apiInfo(0) {}
80 };
81
82 // Support for signed integers and floats.  Audio data fed to/from
83 // the tickStream() routine is assumed to ALWAYS be in host
84 // byte order.  The internal routines will automatically take care of
85 // any necessary byte-swapping between the host format and the
86 // soundcard.  Thus, endian-ness is not a concern in the following
87 // format definitions.
88 typedef unsigned long RtAudioFormat;
89 static const RtAudioFormat RTAUDIO_SINT8 = 0x1;    /*!< 8-bit signed integer. */
90 static const RtAudioFormat RTAUDIO_SINT16 = 0x2;   /*!< 16-bit signed integer. */
91 static const RtAudioFormat RTAUDIO_SINT24 = 0x4;   /*!< Upper 3 bytes of 32-bit signed integer. */
92 static const RtAudioFormat RTAUDIO_SINT32 = 0x8;   /*!< 32-bit signed integer. */
93 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; /*!< Normalized between plus/minus 1.0. */
94 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; /*!< Normalized between plus/minus 1.0. */
95
96 typedef int (*RtAudioCallback)(char *buffer, int bufferSize, void *userData);
97
98 //! The public device information structure for returning queried values.
99 struct RtAudioDeviceInfo {
100   std::string name;      /*!< Character string device identifier. */
101   bool probed;          /*!< true if the device capabilities were successfully probed. */
102   int outputChannels;   /*!< Maximum output channels supported by device. */
103   int inputChannels;    /*!< Maximum input channels supported by device. */
104   int duplexChannels;   /*!< Maximum simultaneous input/output channels supported by device. */
105   bool isDefault;       /*!< true if this is the default output or input device. */
106   std::vector<int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
107   RtAudioFormat nativeFormats;  /*!< Bit mask of supported data formats. */
108
109   // Default constructor.
110   RtAudioDeviceInfo()
111     :probed(false), outputChannels(0), inputChannels(0),
112        duplexChannels(0), isDefault(false), nativeFormats(0) {}
113 };
114
115 // **************************************************************** //
116 //
117 // RtApi class declaration.
118 //
119 // Note that RtApi is an abstract base class and cannot be
120 // explicitly instantiated.  The class RtAudio will create an
121 // instance of an RtApi subclass (RtApiOss, RtApiAlsa,
122 // RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio).
123 //
124 // **************************************************************** //
125
126 class RtApi
127 {
128 public:
129
130   enum StreamState {
131     STREAM_STOPPED,
132     STREAM_RUNNING
133   };
134
135   RtApi();
136   virtual ~RtApi();
137   void openStream( int outputDevice, int outputChannels,
138                    int inputDevice, int inputChannels,
139                    RtAudioFormat format, int sampleRate,
140                    int *bufferSize, int numberOfBuffers );
141   void openStream( int outputDevice, int outputChannels,
142                    int inputDevice, int inputChannels,
143                    RtAudioFormat format, int sampleRate,
144                    int *bufferSize, int *numberOfBuffers );
145   virtual void setStreamCallback( RtAudioCallback callback, void *userData ) = 0;
146   virtual void cancelStreamCallback() = 0;
147   int getDeviceCount(void);
148   RtAudioDeviceInfo getDeviceInfo( int device );
149   char * const getStreamBuffer();
150   RtApi::StreamState getStreamState() const;
151   virtual void tickStream() = 0;
152   virtual void closeStream();
153   virtual void startStream() = 0;
154   virtual void stopStream() = 0;
155   virtual void abortStream() = 0;
156
157 protected:
158
159   static const unsigned int MAX_SAMPLE_RATES;
160   static const unsigned int SAMPLE_RATES[];
161
162   enum { FAILURE, SUCCESS };
163
164   enum StreamMode {
165     OUTPUT,
166     INPUT,
167     DUPLEX,
168     UNINITIALIZED = -75
169   };
170
171   // A protected structure used for buffer conversion.
172   struct ConvertInfo {
173     int channels;
174     int inJump, outJump;
175     RtAudioFormat inFormat, outFormat;
176     std::vector<int> inOffset;
177     std::vector<int> outOffset;
178   };
179
180   // A protected structure for audio streams.
181   struct RtApiStream {
182     int device[2];          // Playback and record, respectively.
183     void *apiHandle;        // void pointer for API specific stream handle information
184     StreamMode mode;         // OUTPUT, INPUT, or DUPLEX.
185     StreamState state;       // STOPPED or RUNNING
186     char *userBuffer;
187     char *deviceBuffer;
188     bool doConvertBuffer[2]; // Playback and record, respectively.
189     bool deInterleave[2];    // Playback and record, respectively.
190     bool doByteSwap[2];      // Playback and record, respectively.
191     int sampleRate;
192     int bufferSize;
193     int nBuffers;
194     int nUserChannels[2];    // Playback and record, respectively.
195     int nDeviceChannels[2];  // Playback and record channels, respectively.
196     RtAudioFormat userFormat;
197     RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
198     StreamMutex mutex;
199     CallbackInfo callbackInfo;
200     ConvertInfo convertInfo[2];
201
202     RtApiStream()
203       :apiHandle(0), userBuffer(0), deviceBuffer(0) {}
204   };
205
206   // A protected device structure for audio devices.
207   struct RtApiDevice {
208     std::string name;      /*!< Character string device identifier. */
209     bool probed;           /*!< true if the device capabilities were successfully probed. */
210     void *apiDeviceId;     // void pointer for API specific device information
211     int maxOutputChannels; /*!< Maximum output channels supported by device. */
212     int maxInputChannels;  /*!< Maximum input channels supported by device. */
213     int maxDuplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
214     int minOutputChannels; /*!< Minimum output channels supported by device. */
215     int minInputChannels;  /*!< Minimum input channels supported by device. */
216     int minDuplexChannels; /*!< Minimum simultaneous input/output channels supported by device. */
217     bool hasDuplexSupport; /*!< true if device supports duplex mode. */
218     bool isDefault;        /*!< true if this is the default output or input device. */
219     std::vector<int> sampleRates; /*!< Supported sample rates. */
220     RtAudioFormat nativeFormats;  /*!< Bit mask of supported data formats. */
221
222     // Default constructor.
223     RtApiDevice()
224       :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
225        maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
226        minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
227   };
228
229   typedef signed short Int16;
230   typedef signed int Int32;
231   typedef float Float32;
232   typedef double Float64;
233
234   char message_[1024];
235   int nDevices_;
236   std::vector<RtApiDevice> devices_;
237   RtApiStream stream_;
238
239   /*!
240     Protected, api-specific method to count and identify the system
241     audio devices.  This function MUST be implemented by all subclasses.
242   */
243   virtual void initialize(void) = 0;
244
245   /*!
246     Protected, api-specific method which attempts to fill an
247     RtAudioDevice structure for a given device.  This function MUST be
248     implemented by all subclasses.  If an error is encountered during
249     the probe, a "warning" message is reported and the value of
250     "probed" remains false (no exception is thrown).  A successful
251     probe is indicated by probed = true.
252   */
253   virtual void probeDeviceInfo( RtApiDevice *info );
254
255   /*!
256     Protected, api-specific method which attempts to open a device
257     with the given parameters.  This function MUST be implemented by
258     all subclasses.  If an error is encountered during the probe, a
259     "warning" message is reported and FAILURE is returned (no
260     exception is thrown). A successful probe is indicated by a return
261     value of SUCCESS.
262   */
263   virtual bool probeDeviceOpen( int device, StreamMode mode, int channels, 
264                                 int sampleRate, RtAudioFormat format,
265                                 int *bufferSize, int numberOfBuffers );
266
267   /*!
268     Protected method which returns the index in the devices array to
269     the default input device.
270   */
271   virtual int getDefaultInputDevice(void);
272
273   /*!
274     Protected method which returns the index in the devices array to
275     the default output device.
276   */
277   virtual int getDefaultOutputDevice(void);
278
279   //! Protected common method to clear an RtApiDevice structure.
280   void clearDeviceInfo( RtApiDevice *info );
281
282   //! Protected common method to clear an RtApiStream structure.
283   void clearStreamInfo();
284
285   //! Protected common error method to allow global control over error handling.
286   void error( RtError::Type type );
287
288   /*!
289     Protected common method used to check whether a stream is open.
290     If not, an "invalid identifier" exception is thrown.
291   */
292   void verifyStream();
293
294   /*!
295     Protected method used to perform format, channel number, and/or interleaving
296     conversions between the user and device buffers.
297   */
298   void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
299
300   //! Protected common method used to perform byte-swapping on buffers.
301   void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format );
302
303   //! Protected common method which returns the number of bytes for a given format.
304   int formatBytes( RtAudioFormat format );
305 };
306
307
308 // **************************************************************** //
309 //
310 // RtAudio class declaration.
311 //
312 // RtAudio is a "controller" used to select an available audio i/o
313 // interface.  It presents a common API for the user to call but all
314 // functionality is implemented by the class RtAudioApi and its
315 // subclasses.  RtAudio creates an instance of an RtAudioApi subclass
316 // based on the user's API choice.  If no choice is made, RtAudio
317 // attempts to make a "logical" API selection.
318 //
319 // **************************************************************** //
320
321 class RtAudio
322 {
323 public:
324
325   //! Audio API specifier arguments.
326   enum RtAudioApi {
327     UNSPECIFIED,    /*!< Search for a working compiled API. */
328     LINUX_ALSA,     /*!< The Advanced Linux Sound Architecture API. */
329     LINUX_OSS,      /*!< The Linux Open Sound System API. */
330     LINUX_JACK,     /*!< The Linux Jack Low-Latency Audio Server API. */
331     MACOSX_CORE,    /*!< Macintosh OS-X Core Audio API. */
332     IRIX_AL,        /*!< The Irix Audio Library API. */
333     WINDOWS_ASIO,   /*!< The Steinberg Audio Stream I/O API. */
334     WINDOWS_DS      /*!< The Microsoft Direct Sound API. */
335   };
336
337   //! The default class constructor.
338   /*!
339     Probes the system to make sure at least one audio input/output
340     device is available and determines the api-specific identifier for
341     each device found.  An RtError error can be thrown if no devices
342     are found or if a memory allocation error occurs.
343
344     If no API argument is specified and multiple API support has been
345     compiled, the default order of use is JACK, ALSA, OSS (Linux
346     systems) and ASIO, DS (Windows systems).
347   */
348   RtAudio( RtAudioApi api=UNSPECIFIED );
349
350   //! A constructor which can be used to open a stream during instantiation.
351   /*!
352     The specified output and/or input device identifiers correspond
353     to those enumerated via the getDeviceInfo() method.  If device =
354     0, the default or first available devices meeting the given
355     parameters is selected.  If an output or input channel value is
356     zero, the corresponding device value is ignored.  When a stream is
357     successfully opened, its identifier is returned via the "streamId"
358     pointer.  An RtError can be thrown if no devices are found
359     for the given parameters, if a memory allocation error occurs, or
360     if a driver error occurs. \sa openStream()
361   */
362   RtAudio( int outputDevice, int outputChannels,
363            int inputDevice, int inputChannels,
364            RtAudioFormat format, int sampleRate,
365            int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED );
366
367   //! An overloaded constructor which opens a stream and also returns \c numberOfBuffers parameter via pointer argument.
368   /*!
369     See the previous constructor call for details.  This overloaded
370     version differs only in that it takes a pointer argument for the
371     \c numberOfBuffers parameter and returns the value used by the
372     audio device (which may be different from that requested).  Note
373     that the \c numberofBuffers parameter is not used with the Linux
374     Jack, Macintosh CoreAudio, and Windows ASIO APIs.
375   */
376   RtAudio( int outputDevice, int outputChannels,
377            int inputDevice, int inputChannels,
378            RtAudioFormat format, int sampleRate,
379            int *bufferSize, int *numberOfBuffers, RtAudioApi api=UNSPECIFIED );
380
381   //! The destructor.
382   /*!
383     Stops and closes an open stream and devices and deallocates
384     buffer and structure memory.
385   */
386   ~RtAudio();
387
388   //! A public method for opening a stream with the specified parameters.
389   /*!
390     An RtError is thrown if a stream cannot be opened.
391
392     \param outputDevice: If equal to 0, the default or first device
393            found meeting the given parameters is opened.  Otherwise, the
394            device number should correspond to one of those enumerated via
395            the getDeviceInfo() method.
396     \param outputChannels: The desired number of output channels.  If
397            equal to zero, the outputDevice identifier is ignored.
398     \param inputDevice: If equal to 0, the default or first device
399            found meeting the given parameters is opened.  Otherwise, the
400            device number should correspond to one of those enumerated via
401            the getDeviceInfo() method.
402     \param inputChannels: The desired number of input channels.  If
403            equal to zero, the inputDevice identifier is ignored.
404     \param format: An RtAudioFormat specifying the desired sample data format.
405     \param sampleRate: The desired sample rate (sample frames per second).
406     \param *bufferSize: A pointer value indicating the desired internal buffer
407            size in sample frames.  The actual value used by the device is
408            returned via the same pointer.  A value of zero can be specified,
409            in which case the lowest allowable value is determined.
410     \param numberOfBuffers: A value which can be used to help control device
411            latency.  More buffers typically result in more robust performance,
412            though at a cost of greater latency.  A value of zero can be
413            specified, in which case the lowest allowable value is used.
414   */
415   void openStream( int outputDevice, int outputChannels,
416                    int inputDevice, int inputChannels,
417                    RtAudioFormat format, int sampleRate,
418                    int *bufferSize, int numberOfBuffers );
419
420   //! A public method for opening a stream and also returning \c numberOfBuffers parameter via pointer argument.
421   /*!
422     See the previous function call for details.  This overloaded
423     version differs only in that it takes a pointer argument for the
424     \c numberOfBuffers parameter and returns the value used by the
425     audio device (which may be different from that requested).  Note
426     that the \c numberofBuffers parameter is not used with the Linux
427     Jack, Macintosh CoreAudio, and Windows ASIO APIs.
428   */
429   void openStream( int outputDevice, int outputChannels,
430                    int inputDevice, int inputChannels,
431                    RtAudioFormat format, int sampleRate,
432                    int *bufferSize, int *numberOfBuffers );
433
434   //! A public method which sets a user-defined callback function for a given stream.
435   /*!
436     This method assigns a callback function to a previously opened
437     stream for non-blocking stream functionality.  A separate process
438     is initiated, though the user function is called only when the
439     stream is "running" (between calls to the startStream() and
440     stopStream() methods, respectively).  The callback process remains
441     active for the duration of the stream and is automatically
442     shutdown when the stream is closed (via the closeStream() method
443     or by object destruction).  The callback process can also be
444     shutdown and the user function de-referenced through an explicit
445     call to the cancelStreamCallback() method.  Note that the stream
446     can use only blocking or callback functionality at a particular
447     time, though it is possible to alternate modes on the same stream
448     through the use of the setStreamCallback() and
449     cancelStreamCallback() methods (the blocking tickStream() method
450     can be used before a callback is set and/or after a callback is
451     cancelled).  An RtError will be thrown if called when no stream is
452     open or a thread errors occurs.
453   */
454   void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); };
455
456   //! A public method which cancels a callback process and function for the stream.
457   /*!
458     This method shuts down a callback process and de-references the
459     user function for the stream.  Callback functionality can
460     subsequently be restarted on the stream via the
461     setStreamCallback() method.  An RtError will be thrown if called
462     when no stream is open.
463    */
464   void cancelStreamCallback() { rtapi_->cancelStreamCallback(); };
465
466   //! A public method which returns the number of audio devices found.
467   int getDeviceCount(void) { return rtapi_->getDeviceCount(); };
468
469   //! Return an RtAudioDeviceInfo structure for a specified device number.
470   /*!
471     Any device integer between 1 and getDeviceCount() is valid.  If
472     a device is busy or otherwise unavailable, the structure member
473     "probed" will have a value of "false" and all other members are
474     undefined.  If the specified device is the current default input
475     or output device, the "isDefault" member will have a value of
476     "true".  An RtError will be thrown for an invalid device argument.
477   */
478   RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); };
479
480   //! A public method which returns a pointer to the buffer for an open stream.
481   /*!
482     The user should fill and/or read the buffer data in interleaved format
483     and then call the tickStream() method.  An RtError will be
484     thrown if called when no stream is open.
485   */
486   char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); };
487
488   //! Public method used to trigger processing of input/output data for a stream.
489   /*!
490     This method blocks until all buffer data is read/written.  An
491     RtError will be thrown if a driver error occurs or if called when
492     no stream is open.
493   */
494   void tickStream() { rtapi_->tickStream(); };
495
496   //! Public method which closes a stream and frees any associated buffers.
497   /*!
498     If a stream is not open, this method issues a warning and
499     returns (an RtError is not thrown).
500   */
501   void closeStream()  { rtapi_->closeStream(); };
502
503   //! Public method which starts a stream.
504   /*!
505     An RtError will be thrown if a driver error occurs or if called
506     when no stream is open.
507   */
508   void startStream() { rtapi_->startStream(); };
509
510   //! Stop a stream, allowing any samples remaining in the queue to be played out and/or read in.
511   /*!
512     An RtError will be thrown if a driver error occurs or if called
513     when no stream is open.
514   */
515   void stopStream() { rtapi_->stopStream(); };
516
517   //! Stop a stream, discarding any samples remaining in the input/output queue.
518   /*!
519     An RtError will be thrown if a driver error occurs or if called
520     when no stream is open.
521   */
522   void abortStream() { rtapi_->abortStream(); };
523
524
525  protected:
526
527   void initialize( RtAudioApi api );
528
529   RtApi *rtapi_;
530 };
531
532
533 // RtApi Subclass prototypes.
534
535 #if defined(__LINUX_ALSA__)
536
537 class RtApiAlsa: public RtApi
538 {
539 public:
540
541   RtApiAlsa();
542   ~RtApiAlsa();
543   void tickStream();
544   void closeStream();
545   void startStream();
546   void stopStream();
547   void abortStream();
548   int streamWillBlock();
549   void setStreamCallback( RtAudioCallback callback, void *userData );
550   void cancelStreamCallback();
551
552   private:
553
554   void initialize(void);
555   void probeDeviceInfo( RtApiDevice *info );
556   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
557                         int sampleRate, RtAudioFormat format,
558                         int *bufferSize, int numberOfBuffers );
559 };
560
561 #endif
562
563 #if defined(__LINUX_JACK__)
564
565 class RtApiJack: public RtApi
566 {
567 public:
568
569   RtApiJack();
570   ~RtApiJack();
571   void tickStream();
572   void closeStream();
573   void startStream();
574   void stopStream();
575   void abortStream();
576   void setStreamCallback( RtAudioCallback callback, void *userData );
577   void cancelStreamCallback();
578   // This function is intended for internal use only.  It must be
579   // public because it is called by the internal callback handler,
580   // which is not a member of RtAudio.  External use of this function
581   // will most likely produce highly undesireable results!
582   void callbackEvent( unsigned long nframes );
583
584   private:
585
586   void initialize(void);
587   void probeDeviceInfo( RtApiDevice *info );
588   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
589                         int sampleRate, RtAudioFormat format,
590                         int *bufferSize, int numberOfBuffers );
591 };
592
593 #endif
594
595 #if defined(__LINUX_OSS__)
596
597 class RtApiOss: public RtApi
598 {
599 public:
600
601   RtApiOss();
602   ~RtApiOss();
603   void tickStream();
604   void closeStream();
605   void startStream();
606   void stopStream();
607   void abortStream();
608   int streamWillBlock();
609   void setStreamCallback( RtAudioCallback callback, void *userData );
610   void cancelStreamCallback();
611
612   private:
613
614   void initialize(void);
615   void probeDeviceInfo( RtApiDevice *info );
616   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
617                         int sampleRate, RtAudioFormat format,
618                         int *bufferSize, int numberOfBuffers );
619 };
620
621 #endif
622
623 #if defined(__MACOSX_CORE__)
624
625 #include <CoreAudio/AudioHardware.h>
626
627 class RtApiCore: public RtApi
628 {
629 public:
630
631   RtApiCore();
632   ~RtApiCore();
633   int getDefaultOutputDevice(void);
634   int getDefaultInputDevice(void);
635   void tickStream();
636   void closeStream();
637   void startStream();
638   void stopStream();
639   void abortStream();
640   void setStreamCallback( RtAudioCallback callback, void *userData );
641   void cancelStreamCallback();
642
643   // This function is intended for internal use only.  It must be
644   // public because it is called by the internal callback handler,
645   // which is not a member of RtAudio.  External use of this function
646   // will most likely produce highly undesireable results!
647   void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData );
648
649   private:
650
651   void initialize(void);
652   void probeDeviceInfo( RtApiDevice *info );
653   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
654                         int sampleRate, RtAudioFormat format,
655                         int *bufferSize, int numberOfBuffers );
656 };
657
658 #endif
659
660 #if defined(__WINDOWS_DS__)
661
662 class RtApiDs: public RtApi
663 {
664 public:
665
666   RtApiDs();
667   ~RtApiDs();
668   int getDefaultOutputDevice(void);
669   int getDefaultInputDevice(void);
670   void tickStream();
671   void closeStream();
672   void startStream();
673   void stopStream();
674   void abortStream();
675   int streamWillBlock();
676   void setStreamCallback( RtAudioCallback callback, void *userData );
677   void cancelStreamCallback();
678
679   public:
680   // \brief Internal structure that provide debug information on the state of a running DSound device.
681   struct RtDsStatistics {
682     // \brief Sample Rate.
683     long sampleRate;
684     // \brief The size of one sample * number of channels on the input device.
685     int inputFrameSize; 
686     // \brief The size of one sample * number of channels on the output device.
687     int outputFrameSize; 
688     /* \brief The number of times the read pointer had to be adjusted to avoid reading from an unsafe buffer position.
689      *
690      * This field is only used when running in DUPLEX mode. INPUT mode devices just wait until the data is 
691      * available.
692      */
693     int numberOfReadOverruns;
694     // \brief The number of times the write pointer had to be adjusted to avoid writing in an unsafe buffer position.
695     int numberOfWriteUnderruns;
696     // \brief Number of bytes by attribute to buffer configuration by which writing must lead the current write pointer.
697     int writeDeviceBufferLeadBytes;
698     // \brief Number of bytes by attributable to the device driver by which writing must lead the current write pointer on this output device.
699     unsigned long writeDeviceSafeLeadBytes;
700     // \brief Number of bytes by which reading must trail the current read pointer on this input device.
701     unsigned long readDeviceSafeLeadBytes; 
702     /* \brief Estimated latency in seconds. 
703     *
704     * For INPUT mode devices, based the latency of the device's safe read pointer, plus one buffer's
705     * worth of additional latency.
706     *
707     * For OUTPUT mode devices, the latency of the device's safe write pointer, plus N buffers of 
708     * additional buffer latency.
709     *
710     * For DUPLEX devices, the sum of latencies for both input and output devices. DUPLEX devices
711     * also back off the read pointers an additional amount in order to maintain synchronization 
712     * between out-of-phase read and write pointers. This time is also included.
713     *
714     * Note that most software packages report latency between the safe write pointer 
715     * and the software lead pointer, excluding the hardware device's safe write pointer 
716     * latency. Figures of 1 or 2ms of latency on Windows audio devices are invariably of this type.
717     * The reality is that hardware devices often have latencies of 30ms or more (often much 
718     * higher for duplex operation).
719     */
720
721     double latency;
722   };
723   // \brief Report on the current state of a running DSound device.
724   static RtDsStatistics getDsStatistics();
725
726   private:
727
728   void initialize(void);
729   void probeDeviceInfo( RtApiDevice *info );
730   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
731                         int sampleRate, RtAudioFormat format,
732                         int *bufferSize, int numberOfBuffers );
733
734   bool coInitialized;
735   bool buffersRolling;
736   long duplexPrerollBytes;
737   static RtDsStatistics statistics;
738
739 };
740
741 #endif
742
743 #if defined(__WINDOWS_ASIO__)
744
745 class RtApiAsio: public RtApi
746 {
747 public:
748
749   RtApiAsio();
750   ~RtApiAsio();
751   void tickStream();
752   void closeStream();
753   void startStream();
754   void stopStream();
755   void abortStream();
756   void setStreamCallback( RtAudioCallback callback, void *userData );
757   void cancelStreamCallback();
758
759   // This function is intended for internal use only.  It must be
760   // public because it is called by the internal callback handler,
761   // which is not a member of RtAudio.  External use of this function
762   // will most likely produce highly undesireable results!
763   void callbackEvent( long bufferIndex );
764
765   private:
766
767   void initialize(void);
768   void probeDeviceInfo( RtApiDevice *info );
769   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
770                         int sampleRate, RtAudioFormat format,
771                         int *bufferSize, int numberOfBuffers );
772
773   bool coInitialized;
774
775 };
776
777 #endif
778
779 #if defined(__IRIX_AL__)
780
781 class RtApiAl: public RtApi
782 {
783 public:
784
785   RtApiAl();
786   ~RtApiAl();
787   int getDefaultOutputDevice(void);
788   int getDefaultInputDevice(void);
789   void tickStream();
790   void closeStream();
791   void startStream();
792   void stopStream();
793   void abortStream();
794   int streamWillBlock();
795   void setStreamCallback( RtAudioCallback callback, void *userData );
796   void cancelStreamCallback();
797
798   private:
799
800   void initialize(void);
801   void probeDeviceInfo( RtApiDevice *info );
802   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
803                         int sampleRate, RtAudioFormat format,
804                         int *bufferSize, int numberOfBuffers );
805 };
806
807 #endif
808
809 // Define the following flag to have extra information spewed to stderr.
810 //#define __RTAUDIO_DEBUG__
811
812 #endif