00001 /************************************************************************/ 00039 /************************************************************************/ 00040 00045 // RtAudio: Version 4.0.6 00046 00047 #ifndef __RTAUDIO_H 00048 #define __RTAUDIO_H 00049 00050 #include <string> 00051 #include <vector> 00052 #include "RtError.h" 00053 00070 typedef unsigned long RtAudioFormat; 00071 static const RtAudioFormat RTAUDIO_SINT8 = 0x1; // 8-bit signed integer. 00072 static const RtAudioFormat RTAUDIO_SINT16 = 0x2; // 16-bit signed integer. 00073 static const RtAudioFormat RTAUDIO_SINT24 = 0x4; // Lower 3 bytes of 32-bit signed integer. 00074 static const RtAudioFormat RTAUDIO_SINT32 = 0x8; // 32-bit signed integer. 00075 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0. 00076 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0. 00077 00115 typedef unsigned int RtAudioStreamFlags; 00116 static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1; // Use non-interleaved buffers (default = interleaved). 00117 static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2; // Attempt to set stream parameters for lowest possible latency. 00118 static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4; // Attempt grab device and prevent use by others. 00119 static const RtAudioStreamFlags RTAUDIO_SCHEDULE_REALTIME = 0x8; // Try to select realtime scheduling for callback thread. 00120 00132 typedef unsigned int RtAudioStreamStatus; 00133 static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1; // Input data was discarded because of an overflow condition at the driver. 00134 static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2; // The output buffer ran low, likely causing a gap in the output sound. 00135 00137 00175 typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer, 00176 unsigned int nFrames, 00177 double streamTime, 00178 RtAudioStreamStatus status, 00179 void *userData ); 00180 00181 00182 // **************************************************************** // 00183 // 00184 // RtAudio class declaration. 00185 // 00186 // RtAudio is a "controller" used to select an available audio i/o 00187 // interface. It presents a common API for the user to call but all 00188 // functionality is implemented by the class RtApi and its 00189 // subclasses. RtAudio creates an instance of an RtApi subclass 00190 // based on the user's API choice. If no choice is made, RtAudio 00191 // attempts to make a "logical" API selection. 00192 // 00193 // **************************************************************** // 00194 00195 class RtApi; 00196 00197 class RtAudio 00198 { 00199 public: 00200 00202 enum Api { 00203 UNSPECIFIED, 00204 LINUX_ALSA, 00205 LINUX_OSS, 00206 UNIX_JACK, 00207 MACOSX_CORE, 00208 WINDOWS_ASIO, 00209 WINDOWS_DS, 00210 RTAUDIO_DUMMY 00211 }; 00212 00214 struct DeviceInfo { 00215 bool probed; 00216 std::string name; 00217 unsigned int outputChannels; 00218 unsigned int inputChannels; 00219 unsigned int duplexChannels; 00220 bool isDefaultOutput; 00221 bool isDefaultInput; 00222 std::vector<unsigned int> sampleRates; 00223 RtAudioFormat nativeFormats; 00225 // Default constructor. 00226 DeviceInfo() 00227 :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0), 00228 isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {} 00229 }; 00230 00232 struct StreamParameters { 00233 unsigned int deviceId; 00234 unsigned int nChannels; 00235 unsigned int firstChannel; 00237 // Default constructor. 00238 StreamParameters() 00239 : deviceId(0), nChannels(0), firstChannel(0) {} 00240 }; 00241 00243 00294 struct StreamOptions { 00295 RtAudioStreamFlags flags; 00296 unsigned int numberOfBuffers; 00297 std::string streamName; 00298 int priority; 00300 // Default constructor. 00301 StreamOptions() 00302 : flags(0), numberOfBuffers(0), priority(0) {} 00303 }; 00304 00306 00311 static void getCompiledApi( std::vector<RtAudio::Api> &apis ) throw(); 00312 00314 00322 RtAudio( RtAudio::Api api=UNSPECIFIED ) throw(); 00323 00325 00329 ~RtAudio() throw(); 00330 00332 RtAudio::Api getCurrentApi( void ) throw(); 00333 00335 00340 unsigned int getDeviceCount( void ) throw(); 00341 00343 00353 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 00354 00356 00363 unsigned int getDefaultOutputDevice( void ) throw(); 00364 00366 00373 unsigned int getDefaultInputDevice( void ) throw(); 00374 00376 00413 void openStream( RtAudio::StreamParameters *outputParameters, 00414 RtAudio::StreamParameters *inputParameters, 00415 RtAudioFormat format, unsigned int sampleRate, 00416 unsigned int *bufferFrames, RtAudioCallback callback, 00417 void *userData = NULL, RtAudio::StreamOptions *options = NULL ); 00418 00420 00424 void closeStream( void ) throw(); 00425 00427 00433 void startStream( void ); 00434 00436 00442 void stopStream( void ); 00443 00445 00451 void abortStream( void ); 00452 00454 bool isStreamOpen( void ) const throw(); 00455 00457 bool isStreamRunning( void ) const throw(); 00458 00460 00463 double getStreamTime( void ); 00464 00466 00474 long getStreamLatency( void ); 00475 00477 00482 unsigned int getStreamSampleRate( void ); 00483 00485 void showWarnings( bool value = true ) throw(); 00486 00487 protected: 00488 00489 void openRtApi( RtAudio::Api api ); 00490 RtApi *rtapi_; 00491 }; 00492 00493 // Operating system dependent thread functionality. 00494 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) 00495 #include <windows.h> 00496 #include <process.h> 00497 00498 typedef unsigned long ThreadHandle; 00499 typedef CRITICAL_SECTION StreamMutex; 00500 00501 #elif defined(__LINUX_ALSA__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) 00502 // Using pthread library for various flavors of unix. 00503 #include <pthread.h> 00504 00505 typedef pthread_t ThreadHandle; 00506 typedef pthread_mutex_t StreamMutex; 00507 00508 #else // Setup for "dummy" behavior 00509 00510 #define __RTAUDIO_DUMMY__ 00511 typedef int ThreadHandle; 00512 typedef int StreamMutex; 00513 00514 #endif 00515 00516 // This global structure type is used to pass callback information 00517 // between the private RtAudio stream structure and global callback 00518 // handling functions. 00519 struct CallbackInfo { 00520 void *object; // Used as a "this" pointer. 00521 ThreadHandle thread; 00522 void *callback; 00523 void *userData; 00524 void *apiInfo; // void pointer for API specific callback information 00525 bool isRunning; 00526 00527 // Default constructor. 00528 CallbackInfo() 00529 :object(0), callback(0), userData(0), apiInfo(0), isRunning(false) {} 00530 }; 00531 00532 // **************************************************************** // 00533 // 00534 // RtApi class declaration. 00535 // 00536 // Subclasses of RtApi contain all API- and OS-specific code necessary 00537 // to fully implement the RtAudio API. 00538 // 00539 // Note that RtApi is an abstract base class and cannot be 00540 // explicitly instantiated. The class RtAudio will create an 00541 // instance of an RtApi subclass (RtApiOss, RtApiAlsa, 00542 // RtApiJack, RtApiCore, RtApiAl, RtApiDs, or RtApiAsio). 00543 // 00544 // **************************************************************** // 00545 00546 #if defined( HAVE_GETTIMEOFDAY ) 00547 #include <sys/time.h> 00548 #endif 00549 00550 #include <sstream> 00551 00552 class RtApi 00553 { 00554 public: 00555 00556 RtApi(); 00557 virtual ~RtApi(); 00558 virtual RtAudio::Api getCurrentApi( void ) = 0; 00559 virtual unsigned int getDeviceCount( void ) = 0; 00560 virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0; 00561 virtual unsigned int getDefaultInputDevice( void ); 00562 virtual unsigned int getDefaultOutputDevice( void ); 00563 void openStream( RtAudio::StreamParameters *outputParameters, 00564 RtAudio::StreamParameters *inputParameters, 00565 RtAudioFormat format, unsigned int sampleRate, 00566 unsigned int *bufferFrames, RtAudioCallback callback, 00567 void *userData, RtAudio::StreamOptions *options ); 00568 virtual void closeStream( void ); 00569 virtual void startStream( void ) = 0; 00570 virtual void stopStream( void ) = 0; 00571 virtual void abortStream( void ) = 0; 00572 long getStreamLatency( void ); 00573 unsigned int getStreamSampleRate( void ); 00574 virtual double getStreamTime( void ); 00575 bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; }; 00576 bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; }; 00577 void showWarnings( bool value ) { showWarnings_ = value; }; 00578 00579 00580 protected: 00581 00582 static const unsigned int MAX_SAMPLE_RATES; 00583 static const unsigned int SAMPLE_RATES[]; 00584 00585 enum { FAILURE, SUCCESS }; 00586 00587 enum StreamState { 00588 STREAM_STOPPED, 00589 STREAM_RUNNING, 00590 STREAM_CLOSED = -50 00591 }; 00592 00593 enum StreamMode { 00594 OUTPUT, 00595 INPUT, 00596 DUPLEX, 00597 UNINITIALIZED = -75 00598 }; 00599 00600 // A protected structure used for buffer conversion. 00601 struct ConvertInfo { 00602 int channels; 00603 int inJump, outJump; 00604 RtAudioFormat inFormat, outFormat; 00605 std::vector<int> inOffset; 00606 std::vector<int> outOffset; 00607 }; 00608 00609 // A protected structure for audio streams. 00610 struct RtApiStream { 00611 unsigned int device[2]; // Playback and record, respectively. 00612 void *apiHandle; // void pointer for API specific stream handle information 00613 StreamMode mode; // OUTPUT, INPUT, or DUPLEX. 00614 StreamState state; // STOPPED, RUNNING, or CLOSED 00615 char *userBuffer[2]; // Playback and record, respectively. 00616 char *deviceBuffer; 00617 bool doConvertBuffer[2]; // Playback and record, respectively. 00618 bool userInterleaved; 00619 bool deviceInterleaved[2]; // Playback and record, respectively. 00620 bool doByteSwap[2]; // Playback and record, respectively. 00621 unsigned int sampleRate; 00622 unsigned int bufferSize; 00623 unsigned int nBuffers; 00624 unsigned int nUserChannels[2]; // Playback and record, respectively. 00625 unsigned int nDeviceChannels[2]; // Playback and record channels, respectively. 00626 unsigned int channelOffset[2]; // Playback and record, respectively. 00627 unsigned long latency[2]; // Playback and record, respectively. 00628 RtAudioFormat userFormat; 00629 RtAudioFormat deviceFormat[2]; // Playback and record, respectively. 00630 StreamMutex mutex; 00631 CallbackInfo callbackInfo; 00632 ConvertInfo convertInfo[2]; 00633 double streamTime; // Number of elapsed seconds since the stream started. 00634 00635 #if defined(HAVE_GETTIMEOFDAY) 00636 struct timeval lastTickTimestamp; 00637 #endif 00638 00639 RtApiStream() 00640 :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; } 00641 }; 00642 00643 typedef signed short Int16; 00644 typedef signed int Int32; 00645 typedef float Float32; 00646 typedef double Float64; 00647 00648 std::ostringstream errorStream_; 00649 std::string errorText_; 00650 bool showWarnings_; 00651 RtApiStream stream_; 00652 00660 virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 00661 unsigned int firstChannel, unsigned int sampleRate, 00662 RtAudioFormat format, unsigned int *bufferSize, 00663 RtAudio::StreamOptions *options ); 00664 00666 void tickStreamTime( void ); 00667 00669 void clearStreamInfo(); 00670 00675 void verifyStream( void ); 00676 00678 void error( RtError::Type type ); 00679 00684 void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info ); 00685 00687 void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format ); 00688 00690 unsigned int formatBytes( RtAudioFormat format ); 00691 00693 void setConvertInfo( StreamMode mode, unsigned int firstChannel ); 00694 }; 00695 00696 // **************************************************************** // 00697 // 00698 // Inline RtAudio definitions. 00699 // 00700 // **************************************************************** // 00701 00702 inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } 00703 inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); } 00704 inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); } 00705 inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); } 00706 inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); } 00707 inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); } 00708 inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); } 00709 inline void RtAudio :: stopStream( void ) { return rtapi_->stopStream(); } 00710 inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); } 00711 inline bool RtAudio :: isStreamOpen( void ) const throw() { return rtapi_->isStreamOpen(); } 00712 inline bool RtAudio :: isStreamRunning( void ) const throw() { return rtapi_->isStreamRunning(); } 00713 inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); } 00714 inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); }; 00715 inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); } 00716 inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); } 00717 00718 // RtApi Subclass prototypes. 00719 00720 #if defined(__MACOSX_CORE__) 00721 00722 #include <CoreAudio/AudioHardware.h> 00723 00724 class RtApiCore: public RtApi 00725 { 00726 public: 00727 00728 RtApiCore(); 00729 ~RtApiCore(); 00730 RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; }; 00731 unsigned int getDeviceCount( void ); 00732 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 00733 unsigned int getDefaultOutputDevice( void ); 00734 unsigned int getDefaultInputDevice( void ); 00735 void closeStream( void ); 00736 void startStream( void ); 00737 void stopStream( void ); 00738 void abortStream( void ); 00739 long getStreamLatency( void ); 00740 00741 // This function is intended for internal use only. It must be 00742 // public because it is called by the internal callback handler, 00743 // which is not a member of RtAudio. External use of this function 00744 // will most likely produce highly undesireable results! 00745 bool callbackEvent( AudioDeviceID deviceId, 00746 const AudioBufferList *inBufferList, 00747 const AudioBufferList *outBufferList ); 00748 00749 private: 00750 00751 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 00752 unsigned int firstChannel, unsigned int sampleRate, 00753 RtAudioFormat format, unsigned int *bufferSize, 00754 RtAudio::StreamOptions *options ); 00755 static const char* getErrorCode( OSStatus code ); 00756 }; 00757 00758 #endif 00759 00760 #if defined(__UNIX_JACK__) 00761 00762 class RtApiJack: public RtApi 00763 { 00764 public: 00765 00766 RtApiJack(); 00767 ~RtApiJack(); 00768 RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; }; 00769 unsigned int getDeviceCount( void ); 00770 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 00771 void closeStream( void ); 00772 void startStream( void ); 00773 void stopStream( void ); 00774 void abortStream( void ); 00775 long getStreamLatency( void ); 00776 00777 // This function is intended for internal use only. It must be 00778 // public because it is called by the internal callback handler, 00779 // which is not a member of RtAudio. External use of this function 00780 // will most likely produce highly undesireable results! 00781 bool callbackEvent( unsigned long nframes ); 00782 00783 private: 00784 00785 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 00786 unsigned int firstChannel, unsigned int sampleRate, 00787 RtAudioFormat format, unsigned int *bufferSize, 00788 RtAudio::StreamOptions *options ); 00789 }; 00790 00791 #endif 00792 00793 #if defined(__WINDOWS_ASIO__) 00794 00795 class RtApiAsio: public RtApi 00796 { 00797 public: 00798 00799 RtApiAsio(); 00800 ~RtApiAsio(); 00801 RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; }; 00802 unsigned int getDeviceCount( void ); 00803 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 00804 void closeStream( void ); 00805 void startStream( void ); 00806 void stopStream( void ); 00807 void abortStream( void ); 00808 long getStreamLatency( void ); 00809 00810 // This function is intended for internal use only. It must be 00811 // public because it is called by the internal callback handler, 00812 // which is not a member of RtAudio. External use of this function 00813 // will most likely produce highly undesireable results! 00814 bool callbackEvent( long bufferIndex ); 00815 00816 private: 00817 00818 std::vector<RtAudio::DeviceInfo> devices_; 00819 void saveDeviceInfo( void ); 00820 bool coInitialized_; 00821 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 00822 unsigned int firstChannel, unsigned int sampleRate, 00823 RtAudioFormat format, unsigned int *bufferSize, 00824 RtAudio::StreamOptions *options ); 00825 }; 00826 00827 #endif 00828 00829 #if defined(__WINDOWS_DS__) 00830 00831 class RtApiDs: public RtApi 00832 { 00833 public: 00834 00835 RtApiDs(); 00836 ~RtApiDs(); 00837 RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; }; 00838 unsigned int getDeviceCount( void ); 00839 unsigned int getDefaultOutputDevice( void ); 00840 unsigned int getDefaultInputDevice( void ); 00841 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 00842 void closeStream( void ); 00843 void startStream( void ); 00844 void stopStream( void ); 00845 void abortStream( void ); 00846 long getStreamLatency( void ); 00847 00848 // This function is intended for internal use only. It must be 00849 // public because it is called by the internal callback handler, 00850 // which is not a member of RtAudio. External use of this function 00851 // will most likely produce highly undesireable results! 00852 void callbackEvent( void ); 00853 00854 private: 00855 00856 bool coInitialized_; 00857 bool buffersRolling; 00858 long duplexPrerollBytes; 00859 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 00860 unsigned int firstChannel, unsigned int sampleRate, 00861 RtAudioFormat format, unsigned int *bufferSize, 00862 RtAudio::StreamOptions *options ); 00863 }; 00864 00865 #endif 00866 00867 #if defined(__LINUX_ALSA__) 00868 00869 class RtApiAlsa: public RtApi 00870 { 00871 public: 00872 00873 RtApiAlsa(); 00874 ~RtApiAlsa(); 00875 RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; }; 00876 unsigned int getDeviceCount( void ); 00877 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 00878 void closeStream( void ); 00879 void startStream( void ); 00880 void stopStream( void ); 00881 void abortStream( void ); 00882 00883 // This function is intended for internal use only. It must be 00884 // public because it is called by the internal callback handler, 00885 // which is not a member of RtAudio. External use of this function 00886 // will most likely produce highly undesireable results! 00887 void callbackEvent( void ); 00888 00889 private: 00890 00891 std::vector<RtAudio::DeviceInfo> devices_; 00892 void saveDeviceInfo( void ); 00893 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 00894 unsigned int firstChannel, unsigned int sampleRate, 00895 RtAudioFormat format, unsigned int *bufferSize, 00896 RtAudio::StreamOptions *options ); 00897 }; 00898 00899 #endif 00900 00901 #if defined(__LINUX_OSS__) 00902 00903 class RtApiOss: public RtApi 00904 { 00905 public: 00906 00907 RtApiOss(); 00908 ~RtApiOss(); 00909 RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; }; 00910 unsigned int getDeviceCount( void ); 00911 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 00912 void closeStream( void ); 00913 void startStream( void ); 00914 void stopStream( void ); 00915 void abortStream( void ); 00916 00917 // This function is intended for internal use only. It must be 00918 // public because it is called by the internal callback handler, 00919 // which is not a member of RtAudio. External use of this function 00920 // will most likely produce highly undesireable results! 00921 void callbackEvent( void ); 00922 00923 private: 00924 00925 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 00926 unsigned int firstChannel, unsigned int sampleRate, 00927 RtAudioFormat format, unsigned int *bufferSize, 00928 RtAudio::StreamOptions *options ); 00929 }; 00930 00931 #endif 00932 00933 #if defined(__RTAUDIO_DUMMY__) 00934 00935 class RtApiDummy: public RtApi 00936 { 00937 public: 00938 00939 RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtError::WARNING ); }; 00940 RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; }; 00941 unsigned int getDeviceCount( void ) { return 0; }; 00942 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) { RtAudio::DeviceInfo info; return info; }; 00943 void closeStream( void ) {}; 00944 void startStream( void ) {}; 00945 void stopStream( void ) {}; 00946 void abortStream( void ) {}; 00947 00948 private: 00949 00950 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 00951 unsigned int firstChannel, unsigned int sampleRate, 00952 RtAudioFormat format, unsigned int *bufferSize, 00953 RtAudio::StreamOptions *options ) { return false; }; 00954 }; 00955 00956 #endif 00957 00958 #endif 00959 00960 // Indentation settings for Vim and Emacs 00961 // 00962 // Local Variables: 00963 // c-basic-offset: 2 00964 // indent-tabs-mode: nil 00965 // End: 00966 // 00967 // vim: et sts=2 sw=2
©2001-2009 Gary P. Scavone, McGill University. All Rights Reserved. Maintained by Gary P. Scavone. |