Home   Class/Enum List   File List   Compound Members  

RtAudio.h

Go to the documentation of this file.
00001 /************************************************************************/
00039 /************************************************************************/
00040 
00045 // RtAudio: Version 4.0.4
00046 
00047 #ifndef __RTAUDIO_H
00048 #define __RTAUDIO_H
00049 
00050 #include <string>
00051 #include <vector>
00052 #include "RtError.h"
00053 
00070 typedef unsigned long RtAudioFormat;
00071 static const RtAudioFormat RTAUDIO_SINT8 = 0x1;    // 8-bit signed integer.
00072 static const RtAudioFormat RTAUDIO_SINT16 = 0x2;   // 16-bit signed integer.
00073 static const RtAudioFormat RTAUDIO_SINT24 = 0x4;   // Lower 3 bytes of 32-bit signed integer.
00074 static const RtAudioFormat RTAUDIO_SINT32 = 0x8;   // 32-bit signed integer.
00075 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
00076 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
00077 
00112 typedef unsigned int RtAudioStreamFlags;
00113 static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1;    // Use non-interleaved buffers (default = interleaved).
00114 static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2;  // Attempt to set stream parameters for lowest possible latency.
00115 static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4;        // Attempt grab device and prevent use by others.
00116 
00128 typedef unsigned int RtAudioStreamStatus;
00129 static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1;    // Input data was discarded because of an overflow condition at the driver.
00130 static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2;  // The output buffer ran low, likely causing a gap in the output sound.
00131 
00133 
00171 typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
00172                                 unsigned int nFrames,
00173                                 double streamTime,
00174                                 RtAudioStreamStatus status,
00175                                 void *userData );
00176 
00177 
00178 // **************************************************************** //
00179 //
00180 // RtAudio class declaration.
00181 //
00182 // RtAudio is a "controller" used to select an available audio i/o
00183 // interface.  It presents a common API for the user to call but all
00184 // functionality is implemented by the class RtApi and its
00185 // subclasses.  RtAudio creates an instance of an RtApi subclass
00186 // based on the user's API choice.  If no choice is made, RtAudio
00187 // attempts to make a "logical" API selection.
00188 //
00189 // **************************************************************** //
00190 
00191 class RtApi;
00192 
00193 class RtAudio
00194 {
00195  public:
00196 
00198   enum Api {
00199     UNSPECIFIED,    
00200     LINUX_ALSA,     
00201     LINUX_OSS,      
00202     UNIX_JACK,      
00203     MACOSX_CORE,    
00204     WINDOWS_ASIO,   
00205     WINDOWS_DS,     
00206     RTAUDIO_DUMMY   
00207   };
00208 
00210   struct DeviceInfo {
00211     bool probed;                  
00212     std::string name;             
00213     unsigned int outputChannels;  
00214     unsigned int inputChannels;   
00215     unsigned int duplexChannels;  
00216     bool isDefaultOutput;         
00217     bool isDefaultInput;          
00218     std::vector<unsigned int> sampleRates; 
00219     RtAudioFormat nativeFormats;  
00221     // Default constructor.
00222     DeviceInfo()
00223       :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0),
00224        isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {}
00225   };
00226 
00228   struct StreamParameters {
00229     unsigned int deviceId;     
00230     unsigned int nChannels;    
00231     unsigned int firstChannel; 
00233     // Default constructor.
00234     StreamParameters()
00235       : deviceId(0), nChannels(0), firstChannel(0) {}
00236   };
00237 
00239 
00284   struct StreamOptions {
00285     RtAudioStreamFlags flags;      
00286     unsigned int numberOfBuffers;  
00287     std::string streamName;        
00289     // Default constructor.
00290     StreamOptions()
00291       : flags(0), numberOfBuffers(0) {}
00292   };
00293 
00295 
00300   static void getCompiledApi( std::vector<RtAudio::Api> &apis ) throw();
00301 
00303 
00311   RtAudio( RtAudio::Api api=UNSPECIFIED ) throw();
00312 
00314 
00318   ~RtAudio() throw();
00319 
00321   RtAudio::Api getCurrentApi( void ) throw();
00322 
00324 
00329   unsigned int getDeviceCount( void ) throw();
00330 
00332 
00342   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00343 
00345 
00352   unsigned int getDefaultOutputDevice( void ) throw();
00353 
00355 
00362   unsigned int getDefaultInputDevice( void ) throw();
00363 
00365 
00402   void openStream( RtAudio::StreamParameters *outputParameters,
00403                    RtAudio::StreamParameters *inputParameters,
00404                    RtAudioFormat format, unsigned int sampleRate,
00405                    unsigned int *bufferFrames, RtAudioCallback callback,
00406                    void *userData = NULL, RtAudio::StreamOptions *options = NULL );
00407 
00409 
00413   void closeStream( void ) throw();
00414 
00416 
00422   void startStream( void );
00423 
00425 
00431   void stopStream( void );
00432 
00434 
00440   void abortStream( void );
00441 
00443   bool isStreamOpen( void ) throw();
00444 
00446   bool isStreamRunning( void ) throw();
00447 
00449 
00452   double getStreamTime( void );
00453 
00455 
00463   long getStreamLatency( void );
00464 
00466   void showWarnings( bool value = true ) throw();
00467 
00468  protected:
00469 
00470   void openRtApi( RtAudio::Api api );
00471   RtApi *rtapi_;
00472 };
00473 
00474 // Operating system dependent thread functionality.
00475 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
00476   #include <windows.h>
00477   #include <process.h>
00478 
00479   typedef unsigned long ThreadHandle;
00480   typedef CRITICAL_SECTION StreamMutex;
00481 
00482 #elif defined(__LINUX_ALSA__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
00483   // Using pthread library for various flavors of unix.
00484   #include <pthread.h>
00485 
00486   typedef pthread_t ThreadHandle;
00487   typedef pthread_mutex_t StreamMutex;
00488 
00489 #else // Setup for "dummy" behavior
00490 
00491   #define __RTAUDIO_DUMMY__
00492   typedef int ThreadHandle;
00493   typedef int StreamMutex;
00494 
00495 #endif
00496 
00497 // This global structure type is used to pass callback information
00498 // between the private RtAudio stream structure and global callback
00499 // handling functions.
00500 struct CallbackInfo {
00501   void *object;    // Used as a "this" pointer.
00502   ThreadHandle thread;
00503   void *callback;
00504   void *userData;
00505   void *apiInfo;   // void pointer for API specific callback information
00506   bool isRunning;
00507 
00508   // Default constructor.
00509   CallbackInfo()
00510     :object(0), callback(0), userData(0), apiInfo(0), isRunning(false) {}
00511 };
00512 
00513 // **************************************************************** //
00514 //
00515 // RtApi class declaration.
00516 //
00517 // Subclasses of RtApi contain all API- and OS-specific code necessary
00518 // to fully implement the RtAudio API.
00519 //
00520 // Note that RtApi is an abstract base class and cannot be
00521 // explicitly instantiated.  The class RtAudio will create an
00522 // instance of an RtApi subclass (RtApiOss, RtApiAlsa,
00523 // RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio).
00524 //
00525 // **************************************************************** //
00526 
00527 #if defined( HAVE_GETTIMEOFDAY )
00528   #include <sys/time.h>
00529 #endif
00530 
00531 #include <sstream>
00532 
00533 class RtApi
00534 {
00535 public:
00536 
00537   RtApi();
00538   virtual ~RtApi();
00539   virtual RtAudio::Api getCurrentApi( void ) = 0;
00540   virtual unsigned int getDeviceCount( void ) = 0;
00541   virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
00542   virtual unsigned int getDefaultInputDevice( void );
00543   virtual unsigned int getDefaultOutputDevice( void );
00544   void openStream( RtAudio::StreamParameters *outputParameters,
00545                    RtAudio::StreamParameters *inputParameters,
00546                    RtAudioFormat format, unsigned int sampleRate,
00547                    unsigned int *bufferFrames, RtAudioCallback callback,
00548                    void *userData, RtAudio::StreamOptions *options );
00549   virtual void closeStream( void );
00550   virtual void startStream( void ) = 0;
00551   virtual void stopStream( void ) = 0;
00552   virtual void abortStream( void ) = 0;
00553   long getStreamLatency( void );
00554   virtual double getStreamTime( void );
00555   bool isStreamOpen( void ) { return stream_.state != STREAM_CLOSED; };
00556   bool isStreamRunning( void ) { return stream_.state == STREAM_RUNNING; };
00557   void showWarnings( bool value ) { showWarnings_ = value; };
00558 
00559 
00560 protected:
00561 
00562   static const unsigned int MAX_SAMPLE_RATES;
00563   static const unsigned int SAMPLE_RATES[];
00564 
00565   enum { FAILURE, SUCCESS };
00566 
00567   enum StreamState {
00568     STREAM_STOPPED,
00569     STREAM_RUNNING,
00570     STREAM_CLOSED = -50
00571   };
00572 
00573   enum StreamMode {
00574     OUTPUT,
00575     INPUT,
00576     DUPLEX,
00577     UNINITIALIZED = -75
00578   };
00579 
00580   // A protected structure used for buffer conversion.
00581   struct ConvertInfo {
00582     int channels;
00583     int inJump, outJump;
00584     RtAudioFormat inFormat, outFormat;
00585     std::vector<int> inOffset;
00586     std::vector<int> outOffset;
00587   };
00588 
00589   // A protected structure for audio streams.
00590   struct RtApiStream {
00591     unsigned int device[2];    // Playback and record, respectively.
00592     void *apiHandle;           // void pointer for API specific stream handle information
00593     StreamMode mode;           // OUTPUT, INPUT, or DUPLEX.
00594     StreamState state;         // STOPPED, RUNNING, or CLOSED
00595     char *userBuffer[2];       // Playback and record, respectively.
00596     char *deviceBuffer;
00597     bool doConvertBuffer[2];   // Playback and record, respectively.
00598     bool userInterleaved;
00599     bool deviceInterleaved[2]; // Playback and record, respectively.
00600     bool doByteSwap[2];        // Playback and record, respectively.
00601     unsigned int sampleRate;
00602     unsigned int bufferSize;
00603     unsigned int nBuffers;
00604     unsigned int nUserChannels[2];    // Playback and record, respectively.
00605     unsigned int nDeviceChannels[2];  // Playback and record channels, respectively.
00606     unsigned int channelOffset[2];    // Playback and record, respectively.
00607     unsigned long latency[2];         // Playback and record, respectively.
00608     RtAudioFormat userFormat;
00609     RtAudioFormat deviceFormat[2];    // Playback and record, respectively.
00610     StreamMutex mutex;
00611     CallbackInfo callbackInfo;
00612     ConvertInfo convertInfo[2];
00613     double streamTime;         // Number of elapsed seconds since the stream started.
00614 
00615 #if defined(HAVE_GETTIMEOFDAY)
00616     struct timeval lastTickTimestamp;
00617 #endif
00618 
00619     RtApiStream()
00620       :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
00621   };
00622 
00623   typedef signed short Int16;
00624   typedef signed int Int32;
00625   typedef float Float32;
00626   typedef double Float64;
00627 
00628   std::ostringstream errorStream_;
00629   std::string errorText_;
00630   bool showWarnings_;
00631   RtApiStream stream_;
00632 
00640   virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00641                                 unsigned int firstChannel, unsigned int sampleRate,
00642                                 RtAudioFormat format, unsigned int *bufferSize,
00643                                 RtAudio::StreamOptions *options );
00644 
00646   void tickStreamTime( void );
00647 
00649   void clearStreamInfo();
00650 
00655   void verifyStream( void );
00656 
00658   void error( RtError::Type type );
00659 
00664   void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
00665 
00667   void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
00668 
00670   unsigned int formatBytes( RtAudioFormat format );
00671 
00673   void setConvertInfo( StreamMode mode, unsigned int firstChannel );
00674 };
00675 
00676 // **************************************************************** //
00677 //
00678 // Inline RtAudio definitions.
00679 //
00680 // **************************************************************** //
00681 
00682 inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
00683 inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); }
00684 inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); }
00685 inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); }
00686 inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); }
00687 inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); }
00688 inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
00689 inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); }
00690 inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
00691 inline bool RtAudio :: isStreamOpen( void ) throw() { return rtapi_->isStreamOpen(); }
00692 inline bool RtAudio :: isStreamRunning( void ) throw() { return rtapi_->isStreamRunning(); }
00693 inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
00694 inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
00695 inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); }
00696 
00697 // RtApi Subclass prototypes.
00698 
00699 #if defined(__MACOSX_CORE__)
00700 
00701 #include <CoreAudio/AudioHardware.h>
00702 
00703 class RtApiCore: public RtApi
00704 {
00705 public:
00706 
00707   RtApiCore();
00708   ~RtApiCore();
00709   RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; };
00710   unsigned int getDeviceCount( void );
00711   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00712   unsigned int getDefaultOutputDevice( void );
00713   unsigned int getDefaultInputDevice( void );
00714   void closeStream( void );
00715   void startStream( void );
00716   void stopStream( void );
00717   void abortStream( void );
00718   long getStreamLatency( void );
00719 
00720   // This function is intended for internal use only.  It must be
00721   // public because it is called by the internal callback handler,
00722   // which is not a member of RtAudio.  External use of this function
00723   // will most likely produce highly undesireable results!
00724   bool callbackEvent( AudioDeviceID deviceId,
00725                       const AudioBufferList *inBufferList,
00726                       const AudioBufferList *outBufferList );
00727 
00728   private:
00729 
00730   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00731                         unsigned int firstChannel, unsigned int sampleRate,
00732                         RtAudioFormat format, unsigned int *bufferSize,
00733                         RtAudio::StreamOptions *options );
00734   static const char* getErrorCode( OSStatus code );
00735 };
00736 
00737 #endif
00738 
00739 #if defined(__UNIX_JACK__)
00740 
00741 class RtApiJack: public RtApi
00742 {
00743 public:
00744 
00745   RtApiJack();
00746   ~RtApiJack();
00747   RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; };
00748   unsigned int getDeviceCount( void );
00749   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00750   void closeStream( void );
00751   void startStream( void );
00752   void stopStream( void );
00753   void abortStream( void );
00754   long getStreamLatency( void );
00755 
00756   // This function is intended for internal use only.  It must be
00757   // public because it is called by the internal callback handler,
00758   // which is not a member of RtAudio.  External use of this function
00759   // will most likely produce highly undesireable results!
00760   bool callbackEvent( unsigned long nframes );
00761 
00762   private:
00763 
00764   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00765                         unsigned int firstChannel, unsigned int sampleRate,
00766                         RtAudioFormat format, unsigned int *bufferSize,
00767                         RtAudio::StreamOptions *options );
00768 };
00769 
00770 #endif
00771 
00772 #if defined(__WINDOWS_ASIO__)
00773 
00774 class RtApiAsio: public RtApi
00775 {
00776 public:
00777 
00778   RtApiAsio();
00779   ~RtApiAsio();
00780   RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; };
00781   unsigned int getDeviceCount( void );
00782   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00783   void closeStream( void );
00784   void startStream( void );
00785   void stopStream( void );
00786   void abortStream( void );
00787   long getStreamLatency( void );
00788 
00789   // This function is intended for internal use only.  It must be
00790   // public because it is called by the internal callback handler,
00791   // which is not a member of RtAudio.  External use of this function
00792   // will most likely produce highly undesireable results!
00793   bool callbackEvent( long bufferIndex );
00794 
00795   private:
00796 
00797   std::vector<RtAudio::DeviceInfo> devices_;
00798   void saveDeviceInfo( void );
00799   bool coInitialized_;
00800   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00801                         unsigned int firstChannel, unsigned int sampleRate,
00802                         RtAudioFormat format, unsigned int *bufferSize,
00803                         RtAudio::StreamOptions *options );
00804 };
00805 
00806 #endif
00807 
00808 #if defined(__WINDOWS_DS__)
00809 
00810 class RtApiDs: public RtApi
00811 {
00812 public:
00813 
00814   RtApiDs();
00815   ~RtApiDs();
00816   RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; };
00817   unsigned int getDeviceCount( void );
00818   unsigned int getDefaultOutputDevice( void );
00819   unsigned int getDefaultInputDevice( void );
00820   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00821   void closeStream( void );
00822   void startStream( void );
00823   void stopStream( void );
00824   void abortStream( void );
00825   long getStreamLatency( void );
00826 
00827   // This function is intended for internal use only.  It must be
00828   // public because it is called by the internal callback handler,
00829   // which is not a member of RtAudio.  External use of this function
00830   // will most likely produce highly undesireable results!
00831   void callbackEvent( void );
00832 
00833   private:
00834 
00835   bool coInitialized_;
00836   bool buffersRolling;
00837   long duplexPrerollBytes;
00838   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00839                         unsigned int firstChannel, unsigned int sampleRate,
00840                         RtAudioFormat format, unsigned int *bufferSize,
00841                         RtAudio::StreamOptions *options );
00842 };
00843 
00844 #endif
00845 
00846 #if defined(__LINUX_ALSA__)
00847 
00848 class RtApiAlsa: public RtApi
00849 {
00850 public:
00851 
00852   RtApiAlsa();
00853   ~RtApiAlsa();
00854   RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; };
00855   unsigned int getDeviceCount( void );
00856   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00857   void closeStream( void );
00858   void startStream( void );
00859   void stopStream( void );
00860   void abortStream( void );
00861 
00862   // This function is intended for internal use only.  It must be
00863   // public because it is called by the internal callback handler,
00864   // which is not a member of RtAudio.  External use of this function
00865   // will most likely produce highly undesireable results!
00866   void callbackEvent( void );
00867 
00868   private:
00869 
00870   std::vector<RtAudio::DeviceInfo> devices_;
00871   void saveDeviceInfo( void );
00872   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00873                         unsigned int firstChannel, unsigned int sampleRate,
00874                         RtAudioFormat format, unsigned int *bufferSize,
00875                         RtAudio::StreamOptions *options );
00876 };
00877 
00878 #endif
00879 
00880 #if defined(__LINUX_OSS__)
00881 
00882 class RtApiOss: public RtApi
00883 {
00884 public:
00885 
00886   RtApiOss();
00887   ~RtApiOss();
00888   RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; };
00889   unsigned int getDeviceCount( void );
00890   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00891   void closeStream( void );
00892   void startStream( void );
00893   void stopStream( void );
00894   void abortStream( void );
00895 
00896   // This function is intended for internal use only.  It must be
00897   // public because it is called by the internal callback handler,
00898   // which is not a member of RtAudio.  External use of this function
00899   // will most likely produce highly undesireable results!
00900   void callbackEvent( void );
00901 
00902   private:
00903 
00904   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00905                         unsigned int firstChannel, unsigned int sampleRate,
00906                         RtAudioFormat format, unsigned int *bufferSize,
00907                         RtAudio::StreamOptions *options );
00908 };
00909 
00910 #endif
00911 
00912 #if defined(__RTAUDIO_DUMMY__)
00913 
00914 class RtApiDummy: public RtApi
00915 {
00916 public:
00917 
00918   RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtError::WARNING ); };
00919   RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; };
00920   unsigned int getDeviceCount( void ) { return 0; };
00921   RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) { RtAudio::DeviceInfo info; return info; };
00922   void closeStream( void ) {};
00923   void startStream( void ) {};
00924   void stopStream( void ) {};
00925   void abortStream( void ) {};
00926 
00927   private:
00928 
00929   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00930                         unsigned int firstChannel, unsigned int sampleRate,
00931                         RtAudioFormat format, unsigned int *bufferSize,
00932                         RtAudio::StreamOptions *options ) { return false; };
00933 };
00934 
00935 #endif
00936 
00937 #endif
00938 
00939 // Indentation settings for Vim and Emacs
00940 //
00941 // Local Variables:
00942 // c-basic-offset: 2
00943 // indent-tabs-mode: nil
00944 // End:
00945 //
00946 // vim: et sts=2 sw=2

©2001-2008 Gary P. Scavone, McGill University. All Rights Reserved.
Maintained by Gary P. Scavone.