Tutorial   Class/Enum List   File List   Compound Members  

RtAudio.h

00001 /************************************************************************/
00038 /************************************************************************/
00039 
00040 // RtAudio: Version 3.0, 11 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     //      :apiHandle(0), mode(UNINITIALIZED), state(STREAM_STOPPED),
00190     //       userBuffer(0), deviceBuffer(0) {}
00191   };
00192 
00193   // A protected device structure for audio devices.
00194   struct RtApiDevice {
00195     std::string name;      
00196     bool probed;           
00197     void *apiDeviceId;     // void pointer for API specific device information
00198     int maxOutputChannels; 
00199     int maxInputChannels;  
00200     int maxDuplexChannels; 
00201     int minOutputChannels; 
00202     int minInputChannels;  
00203     int minDuplexChannels; 
00204     bool hasDuplexSupport; 
00205     bool isDefault;        
00206     std::vector<int> sampleRates; 
00207     RtAudioFormat nativeFormats;  
00209     // Default constructor.
00210     RtApiDevice()
00211       :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0),
00212        maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0),
00213        minDuplexChannels(0), isDefault(false), nativeFormats(0) {}
00214   };
00215 
00216   typedef signed short Int16;
00217   typedef signed int Int32;
00218   typedef float Float32;
00219   typedef double Float64;
00220 
00221   char message_[256];
00222   int nDevices_;
00223   std::vector<RtApiDevice> devices_;
00224   RtApiStream stream_;
00225 
00230   virtual void initialize(void) = 0;
00231 
00240   virtual void probeDeviceInfo( RtApiDevice *info );
00241 
00250   virtual bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00251                                 int sampleRate, RtAudioFormat format,
00252                                 int *bufferSize, int numberOfBuffers );
00253 
00258   virtual int getDefaultInputDevice(void);
00259 
00264   virtual int getDefaultOutputDevice(void);
00265 
00267   void clearDeviceInfo( RtApiDevice *info );
00268 
00270   void clearStreamInfo();
00271 
00273   void error( RtError::Type type );
00274 
00279   void verifyStream();
00280 
00285   void convertStreamBuffer( StreamMode mode );
00286 
00288   void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format );
00289 
00291   int formatBytes( RtAudioFormat format );
00292 };
00293 
00294 
00295 // **************************************************************** //
00296 //
00297 // RtAudio class declaration.
00298 //
00299 // RtAudio is a "controller" used to select an available audio i/o
00300 // interface.  It presents a common API for the user to call but all
00301 // functionality is implemented by the class RtAudioApi and its
00302 // subclasses.  RtAudio creates an instance of an RtAudioApi subclass
00303 // based on the user's API choice.  If no choice is made, RtAudio
00304 // attempts to make a "logical" API selection.
00305 //
00306 // **************************************************************** //
00307 
00308 class RtAudio
00309 {
00310 public:
00311 
00313   enum RtAudioApi {
00314     UNSPECIFIED,    
00315     LINUX_ALSA,     
00316     LINUX_OSS,      
00317     LINUX_JACK,     
00318     MACOSX_CORE,    
00319     IRIX_AL,        
00320     WINDOWS_ASIO,   
00321     WINDOWS_DS      
00322   };
00323 
00325 
00335   RtAudio( RtAudioApi api=UNSPECIFIED );
00336 
00338 
00349   RtAudio( int outputDevice, int outputChannels,
00350            int inputDevice, int inputChannels,
00351            RtAudioFormat format, int sampleRate,
00352            int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED );
00353 
00355 
00359   ~RtAudio();
00360 
00362 
00388   void openStream( int outputDevice, int outputChannels,
00389                    int inputDevice, int inputChannels,
00390                    RtAudioFormat format, int sampleRate,
00391                    int *bufferSize, int numberOfBuffers );
00392 
00394 
00413   void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); };
00414 
00416 
00423   void cancelStreamCallback() { rtapi_->cancelStreamCallback(); };
00424 
00426   int getDeviceCount(void) { return rtapi_->getDeviceCount(); };
00427 
00429 
00437   RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); };
00438 
00440 
00445   char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); };
00446 
00448 
00453   void tickStream() { rtapi_->tickStream(); };
00454 
00456 
00460   void closeStream()  { rtapi_->closeStream(); };
00461 
00463 
00467   void startStream() { rtapi_->startStream(); };
00468 
00470 
00474   void stopStream() { rtapi_->stopStream(); };
00475 
00477 
00481   void abortStream() { rtapi_->abortStream(); };
00482 
00483 
00484  protected:
00485 
00486   void initialize( RtAudioApi api );
00487 
00488   RtApi *rtapi_;
00489 };
00490 
00491 
00492 // RtApi Subclass prototypes.
00493 
00494 #if defined(__LINUX_ALSA__)
00495 
00496 class RtApiAlsa: public RtApi
00497 {
00498 public:
00499 
00500   RtApiAlsa();
00501   ~RtApiAlsa();
00502   void tickStream();
00503   void closeStream();
00504   void startStream();
00505   void stopStream();
00506   void abortStream();
00507   int streamWillBlock();
00508   void setStreamCallback( RtAudioCallback callback, void *userData );
00509   void cancelStreamCallback();
00510 
00511   private:
00512 
00513   void initialize(void);
00514   void probeDeviceInfo( RtApiDevice *info );
00515   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00516                         int sampleRate, RtAudioFormat format,
00517                         int *bufferSize, int numberOfBuffers );
00518 };
00519 
00520 #endif
00521 
00522 #if defined(__LINUX_JACK__)
00523 
00524 class RtApiJack: public RtApi
00525 {
00526 public:
00527 
00528   RtApiJack();
00529   ~RtApiJack();
00530   void tickStream();
00531   void closeStream();
00532   void startStream();
00533   void stopStream();
00534   void abortStream();
00535   void setStreamCallback( RtAudioCallback callback, void *userData );
00536   void cancelStreamCallback();
00537   // This function is intended for internal use only.  It must be
00538   // public because it is called by the internal callback handler,
00539   // which is not a member of RtAudio.  External use of this function
00540   // will most likely produce highly undesireable results!
00541   void callbackEvent( unsigned long nframes );
00542 
00543   private:
00544 
00545   void initialize(void);
00546   void probeDeviceInfo( RtApiDevice *info );
00547   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00548                         int sampleRate, RtAudioFormat format,
00549                         int *bufferSize, int numberOfBuffers );
00550 };
00551 
00552 #endif
00553 
00554 #if defined(__LINUX_OSS__)
00555 
00556 class RtApiOss: public RtApi
00557 {
00558 public:
00559 
00560   RtApiOss();
00561   ~RtApiOss();
00562   void tickStream();
00563   void closeStream();
00564   void startStream();
00565   void stopStream();
00566   void abortStream();
00567   int streamWillBlock();
00568   void setStreamCallback( RtAudioCallback callback, void *userData );
00569   void cancelStreamCallback();
00570 
00571   private:
00572 
00573   void initialize(void);
00574   void probeDeviceInfo( RtApiDevice *info );
00575   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00576                         int sampleRate, RtAudioFormat format,
00577                         int *bufferSize, int numberOfBuffers );
00578 };
00579 
00580 #endif
00581 
00582 #if defined(__MACOSX_CORE__)
00583 
00584 #include <CoreAudio/AudioHardware.h>
00585 
00586 class RtApiCore: public RtApi
00587 {
00588 public:
00589 
00590   RtApiCore();
00591   ~RtApiCore();
00592   int getDefaultOutputDevice(void);
00593   int getDefaultInputDevice(void);
00594   void tickStream();
00595   void closeStream();
00596   void startStream();
00597   void stopStream();
00598   void abortStream();
00599   void setStreamCallback( RtAudioCallback callback, void *userData );
00600   void cancelStreamCallback();
00601 
00602   // This function is intended for internal use only.  It must be
00603   // public because it is called by the internal callback handler,
00604   // which is not a member of RtAudio.  External use of this function
00605   // will most likely produce highly undesireable results!
00606   void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData );
00607 
00608   private:
00609 
00610   void initialize(void);
00611   void probeDeviceInfo( RtApiDevice *info );
00612   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00613                         int sampleRate, RtAudioFormat format,
00614                         int *bufferSize, int numberOfBuffers );
00615 };
00616 
00617 #endif
00618 
00619 #if defined(__WINDOWS_DS__)
00620 
00621 class RtApiDs: public RtApi
00622 {
00623 public:
00624 
00625   RtApiDs();
00626   ~RtApiDs();
00627   int getDefaultOutputDevice(void);
00628   int getDefaultInputDevice(void);
00629   void tickStream();
00630   void closeStream();
00631   void startStream();
00632   void stopStream();
00633   void abortStream();
00634   int streamWillBlock();
00635   void setStreamCallback( RtAudioCallback callback, void *userData );
00636   void cancelStreamCallback();
00637 
00638   private:
00639 
00640   void initialize(void);
00641   void probeDeviceInfo( RtApiDevice *info );
00642   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00643                         int sampleRate, RtAudioFormat format,
00644                         int *bufferSize, int numberOfBuffers );
00645 };
00646 
00647 #endif
00648 
00649 #if defined(__WINDOWS_ASIO__)
00650 
00651 class RtApiAsio: public RtApi
00652 {
00653 public:
00654 
00655   RtApiAsio();
00656   ~RtApiAsio();
00657   void tickStream();
00658   void closeStream();
00659   void startStream();
00660   void stopStream();
00661   void abortStream();
00662   void setStreamCallback( RtAudioCallback callback, void *userData );
00663   void cancelStreamCallback();
00664 
00665   // This function is intended for internal use only.  It must be
00666   // public because it is called by the internal callback handler,
00667   // which is not a member of RtAudio.  External use of this function
00668   // will most likely produce highly undesireable results!
00669   void callbackEvent( long bufferIndex );
00670 
00671   private:
00672 
00673   void initialize(void);
00674   void probeDeviceInfo( RtApiDevice *info );
00675   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00676                         int sampleRate, RtAudioFormat format,
00677                         int *bufferSize, int numberOfBuffers );
00678 };
00679 
00680 #endif
00681 
00682 #if defined(__IRIX_AL__)
00683 
00684 class RtApiAl: public RtApi
00685 {
00686 public:
00687 
00688   RtApiAl();
00689   ~RtApiAl();
00690   int getDefaultOutputDevice(void);
00691   int getDefaultInputDevice(void);
00692   void tickStream();
00693   void closeStream();
00694   void startStream();
00695   void stopStream();
00696   void abortStream();
00697   int streamWillBlock();
00698   void setStreamCallback( RtAudioCallback callback, void *userData );
00699   void cancelStreamCallback();
00700 
00701   private:
00702 
00703   void initialize(void);
00704   void probeDeviceInfo( RtApiDevice *info );
00705   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00706                         int sampleRate, RtAudioFormat format,
00707                         int *bufferSize, int numberOfBuffers );
00708 };
00709 
00710 #endif
00711 
00712 // Define the following flag to have extra information spewed to stderr.
00713 //#define __RTAUDIO_DEBUG__
00714 
00715 #endif

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