Tutorial   Class/Enum List   File List   Compound Members  

RtAudio.h

00001 /************************************************************************/
00038 /************************************************************************/
00039 
00040 #if !defined(__RTAUDIO_H)
00041 #define __RTAUDIO_H
00042 
00043 #include <map>
00044 
00045 #if defined(__LINUX_ALSA__)
00046   #include <alsa/asoundlib.h>
00047   #include <pthread.h>
00048   #include <unistd.h>
00049 
00050   typedef snd_pcm_t *AUDIO_HANDLE;
00051   typedef int DEVICE_ID;
00052   typedef pthread_t THREAD_HANDLE;
00053   typedef pthread_mutex_t MUTEX;
00054 
00055 #elif defined(__LINUX_OSS__)
00056   #include <pthread.h>
00057   #include <unistd.h>
00058 
00059   typedef int AUDIO_HANDLE;
00060   typedef int DEVICE_ID;
00061   typedef pthread_t THREAD_HANDLE;
00062   typedef pthread_mutex_t MUTEX;
00063 
00064 #elif defined(__WINDOWS_DS__)
00065   #include <windows.h>
00066   #include <process.h>
00067 
00068   // The following struct is used to hold the extra variables
00069   // specific to the DirectSound implementation.
00070   typedef struct {
00071     void * object;
00072     void * buffer;
00073     UINT bufferPointer;
00074   } AUDIO_HANDLE;
00075 
00076   typedef LPGUID DEVICE_ID;
00077   typedef unsigned long THREAD_HANDLE;
00078   typedef CRITICAL_SECTION MUTEX;
00079 
00080 #elif defined(__WINDOWS_ASIO__)
00081   #include <windows.h>
00082   #include <process.h>
00083 
00084   typedef int AUDIO_HANDLE;
00085   typedef int DEVICE_ID;
00086   typedef unsigned long THREAD_HANDLE;
00087   typedef CRITICAL_SECTION MUTEX;
00088 
00089 #elif defined(__IRIX_AL__)
00090   #include <dmedia/audio.h>
00091   #include <pthread.h>
00092   #include <unistd.h>
00093 
00094   typedef ALport AUDIO_HANDLE;
00095   typedef long DEVICE_ID;
00096   typedef pthread_t THREAD_HANDLE;
00097   typedef pthread_mutex_t MUTEX;
00098 
00099 #elif defined(__MACOSX_CORE__)
00100 
00101   #include <CoreAudio/AudioHardware.h>
00102   #include <pthread.h>
00103 
00104   typedef unsigned int AUDIO_HANDLE;
00105   typedef AudioDeviceID DEVICE_ID;
00106   typedef pthread_t THREAD_HANDLE;
00107   typedef pthread_mutex_t MUTEX;
00108 
00109 #endif
00110 
00111 
00112 /************************************************************************/
00125 /************************************************************************/
00126 
00127 class RtError
00128 {
00129 public:
00131   enum TYPE {
00132     WARNING,
00133     DEBUG_WARNING,
00134     UNSPECIFIED,
00135     NO_DEVICES_FOUND,
00136     INVALID_DEVICE,
00137     INVALID_STREAM,
00138     MEMORY_ERROR,
00139     INVALID_PARAMETER,
00140     DRIVER_ERROR,
00141     SYSTEM_ERROR,
00142     THREAD_ERROR
00143   };
00144 
00145 protected:
00146   char error_message[256];
00147   TYPE type;
00148 
00149 public:
00151   RtError(const char *p, TYPE tipe = RtError::UNSPECIFIED);
00152 
00154   virtual ~RtError(void);
00155 
00157   virtual void printMessage(void);
00158 
00160   virtual const TYPE& getType(void) { return type; }
00161 
00163   virtual const char *getMessage(void) { return error_message; }
00164 };
00165 
00166 
00167 // This public structure type is used to pass callback information
00168 // between the private RtAudio stream structure and global callback
00169 // handling functions.
00170 typedef struct {
00171   void *object;  // Used as a "this" pointer.
00172   int streamId;
00173   DEVICE_ID device[2];
00174   THREAD_HANDLE thread;
00175   void *callback;
00176   void *buffers;
00177   unsigned long waitTime;
00178   bool blockTick;
00179   bool stopStream;
00180   bool usingCallback;
00181   void *userData;
00182 } CALLBACK_INFO;
00183 
00184 
00185 // *************************************************** //
00186 //
00187 // RtAudio class declaration.
00188 //
00189 // *************************************************** //
00190 
00191 class RtAudio
00192 {
00193 public:
00194 
00195   // Support for signed integers and floats.  Audio data fed to/from
00196   // the tickStream() routine is assumed to ALWAYS be in host
00197   // byte order.  The internal routines will automatically take care of
00198   // any necessary byte-swapping between the host format and the
00199   // soundcard.  Thus, endian-ness is not a concern in the following
00200   // format definitions.
00201   typedef unsigned long RTAUDIO_FORMAT;
00202   static const RTAUDIO_FORMAT RTAUDIO_SINT8; 
00203   static const RTAUDIO_FORMAT RTAUDIO_SINT16; 
00204   static const RTAUDIO_FORMAT RTAUDIO_SINT24; 
00205   static const RTAUDIO_FORMAT RTAUDIO_SINT32; 
00206   static const RTAUDIO_FORMAT RTAUDIO_FLOAT32; 
00207   static const RTAUDIO_FORMAT RTAUDIO_FLOAT64; 
00209   //static const int MAX_SAMPLE_RATES = 14;
00210   enum { MAX_SAMPLE_RATES = 14 };
00211 
00212   typedef int (*RTAUDIO_CALLBACK)(char *buffer, int bufferSize, void *userData);
00213 
00215   typedef struct {
00216     char name[128];    
00217     DEVICE_ID id[2];  /* No value reported by getDeviceInfo(). */
00218     bool probed;       
00219     int maxOutputChannels; 
00220     int maxInputChannels;  
00221     int maxDuplexChannels; 
00222     int minOutputChannels; 
00223     int minInputChannels;  
00224     int minDuplexChannels; 
00225     bool hasDuplexSupport; 
00226     bool isDefault;        
00227     int nSampleRates;      
00228     int sampleRates[MAX_SAMPLE_RATES]; 
00229     RTAUDIO_FORMAT nativeFormats;     
00230   } RTAUDIO_DEVICE;
00231 
00233 
00239   RtAudio();
00240 
00242 
00253   RtAudio(int *streamId,
00254           int outputDevice, int outputChannels,
00255           int inputDevice, int inputChannels,
00256           RTAUDIO_FORMAT format, int sampleRate,
00257           int *bufferSize, int numberOfBuffers);
00258 
00260 
00264   ~RtAudio();
00265 
00267 
00294   int openStream(int outputDevice, int outputChannels,
00295                  int inputDevice, int inputChannels,
00296                  RTAUDIO_FORMAT format, int sampleRate,
00297                  int *bufferSize, int numberOfBuffers);
00298 
00300 
00319   void setStreamCallback(int streamId, RTAUDIO_CALLBACK callback, void *userData);
00320 
00322 
00329   void cancelStreamCallback(int streamId);
00330 
00332   int getDeviceCount(void);
00333 
00335 
00343   void getDeviceInfo(int device, RTAUDIO_DEVICE *info);
00344 
00346 
00351   char * const getStreamBuffer(int streamId);
00352 
00354 
00359   void tickStream(int streamId);
00360 
00362 
00366   void closeStream(int streamId);
00367 
00369 
00373   void startStream(int streamId);
00374 
00376 
00380   void stopStream(int streamId);
00381 
00383 
00387   void abortStream(int streamId);
00388 
00390 
00395   int streamWillBlock(int streamId);
00396 
00397 #if (defined(__MACOSX_CORE__) || defined(__WINDOWS_ASIO__))
00398   // This function is intended for internal use only.  It must be
00399   // public because it is called by the internal callback handler,
00400   // which is not a member of RtAudio.  External use of this function
00401   // will most likely produce highly undesireable results!
00402   void callbackEvent(int streamId, DEVICE_ID deviceId, void *inData, void *outData);
00403 #endif
00404 
00405 protected:
00406 
00407 private:
00408 
00409   static const unsigned int SAMPLE_RATES[MAX_SAMPLE_RATES];
00410 
00411   enum { FAILURE, SUCCESS };
00412 
00413   enum STREAM_MODE {
00414     OUTPUT,
00415     INPUT,
00416     DUPLEX,
00417     UNINITIALIZED = -75
00418   };
00419 
00420   enum STREAM_STATE {
00421     STREAM_STOPPED,
00422     STREAM_RUNNING
00423   };
00424 
00425   typedef struct {
00426     int device[2];          // Playback and record, respectively.
00427     STREAM_MODE mode;       // OUTPUT, INPUT, or DUPLEX.
00428     AUDIO_HANDLE handle[2]; // Playback and record handles, respectively.
00429     STREAM_STATE state;     // STOPPED or RUNNING
00430     char *userBuffer;
00431     char *deviceBuffer;
00432     bool doConvertBuffer[2]; // Playback and record, respectively.
00433     bool deInterleave[2];    // Playback and record, respectively.
00434     bool doByteSwap[2];      // Playback and record, respectively.
00435     int sampleRate;
00436     int bufferSize;
00437     int nBuffers;
00438     int nUserChannels[2];    // Playback and record, respectively.
00439     int nDeviceChannels[2];  // Playback and record channels, respectively.
00440     RTAUDIO_FORMAT userFormat;
00441     RTAUDIO_FORMAT deviceFormat[2]; // Playback and record, respectively.
00442     MUTEX mutex;
00443     CALLBACK_INFO callbackInfo;
00444   } RTAUDIO_STREAM;
00445 
00446   typedef signed short INT16;
00447   typedef signed int INT32;
00448   typedef float FLOAT32;
00449   typedef double FLOAT64;
00450 
00451   char message[256];
00452   int nDevices;
00453   RTAUDIO_DEVICE *devices;
00454 
00455   std::map<int, void *> streams;
00456 
00458   void error(RtError::TYPE type);
00459 
00464   void initialize(void);
00465 
00470   int getDefaultInputDevice(void);
00471 
00476   int getDefaultOutputDevice(void);
00477 
00479   void clearDeviceInfo(RTAUDIO_DEVICE *info);
00480 
00488   void probeDeviceInfo(RTAUDIO_DEVICE *info);
00489 
00496   bool probeDeviceOpen(int device, RTAUDIO_STREAM *stream,
00497                        STREAM_MODE mode, int channels, 
00498                        int sampleRate, RTAUDIO_FORMAT format,
00499                        int *bufferSize, int numberOfBuffers);
00500 
00507   void *verifyStream(int streamId);
00508 
00513   void convertStreamBuffer(RTAUDIO_STREAM *stream, STREAM_MODE mode);
00514 
00516   void byteSwapBuffer(char *buffer, int samples, RTAUDIO_FORMAT format);
00517 
00519   int formatBytes(RTAUDIO_FORMAT format);
00520 };
00521 
00522 // Define the following flag to have extra information spewed to stderr.
00523 //#define __RTAUDIO_DEBUG__
00524 
00525 #endif

©2001-2002 Gary P. Scavone, CCRMA, Stanford University. All Rights Reserved.
Maintained by Gary P. Scavone, gary@ccrma.stanford.edu