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 <CoreServices/CoreServices.h>
00102   #include <CoreAudio/AudioHardware.h>
00103   #include <pthread.h>
00104 
00105   typedef unsigned int AUDIO_HANDLE;
00106   typedef AudioDeviceID DEVICE_ID;
00107   typedef pthread_t THREAD_HANDLE;
00108   typedef pthread_mutex_t MUTEX;
00109 
00110 #endif
00111 
00112 
00113 /************************************************************************/
00126 /************************************************************************/
00127 
00128 class RtError
00129 {
00130 public:
00132   enum TYPE {
00133     WARNING,
00134     DEBUG_WARNING,
00135     UNSPECIFIED,
00136     NO_DEVICES_FOUND,
00137     INVALID_DEVICE,
00138     INVALID_STREAM,
00139     MEMORY_ERROR,
00140     INVALID_PARAMETER,
00141     DRIVER_ERROR,
00142     SYSTEM_ERROR,
00143     THREAD_ERROR
00144   };
00145 
00146 protected:
00147   char error_message[256];
00148   TYPE type;
00149 
00150 public:
00152   RtError(const char *p, TYPE tipe = RtError::UNSPECIFIED);
00153 
00155   virtual ~RtError(void);
00156 
00158   virtual void printMessage(void);
00159 
00161   virtual const TYPE& getType(void) { return type; }
00162 
00164   virtual const char *getMessage(void) { return error_message; }
00165 };
00166 
00167 
00168 // This public structure type is used to pass callback information
00169 // between the private RtAudio stream structure and global callback
00170 // handling functions.
00171 typedef struct {
00172   void *object;  // Used as a "this" pointer.
00173   int streamId;
00174   DEVICE_ID device[2];
00175   THREAD_HANDLE thread;
00176   void *callback;
00177   void *buffers;
00178   unsigned long waitTime;
00179   bool blockTick;
00180   bool stopStream;
00181   bool usingCallback;
00182   void *userData;
00183 } CALLBACK_INFO;
00184 
00185 
00186 // *************************************************** //
00187 //
00188 // RtAudio class declaration.
00189 //
00190 // *************************************************** //
00191 
00192 class RtAudio
00193 {
00194 public:
00195 
00196   // Support for signed integers and floats.  Audio data fed to/from
00197   // the tickStream() routine is assumed to ALWAYS be in host
00198   // byte order.  The internal routines will automatically take care of
00199   // any necessary byte-swapping between the host format and the
00200   // soundcard.  Thus, endian-ness is not a concern in the following
00201   // format definitions.
00202   typedef unsigned long RTAUDIO_FORMAT;
00203   static const RTAUDIO_FORMAT RTAUDIO_SINT8; 
00204   static const RTAUDIO_FORMAT RTAUDIO_SINT16; 
00205   static const RTAUDIO_FORMAT RTAUDIO_SINT24; 
00206   static const RTAUDIO_FORMAT RTAUDIO_SINT32; 
00207   static const RTAUDIO_FORMAT RTAUDIO_FLOAT32; 
00208   static const RTAUDIO_FORMAT RTAUDIO_FLOAT64; 
00210   //static const int MAX_SAMPLE_RATES = 14;
00211   enum { MAX_SAMPLE_RATES = 14 };
00212 
00213   typedef int (*RTAUDIO_CALLBACK)(char *buffer, int bufferSize, void *userData);
00214 
00216   typedef struct {
00217     char name[128];    
00218     DEVICE_ID id[2];  /* No value reported by getDeviceInfo(). */
00219     bool probed;       
00220     int maxOutputChannels; 
00221     int maxInputChannels;  
00222     int maxDuplexChannels; 
00223     int minOutputChannels; 
00224     int minInputChannels;  
00225     int minDuplexChannels; 
00226     bool hasDuplexSupport; 
00227     bool isDefault;        
00228     int nSampleRates;      
00229     int sampleRates[MAX_SAMPLE_RATES]; 
00230     RTAUDIO_FORMAT nativeFormats;     
00231   } RTAUDIO_DEVICE;
00232 
00234 
00240   RtAudio();
00241 
00243 
00254   RtAudio(int *streamId,
00255           int outputDevice, int outputChannels,
00256           int inputDevice, int inputChannels,
00257           RTAUDIO_FORMAT format, int sampleRate,
00258           int *bufferSize, int numberOfBuffers);
00259 
00261 
00265   ~RtAudio();
00266 
00268 
00295   int openStream(int outputDevice, int outputChannels,
00296                  int inputDevice, int inputChannels,
00297                  RTAUDIO_FORMAT format, int sampleRate,
00298                  int *bufferSize, int numberOfBuffers);
00299 
00301 
00320   void setStreamCallback(int streamId, RTAUDIO_CALLBACK callback, void *userData);
00321 
00323 
00330   void cancelStreamCallback(int streamId);
00331 
00333   int getDeviceCount(void);
00334 
00336 
00344   void getDeviceInfo(int device, RTAUDIO_DEVICE *info);
00345 
00347 
00352   char * const getStreamBuffer(int streamId);
00353 
00355 
00360   void tickStream(int streamId);
00361 
00363 
00367   void closeStream(int streamId);
00368 
00370 
00374   void startStream(int streamId);
00375 
00377 
00381   void stopStream(int streamId);
00382 
00384 
00388   void abortStream(int streamId);
00389 
00391 
00396   int streamWillBlock(int streamId);
00397 
00398 #if (defined(__MACOSX_CORE__) || defined(__WINDOWS_ASIO__))
00399   // This function is intended for internal use only.  It must be
00400   // public because it is called by the internal callback handler,
00401   // which is not a member of RtAudio.  External use of this function
00402   // will most likely produce highly undesireable results!
00403   void callbackEvent(int streamId, DEVICE_ID deviceId, void *inData, void *outData);
00404 #endif
00405 
00406 protected:
00407 
00408 private:
00409 
00410   static const unsigned int SAMPLE_RATES[MAX_SAMPLE_RATES];
00411 
00412   enum { FAILURE, SUCCESS };
00413 
00414   enum STREAM_MODE {
00415     OUTPUT,
00416     INPUT,
00417     DUPLEX,
00418     UNINITIALIZED = -75
00419   };
00420 
00421   enum STREAM_STATE {
00422     STREAM_STOPPED,
00423     STREAM_RUNNING
00424   };
00425 
00426   typedef struct {
00427     int device[2];          // Playback and record, respectively.
00428     STREAM_MODE mode;       // OUTPUT, INPUT, or DUPLEX.
00429     AUDIO_HANDLE handle[2]; // Playback and record handles, respectively.
00430     STREAM_STATE state;     // STOPPED or RUNNING
00431     char *userBuffer;
00432     char *deviceBuffer;
00433     bool doConvertBuffer[2]; // Playback and record, respectively.
00434     bool deInterleave[2];    // Playback and record, respectively.
00435     bool doByteSwap[2];      // Playback and record, respectively.
00436     int sampleRate;
00437     int bufferSize;
00438     int nBuffers;
00439     int nUserChannels[2];    // Playback and record, respectively.
00440     int nDeviceChannels[2];  // Playback and record channels, respectively.
00441     RTAUDIO_FORMAT userFormat;
00442     RTAUDIO_FORMAT deviceFormat[2]; // Playback and record, respectively.
00443     MUTEX mutex;
00444     CALLBACK_INFO callbackInfo;
00445   } RTAUDIO_STREAM;
00446 
00447   typedef signed short INT16;
00448   typedef signed int INT32;
00449   typedef float FLOAT32;
00450   typedef double FLOAT64;
00451 
00452   char message[256];
00453   int nDevices;
00454   RTAUDIO_DEVICE *devices;
00455 
00456   std::map<int, void *> streams;
00457 
00459   void error(RtError::TYPE type);
00460 
00465   void initialize(void);
00466 
00471   int getDefaultInputDevice(void);
00472 
00477   int getDefaultOutputDevice(void);
00478 
00480   void clearDeviceInfo(RTAUDIO_DEVICE *info);
00481 
00489   void probeDeviceInfo(RTAUDIO_DEVICE *info);
00490 
00497   bool probeDeviceOpen(int device, RTAUDIO_STREAM *stream,
00498                        STREAM_MODE mode, int channels, 
00499                        int sampleRate, RTAUDIO_FORMAT format,
00500                        int *bufferSize, int numberOfBuffers);
00501 
00508   void *verifyStream(int streamId);
00509 
00514   void convertStreamBuffer(RTAUDIO_STREAM *stream, STREAM_MODE mode);
00515 
00517   void byteSwapBuffer(char *buffer, int samples, RTAUDIO_FORMAT format);
00518 
00520   int formatBytes(RTAUDIO_FORMAT format);
00521 };
00522 
00523 // Define the following flag to have extra information spewed to stderr.
00524 //#define __RTAUDIO_DEBUG__
00525 
00526 #endif

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