Home   Class/Enum List   File List   Compound Members  

RtAudio.h
Go to the documentation of this file.
1 /************************************************************************/
39 /************************************************************************/
40 
45 #ifndef __RTAUDIO_H
46 #define __RTAUDIO_H
47 
48 #include <string>
49 #include <vector>
50 #include "RtError.h"
51 
52 // RtAudio version
53 static const std::string VERSION( "4.0.12" );
54 
71 typedef unsigned long RtAudioFormat;
72 static const RtAudioFormat RTAUDIO_SINT8 = 0x1; // 8-bit signed integer.
73 static const RtAudioFormat RTAUDIO_SINT16 = 0x2; // 16-bit signed integer.
74 static const RtAudioFormat RTAUDIO_SINT24 = 0x4; // 24-bit signed integer.
75 static const RtAudioFormat RTAUDIO_SINT32 = 0x8; // 32-bit signed integer.
76 static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
77 static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
78 
121 typedef unsigned int RtAudioStreamFlags;
122 static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1; // Use non-interleaved buffers (default = interleaved).
123 static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2; // Attempt to set stream parameters for lowest possible latency.
124 static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4; // Attempt grab device and prevent use by others.
125 static const RtAudioStreamFlags RTAUDIO_SCHEDULE_REALTIME = 0x8; // Try to select realtime scheduling for callback thread.
126 static const RtAudioStreamFlags RTAUDIO_ALSA_USE_DEFAULT = 0x10; // Use the "default" PCM device (ALSA only).
127 
139 typedef unsigned int RtAudioStreamStatus;
140 static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1; // Input data was discarded because of an overflow condition at the driver.
141 static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2; // The output buffer ran low, likely causing a gap in the output sound.
142 
144 
182 typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
183  unsigned int nFrames,
184  double streamTime,
185  RtAudioStreamStatus status,
186  void *userData );
187 
189 
193 typedef void (*RtAudioErrorCallback)( RtError::Type type, const std::string &errorText );
194 
195 // **************************************************************** //
196 //
197 // RtAudio class declaration.
198 //
199 // RtAudio is a "controller" used to select an available audio i/o
200 // interface. It presents a common API for the user to call but all
201 // functionality is implemented by the class RtApi and its
202 // subclasses. RtAudio creates an instance of an RtApi subclass
203 // based on the user's API choice. If no choice is made, RtAudio
204 // attempts to make a "logical" API selection.
205 //
206 // **************************************************************** //
207 
208 class RtApi;
209 
210 class RtAudio
211 {
212  public:
213 
215  enum Api {
225  };
226 
228  struct DeviceInfo {
229  bool probed;
230  std::string name;
231  unsigned int outputChannels;
232  unsigned int inputChannels;
233  unsigned int duplexChannels;
236  std::vector<unsigned int> sampleRates;
239  // Default constructor.
240  DeviceInfo()
242  isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {}
243  };
244 
247  unsigned int deviceId;
248  unsigned int nChannels;
249  unsigned int firstChannel;
251  // Default constructor.
253  : deviceId(0), nChannels(0), firstChannel(0) {}
254  };
255 
257 
313  struct StreamOptions {
315  unsigned int numberOfBuffers;
316  std::string streamName;
317  int priority;
319  // Default constructor.
320  StreamOptions()
321  : flags(0), numberOfBuffers(0), priority(0) {}
322  };
323 
325  static std::string getVersion( void ) { return VERSION; }
326 
328 
333  static void getCompiledApi( std::vector<RtAudio::Api> &apis ) throw();
334 
336 
344  RtAudio( RtAudio::Api api=UNSPECIFIED ) throw();
345 
347 
351  ~RtAudio() throw();
352 
354  RtAudio::Api getCurrentApi( void ) throw();
355 
357 
362  unsigned int getDeviceCount( void ) throw();
363 
365 
375  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
376 
378 
385  unsigned int getDefaultOutputDevice( void ) throw();
386 
388 
395  unsigned int getDefaultInputDevice( void ) throw();
396 
398 
437  void openStream( RtAudio::StreamParameters *outputParameters,
438  RtAudio::StreamParameters *inputParameters,
439  RtAudioFormat format, unsigned int sampleRate,
440  unsigned int *bufferFrames, RtAudioCallback callback,
441  void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL );
442 
444 
448  void closeStream( void ) throw();
449 
451 
457  void startStream( void );
458 
460 
466  void stopStream( void );
467 
469 
475  void abortStream( void );
476 
478  bool isStreamOpen( void ) const throw();
479 
481  bool isStreamRunning( void ) const throw();
482 
484 
487  double getStreamTime( void );
488 
490 
498  long getStreamLatency( void );
499 
501 
506  unsigned int getStreamSampleRate( void );
507 
509  void showWarnings( bool value = true ) throw();
510 
511  protected:
512 
513  void openRtApi( RtAudio::Api api );
514  RtApi *rtapi_;
515 };
516 
517 // Operating system dependent thread functionality.
518 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
519  #include <windows.h>
520  #include <process.h>
521 
522  typedef unsigned long ThreadHandle;
523  typedef CRITICAL_SECTION StreamMutex;
524 
525 #elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
526  // Using pthread library for various flavors of unix.
527  #include <pthread.h>
528 
529  typedef pthread_t ThreadHandle;
530  typedef pthread_mutex_t StreamMutex;
531 
532 #else // Setup for "dummy" behavior
533 
534  #define __RTAUDIO_DUMMY__
535  typedef int ThreadHandle;
536  typedef int StreamMutex;
537 
538 #endif
539 
540 // This global structure type is used to pass callback information
541 // between the private RtAudio stream structure and global callback
542 // handling functions.
543 struct CallbackInfo {
544  void *object; // Used as a "this" pointer.
545  ThreadHandle thread;
546  void *callback;
547  void *userData;
548  void *errorCallback;
549  void *apiInfo; // void pointer for API specific callback information
550  bool isRunning;
551  bool doRealtime;
552  int priority;
553 
554  // Default constructor.
555  CallbackInfo()
556  :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false) {}
557 };
558 
559 // **************************************************************** //
560 //
561 // RtApi class declaration.
562 //
563 // Subclasses of RtApi contain all API- and OS-specific code necessary
564 // to fully implement the RtAudio API.
565 //
566 // Note that RtApi is an abstract base class and cannot be
567 // explicitly instantiated. The class RtAudio will create an
568 // instance of an RtApi subclass (RtApiOss, RtApiAlsa,
569 // RtApiJack, RtApiCore, RtApiDs, or RtApiAsio).
570 //
571 // **************************************************************** //
572 
573 #pragma pack(push, 1)
574 class S24 {
575 
576  protected:
577  unsigned char c3[3];
578 
579  public:
580  S24() {}
581 
582  S24& operator = ( const int& i ) {
583  c3[0] = (i & 0x000000ff);
584  c3[1] = (i & 0x0000ff00) >> 8;
585  c3[2] = (i & 0x00ff0000) >> 16;
586  return *this;
587  }
588 
589  S24( const S24& v ) { *this = v; }
590  S24( const double& d ) { *this = (int) d; }
591  S24( const float& f ) { *this = (int) f; }
592  S24( const signed short& s ) { *this = (int) s; }
593  S24( const char& c ) { *this = (int) c; }
594 
595  int asInt() {
596  int i = c3[0] | (c3[1] << 8) | (c3[2] << 16);
597  if (i & 0x800000) i |= ~0xffffff;
598  return i;
599  }
600 };
601 #pragma pack(pop)
602 
603 #if defined( HAVE_GETTIMEOFDAY )
604  #include <sys/time.h>
605 #endif
606 
607 #include <sstream>
608 
609 class RtApi
610 {
611 public:
612 
613  RtApi();
614  virtual ~RtApi();
615  virtual RtAudio::Api getCurrentApi( void ) = 0;
616  virtual unsigned int getDeviceCount( void ) = 0;
617  virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
618  virtual unsigned int getDefaultInputDevice( void );
619  virtual unsigned int getDefaultOutputDevice( void );
620  void openStream( RtAudio::StreamParameters *outputParameters,
621  RtAudio::StreamParameters *inputParameters,
622  RtAudioFormat format, unsigned int sampleRate,
623  unsigned int *bufferFrames, RtAudioCallback callback,
624  void *userData, RtAudio::StreamOptions *options,
625  RtAudioErrorCallback errorCallback );
626  virtual void closeStream( void );
627  virtual void startStream( void ) = 0;
628  virtual void stopStream( void ) = 0;
629  virtual void abortStream( void ) = 0;
630  long getStreamLatency( void );
631  unsigned int getStreamSampleRate( void );
632  virtual double getStreamTime( void );
633  bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; }
634  bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; }
635  void showWarnings( bool value ) { showWarnings_ = value; }
636 
637 
638 protected:
639 
640  static const unsigned int MAX_SAMPLE_RATES;
641  static const unsigned int SAMPLE_RATES[];
642 
643  enum { FAILURE, SUCCESS };
644 
645  enum StreamState {
646  STREAM_STOPPED,
647  STREAM_STOPPING,
648  STREAM_RUNNING,
649  STREAM_CLOSED = -50
650  };
651 
652  enum StreamMode {
653  OUTPUT,
654  INPUT,
655  DUPLEX,
656  UNINITIALIZED = -75
657  };
658 
659  // A protected structure used for buffer conversion.
660  struct ConvertInfo {
661  int channels;
662  int inJump, outJump;
663  RtAudioFormat inFormat, outFormat;
664  std::vector<int> inOffset;
665  std::vector<int> outOffset;
666  };
667 
668  // A protected structure for audio streams.
669  struct RtApiStream {
670  unsigned int device[2]; // Playback and record, respectively.
671  void *apiHandle; // void pointer for API specific stream handle information
672  StreamMode mode; // OUTPUT, INPUT, or DUPLEX.
673  StreamState state; // STOPPED, RUNNING, or CLOSED
674  char *userBuffer[2]; // Playback and record, respectively.
675  char *deviceBuffer;
676  bool doConvertBuffer[2]; // Playback and record, respectively.
677  bool userInterleaved;
678  bool deviceInterleaved[2]; // Playback and record, respectively.
679  bool doByteSwap[2]; // Playback and record, respectively.
680  unsigned int sampleRate;
681  unsigned int bufferSize;
682  unsigned int nBuffers;
683  unsigned int nUserChannels[2]; // Playback and record, respectively.
684  unsigned int nDeviceChannels[2]; // Playback and record channels, respectively.
685  unsigned int channelOffset[2]; // Playback and record, respectively.
686  unsigned long latency[2]; // Playback and record, respectively.
687  RtAudioFormat userFormat;
688  RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
689  StreamMutex mutex;
690  CallbackInfo callbackInfo;
691  ConvertInfo convertInfo[2];
692  double streamTime; // Number of elapsed seconds since the stream started.
693 
694 #if defined(HAVE_GETTIMEOFDAY)
695  struct timeval lastTickTimestamp;
696 #endif
697 
698  RtApiStream()
699  :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
700  };
701 
702  typedef S24 Int24;
703  typedef signed short Int16;
704  typedef signed int Int32;
705  typedef float Float32;
706  typedef double Float64;
707 
708  std::ostringstream errorStream_;
709  std::string errorText_;
710  bool showWarnings_;
711  RtApiStream stream_;
712 
720  virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
721  unsigned int firstChannel, unsigned int sampleRate,
722  RtAudioFormat format, unsigned int *bufferSize,
723  RtAudio::StreamOptions *options );
724 
726  void tickStreamTime( void );
727 
729  void clearStreamInfo();
730 
735  void verifyStream( void );
736 
738  void error( RtError::Type type );
739 
744  void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
745 
747  void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
748 
750  unsigned int formatBytes( RtAudioFormat format );
751 
753  void setConvertInfo( StreamMode mode, unsigned int firstChannel );
754 };
755 
756 // **************************************************************** //
757 //
758 // Inline RtAudio definitions.
759 //
760 // **************************************************************** //
761 
762 inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
763 inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); }
764 inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); }
765 inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); }
766 inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); }
767 inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); }
768 inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
769 inline void RtAudio :: stopStream( void ) { return rtapi_->stopStream(); }
770 inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
771 inline bool RtAudio :: isStreamOpen( void ) const throw() { return rtapi_->isStreamOpen(); }
772 inline bool RtAudio :: isStreamRunning( void ) const throw() { return rtapi_->isStreamRunning(); }
773 inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
774 inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); }
775 inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
776 inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); }
777 
778 // RtApi Subclass prototypes.
779 
780 #if defined(__MACOSX_CORE__)
781 
782 #include <CoreAudio/AudioHardware.h>
783 
784 class RtApiCore: public RtApi
785 {
786 public:
787 
788  RtApiCore();
789  ~RtApiCore();
791  unsigned int getDeviceCount( void );
792  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
793  unsigned int getDefaultOutputDevice( void );
794  unsigned int getDefaultInputDevice( void );
795  void closeStream( void );
796  void startStream( void );
797  void stopStream( void );
798  void abortStream( void );
799  long getStreamLatency( void );
800 
801  // This function is intended for internal use only. It must be
802  // public because it is called by the internal callback handler,
803  // which is not a member of RtAudio. External use of this function
804  // will most likely produce highly undesireable results!
805  bool callbackEvent( AudioDeviceID deviceId,
806  const AudioBufferList *inBufferList,
807  const AudioBufferList *outBufferList );
808 
809  private:
810 
811  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
812  unsigned int firstChannel, unsigned int sampleRate,
813  RtAudioFormat format, unsigned int *bufferSize,
814  RtAudio::StreamOptions *options );
815  static const char* getErrorCode( OSStatus code );
816 };
817 
818 #endif
819 
820 #if defined(__UNIX_JACK__)
821 
822 class RtApiJack: public RtApi
823 {
824 public:
825 
826  RtApiJack();
827  ~RtApiJack();
828  RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; }
829  unsigned int getDeviceCount( void );
830  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
831  void closeStream( void );
832  void startStream( void );
833  void stopStream( void );
834  void abortStream( void );
835  long getStreamLatency( void );
836 
837  // This function is intended for internal use only. It must be
838  // public because it is called by the internal callback handler,
839  // which is not a member of RtAudio. External use of this function
840  // will most likely produce highly undesireable results!
841  bool callbackEvent( unsigned long nframes );
842 
843  private:
844 
845  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
846  unsigned int firstChannel, unsigned int sampleRate,
847  RtAudioFormat format, unsigned int *bufferSize,
848  RtAudio::StreamOptions *options );
849 };
850 
851 #endif
852 
853 #if defined(__WINDOWS_ASIO__)
854 
855 class RtApiAsio: public RtApi
856 {
857 public:
858 
859  RtApiAsio();
860  ~RtApiAsio();
862  unsigned int getDeviceCount( void );
863  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
864  void closeStream( void );
865  void startStream( void );
866  void stopStream( void );
867  void abortStream( void );
868  long getStreamLatency( void );
869 
870  // This function is intended for internal use only. It must be
871  // public because it is called by the internal callback handler,
872  // which is not a member of RtAudio. External use of this function
873  // will most likely produce highly undesireable results!
874  bool callbackEvent( long bufferIndex );
875 
876  private:
877 
878  std::vector<RtAudio::DeviceInfo> devices_;
879  void saveDeviceInfo( void );
880  bool coInitialized_;
881  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
882  unsigned int firstChannel, unsigned int sampleRate,
883  RtAudioFormat format, unsigned int *bufferSize,
884  RtAudio::StreamOptions *options );
885 };
886 
887 #endif
888 
889 #if defined(__WINDOWS_DS__)
890 
891 class RtApiDs: public RtApi
892 {
893 public:
894 
895  RtApiDs();
896  ~RtApiDs();
898  unsigned int getDeviceCount( void );
899  unsigned int getDefaultOutputDevice( void );
900  unsigned int getDefaultInputDevice( void );
901  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
902  void closeStream( void );
903  void startStream( void );
904  void stopStream( void );
905  void abortStream( void );
906  long getStreamLatency( void );
907 
908  // This function is intended for internal use only. It must be
909  // public because it is called by the internal callback handler,
910  // which is not a member of RtAudio. External use of this function
911  // will most likely produce highly undesireable results!
912  void callbackEvent( void );
913 
914  private:
915 
916  bool coInitialized_;
917  bool buffersRolling;
918  long duplexPrerollBytes;
919  std::vector<struct DsDevice> dsDevices;
920  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
921  unsigned int firstChannel, unsigned int sampleRate,
922  RtAudioFormat format, unsigned int *bufferSize,
923  RtAudio::StreamOptions *options );
924 };
925 
926 #endif
927 
928 #if defined(__LINUX_ALSA__)
929 
930 class RtApiAlsa: public RtApi
931 {
932 public:
933 
934  RtApiAlsa();
935  ~RtApiAlsa();
937  unsigned int getDeviceCount( void );
938  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
939  void closeStream( void );
940  void startStream( void );
941  void stopStream( void );
942  void abortStream( void );
943 
944  // This function is intended for internal use only. It must be
945  // public because it is called by the internal callback handler,
946  // which is not a member of RtAudio. External use of this function
947  // will most likely produce highly undesireable results!
948  void callbackEvent( void );
949 
950  private:
951 
952  std::vector<RtAudio::DeviceInfo> devices_;
953  void saveDeviceInfo( void );
954  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
955  unsigned int firstChannel, unsigned int sampleRate,
956  RtAudioFormat format, unsigned int *bufferSize,
957  RtAudio::StreamOptions *options );
958 };
959 
960 #endif
961 
962 #if defined(__LINUX_PULSE__)
963 
964 class RtApiPulse: public RtApi
965 {
966 public:
967  ~RtApiPulse();
969  unsigned int getDeviceCount( void );
970  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
971  void closeStream( void );
972  void startStream( void );
973  void stopStream( void );
974  void abortStream( void );
975 
976  // This function is intended for internal use only. It must be
977  // public because it is called by the internal callback handler,
978  // which is not a member of RtAudio. External use of this function
979  // will most likely produce highly undesireable results!
980  void callbackEvent( void );
981 
982  private:
983 
984  std::vector<RtAudio::DeviceInfo> devices_;
985  void saveDeviceInfo( void );
986  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
987  unsigned int firstChannel, unsigned int sampleRate,
988  RtAudioFormat format, unsigned int *bufferSize,
989  RtAudio::StreamOptions *options );
990 };
991 
992 #endif
993 
994 #if defined(__LINUX_OSS__)
995 
996 class RtApiOss: public RtApi
997 {
998 public:
999 
1000  RtApiOss();
1001  ~RtApiOss();
1003  unsigned int getDeviceCount( void );
1004  RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
1005  void closeStream( void );
1006  void startStream( void );
1007  void stopStream( void );
1008  void abortStream( void );
1009 
1010  // This function is intended for internal use only. It must be
1011  // public because it is called by the internal callback handler,
1012  // which is not a member of RtAudio. External use of this function
1013  // will most likely produce highly undesireable results!
1014  void callbackEvent( void );
1015 
1016  private:
1017 
1018  bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
1019  unsigned int firstChannel, unsigned int sampleRate,
1020  RtAudioFormat format, unsigned int *bufferSize,
1021  RtAudio::StreamOptions *options );
1022 };
1023 
1024 #endif
1025 
1026 #if defined(__RTAUDIO_DUMMY__)
1027 
1028 class RtApiDummy: public RtApi
1029 {
1030 public:
1031 
1032  RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtError::WARNING ); }
1034  unsigned int getDeviceCount( void ) { return 0; }
1035  RtAudio::DeviceInfo getDeviceInfo( unsigned int /*device*/ ) { RtAudio::DeviceInfo info; return info; }
1036  void closeStream( void ) {}
1037  void startStream( void ) {}
1038  void stopStream( void ) {}
1039  void abortStream( void ) {}
1040 
1041  private:
1042 
1043  bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/,
1044  unsigned int /*firstChannel*/, unsigned int /*sampleRate*/,
1045  RtAudioFormat /*format*/, unsigned int * /*bufferSize*/,
1046  RtAudio::StreamOptions * /*options*/ ) { return false; }
1047 };
1048 
1049 #endif
1050 
1051 #endif
1052 
1053 // Indentation settings for Vim and Emacs
1054 //
1055 // Local Variables:
1056 // c-basic-offset: 2
1057 // indent-tabs-mode: nil
1058 // End:
1059 //
1060 // vim: et sts=2 sw=2

©2001-2013 Gary P. Scavone, McGill University. All Rights Reserved.
Maintained by Gary P. Scavone.