Tutorial   Class/Enum List   File List   Compound Members  

RtAudio.h

00001 /************************************************************************/
00038 /************************************************************************/
00039 
00040 // RtAudio: Version 3.0.1, 22 March 2004
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   RtApi();
00131   virtual ~RtApi();
00132   void openStream( int outputDevice, int outputChannels,
00133                    int inputDevice, int inputChannels,
00134                    RtAudioFormat format, int sampleRate,
00135                    int *bufferSize, int numberOfBuffers );
00136   virtual void setStreamCallback( RtAudioCallback callback, void *userData ) = 0;
00137   virtual void cancelStreamCallback() = 0;
00138   int getDeviceCount(void);
00139   RtAudioDeviceInfo getDeviceInfo( int device );
00140   char * const getStreamBuffer();
00141   virtual void tickStream() = 0;
00142   virtual void closeStream();
00143   virtual void startStream() = 0;
00144   virtual void stopStream() = 0;
00145   virtual void abortStream() = 0;
00146 
00147 protected:
00148 
00149   static const unsigned int MAX_SAMPLE_RATES;
00150   static const unsigned int SAMPLE_RATES[];
00151 
00152   enum { FAILURE, SUCCESS };
00153 
00154   enum StreamMode {
00155     OUTPUT,
00156     INPUT,
00157     DUPLEX,
00158     UNINITIALIZED = -75
00159   };
00160 
00161   enum StreamState {
00162     STREAM_STOPPED,
00163     STREAM_RUNNING
00164   };
00165 
00166   // A protected structure for audio streams.
00167   struct RtApiStream {
00168     int device[2];          // Playback and record, respectively.
00169     void *apiHandle;        // void pointer for API specific stream handle information
00170     StreamMode mode;         // OUTPUT, INPUT, or DUPLEX.
00171     StreamState state;       // STOPPED or RUNNING
00172     char *userBuffer;
00173     char *deviceBuffer;
00174     bool doConvertBuffer[2]; // Playback and record, respectively.
00175     bool deInterleave[2];    // Playback and record, respectively.
00176     bool doByteSwap[2];      // Playback and record, respectively.
00177     int sampleRate;
00178     int bufferSize;
00179     int nBuffers;
00180     int nUserChannels[2];    // Playback and record, respectively.
00181     int nDeviceChannels[2];  // Playback and record channels, respectively.
00182     RtAudioFormat userFormat;
00183     RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
00184     StreamMutex mutex;
00185     CallbackInfo callbackInfo;
00186 
00187     RtApiStream()
00188       :apiHandle(0), userBuffer(0), deviceBuffer(0) {}
00189     //      mode(UNINITIALIZED), state(STREAM_STOPPED),
00190   };
00191 
00192   // A protected device structure for audio devices.
00193   struct RtApiDevice {
00194     std::string name;      
00195     bool probed;           
00196     void *apiDeviceId;     // void pointer for API specific device information
00197     int maxOutputChannels; 
00198     int maxInputChannels;  
00199     int maxDuplexChannels; 
00200     int minOutputChannels; 
00201     int minInputChannels;  
00202     int minDuplexChannels; 
00203     bool hasDuplexSupport; 
00204     bool isDefault;        
00205     std::vector<int> sampleRates; 
00206     RtAudioFormat nativeFormats;  
00208     // Default constructor.
00209     RtApiDevice()
00210       :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
00211        maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
00212        minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
00213   };
00214 
00215   typedef signed short Int16;
00216   typedef signed int Int32;
00217   typedef float Float32;
00218   typedef double Float64;
00219 
00220   char message_[256];
00221   int nDevices_;
00222   std::vector<RtApiDevice> devices_;
00223   RtApiStream stream_;
00224 
00229   virtual void initialize(void) = 0;
00230 
00239   virtual void probeDeviceInfo( RtApiDevice *info );
00240 
00249   virtual bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00250                                 int sampleRate, RtAudioFormat format,
00251                                 int *bufferSize, int numberOfBuffers );
00252 
00257   virtual int getDefaultInputDevice(void);
00258 
00263   virtual int getDefaultOutputDevice(void);
00264 
00266   void clearDeviceInfo( RtApiDevice *info );
00267 
00269   void clearStreamInfo();
00270 
00272   void error( RtError::Type type );
00273 
00278   void verifyStream();
00279 
00284   void convertStreamBuffer( StreamMode mode );
00285 
00287   void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format );
00288 
00290   int formatBytes( RtAudioFormat format );
00291 };
00292 
00293 
00294 // **************************************************************** //
00295 //
00296 // RtAudio class declaration.
00297 //
00298 // RtAudio is a "controller" used to select an available audio i/o
00299 // interface.  It presents a common API for the user to call but all
00300 // functionality is implemented by the class RtAudioApi and its
00301 // subclasses.  RtAudio creates an instance of an RtAudioApi subclass
00302 // based on the user's API choice.  If no choice is made, RtAudio
00303 // attempts to make a "logical" API selection.
00304 //
00305 // **************************************************************** //
00306 
00307 class RtAudio
00308 {
00309 public:
00310 
00312   enum RtAudioApi {
00313     UNSPECIFIED,    
00314     LINUX_ALSA,     
00315     LINUX_OSS,      
00316     LINUX_JACK,     
00317     MACOSX_CORE,    
00318     IRIX_AL,        
00319     WINDOWS_ASIO,   
00320     WINDOWS_DS      
00321   };
00322 
00324 
00334   RtAudio( RtAudioApi api=UNSPECIFIED );
00335 
00337 
00348   RtAudio( int outputDevice, int outputChannels,
00349            int inputDevice, int inputChannels,
00350            RtAudioFormat format, int sampleRate,
00351            int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED );
00352 
00354 
00358   ~RtAudio();
00359 
00361 
00387   void openStream( int outputDevice, int outputChannels,
00388                    int inputDevice, int inputChannels,
00389                    RtAudioFormat format, int sampleRate,
00390                    int *bufferSize, int numberOfBuffers );
00391 
00393 
00412   void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); };
00413 
00415 
00422   void cancelStreamCallback() { rtapi_->cancelStreamCallback(); };
00423 
00425   int getDeviceCount(void) { return rtapi_->getDeviceCount(); };
00426 
00428 
00436   RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); };
00437 
00439 
00444   char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); };
00445 
00447 
00452   void tickStream() { rtapi_->tickStream(); };
00453 
00455 
00459   void closeStream()  { rtapi_->closeStream(); };
00460 
00462 
00466   void startStream() { rtapi_->startStream(); };
00467 
00469 
00473   void stopStream() { rtapi_->stopStream(); };
00474 
00476 
00480   void abortStream() { rtapi_->abortStream(); };
00481 
00482 
00483  protected:
00484 
00485   void initialize( RtAudioApi api );
00486 
00487   RtApi *rtapi_;
00488 };
00489 
00490 
00491 // RtApi Subclass prototypes.
00492 
00493 #if defined(__LINUX_ALSA__)
00494 
00495 class RtApiAlsa: public RtApi
00496 {
00497 public:
00498 
00499   RtApiAlsa();
00500   ~RtApiAlsa();
00501   void tickStream();
00502   void closeStream();
00503   void startStream();
00504   void stopStream();
00505   void abortStream();
00506   int streamWillBlock();
00507   void setStreamCallback( RtAudioCallback callback, void *userData );
00508   void cancelStreamCallback();
00509 
00510   private:
00511 
00512   void initialize(void);
00513   void probeDeviceInfo( RtApiDevice *info );
00514   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00515                         int sampleRate, RtAudioFormat format,
00516                         int *bufferSize, int numberOfBuffers );
00517 };
00518 
00519 #endif
00520 
00521 #if defined(__LINUX_JACK__)
00522 
00523 class RtApiJack: public RtApi
00524 {
00525 public:
00526 
00527   RtApiJack();
00528   ~RtApiJack();
00529   void tickStream();
00530   void closeStream();
00531   void startStream();
00532   void stopStream();
00533   void abortStream();
00534   void setStreamCallback( RtAudioCallback callback, void *userData );
00535   void cancelStreamCallback();
00536   // This function is intended for internal use only.  It must be
00537   // public because it is called by the internal callback handler,
00538   // which is not a member of RtAudio.  External use of this function
00539   // will most likely produce highly undesireable results!
00540   void callbackEvent( unsigned long nframes );
00541 
00542   private:
00543 
00544   void initialize(void);
00545   void probeDeviceInfo( RtApiDevice *info );
00546   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00547                         int sampleRate, RtAudioFormat format,
00548                         int *bufferSize, int numberOfBuffers );
00549 };
00550 
00551 #endif
00552 
00553 #if defined(__LINUX_OSS__)
00554 
00555 class RtApiOss: public RtApi
00556 {
00557 public:
00558 
00559   RtApiOss();
00560   ~RtApiOss();
00561   void tickStream();
00562   void closeStream();
00563   void startStream();
00564   void stopStream();
00565   void abortStream();
00566   int streamWillBlock();
00567   void setStreamCallback( RtAudioCallback callback, void *userData );
00568   void cancelStreamCallback();
00569 
00570   private:
00571 
00572   void initialize(void);
00573   void probeDeviceInfo( RtApiDevice *info );
00574   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00575                         int sampleRate, RtAudioFormat format,
00576                         int *bufferSize, int numberOfBuffers );
00577 };
00578 
00579 #endif
00580 
00581 #if defined(__MACOSX_CORE__)
00582 
00583 #include <CoreAudio/AudioHardware.h>
00584 
00585 class RtApiCore: public RtApi
00586 {
00587 public:
00588 
00589   RtApiCore();
00590   ~RtApiCore();
00591   int getDefaultOutputDevice(void);
00592   int getDefaultInputDevice(void);
00593   void tickStream();
00594   void closeStream();
00595   void startStream();
00596   void stopStream();
00597   void abortStream();
00598   void setStreamCallback( RtAudioCallback callback, void *userData );
00599   void cancelStreamCallback();
00600 
00601   // This function is intended for internal use only.  It must be
00602   // public because it is called by the internal callback handler,
00603   // which is not a member of RtAudio.  External use of this function
00604   // will most likely produce highly undesireable results!
00605   void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData );
00606 
00607   private:
00608 
00609   void initialize(void);
00610   void probeDeviceInfo( RtApiDevice *info );
00611   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00612                         int sampleRate, RtAudioFormat format,
00613                         int *bufferSize, int numberOfBuffers );
00614 };
00615 
00616 #endif
00617 
00618 #if defined(__WINDOWS_DS__)
00619 
00620 class RtApiDs: public RtApi
00621 {
00622 public:
00623 
00624   RtApiDs();
00625   ~RtApiDs();
00626   int getDefaultOutputDevice(void);
00627   int getDefaultInputDevice(void);
00628   void tickStream();
00629   void closeStream();
00630   void startStream();
00631   void stopStream();
00632   void abortStream();
00633   int streamWillBlock();
00634   void setStreamCallback( RtAudioCallback callback, void *userData );
00635   void cancelStreamCallback();
00636 
00637   private:
00638 
00639   void initialize(void);
00640   void probeDeviceInfo( RtApiDevice *info );
00641   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00642                         int sampleRate, RtAudioFormat format,
00643                         int *bufferSize, int numberOfBuffers );
00644 };
00645 
00646 #endif
00647 
00648 #if defined(__WINDOWS_ASIO__)
00649 
00650 class RtApiAsio: public RtApi
00651 {
00652 public:
00653 
00654   RtApiAsio();
00655   ~RtApiAsio();
00656   void tickStream();
00657   void closeStream();
00658   void startStream();
00659   void stopStream();
00660   void abortStream();
00661   void setStreamCallback( RtAudioCallback callback, void *userData );
00662   void cancelStreamCallback();
00663 
00664   // This function is intended for internal use only.  It must be
00665   // public because it is called by the internal callback handler,
00666   // which is not a member of RtAudio.  External use of this function
00667   // will most likely produce highly undesireable results!
00668   void callbackEvent( long bufferIndex );
00669 
00670   private:
00671 
00672   void initialize(void);
00673   void probeDeviceInfo( RtApiDevice *info );
00674   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00675                         int sampleRate, RtAudioFormat format,
00676                         int *bufferSize, int numberOfBuffers );
00677 };
00678 
00679 #endif
00680 
00681 #if defined(__IRIX_AL__)
00682 
00683 class RtApiAl: public RtApi
00684 {
00685 public:
00686 
00687   RtApiAl();
00688   ~RtApiAl();
00689   int getDefaultOutputDevice(void);
00690   int getDefaultInputDevice(void);
00691   void tickStream();
00692   void closeStream();
00693   void startStream();
00694   void stopStream();
00695   void abortStream();
00696   int streamWillBlock();
00697   void setStreamCallback( RtAudioCallback callback, void *userData );
00698   void cancelStreamCallback();
00699 
00700   private:
00701 
00702   void initialize(void);
00703   void probeDeviceInfo( RtApiDevice *info );
00704   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00705                         int sampleRate, RtAudioFormat format,
00706                         int *bufferSize, int numberOfBuffers );
00707 };
00708 
00709 #endif
00710 
00711 // Define the following flag to have extra information spewed to stderr.
00712 //#define __RTAUDIO_DEBUG__
00713 
00714 #endif

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