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
|