Updates to OS-X sample rate querying, other small changes suggested by Martin Koegler.
authorGary Scavone <gary@music.mcgill.ca>
Tue, 7 Jan 2014 00:53:30 +0000 (16:53 -0800)
committerGary Scavone <gary@music.mcgill.ca>
Tue, 7 Jan 2014 00:53:30 +0000 (16:53 -0800)
RtAudio.cpp
RtAudio.h
doc/doxygen/tutorial.txt

index f9259df42dd2ee34f18ffb22a5ad7f27330be63d..0a7d9ebda0537975a6c247acde50b46ae201d797 100644 (file)
@@ -75,6 +75,11 @@ const unsigned int RtApi::SAMPLE_RATES[] = {
 //\r
 // *************************************************** //\r
 \r
+std::string RtAudio :: getVersion( void ) throw()\r
+{\r
+  return std::string( RTAUDIO_VERSION );\r
+}\r
+\r
 void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) throw()\r
 {\r
   apis.clear();\r
@@ -176,7 +181,8 @@ RtAudio :: RtAudio( RtAudio::Api api ) throw()
   // definition __RTAUDIO_DUMMY__ is automatically defined if no\r
   // API-specific definitions are passed to the compiler. But just in\r
   // case something weird happens, we'll print out an error message.\r
-  std::cerr << "\nRtAudio: no compiled API support found ... critical error!!\n\n";\r
+  std::string errorText = "\nRtAudio: no compiled API support found ... critical error!!\n\n";\r
+  throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) );\r
 }\r
 \r
 RtAudio :: ~RtAudio() throw()\r
@@ -213,7 +219,7 @@ RtApi :: RtApi()
   stream_.userBuffer[1] = 0;\r
   MUTEX_INITIALIZE( &stream_.mutex );\r
   showWarnings_ = true;\r
-  firstErrorOccurred = false;\r
+  firstErrorOccurred_ = false;\r
 }\r
 \r
 RtApi :: ~RtApi()\r
@@ -718,18 +724,37 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
     return info;\r
   }\r
 \r
-  Float64 minimumRate = 100000000.0, maximumRate = 0.0;\r
+  // The sample rate reporting mechanism is a bit of a mystery.  It\r
+  // seems that it can either return individual rates or a range of\r
+  // rates.  I assume that if the min / max range values are the same,\r
+  // then that represents a single supported rate and if the min / max\r
+  // range values are different, the device supports an arbitrary\r
+  // range of values (though there might be multiple ranges, so we'll\r
+  // use the most conservative range).\r
+  Float64 minimumRate = 1.0, maximumRate = 10000000000.0;\r
+  bool haveValueRange = false;\r
+  info.sampleRates.clear();\r
   for ( UInt32 i=0; i<nRanges; i++ ) {\r
-    if ( rangeList[i].mMinimum < minimumRate ) minimumRate = rangeList[i].mMinimum;\r
-    if ( rangeList[i].mMaximum > maximumRate ) maximumRate = rangeList[i].mMaximum;\r
+    if ( rangeList[i].mMinimum == rangeList[i].mMaximum )\r
+      info.sampleRates.push_back( (unsigned int) rangeList[i].mMinimum );\r
+    else {\r
+      haveValueRange = true;\r
+      if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;\r
+      if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;\r
+    }\r
   }\r
 \r
-  info.sampleRates.clear();\r
-  for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {\r
-    if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate )\r
-      info.sampleRates.push_back( SAMPLE_RATES[k] );\r
+  if ( haveValueRange ) {\r
+    for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {\r
+      if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate )\r
+        info.sampleRates.push_back( SAMPLE_RATES[k] );\r
+    }\r
   }\r
 \r
+  // Sort and remove any redundant values\r
+  std::sort( info.sampleRates.begin(), info.sampleRates.end() );\r
+  info.sampleRates.erase( unique( info.sampleRates.begin(), info.sampleRates.end() ), info.sampleRates.end() );\r
+\r
   if ( info.sampleRates.size() == 0 ) {\r
     errorStream_ << "RtApiCore::probeDeviceInfo: No supported sample rates found for device (" << device << ").";\r
     errorText_ = errorStream_.str();\r
@@ -791,7 +816,6 @@ static OSStatus rateListener( AudioObjectID inDevice,
                               const AudioObjectPropertyAddress /*properties*/[],\r
                               void* ratePointer )\r
 {\r
-\r
   Float64 *rate = (Float64 *) ratePointer;\r
   UInt32 dataSize = sizeof( Float64 );\r
   AudioObjectPropertyAddress property = { kAudioDevicePropertyNominalSampleRate,\r
@@ -863,6 +887,7 @@ bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
 \r
   result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );\r
   if (result != noErr || dataSize == 0) {\r
+    free( bufferList );\r
     errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration for device (" << device << ").";\r
     errorText_ = errorStream_.str();\r
     return FAILURE;\r
@@ -1003,7 +1028,6 @@ bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
   dataSize = sizeof( Float64 );\r
   property.mSelector = kAudioDevicePropertyNominalSampleRate;\r
   result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &nominalRate );\r
-\r
   if ( result != noErr ) {\r
     errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting current sample rate.";\r
     errorText_ = errorStream_.str();\r
@@ -1025,8 +1049,8 @@ bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
 \r
     nominalRate = (Float64) sampleRate;\r
     result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &nominalRate );\r
-\r
     if ( result != noErr ) {\r
+      AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate );\r
       errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate for device (" << device << ").";\r
       errorText_ = errorStream_.str();\r
       return FAILURE;\r
@@ -7846,10 +7870,10 @@ void RtApi :: error( RtAudioError::Type type )
   if ( errorCallback ) {\r
     // abortStream() can generate new error messages. Ignore them. Just keep original one.\r
 \r
-    if ( firstErrorOccurred )\r
+    if ( firstErrorOccurred_ )\r
       return;\r
 \r
-    firstErrorOccurred = true;\r
+    firstErrorOccurred_ = true;\r
     const std::string errorMessage = errorText_;\r
 \r
     if ( type != RtAudioError::WARNING && stream_.state != STREAM_STOPPED) {\r
@@ -7858,7 +7882,7 @@ void RtApi :: error( RtAudioError::Type type )
     }\r
 \r
     errorCallback( type, errorMessage );\r
-    firstErrorOccurred = false;\r
+    firstErrorOccurred_ = false;\r
     return;\r
   }\r
 \r
index d1fbd65253196922db5031913e56f062997d221b..f8285c09c398f81ee82fc50ea80d5c0103c676d6 100644 (file)
--- a/RtAudio.h
+++ b/RtAudio.h
 #ifndef __RTAUDIO_H
 #define __RTAUDIO_H
 
+#define RTAUDIO_VERSION "4.1.0pre"
+
 #include <string>
 #include <vector>
 #include <exception>
 #include <iostream>
 
-// RtAudio version: 4.1.0pre
-
 /*! \typedef typedef unsigned long RtAudioFormat;
     \brief RtAudio data format type.
 
@@ -373,7 +373,7 @@ class RtAudio
   };
 
   //! A static function to determine the current RtAudio version.
-  static std::string getVersion( void ) { return "4.1.0"; } 
+  static std::string getVersion( void ) throw();
 
   //! A static function to determine the available compiled audio APIs.
   /*!
@@ -760,7 +760,7 @@ protected:
   std::string errorText_;
   bool showWarnings_;
   RtApiStream stream_;
-  bool firstErrorOccurred;
+  bool firstErrorOccurred_;
 
   /*!
     Protected, api-specific method that attempts to open a device
index da05da6a2ee891222ab4ac0d605d3b959a110ffb..41f3bc03b05d568b1b6326454e1e2dc90eca7495 100644 (file)
@@ -17,6 +17,10 @@ RtAudio incorporates the concept of audio streams, which represent audio output
 
 \section whatsnew Latest Updates (Version 4.1.0)
 
+A minor API change was made. The RtError class was renamed RtAudioError and embedded directly in RtAudio.h.  Thus, all references to RtError should be renamed to RtAudioError and the RtError.h file should be deleted.
+
+Changes in the previous 4.0.12 release included:
+
 - new functionality to allow error reporting via a client-supplied function (thanks to Pavel Mogilevskiy)
 - new function to return the version number
 - updated RtAudio.cpp and ASIO files for UNICODE support (thanks to Renaud Schoonbroodt)