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