Tutorial   Class/Enum List   File List   Compound Members  

RtAudio.h

00001 /************************************************************************/
00038 /************************************************************************/
00039 
00040 // RtAudio: Version 3.0.3 (18 November 2005)
00041 
00042 #ifndef __RTAUDIO_H
00043 #define __RTAUDIO_H
00044 
00045 #include "RtError.h"
00046 #include <string>
00047 #include <vector>
00048 
00049 // Operating system dependent thread functionality.
00050 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
00051   #include <windows.h>
00052   #include <process.h>
00053 
00054   typedef unsigned long ThreadHandle;
00055   typedef CRITICAL_SECTION StreamMutex;
00056 
00057 #else // Various unix flavors with pthread support.
00058   #include <pthread.h>
00059 
00060   typedef pthread_t ThreadHandle;
00061   typedef pthread_mutex_t StreamMutex;
00062 
00063 #endif
00064 
00065 // This global structure type is used to pass callback information
00066 // between the private RtAudio stream structure and global callback
00067 // handling functions.
00068 struct CallbackInfo {
00069   void *object;    // Used as a "this" pointer.
00070   ThreadHandle thread;
00071   bool usingCallback;
00072   void *callback;
00073   void *userData;
00074   void *apiInfo;   // void pointer for API specific callback information
00075 
00076   // Default constructor.
00077   CallbackInfo()
00078     :object(0), usingCallback(false), callback(0),
00079      userData(0), apiInfo(0) {}
00080 };
00081 
00082 // Support for signed integers and floats.  Audio data fed to/from
00083 // the tickStream() routine is assumed to ALWAYS be in host
00084 // byte order.  The internal routines will automatically take care of
00085 // any necessary byte-swapping between the host format and the
00086 // soundcard.  Thus, endian-ness is not a concern in the following
00087 // format definitions.
00088 typedef unsigned long RtAudioFormat;
00089 static const RtAudioFormat RTAUDIO_SINT8 = 0x1;    
00090 static const RtAudioFormat RTAUDIO_SINT16 = 0x2;   
00091 static const RtAudioFormat RTAUDIO_SINT24 = 0x4;   
00092 static const RtAudioFormat RTAUDIO_SINT32 = 0x8;   
00093 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; 
00094 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; 
00096 typedef int (*RtAudioCallback)(char *buffer, int bufferSize, void *userData);
00097 
00099 struct RtAudioDeviceInfo {
00100   std::string name;      
00101   bool probed;          
00102   int outputChannels;   
00103   int inputChannels;    
00104   int duplexChannels;   
00105   bool isDefault;       
00106   std::vector<int> sampleRates; 
00107   RtAudioFormat nativeFormats;  
00109   // Default constructor.
00110   RtAudioDeviceInfo()
00111     :probed(false), outputChannels(0), inputChannels(0),
00112        duplexChannels(0), isDefault(false), nativeFormats(0) {}
00113 };
00114 
00115 // **************************************************************** //
00116 //
00117 // RtApi class declaration.
00118 //
00119 // Note that RtApi is an abstract base class and cannot be
00120 // explicitly instantiated.  The class RtAudio will create an
00121 // instance of an RtApi subclass (RtApiOss, RtApiAlsa,
00122 // RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio).
00123 //
00124 // **************************************************************** //
00125 
00126 class RtApi
00127 {
00128 public:
00129 
00130   enum StreamState {
00131     STREAM_STOPPED,
00132     STREAM_RUNNING
00133   };
00134 
00135   RtApi();
00136   virtual ~RtApi();
00137   void openStream( int outputDevice, int outputChannels,
00138                    int inputDevice, int inputChannels,
00139                    RtAudioFormat format, int sampleRate,
00140                    int *bufferSize, int numberOfBuffers );
00141   void openStream( int outputDevice, int outputChannels,
00142                    int inputDevice, int inputChannels,
00143                    RtAudioFormat format, int sampleRate,
00144                    int *bufferSize, int *numberOfBuffers );
00145   virtual void setStreamCallback( RtAudioCallback callback, void *userData ) = 0;
00146   virtual void cancelStreamCallback() = 0;
00147   int getDeviceCount(void);
00148   RtAudioDeviceInfo getDeviceInfo( int device );
00149   char * const getStreamBuffer();
00150   RtApi::StreamState getStreamState() const;
00151   virtual void tickStream() = 0;
00152   virtual void closeStream();
00153   virtual void startStream() = 0;
00154   virtual void stopStream() = 0;
00155   virtual void abortStream() = 0;
00156 
00157 protected:
00158 
00159   static const unsigned int MAX_SAMPLE_RATES;
00160   static const unsigned int SAMPLE_RATES[];
00161 
00162   enum { FAILURE, SUCCESS };
00163 
00164   enum StreamMode {
00165     OUTPUT,
00166     INPUT,
00167     DUPLEX,
00168     UNINITIALIZED = -75
00169   };
00170 
00171   // A protected structure used for buffer conversion.
00172   struct ConvertInfo {
00173     int channels;
00174     int inJump, outJump;
00175     RtAudioFormat inFormat, outFormat;
00176     std::vector<int> inOffset;
00177     std::vector<int> outOffset;
00178   };
00179 
00180   // A protected structure for audio streams.
00181   struct RtApiStream {
00182     int device[2];          // Playback and record, respectively.
00183     void *apiHandle;        // void pointer for API specific stream handle information
00184     StreamMode mode;         // OUTPUT, INPUT, or DUPLEX.
00185     StreamState state;       // STOPPED or RUNNING
00186     char *userBuffer;
00187     char *deviceBuffer;
00188     bool doConvertBuffer[2]; // Playback and record, respectively.
00189     bool deInterleave[2];    // Playback and record, respectively.
00190     bool doByteSwap[2];      // Playback and record, respectively.
00191     int sampleRate;
00192     int bufferSize;
00193     int nBuffers;
00194     int nUserChannels[2];    // Playback and record, respectively.
00195     int nDeviceChannels[2];  // Playback and record channels, respectively.
00196     RtAudioFormat userFormat;
00197     RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
00198     StreamMutex mutex;
00199     CallbackInfo callbackInfo;
00200     ConvertInfo convertInfo[2];
00201 
00202     RtApiStream()
00203       :apiHandle(0), userBuffer(0), deviceBuffer(0) {}
00204   };
00205 
00206   // A protected device structure for audio devices.
00207   struct RtApiDevice {
00208     std::string name;      
00209     bool probed;           
00210     void *apiDeviceId;     // void pointer for API specific device information
00211     int maxOutputChannels; 
00212     int maxInputChannels;  
00213     int maxDuplexChannels; 
00214     int minOutputChannels; 
00215     int minInputChannels;  
00216     int minDuplexChannels; 
00217     bool hasDuplexSupport; 
00218     bool isDefault;        
00219     std::vector<int> sampleRates; 
00220     RtAudioFormat nativeFormats;  
00222     // Default constructor.
00223     RtApiDevice()
00224       :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
00225        maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
00226        minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
00227   };
00228 
00229   typedef signed short Int16;
00230   typedef signed int Int32;
00231   typedef float Float32;
00232   typedef double Float64;
00233 
00234   char message_[1024];
00235   int nDevices_;
00236   std::vector<RtApiDevice> devices_;
00237   RtApiStream stream_;
00238 
00243   virtual void initialize(void) = 0;
00244 
00253   virtual void probeDeviceInfo( RtApiDevice *info );
00254 
00263   virtual bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00264                                 int sampleRate, RtAudioFormat format,
00265                                 int *bufferSize, int numberOfBuffers );
00266 
00271   virtual int getDefaultInputDevice(void);
00272 
00277   virtual int getDefaultOutputDevice(void);
00278 
00280   void clearDeviceInfo( RtApiDevice *info );
00281 
00283   void clearStreamInfo();
00284 
00286   void error( RtError::Type type );
00287 
00292   void verifyStream();
00293 
00298   void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
00299 
00301   void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format );
00302 
00304   int formatBytes( RtAudioFormat format );
00305 };
00306 
00307 
00308 // **************************************************************** //
00309 //
00310 // RtAudio class declaration.
00311 //
00312 // RtAudio is a "controller" used to select an available audio i/o
00313 // interface.  It presents a common API for the user to call but all
00314 // functionality is implemented by the class RtAudioApi and its
00315 // subclasses.  RtAudio creates an instance of an RtAudioApi subclass
00316 // based on the user's API choice.  If no choice is made, RtAudio
00317 // attempts to make a "logical" API selection.
00318 //
00319 // **************************************************************** //
00320 
00321 class RtAudio
00322 {
00323 public:
00324 
00326   enum RtAudioApi {
00327     UNSPECIFIED,    
00328     LINUX_ALSA,     
00329     LINUX_OSS,      
00330     LINUX_JACK,     
00331     MACOSX_CORE,    
00332     IRIX_AL,        
00333     WINDOWS_ASIO,   
00334     WINDOWS_DS      
00335   };
00336 
00338 
00348   RtAudio( RtAudioApi api=UNSPECIFIED );
00349 
00351 
00362   RtAudio( int outputDevice, int outputChannels,
00363            int inputDevice, int inputChannels,
00364            RtAudioFormat format, int sampleRate,
00365            int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED );
00366 
00368 
00376   RtAudio( int outputDevice, int outputChannels,
00377            int inputDevice, int inputChannels,
00378            RtAudioFormat format, int sampleRate,
00379            int *bufferSize, int *numberOfBuffers, RtAudioApi api=UNSPECIFIED );
00380 
00382 
00386   ~RtAudio();
00387 
00389 
00415   void openStream( int outputDevice, int outputChannels,
00416                    int inputDevice, int inputChannels,
00417                    RtAudioFormat format, int sampleRate,
00418                    int *bufferSize, int numberOfBuffers );
00419 
00421 
00429   void openStream( int outputDevice, int outputChannels,
00430                    int inputDevice, int inputChannels,
00431                    RtAudioFormat format, int sampleRate,
00432                    int *bufferSize, int *numberOfBuffers );
00433 
00435 
00454   void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); };
00455 
00457 
00464   void cancelStreamCallback() { rtapi_->cancelStreamCallback(); };
00465 
00467   int getDeviceCount(void) { return rtapi_->getDeviceCount(); };
00468 
00470 
00478   RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); };
00479 
00481 
00486   char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); };
00487 
00489 
00494   void tickStream() { rtapi_->tickStream(); };
00495 
00497 
00501   void closeStream()  { rtapi_->closeStream(); };
00502 
00504 
00508   void startStream() { rtapi_->startStream(); };
00509 
00511 
00515   void stopStream() { rtapi_->stopStream(); };
00516 
00518 
00522   void abortStream() { rtapi_->abortStream(); };
00523 
00524 
00525  protected:
00526 
00527   void initialize( RtAudioApi api );
00528 
00529   RtApi *rtapi_;
00530 };
00531 
00532 
00533 // RtApi Subclass prototypes.
00534 
00535 #if defined(__LINUX_ALSA__)
00536 
00537 class RtApiAlsa: public RtApi
00538 {
00539 public:
00540 
00541   RtApiAlsa();
00542   ~RtApiAlsa();
00543   void tickStream();
00544   void closeStream();
00545   void startStream();
00546   void stopStream();
00547   void abortStream();
00548   int streamWillBlock();
00549   void setStreamCallback( RtAudioCallback callback, void *userData );
00550   void cancelStreamCallback();
00551 
00552   private:
00553 
00554   void initialize(void);
00555   bool primeOutputBuffer();
00556   void probeDeviceInfo( RtApiDevice *info );
00557   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00558                         int sampleRate, RtAudioFormat format,
00559                         int *bufferSize, int numberOfBuffers );
00560 };
00561 
00562 #endif
00563 
00564 #if defined(__LINUX_JACK__)
00565 
00566 class RtApiJack: public RtApi
00567 {
00568 public:
00569 
00570   RtApiJack();
00571   ~RtApiJack();
00572   void tickStream();
00573   void closeStream();
00574   void startStream();
00575   void stopStream();
00576   void abortStream();
00577   void setStreamCallback( RtAudioCallback callback, void *userData );
00578   void cancelStreamCallback();
00579   // This function is intended for internal use only.  It must be
00580   // public because it is called by the internal callback handler,
00581   // which is not a member of RtAudio.  External use of this function
00582   // will most likely produce highly undesireable results!
00583   void callbackEvent( unsigned long nframes );
00584 
00585   private:
00586 
00587   void initialize(void);
00588   void probeDeviceInfo( RtApiDevice *info );
00589   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00590                         int sampleRate, RtAudioFormat format,
00591                         int *bufferSize, int numberOfBuffers );
00592 };
00593 
00594 #endif
00595 
00596 #if defined(__LINUX_OSS__)
00597 
00598 class RtApiOss: public RtApi
00599 {
00600 public:
00601 
00602   RtApiOss();
00603   ~RtApiOss();
00604   void tickStream();
00605   void closeStream();
00606   void startStream();
00607   void stopStream();
00608   void abortStream();
00609   int streamWillBlock();
00610   void setStreamCallback( RtAudioCallback callback, void *userData );
00611   void cancelStreamCallback();
00612 
00613   private:
00614 
00615   void initialize(void);
00616   void probeDeviceInfo( RtApiDevice *info );
00617   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00618                         int sampleRate, RtAudioFormat format,
00619                         int *bufferSize, int numberOfBuffers );
00620 };
00621 
00622 #endif
00623 
00624 #if defined(__MACOSX_CORE__)
00625 
00626 #include <CoreAudio/AudioHardware.h>
00627 
00628 class RtApiCore: public RtApi
00629 {
00630 public:
00631 
00632   RtApiCore();
00633   ~RtApiCore();
00634   int getDefaultOutputDevice(void);
00635   int getDefaultInputDevice(void);
00636   void tickStream();
00637   void closeStream();
00638   void startStream();
00639   void stopStream();
00640   void abortStream();
00641   void setStreamCallback( RtAudioCallback callback, void *userData );
00642   void cancelStreamCallback();
00643 
00644   // This function is intended for internal use only.  It must be
00645   // public because it is called by the internal callback handler,
00646   // which is not a member of RtAudio.  External use of this function
00647   // will most likely produce highly undesireable results!
00648   void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData );
00649 
00650   private:
00651 
00652   void initialize(void);
00653   void probeDeviceInfo( RtApiDevice *info );
00654   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00655                         int sampleRate, RtAudioFormat format,
00656                         int *bufferSize, int numberOfBuffers );
00657 };
00658 
00659 #endif
00660 
00661 #if defined(__WINDOWS_DS__)
00662 
00663 class RtApiDs: public RtApi
00664 {
00665 public:
00666 
00667   RtApiDs();
00668   ~RtApiDs();
00669   int getDefaultOutputDevice(void);
00670   int getDefaultInputDevice(void);
00671   void tickStream();
00672   void closeStream();
00673   void startStream();
00674   void stopStream();
00675   void abortStream();
00676   int streamWillBlock();
00677   void setStreamCallback( RtAudioCallback callback, void *userData );
00678   void cancelStreamCallback();
00679 
00680   public:
00681   // \brief Internal structure that provide debug information on the state of a running DSound device.
00682   struct RtDsStatistics {
00683     // \brief Sample Rate.
00684     long sampleRate;
00685     // \brief The size of one sample * number of channels on the input device.
00686     int inputFrameSize; 
00687     // \brief The size of one sample * number of channels on the output device.
00688     int outputFrameSize; 
00689     /* \brief The number of times the read pointer had to be adjusted to avoid reading from an unsafe buffer position.
00690      *
00691      * This field is only used when running in DUPLEX mode. INPUT mode devices just wait until the data is 
00692      * available.
00693      */
00694     int numberOfReadOverruns;
00695     // \brief The number of times the write pointer had to be adjusted to avoid writing in an unsafe buffer position.
00696     int numberOfWriteUnderruns;
00697     // \brief Number of bytes by attribute to buffer configuration by which writing must lead the current write pointer.
00698     int writeDeviceBufferLeadBytes;
00699     // \brief Number of bytes by attributable to the device driver by which writing must lead the current write pointer on this output device.
00700     unsigned long writeDeviceSafeLeadBytes;
00701     // \brief Number of bytes by which reading must trail the current read pointer on this input device.
00702     unsigned long readDeviceSafeLeadBytes; 
00703     /* \brief Estimated latency in seconds. 
00704     *
00705     * For INPUT mode devices, based the latency of the device's safe read pointer, plus one buffer's
00706     * worth of additional latency.
00707     *
00708     * For OUTPUT mode devices, the latency of the device's safe write pointer, plus N buffers of 
00709     * additional buffer latency.
00710     *
00711     * For DUPLEX devices, the sum of latencies for both input and output devices. DUPLEX devices
00712     * also back off the read pointers an additional amount in order to maintain synchronization 
00713     * between out-of-phase read and write pointers. This time is also included.
00714     *
00715     * Note that most software packages report latency between the safe write pointer 
00716     * and the software lead pointer, excluding the hardware device's safe write pointer 
00717     * latency. Figures of 1 or 2ms of latency on Windows audio devices are invariably of this type.
00718     * The reality is that hardware devices often have latencies of 30ms or more (often much 
00719     * higher for duplex operation).
00720     */
00721 
00722     double latency;
00723   };
00724   // \brief Report on the current state of a running DSound device.
00725   static RtDsStatistics getDsStatistics();
00726 
00727   private:
00728 
00729   void initialize(void);
00730   void probeDeviceInfo( RtApiDevice *info );
00731   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00732                         int sampleRate, RtAudioFormat format,
00733                         int *bufferSize, int numberOfBuffers );
00734 
00735   bool coInitialized;
00736   bool buffersRolling;
00737   long duplexPrerollBytes;
00738   static RtDsStatistics statistics;
00739 
00740 };
00741 
00742 #endif
00743 
00744 #if defined(__WINDOWS_ASIO__)
00745 
00746 class RtApiAsio: public RtApi
00747 {
00748 public:
00749 
00750   RtApiAsio();
00751   ~RtApiAsio();
00752   void tickStream();
00753   void closeStream();
00754   void startStream();
00755   void stopStream();
00756   void abortStream();
00757   void setStreamCallback( RtAudioCallback callback, void *userData );
00758   void cancelStreamCallback();
00759 
00760   // This function is intended for internal use only.  It must be
00761   // public because it is called by the internal callback handler,
00762   // which is not a member of RtAudio.  External use of this function
00763   // will most likely produce highly undesireable results!
00764   void callbackEvent( long bufferIndex );
00765 
00766   private:
00767 
00768   void initialize(void);
00769   void probeDeviceInfo( RtApiDevice *info );
00770   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00771                         int sampleRate, RtAudioFormat format,
00772                         int *bufferSize, int numberOfBuffers );
00773 
00774   bool coInitialized;
00775 
00776 };
00777 
00778 #endif
00779 
00780 #if defined(__IRIX_AL__)
00781 
00782 class RtApiAl: public RtApi
00783 {
00784 public:
00785 
00786   RtApiAl();
00787   ~RtApiAl();
00788   int getDefaultOutputDevice(void);
00789   int getDefaultInputDevice(void);
00790   void tickStream();
00791   void closeStream();
00792   void startStream();
00793   void stopStream();
00794   void abortStream();
00795   int streamWillBlock();
00796   void setStreamCallback( RtAudioCallback callback, void *userData );
00797   void cancelStreamCallback();
00798 
00799   private:
00800 
00801   void initialize(void);
00802   void probeDeviceInfo( RtApiDevice *info );
00803   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00804                         int sampleRate, RtAudioFormat format,
00805                         int *bufferSize, int numberOfBuffers );
00806 };
00807 
00808 #endif
00809 
00810 // Define the following flag to have extra information spewed to stderr.
00811 //#define __RTAUDIO_DEBUG__
00812 
00813 #endif

©2001-2005 Gary P. Scavone, McGill University. All Rights Reserved.
Maintained by Gary P. Scavone, gary@music.mcgill.ca