00001 /************************************************************************/ 00038 /************************************************************************/ 00039 00040 // RtAudio: Version 3.0, 11 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 // :apiHandle(0), mode(UNINITIALIZED), state(STREAM_STOPPED), 00190 // userBuffer(0), deviceBuffer(0) {} 00191 }; 00192 00193 // A protected device structure for audio devices. 00194 struct RtApiDevice { 00195 std::string name; 00196 bool probed; 00197 void *apiDeviceId; // void pointer for API specific device information 00198 int maxOutputChannels; 00199 int maxInputChannels; 00200 int maxDuplexChannels; 00201 int minOutputChannels; 00202 int minInputChannels; 00203 int minDuplexChannels; 00204 bool hasDuplexSupport; 00205 bool isDefault; 00206 std::vector<int> sampleRates; 00207 RtAudioFormat nativeFormats; 00209 // Default constructor. 00210 RtApiDevice() 00211 :probed(false), apiDeviceId(0), maxOutputChannels(0), maxInputChannels(0), 00212 maxDuplexChannels(0), minOutputChannels(0), minInputChannels(0), 00213 minDuplexChannels(0), isDefault(false), nativeFormats(0) {} 00214 }; 00215 00216 typedef signed short Int16; 00217 typedef signed int Int32; 00218 typedef float Float32; 00219 typedef double Float64; 00220 00221 char message_[256]; 00222 int nDevices_; 00223 std::vector<RtApiDevice> devices_; 00224 RtApiStream stream_; 00225 00230 virtual void initialize(void) = 0; 00231 00240 virtual void probeDeviceInfo( RtApiDevice *info ); 00241 00250 virtual bool probeDeviceOpen( int device, StreamMode mode, int channels, 00251 int sampleRate, RtAudioFormat format, 00252 int *bufferSize, int numberOfBuffers ); 00253 00258 virtual int getDefaultInputDevice(void); 00259 00264 virtual int getDefaultOutputDevice(void); 00265 00267 void clearDeviceInfo( RtApiDevice *info ); 00268 00270 void clearStreamInfo(); 00271 00273 void error( RtError::Type type ); 00274 00279 void verifyStream(); 00280 00285 void convertStreamBuffer( StreamMode mode ); 00286 00288 void byteSwapBuffer( char *buffer, int samples, RtAudioFormat format ); 00289 00291 int formatBytes( RtAudioFormat format ); 00292 }; 00293 00294 00295 // **************************************************************** // 00296 // 00297 // RtAudio class declaration. 00298 // 00299 // RtAudio is a "controller" used to select an available audio i/o 00300 // interface. It presents a common API for the user to call but all 00301 // functionality is implemented by the class RtAudioApi and its 00302 // subclasses. RtAudio creates an instance of an RtAudioApi subclass 00303 // based on the user's API choice. If no choice is made, RtAudio 00304 // attempts to make a "logical" API selection. 00305 // 00306 // **************************************************************** // 00307 00308 class RtAudio 00309 { 00310 public: 00311 00313 enum RtAudioApi { 00314 UNSPECIFIED, 00315 LINUX_ALSA, 00316 LINUX_OSS, 00317 LINUX_JACK, 00318 MACOSX_CORE, 00319 IRIX_AL, 00320 WINDOWS_ASIO, 00321 WINDOWS_DS 00322 }; 00323 00325 00335 RtAudio( RtAudioApi api=UNSPECIFIED ); 00336 00338 00349 RtAudio( int outputDevice, int outputChannels, 00350 int inputDevice, int inputChannels, 00351 RtAudioFormat format, int sampleRate, 00352 int *bufferSize, int numberOfBuffers, RtAudioApi api=UNSPECIFIED ); 00353 00355 00359 ~RtAudio(); 00360 00362 00388 void openStream( int outputDevice, int outputChannels, 00389 int inputDevice, int inputChannels, 00390 RtAudioFormat format, int sampleRate, 00391 int *bufferSize, int numberOfBuffers ); 00392 00394 00413 void setStreamCallback(RtAudioCallback callback, void *userData) { rtapi_->setStreamCallback( callback, userData ); }; 00414 00416 00423 void cancelStreamCallback() { rtapi_->cancelStreamCallback(); }; 00424 00426 int getDeviceCount(void) { return rtapi_->getDeviceCount(); }; 00427 00429 00437 RtAudioDeviceInfo getDeviceInfo(int device) { return rtapi_->getDeviceInfo( device ); }; 00438 00440 00445 char * const getStreamBuffer() { return rtapi_->getStreamBuffer(); }; 00446 00448 00453 void tickStream() { rtapi_->tickStream(); }; 00454 00456 00460 void closeStream() { rtapi_->closeStream(); }; 00461 00463 00467 void startStream() { rtapi_->startStream(); }; 00468 00470 00474 void stopStream() { rtapi_->stopStream(); }; 00475 00477 00481 void abortStream() { rtapi_->abortStream(); }; 00482 00483 00484 protected: 00485 00486 void initialize( RtAudioApi api ); 00487 00488 RtApi *rtapi_; 00489 }; 00490 00491 00492 // RtApi Subclass prototypes. 00493 00494 #if defined(__LINUX_ALSA__) 00495 00496 class RtApiAlsa: public RtApi 00497 { 00498 public: 00499 00500 RtApiAlsa(); 00501 ~RtApiAlsa(); 00502 void tickStream(); 00503 void closeStream(); 00504 void startStream(); 00505 void stopStream(); 00506 void abortStream(); 00507 int streamWillBlock(); 00508 void setStreamCallback( RtAudioCallback callback, void *userData ); 00509 void cancelStreamCallback(); 00510 00511 private: 00512 00513 void initialize(void); 00514 void probeDeviceInfo( RtApiDevice *info ); 00515 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00516 int sampleRate, RtAudioFormat format, 00517 int *bufferSize, int numberOfBuffers ); 00518 }; 00519 00520 #endif 00521 00522 #if defined(__LINUX_JACK__) 00523 00524 class RtApiJack: public RtApi 00525 { 00526 public: 00527 00528 RtApiJack(); 00529 ~RtApiJack(); 00530 void tickStream(); 00531 void closeStream(); 00532 void startStream(); 00533 void stopStream(); 00534 void abortStream(); 00535 void setStreamCallback( RtAudioCallback callback, void *userData ); 00536 void cancelStreamCallback(); 00537 // This function is intended for internal use only. It must be 00538 // public because it is called by the internal callback handler, 00539 // which is not a member of RtAudio. External use of this function 00540 // will most likely produce highly undesireable results! 00541 void callbackEvent( unsigned long nframes ); 00542 00543 private: 00544 00545 void initialize(void); 00546 void probeDeviceInfo( RtApiDevice *info ); 00547 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00548 int sampleRate, RtAudioFormat format, 00549 int *bufferSize, int numberOfBuffers ); 00550 }; 00551 00552 #endif 00553 00554 #if defined(__LINUX_OSS__) 00555 00556 class RtApiOss: public RtApi 00557 { 00558 public: 00559 00560 RtApiOss(); 00561 ~RtApiOss(); 00562 void tickStream(); 00563 void closeStream(); 00564 void startStream(); 00565 void stopStream(); 00566 void abortStream(); 00567 int streamWillBlock(); 00568 void setStreamCallback( RtAudioCallback callback, void *userData ); 00569 void cancelStreamCallback(); 00570 00571 private: 00572 00573 void initialize(void); 00574 void probeDeviceInfo( RtApiDevice *info ); 00575 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00576 int sampleRate, RtAudioFormat format, 00577 int *bufferSize, int numberOfBuffers ); 00578 }; 00579 00580 #endif 00581 00582 #if defined(__MACOSX_CORE__) 00583 00584 #include <CoreAudio/AudioHardware.h> 00585 00586 class RtApiCore: public RtApi 00587 { 00588 public: 00589 00590 RtApiCore(); 00591 ~RtApiCore(); 00592 int getDefaultOutputDevice(void); 00593 int getDefaultInputDevice(void); 00594 void tickStream(); 00595 void closeStream(); 00596 void startStream(); 00597 void stopStream(); 00598 void abortStream(); 00599 void setStreamCallback( RtAudioCallback callback, void *userData ); 00600 void cancelStreamCallback(); 00601 00602 // This function is intended for internal use only. It must be 00603 // public because it is called by the internal callback handler, 00604 // which is not a member of RtAudio. External use of this function 00605 // will most likely produce highly undesireable results! 00606 void callbackEvent( AudioDeviceID deviceId, void *inData, void *outData ); 00607 00608 private: 00609 00610 void initialize(void); 00611 void probeDeviceInfo( RtApiDevice *info ); 00612 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00613 int sampleRate, RtAudioFormat format, 00614 int *bufferSize, int numberOfBuffers ); 00615 }; 00616 00617 #endif 00618 00619 #if defined(__WINDOWS_DS__) 00620 00621 class RtApiDs: public RtApi 00622 { 00623 public: 00624 00625 RtApiDs(); 00626 ~RtApiDs(); 00627 int getDefaultOutputDevice(void); 00628 int getDefaultInputDevice(void); 00629 void tickStream(); 00630 void closeStream(); 00631 void startStream(); 00632 void stopStream(); 00633 void abortStream(); 00634 int streamWillBlock(); 00635 void setStreamCallback( RtAudioCallback callback, void *userData ); 00636 void cancelStreamCallback(); 00637 00638 private: 00639 00640 void initialize(void); 00641 void probeDeviceInfo( RtApiDevice *info ); 00642 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00643 int sampleRate, RtAudioFormat format, 00644 int *bufferSize, int numberOfBuffers ); 00645 }; 00646 00647 #endif 00648 00649 #if defined(__WINDOWS_ASIO__) 00650 00651 class RtApiAsio: public RtApi 00652 { 00653 public: 00654 00655 RtApiAsio(); 00656 ~RtApiAsio(); 00657 void tickStream(); 00658 void closeStream(); 00659 void startStream(); 00660 void stopStream(); 00661 void abortStream(); 00662 void setStreamCallback( RtAudioCallback callback, void *userData ); 00663 void cancelStreamCallback(); 00664 00665 // This function is intended for internal use only. It must be 00666 // public because it is called by the internal callback handler, 00667 // which is not a member of RtAudio. External use of this function 00668 // will most likely produce highly undesireable results! 00669 void callbackEvent( long bufferIndex ); 00670 00671 private: 00672 00673 void initialize(void); 00674 void probeDeviceInfo( RtApiDevice *info ); 00675 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00676 int sampleRate, RtAudioFormat format, 00677 int *bufferSize, int numberOfBuffers ); 00678 }; 00679 00680 #endif 00681 00682 #if defined(__IRIX_AL__) 00683 00684 class RtApiAl: public RtApi 00685 { 00686 public: 00687 00688 RtApiAl(); 00689 ~RtApiAl(); 00690 int getDefaultOutputDevice(void); 00691 int getDefaultInputDevice(void); 00692 void tickStream(); 00693 void closeStream(); 00694 void startStream(); 00695 void stopStream(); 00696 void abortStream(); 00697 int streamWillBlock(); 00698 void setStreamCallback( RtAudioCallback callback, void *userData ); 00699 void cancelStreamCallback(); 00700 00701 private: 00702 00703 void initialize(void); 00704 void probeDeviceInfo( RtApiDevice *info ); 00705 bool probeDeviceOpen( int device, StreamMode mode, int channels, 00706 int sampleRate, RtAudioFormat format, 00707 int *bufferSize, int numberOfBuffers ); 00708 }; 00709 00710 #endif 00711 00712 // Define the following flag to have extra information spewed to stderr. 00713 //#define __RTAUDIO_DEBUG__ 00714 00715 #endif
![]() |
©2001-2004 Gary P. Scavone, McGill University. All Rights Reserved. Maintained by Gary P. Scavone, gary@music.mcgill.ca |