00001 /************************************************************************/ 00038 /************************************************************************/ 00039 00040 // RtAudio: Version 3.0.1, 22 March 2004 00041 00042 #ifndef __RTAUDIO_H 00043 #define __RTAUDIO_H 00044 00045 #include "RtError.h" 00046 #include <string> 00047 #include <vector> 00048 00049 // Operating system dependent thread functionality. 00050 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) 00051 #include <windows.h> 00052 #include <process.h> 00053 00054 typedef unsigned long ThreadHandle; 00055 typedef CRITICAL_SECTION StreamMutex; 00056 00057 #else // Various unix flavors with pthread support. 00058 #include <pthread.h> 00059 00060 typedef pthread_t ThreadHandle; 00061 typedef pthread_mutex_t StreamMutex; 00062 00063 #endif 00064 00065 // This global structure type is used to pass callback information 00066 // between the private RtAudio stream structure and global callback 00067 // handling functions. 00068 struct CallbackInfo { 00069 void *object; // Used as a "this" pointer. 00070 ThreadHandle thread; 00071 bool usingCallback; 00072 void *callback; 00073 void *userData; 00074 void *apiInfo; // void pointer for API specific callback information 00075 00076 // Default constructor. 00077 CallbackInfo() 00078 :object(0), usingCallback(false), callback(0), 00079 userData(0), apiInfo(0) {} 00080 }; 00081 00082 // Support for signed integers and floats. Audio data fed to/from 00083 // the tickStream() routine is assumed to ALWAYS be in host 00084 // byte order. The internal routines will automatically take care of 00085 // any necessary byte-swapping between the host format and the 00086 // soundcard. Thus, endian-ness is not a concern in the following 00087 // format definitions. 00088 typedef unsigned long RtAudioFormat; 00089 static const RtAudioFormat RTAUDIO_SINT8 = 0x1; 00090 static const RtAudioFormat RTAUDIO_SINT16 = 0x2; 00091 static const RtAudioFormat RTAUDIO_SINT24 = 0x4; 00092 static const RtAudioFormat RTAUDIO_SINT32 = 0x8; 00093 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; 00094 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; 00096 typedef int (*RtAudioCallback)(char *buffer, int bufferSize, void *userData); 00097 00099 struct RtAudioDeviceInfo { 00100 std::string name; 00101 bool probed; 00102 int outputChannels; 00103 int inputChannels; 00104 int duplexChannels; 00105 bool isDefault; 00106 std::vector<int> sampleRates; 00107 RtAudioFormat nativeFormats; 00109 // Default constructor. 00110 RtAudioDeviceInfo() 00111 :probed(false), outputChannels(0), inputChannels(0), 00112 duplexChannels(0), isDefault(false), nativeFormats(0) {} 00113 }; 00114 00115 // **************************************************************** // 00116 // 00117 // RtApi class declaration. 00118 // 00119 // Note that RtApi is an abstract base class and cannot be 00120 // explicitly instantiated. The class RtAudio will create an 00121 // instance of an RtApi subclass (RtApiOss, RtApiAlsa, 00122 // RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio). 00123 // 00124 // **************************************************************** // 00125 00126 class RtApi 00127 { 00128 public: 00129 00130 RtApi(); 00131 virtual ~RtApi(); 00132 void openStream( int outputDevice, int outputChannels, 00133 int inputDevice, int inputChannels, 00134 RtAudioFormat format, int sampleRate, 00135 int *bufferSize, int numberOfBuffers ); 00136 virtual void setStreamCallback( RtAudioCallback callback, void *userData ) = 0; 00137 virtual void cancelStreamCallback() = 0; 00138 int getDeviceCount(void); 00139 RtAudioDeviceInfo getDeviceInfo( int device ); 00140 char * const getStreamBuffer(); 00141 virtual void tickStream() = 0; 00142 virtual void closeStream(); 00143 virtual void startStream() = 0; 00144 virtual void stopStream() = 0; 00145 virtual void abortStream() = 0; 00146 00147 protected: 00148 00149 static const unsigned int MAX_SAMPLE_RATES; 00150 static const unsigned int SAMPLE_RATES[]; 00151 00152 enum { FAILURE, SUCCESS }; 00153 00154 enum StreamMode { 00155 OUTPUT, 00156 INPUT, 00157 DUPLEX, 00158 UNINITIALIZED = -75 00159 }; 00160 00161 enum StreamState { 00162 STREAM_STOPPED, 00163 STREAM_RUNNING 00164 }; 00165 00166 // A protected structure for audio streams. 00167 struct RtApiStream { 00168 int device[2]; // Playback and record, respectively. 00169 void *apiHandle; // void pointer for API specific stream handle information 00170 StreamMode mode; // OUTPUT, INPUT, or DUPLEX. 00171 StreamState state; // STOPPED or RUNNING 00172 char *userBuffer; 00173 char *deviceBuffer; 00174 bool doConvertBuffer[2]; // Playback and record, respectively. 00175 bool deInterleave[2]; // Playback and record, respectively. 00176 bool doByteSwap[2]; // Playback and record, respectively. 00177 int sampleRate; 00178 int bufferSize; 00179 int nBuffers; 00180 int nUserChannels[2]; // Playback and record, respectively. 00181 int nDeviceChannels[2]; // Playback and record channels, respectively. 00182 RtAudioFormat userFormat; 00183 RtAudioFormat deviceFormat[2]; // Playback and record, respectively. 00184 StreamMutex mutex; 00185 CallbackInfo callbackInfo; 00186 00187 RtApiStream() 00188 :apiHandle(0), userBuffer(0), deviceBuffer(0) {} 00189 // mode(UNINITIALIZED), state(STREAM_STOPPED), 00190 }; 00191 00192 // A protected device structure for audio devices. 00193 struct RtApiDevice { 00194 std::string name; 00195 bool probed; 00196 void *apiDeviceId; // void pointer for API specific device information 00197 int maxOutputChannels; 00198 int maxInputChannels; 00199 int maxDuplexChannels; 00200 int minOutputChannels; 00201 int minInputChannels; 00202 int minDuplexChannels; 00203 bool hasDuplexSupport; 00204 bool isDefault; 00205 std::vector<int> sampleRates; 00206 RtAudioFormat nativeFormats; 00208 // Default constructor. 00209 RtApiDevice() 00210 :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0), 00211 maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0), 00212 minDuplexChannels(0), isDefault(false), nativeFormats(0) {} 00213 }; 00214 00215 typedef signed short Int16; 00216 typedef signed int Int32; 00217 typedef float Float32; 00218 typedef double Float64; 00219 00220 char message_[256]; 00221 int nDevices_; 00222 std::vector<RtApiDevice> devices_; 00223 RtApiStream stream_; 00224 00229 virtual void initialize(void) = 0; 00230 00239 virtual void probeDeviceInfo( RtApiDevice *info ); 00240 00249 virtual bool probeDeviceOpen( int device, StreamMode mode, int channels, 00250 int sampleRate, RtAudioFormat format, 00251 int *bufferSize, int numberOfBuffers ); 00252 00257 virtual int getDefaultInputDevice(void); 00258 00263 virtual int getDefaultOutputDevice(void); 00264 00266 void clearDeviceInfo( RtApiDevice *info ); 00267 00269 void clearStreamInfo(); 00270 00272 void error( RtError::Type type ); 00273 00278 void verifyStream(); 00279 00284 void convertStreamBuffer( StreamMode mode ); 00285 00287 void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format ); 00288 00290 int formatBytes( RtAudioFormat format ); 00291 }; 00292 00293 00294 // **************************************************************** // 00295 // 00296 // RtAudio class declaration. 00297 // 00298 // RtAudio is a "controller" used to select an available audio i/o 00299 // interface. It presents a common API for the user to call but all 00300 // functionality is implemented by the class RtAudioApi and its 00301 // subclasses. RtAudio creates an instance of an RtAudioApi subclass 00302 // based on the user's API choice. If no choice is made, RtAudio 00303 // attempts to make a "logical" API selection. 00304 // 00305 // **************************************************************** // 00306 00307 class RtAudio 00308 { 00309 public: 00310 00312 enum RtAudioApi { 00313 UNSPECIFIED, 00314 LINUX_ALSA, 00315 LINUX_OSS, 00316 LINUX_JACK, 00317 MACOSX_CORE, 00318 IRIX_AL, 00319 WINDOWS_ASIO, 00320 WINDOWS_DS 00321 }; 00322 00324 00334 RtAudio( RtAudioApi api=UNSPECIFIED ); 00335 00337 00348 RtAudio( int outputDevice, int outputChannels, 00349 int inputDevice, int inputChannels, 00350 RtAudioFormat format, int sampleRate, 00351 int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED ); 00352 00354 00358 ~RtAudio(); 00359 00361 00387 void openStream( int outputDevice, int outputChannels, 00388 int inputDevice, int inputChannels, 00389 RtAudioFormat format, int sampleRate, 00390 int *bufferSize, int numberOfBuffers ); 00391 00393 00412 void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); }; 00413 00415 00422 void cancelStreamCallback() { rtapi_->cancelStreamCallback(); }; 00423 00425 int getDeviceCount(void) { return rtapi_->getDeviceCount(); }; 00426 00428 00436 RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); }; 00437 00439 00444 char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); }; 00445 00447 00452 void tickStream() { rtapi_->tickStream(); }; 00453 00455 00459 void closeStream() { rtapi_->closeStream(); }; 00460 00462 00466 void startStream() { rtapi_->startStream(); }; 00467 00469 00473 void stopStream() { rtapi_->stopStream(); }; 00474 00476 00480 void abortStream() { rtapi_->abortStream(); }; 00481 00482 00483 protected: 00484 00485 void initialize( RtAudioApi api ); 00486 00487 RtApi *rtapi_; 00488 }; 00489 00490 00491 // RtApi Subclass prototypes. 00492 00493 #if defined(__LINUX_ALSA__) 00494 00495 class RtApiAlsa: public RtApi 00496 { 00497 public: 00498 00499 RtApiAlsa(); 00500 ~RtApiAlsa(); 00501 void tickStream(); 00502 void closeStream(); 00503 void startStream(); 00504 void stopStream(); 00505 void abortStream(); 00506 int streamWillBlock(); 00507 void setStreamCallback( RtAudioCallback callback, void *userData ); 00508 void cancelStreamCallback(); 00509 00510 private: 00511 00512 void initialize(void); 00513 void probeDeviceInfo( RtApiDevice *info ); 00514 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00515 int sampleRate, RtAudioFormat format, 00516 int *bufferSize, int numberOfBuffers ); 00517 }; 00518 00519 #endif 00520 00521 #if defined(__LINUX_JACK__) 00522 00523 class RtApiJack: public RtApi 00524 { 00525 public: 00526 00527 RtApiJack(); 00528 ~RtApiJack(); 00529 void tickStream(); 00530 void closeStream(); 00531 void startStream(); 00532 void stopStream(); 00533 void abortStream(); 00534 void setStreamCallback( RtAudioCallback callback, void *userData ); 00535 void cancelStreamCallback(); 00536 // This function is intended for internal use only. It must be 00537 // public because it is called by the internal callback handler, 00538 // which is not a member of RtAudio. External use of this function 00539 // will most likely produce highly undesireable results! 00540 void callbackEvent( unsigned long nframes ); 00541 00542 private: 00543 00544 void initialize(void); 00545 void probeDeviceInfo( RtApiDevice *info ); 00546 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00547 int sampleRate, RtAudioFormat format, 00548 int *bufferSize, int numberOfBuffers ); 00549 }; 00550 00551 #endif 00552 00553 #if defined(__LINUX_OSS__) 00554 00555 class RtApiOss: public RtApi 00556 { 00557 public: 00558 00559 RtApiOss(); 00560 ~RtApiOss(); 00561 void tickStream(); 00562 void closeStream(); 00563 void startStream(); 00564 void stopStream(); 00565 void abortStream(); 00566 int streamWillBlock(); 00567 void setStreamCallback( RtAudioCallback callback, void *userData ); 00568 void cancelStreamCallback(); 00569 00570 private: 00571 00572 void initialize(void); 00573 void probeDeviceInfo( RtApiDevice *info ); 00574 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00575 int sampleRate, RtAudioFormat format, 00576 int *bufferSize, int numberOfBuffers ); 00577 }; 00578 00579 #endif 00580 00581 #if defined(__MACOSX_CORE__) 00582 00583 #include <CoreAudio/AudioHardware.h> 00584 00585 class RtApiCore: public RtApi 00586 { 00587 public: 00588 00589 RtApiCore(); 00590 ~RtApiCore(); 00591 int getDefaultOutputDevice(void); 00592 int getDefaultInputDevice(void); 00593 void tickStream(); 00594 void closeStream(); 00595 void startStream(); 00596 void stopStream(); 00597 void abortStream(); 00598 void setStreamCallback( RtAudioCallback callback, void *userData ); 00599 void cancelStreamCallback(); 00600 00601 // This function is intended for internal use only. It must be 00602 // public because it is called by the internal callback handler, 00603 // which is not a member of RtAudio. External use of this function 00604 // will most likely produce highly undesireable results! 00605 void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData ); 00606 00607 private: 00608 00609 void initialize(void); 00610 void probeDeviceInfo( RtApiDevice *info ); 00611 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00612 int sampleRate, RtAudioFormat format, 00613 int *bufferSize, int numberOfBuffers ); 00614 }; 00615 00616 #endif 00617 00618 #if defined(__WINDOWS_DS__) 00619 00620 class RtApiDs: public RtApi 00621 { 00622 public: 00623 00624 RtApiDs(); 00625 ~RtApiDs(); 00626 int getDefaultOutputDevice(void); 00627 int getDefaultInputDevice(void); 00628 void tickStream(); 00629 void closeStream(); 00630 void startStream(); 00631 void stopStream(); 00632 void abortStream(); 00633 int streamWillBlock(); 00634 void setStreamCallback( RtAudioCallback callback, void *userData ); 00635 void cancelStreamCallback(); 00636 00637 private: 00638 00639 void initialize(void); 00640 void probeDeviceInfo( RtApiDevice *info ); 00641 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00642 int sampleRate, RtAudioFormat format, 00643 int *bufferSize, int numberOfBuffers ); 00644 }; 00645 00646 #endif 00647 00648 #if defined(__WINDOWS_ASIO__) 00649 00650 class RtApiAsio: public RtApi 00651 { 00652 public: 00653 00654 RtApiAsio(); 00655 ~RtApiAsio(); 00656 void tickStream(); 00657 void closeStream(); 00658 void startStream(); 00659 void stopStream(); 00660 void abortStream(); 00661 void setStreamCallback( RtAudioCallback callback, void *userData ); 00662 void cancelStreamCallback(); 00663 00664 // This function is intended for internal use only. It must be 00665 // public because it is called by the internal callback handler, 00666 // which is not a member of RtAudio. External use of this function 00667 // will most likely produce highly undesireable results! 00668 void callbackEvent( long bufferIndex ); 00669 00670 private: 00671 00672 void initialize(void); 00673 void probeDeviceInfo( RtApiDevice *info ); 00674 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00675 int sampleRate, RtAudioFormat format, 00676 int *bufferSize, int numberOfBuffers ); 00677 }; 00678 00679 #endif 00680 00681 #if defined(__IRIX_AL__) 00682 00683 class RtApiAl: public RtApi 00684 { 00685 public: 00686 00687 RtApiAl(); 00688 ~RtApiAl(); 00689 int getDefaultOutputDevice(void); 00690 int getDefaultInputDevice(void); 00691 void tickStream(); 00692 void closeStream(); 00693 void startStream(); 00694 void stopStream(); 00695 void abortStream(); 00696 int streamWillBlock(); 00697 void setStreamCallback( RtAudioCallback callback, void *userData ); 00698 void cancelStreamCallback(); 00699 00700 private: 00701 00702 void initialize(void); 00703 void probeDeviceInfo( RtApiDevice *info ); 00704 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00705 int sampleRate, RtAudioFormat format, 00706 int *bufferSize, int numberOfBuffers ); 00707 }; 00708 00709 #endif 00710 00711 // Define the following flag to have extra information spewed to stderr. 00712 //#define __RTAUDIO_DEBUG__ 00713 00714 #endif
![]() |
©2001-2004 Gary P. Scavone, McGill University. All Rights Reserved. Maintained by Gary P. Scavone, gary@music.mcgill.ca |