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
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 ErrorType {
00568     WARNING,
00569     INVALID_CALL,
00570     SYSTEM
00571   };
00572 
00573   enum StreamState {
00574     STREAM_STOPPED,
00575     STREAM_RUNNING,
00576     STREAM_CLOSED = -50
00577   };
00578 
00579   enum StreamMode {
00580     OUTPUT,
00581     INPUT,
00582     DUPLEX,
00583     UNINITIALIZED = -75
00584   };
00585 
00586   // A protected structure used for buffer conversion.
00587   struct ConvertInfo {
00588     int channels;
00589     int inJump, outJump;
00590     RtAudioFormat inFormat, outFormat;
00591     std::vector<int> inOffset;
00592     std::vector<int> outOffset;
00593   };
00594 
00595   // A protected structure for audio streams.
00596   struct RtApiStream {
00597     unsigned int device[2];    // Playback and record, respectively.
00598     void *apiHandle;           // void pointer for API specific stream handle information
00599     StreamMode mode;           // OUTPUT, INPUT, or DUPLEX.
00600     StreamState state;         // STOPPED, RUNNING, or CLOSED
00601     char *userBuffer[2];       // Playback and record, respectively.
00602     char *deviceBuffer;
00603     bool doConvertBuffer[2];   // Playback and record, respectively.
00604     bool userInterleaved;
00605     bool deviceInterleaved[2]; // Playback and record, respectively.
00606     bool doByteSwap[2];        // Playback and record, respectively.
00607     unsigned int sampleRate;
00608     unsigned int bufferSize;
00609     unsigned int nBuffers;
00610     unsigned int nUserChannels[2];    // Playback and record, respectively.
00611     unsigned int nDeviceChannels[2];  // Playback and record channels, respectively.
00612     unsigned int channelOffset[2];    // Playback and record, respectively.
00613     unsigned long latency[2];         // Playback and record, respectively.
00614     RtAudioFormat userFormat;
00615     RtAudioFormat deviceFormat[2];    // Playback and record, respectively.
00616     StreamMutex mutex;
00617     CallbackInfo callbackInfo;
00618     ConvertInfo convertInfo[2];
00619     double streamTime;         // Number of elapsed seconds since the stream started.
00620 
00621 #if defined(HAVE_GETTIMEOFDAY)
00622     struct timeval lastTickTimestamp;
00623 #endif
00624 
00625     RtApiStream()
00626       :apiHandle(0), deviceBuffer(0) {}
00627   };
00628 
00629   typedef signed short Int16;
00630   typedef signed int Int32;
00631   typedef float Float32;
00632   typedef double Float64;
00633 
00634   std::ostringstream errorStream_;
00635   std::string errorText_;
00636   bool showWarnings_;
00637   RtApiStream stream_;
00638 
00646   virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00647                                 unsigned int firstChannel, unsigned int sampleRate,
00648                                 RtAudioFormat format, unsigned int *bufferSize,
00649                                 RtAudio::StreamOptions *options );
00650 
00652   void tickStreamTime( void );
00653 
00655   void clearStreamInfo();
00656 
00661   void verifyStream( void );
00662 
00664   void error( ErrorType type );
00665 
00670   void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
00671 
00673   void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
00674 
00676   unsigned int formatBytes( RtAudioFormat format );
00677 
00679   void setConvertInfo( StreamMode mode, unsigned int firstChannel );
00680 };
00681 
00682 // **************************************************************** //
00683 //
00684 // Inline RtAudio definitions.
00685 //
00686 // **************************************************************** //
00687 
00688 inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); };
00689 inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); };
00690 inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); };
00691 inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); };
00692 inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); };
00693 inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); };
00694 inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); };
00695 inline void RtAudio :: stopStream( void )  { return rtapi_->stopStream(); };
00696 inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); };
00697 inline bool RtAudio :: isStreamOpen( void ) throw() { return rtapi_->isStreamOpen(); };
00698 inline bool RtAudio :: isStreamRunning( void ) throw() { return rtapi_->isStreamRunning(); };
00699 inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); };
00700 inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); };
00701 inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); };
00702 
00703 // RtApi Subclass prototypes.
00704 
00705 #if defined(__MACOSX_CORE__)
00706 
00707 #include <CoreAudio/AudioHardware.h>
00708 
00709 class RtApiCore: public RtApi
00710 {
00711 public:
00712 
00713   RtApiCore();
00714   ~RtApiCore();
00715   RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; };
00716   unsigned int getDeviceCount( void );
00717   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00718   unsigned int getDefaultOutputDevice( void );
00719   unsigned int getDefaultInputDevice( void );
00720   void closeStream( void );
00721   void startStream( void );
00722   void stopStream( void );
00723   void abortStream( void );
00724   long getStreamLatency( void );
00725 
00726   // This function is intended for internal use only.  It must be
00727   // public because it is called by the internal callback handler,
00728   // which is not a member of RtAudio.  External use of this function
00729   // will most likely produce highly undesireable results!
00730   bool callbackEvent( AudioDeviceID deviceId,
00731                       const AudioBufferList *inBufferList,
00732                       const AudioBufferList *outBufferList );
00733 
00734   private:
00735 
00736   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00737                         unsigned int firstChannel, unsigned int sampleRate,
00738                         RtAudioFormat format, unsigned int *bufferSize,
00739                         RtAudio::StreamOptions *options );
00740   static const char* getErrorCode( OSStatus code );
00741 };
00742 
00743 #endif
00744 
00745 #if defined(__UNIX_JACK__)
00746 
00747 class RtApiJack: public RtApi
00748 {
00749 public:
00750 
00751   RtApiJack();
00752   ~RtApiJack();
00753   RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; };
00754   unsigned int getDeviceCount( void );
00755   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00756   void closeStream( void );
00757   void startStream( void );
00758   void stopStream( void );
00759   void abortStream( void );
00760   long getStreamLatency( void );
00761 
00762   // This function is intended for internal use only.  It must be
00763   // public because it is called by the internal callback handler,
00764   // which is not a member of RtAudio.  External use of this function
00765   // will most likely produce highly undesireable results!
00766   bool callbackEvent( unsigned long nframes );
00767 
00768   private:
00769 
00770   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00771                         unsigned int firstChannel, unsigned int sampleRate,
00772                         RtAudioFormat format, unsigned int *bufferSize,
00773                         RtAudio::StreamOptions *options );
00774 };
00775 
00776 #endif
00777 
00778 #if defined(__WINDOWS_ASIO__)
00779 
00780 class RtApiAsio: public RtApi
00781 {
00782 public:
00783 
00784   RtApiAsio();
00785   ~RtApiAsio();
00786   RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; };
00787   unsigned int getDeviceCount( void );
00788   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00789   void closeStream( void );
00790   void startStream( void );
00791   void stopStream( void );
00792   void abortStream( void );
00793   long getStreamLatency( void );
00794 
00795   // This function is intended for internal use only.  It must be
00796   // public because it is called by the internal callback handler,
00797   // which is not a member of RtAudio.  External use of this function
00798   // will most likely produce highly undesireable results!
00799   bool callbackEvent( long bufferIndex );
00800 
00801   private:
00802 
00803   bool coInitialized_;
00804   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00805                         unsigned int firstChannel, unsigned int sampleRate,
00806                         RtAudioFormat format, unsigned int *bufferSize,
00807                         RtAudio::StreamOptions *options );
00808 };
00809 
00810 #endif
00811 
00812 #if defined(__WINDOWS_DS__)
00813 
00814 class RtApiDs: public RtApi
00815 {
00816 public:
00817 
00818   RtApiDs();
00819   ~RtApiDs();
00820   RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; };
00821   unsigned int getDeviceCount( void );
00822   unsigned int getDefaultOutputDevice( void );
00823   unsigned int getDefaultInputDevice( void );
00824   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00825   void closeStream( void );
00826   void startStream( void );
00827   void stopStream( void );
00828   void abortStream( void );
00829   long getStreamLatency( void );
00830 
00831   // This function is intended for internal use only.  It must be
00832   // public because it is called by the internal callback handler,
00833   // which is not a member of RtAudio.  External use of this function
00834   // will most likely produce highly undesireable results!
00835   void callbackEvent( void );
00836 
00837   private:
00838 
00839   bool coInitialized_;
00840   bool buffersRolling;
00841   long duplexPrerollBytes;
00842   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00843                         unsigned int firstChannel, unsigned int sampleRate,
00844                         RtAudioFormat format, unsigned int *bufferSize,
00845                         RtAudio::StreamOptions *options );
00846 };
00847 
00848 #endif
00849 
00850 #if defined(__LINUX_ALSA__)
00851 
00852 class RtApiAlsa: public RtApi
00853 {
00854 public:
00855 
00856   RtApiAlsa();
00857   ~RtApiAlsa();
00858   RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; };
00859   unsigned int getDeviceCount( void );
00860   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00861   void closeStream( void );
00862   void startStream( void );
00863   void stopStream( void );
00864   void abortStream( void );
00865 
00866   // This function is intended for internal use only.  It must be
00867   // public because it is called by the internal callback handler,
00868   // which is not a member of RtAudio.  External use of this function
00869   // will most likely produce highly undesireable results!
00870   void callbackEvent( void );
00871 
00872   private:
00873 
00874   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00875                         unsigned int firstChannel, unsigned int sampleRate,
00876                         RtAudioFormat format, unsigned int *bufferSize,
00877                         RtAudio::StreamOptions *options );
00878 };
00879 
00880 #endif
00881 
00882 #if defined(__LINUX_OSS__)
00883 
00884 class RtApiOss: public RtApi
00885 {
00886 public:
00887 
00888   RtApiOss();
00889   ~RtApiOss();
00890   RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; };
00891   unsigned int getDeviceCount( void );
00892   RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
00893   void closeStream( void );
00894   void startStream( void );
00895   void stopStream( void );
00896   void abortStream( void );
00897 
00898   // This function is intended for internal use only.  It must be
00899   // public because it is called by the internal callback handler,
00900   // which is not a member of RtAudio.  External use of this function
00901   // will most likely produce highly undesireable results!
00902   void callbackEvent( void );
00903 
00904   private:
00905 
00906   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00907                         unsigned int firstChannel, unsigned int sampleRate,
00908                         RtAudioFormat format, unsigned int *bufferSize,
00909                         RtAudio::StreamOptions *options );
00910 };
00911 
00912 #endif
00913 
00914 #if defined(__RTAUDIO_DUMMY__)
00915 
00916 class RtApiDummy: public RtApi
00917 {
00918 public:
00919 
00920   RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( WARNING ); };
00921   RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; };
00922   unsigned int getDeviceCount( void ) { return 0; };
00923   RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) { RtAudio::DeviceInfo info; return info; };
00924   void closeStream( void ) {};
00925   void startStream( void ) {};
00926   void stopStream( void ) {};
00927   void abortStream( void ) {};
00928 
00929   private:
00930 
00931   bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 
00932                         unsigned int firstChannel, unsigned int sampleRate,
00933                         RtAudioFormat format, unsigned int *bufferSize,
00934                         RtAudio::StreamOptions *options ) { return false; };
00935 };
00936 
00937 #endif
00938 
00939 #endif
00940 
00941 // Indentation settings for Vim and Emacs
00942 //
00943 // Local Variables:
00944 // c-basic-offset: 2
00945 // indent-tabs-mode: nil
00946 // End:
00947 //
00948 // vim: et sts=2 sw=2

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