diff options
| author | Gary Scavone <gary@music.mcgill.ca> | 2014-01-06 16:53:30 -0800 |
|---|---|---|
| committer | Gary Scavone <gary@music.mcgill.ca> | 2014-01-06 16:53:30 -0800 |
| commit | ee76af899f7f27f4784d3bbae27f2c63f0f1e6ce (patch) | |
| tree | a511dce650149d3969c50e0b685136a56a113901 /RtAudio.cpp | |
| parent | 9d0703f03ac2972409816f147e2141b3fe315a54 (diff) | |
Updates to OS-X sample rate querying, other small changes suggested by Martin Koegler.
Diffstat (limited to 'RtAudio.cpp')
| -rw-r--r-- | RtAudio.cpp | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/RtAudio.cpp b/RtAudio.cpp index f9259df..0a7d9eb 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -75,6 +75,11 @@ const unsigned int RtApi::SAMPLE_RATES[] = { //
// *************************************************** //
+std::string RtAudio :: getVersion( void ) throw()
+{
+ return std::string( RTAUDIO_VERSION );
+}
+
void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) throw()
{
apis.clear();
@@ -176,7 +181,8 @@ RtAudio :: RtAudio( RtAudio::Api api ) throw() // definition __RTAUDIO_DUMMY__ is automatically defined if no
// API-specific definitions are passed to the compiler. But just in
// case something weird happens, we'll print out an error message.
- std::cerr << "\nRtAudio: no compiled API support found ... critical error!!\n\n";
+ std::string errorText = "\nRtAudio: no compiled API support found ... critical error!!\n\n";
+ throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) );
}
RtAudio :: ~RtAudio() throw()
@@ -213,7 +219,7 @@ RtApi :: RtApi() stream_.userBuffer[1] = 0;
MUTEX_INITIALIZE( &stream_.mutex );
showWarnings_ = true;
- firstErrorOccurred = false;
+ firstErrorOccurred_ = false;
}
RtApi :: ~RtApi()
@@ -718,18 +724,37 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device ) return info;
}
- Float64 minimumRate = 100000000.0, maximumRate = 0.0;
+ // The sample rate reporting mechanism is a bit of a mystery. It
+ // seems that it can either return individual rates or a range of
+ // rates. I assume that if the min / max range values are the same,
+ // then that represents a single supported rate and if the min / max
+ // range values are different, the device supports an arbitrary
+ // range of values (though there might be multiple ranges, so we'll
+ // use the most conservative range).
+ Float64 minimumRate = 1.0, maximumRate = 10000000000.0;
+ bool haveValueRange = false;
+ info.sampleRates.clear();
for ( UInt32 i=0; i<nRanges; i++ ) {
- if ( rangeList[i].mMinimum < minimumRate ) minimumRate = rangeList[i].mMinimum;
- if ( rangeList[i].mMaximum > maximumRate ) maximumRate = rangeList[i].mMaximum;
+ if ( rangeList[i].mMinimum == rangeList[i].mMaximum )
+ info.sampleRates.push_back( (unsigned int) rangeList[i].mMinimum );
+ else {
+ haveValueRange = true;
+ if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;
+ if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;
+ }
}
- info.sampleRates.clear();
- for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
- if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate )
- info.sampleRates.push_back( SAMPLE_RATES[k] );
+ if ( haveValueRange ) {
+ for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
+ if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate )
+ info.sampleRates.push_back( SAMPLE_RATES[k] );
+ }
}
+ // Sort and remove any redundant values
+ std::sort( info.sampleRates.begin(), info.sampleRates.end() );
+ info.sampleRates.erase( unique( info.sampleRates.begin(), info.sampleRates.end() ), info.sampleRates.end() );
+
if ( info.sampleRates.size() == 0 ) {
errorStream_ << "RtApiCore::probeDeviceInfo: No supported sample rates found for device (" << device << ").";
errorText_ = errorStream_.str();
@@ -791,7 +816,6 @@ static OSStatus rateListener( AudioObjectID inDevice, const AudioObjectPropertyAddress /*properties*/[],
void* ratePointer )
{
-
Float64 *rate = (Float64 *) ratePointer;
UInt32 dataSize = sizeof( Float64 );
AudioObjectPropertyAddress property = { kAudioDevicePropertyNominalSampleRate,
@@ -863,6 +887,7 @@ bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
if (result != noErr || dataSize == 0) {
+ free( bufferList );
errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration for device (" << device << ").";
errorText_ = errorStream_.str();
return FAILURE;
@@ -1003,7 +1028,6 @@ bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne dataSize = sizeof( Float64 );
property.mSelector = kAudioDevicePropertyNominalSampleRate;
result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &nominalRate );
-
if ( result != noErr ) {
errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting current sample rate.";
errorText_ = errorStream_.str();
@@ -1025,8 +1049,8 @@ bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne nominalRate = (Float64) sampleRate;
result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &nominalRate );
-
if ( result != noErr ) {
+ AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate for device (" << device << ").";
errorText_ = errorStream_.str();
return FAILURE;
@@ -7846,10 +7870,10 @@ void RtApi :: error( RtAudioError::Type type ) if ( errorCallback ) {
// abortStream() can generate new error messages. Ignore them. Just keep original one.
- if ( firstErrorOccurred )
+ if ( firstErrorOccurred_ )
return;
- firstErrorOccurred = true;
+ firstErrorOccurred_ = true;
const std::string errorMessage = errorText_;
if ( type != RtAudioError::WARNING && stream_.state != STREAM_STOPPED) {
@@ -7858,7 +7882,7 @@ void RtApi :: error( RtAudioError::Type type ) }
errorCallback( type, errorMessage );
- firstErrorOccurred = false;
+ firstErrorOccurred_ = false;
return;
}
|
