Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   Tutorial


RtAudio.h

00001 /************************************************************************/
00038 /************************************************************************/
00039 
00040 // RtAudio: Version 3.0.2 (13 October 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   void probeDeviceInfo( RtApiDevice *info );
00556   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00557                         int sampleRate, RtAudioFormat format,
00558                         int *bufferSize, int numberOfBuffers );
00559 };
00560 
00561 #endif
00562 
00563 #if defined(__LINUX_JACK__)
00564 
00565 class RtApiJack: public RtApi
00566 {
00567 public:
00568 
00569   RtApiJack();
00570   ~RtApiJack();
00571   void tickStream();
00572   void closeStream();
00573   void startStream();
00574   void stopStream();
00575   void abortStream();
00576   void setStreamCallback( RtAudioCallback callback, void *userData );
00577   void cancelStreamCallback();
00578   // This function is intended for internal use only.  It must be
00579   // public because it is called by the internal callback handler,
00580   // which is not a member of RtAudio.  External use of this function
00581   // will most likely produce highly undesireable results!
00582   void callbackEvent( unsigned long nframes );
00583 
00584   private:
00585 
00586   void initialize(void);
00587   void probeDeviceInfo( RtApiDevice *info );
00588   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00589                         int sampleRate, RtAudioFormat format,
00590                         int *bufferSize, int numberOfBuffers );
00591 };
00592 
00593 #endif
00594 
00595 #if defined(__LINUX_OSS__)
00596 
00597 class RtApiOss: public RtApi
00598 {
00599 public:
00600 
00601   RtApiOss();
00602   ~RtApiOss();
00603   void tickStream();
00604   void closeStream();
00605   void startStream();
00606   void stopStream();
00607   void abortStream();
00608   int streamWillBlock();
00609   void setStreamCallback( RtAudioCallback callback, void *userData );
00610   void cancelStreamCallback();
00611 
00612   private:
00613 
00614   void initialize(void);
00615   void probeDeviceInfo( RtApiDevice *info );
00616   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00617                         int sampleRate, RtAudioFormat format,
00618                         int *bufferSize, int numberOfBuffers );
00619 };
00620 
00621 #endif
00622 
00623 #if defined(__MACOSX_CORE__)
00624 
00625 #include <CoreAudio/AudioHardware.h>
00626 
00627 class RtApiCore: public RtApi
00628 {
00629 public:
00630 
00631   RtApiCore();
00632   ~RtApiCore();
00633   int getDefaultOutputDevice(void);
00634   int getDefaultInputDevice(void);
00635   void tickStream();
00636   void closeStream();
00637   void startStream();
00638   void stopStream();
00639   void abortStream();
00640   void setStreamCallback( RtAudioCallback callback, void *userData );
00641   void cancelStreamCallback();
00642 
00643   // This function is intended for internal use only.  It must be
00644   // public because it is called by the internal callback handler,
00645   // which is not a member of RtAudio.  External use of this function
00646   // will most likely produce highly undesireable results!
00647   void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData );
00648 
00649   private:
00650 
00651   void initialize(void);
00652   void probeDeviceInfo( RtApiDevice *info );
00653   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00654                         int sampleRate, RtAudioFormat format,
00655                         int *bufferSize, int numberOfBuffers );
00656 };
00657 
00658 #endif
00659 
00660 #if defined(__WINDOWS_DS__)
00661 
00662 class RtApiDs: public RtApi
00663 {
00664 public:
00665 
00666   RtApiDs();
00667   ~RtApiDs();
00668   int getDefaultOutputDevice(void);
00669   int getDefaultInputDevice(void);
00670   void tickStream();
00671   void closeStream();
00672   void startStream();
00673   void stopStream();
00674   void abortStream();
00675   int streamWillBlock();
00676   void setStreamCallback( RtAudioCallback callback, void *userData );
00677   void cancelStreamCallback();
00678 
00679   public:
00680   // \brief Internal structure that provide debug information on the state of a running DSound device.
00681   struct RtDsStatistics {
00682     // \brief Sample Rate.
00683     long sampleRate;
00684     // \brief The size of one sample * number of channels on the input device.
00685     int inputFrameSize; 
00686     // \brief The size of one sample * number of channels on the output device.
00687     int outputFrameSize; 
00688     /* \brief The number of times the read pointer had to be adjusted to avoid reading from an unsafe buffer position.
00689      *
00690      * This field is only used when running in DUPLEX mode. INPUT mode devices just wait until the data is 
00691      * available.
00692      */
00693     int numberOfReadOverruns;
00694     // \brief The number of times the write pointer had to be adjusted to avoid writing in an unsafe buffer position.
00695     int numberOfWriteUnderruns;
00696     // \brief Number of bytes by attribute to buffer configuration by which writing must lead the current write pointer.
00697     int writeDeviceBufferLeadBytes;
00698     // \brief Number of bytes by attributable to the device driver by which writing must lead the current write pointer on this output device.
00699     unsigned long writeDeviceSafeLeadBytes;
00700     // \brief Number of bytes by which reading must trail the current read pointer on this input device.
00701     unsigned long readDeviceSafeLeadBytes; 
00702     /* \brief Estimated latency in seconds. 
00703     *
00704     * For INPUT mode devices, based the latency of the device's safe read pointer, plus one buffer's
00705     * worth of additional latency.
00706     *
00707     * For OUTPUT mode devices, the latency of the device's safe write pointer, plus N buffers of 
00708     * additional buffer latency.
00709     *
00710     * For DUPLEX devices, the sum of latencies for both input and output devices. DUPLEX devices
00711     * also back off the read pointers an additional amount in order to maintain synchronization 
00712     * between out-of-phase read and write pointers. This time is also included.
00713     *
00714     * Note that most software packages report latency between the safe write pointer 
00715     * and the software lead pointer, excluding the hardware device's safe write pointer 
00716     * latency. Figures of 1 or 2ms of latency on Windows audio devices are invariably of this type.
00717     * The reality is that hardware devices often have latencies of 30ms or more (often much 
00718     * higher for duplex operation).
00719     */
00720 
00721     double latency;
00722   };
00723   // \brief Report on the current state of a running DSound device.
00724   static RtDsStatistics getDsStatistics();
00725 
00726   private:
00727 
00728   void initialize(void);
00729   void probeDeviceInfo( RtApiDevice *info );
00730   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00731                         int sampleRate, RtAudioFormat format,
00732                         int *bufferSize, int numberOfBuffers );
00733 
00734   bool coInitialized;
00735   bool buffersRolling;
00736   long duplexPrerollBytes;
00737   static RtDsStatistics statistics;
00738 
00739 };
00740 
00741 #endif
00742 
00743 #if defined(__WINDOWS_ASIO__)
00744 
00745 class RtApiAsio: public RtApi
00746 {
00747 public:
00748 
00749   RtApiAsio();
00750   ~RtApiAsio();
00751   void tickStream();
00752   void closeStream();
00753   void startStream();
00754   void stopStream();
00755   void abortStream();
00756   void setStreamCallback( RtAudioCallback callback, void *userData );
00757   void cancelStreamCallback();
00758 
00759   // This function is intended for internal use only.  It must be
00760   // public because it is called by the internal callback handler,
00761   // which is not a member of RtAudio.  External use of this function
00762   // will most likely produce highly undesireable results!
00763   void callbackEvent( long bufferIndex );
00764 
00765   private:
00766 
00767   void initialize(void);
00768   void probeDeviceInfo( RtApiDevice *info );
00769   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00770                         int sampleRate, RtAudioFormat format,
00771                         int *bufferSize, int numberOfBuffers );
00772 
00773   bool coInitialized;
00774 
00775 };
00776 
00777 #endif
00778 
00779 #if defined(__IRIX_AL__)
00780 
00781 class RtApiAl: public RtApi
00782 {
00783 public:
00784 
00785   RtApiAl();
00786   ~RtApiAl();
00787   int getDefaultOutputDevice(void);
00788   int getDefaultInputDevice(void);
00789   void tickStream();
00790   void closeStream();
00791   void startStream();
00792   void stopStream();
00793   void abortStream();
00794   int streamWillBlock();
00795   void setStreamCallback( RtAudioCallback callback, void *userData );
00796   void cancelStreamCallback();
00797 
00798   private:
00799 
00800   void initialize(void);
00801   void probeDeviceInfo( RtApiDevice *info );
00802   bool probeDeviceOpen( int device, StreamMode mode, int channels, 
00803                         int sampleRate, RtAudioFormat format,
00804                         int *bufferSize, int numberOfBuffers );
00805 };
00806 
00807 #endif
00808 
00809 // Define the following flag to have extra information spewed to stderr.
00810 //#define __RTAUDIO_DEBUG__
00811 
00812 #endif

The Synthesis ToolKit in C++ (STK)
©1995-2005 Perry R. Cook and Gary P. Scavone. All Rights Reserved.