Browse Source

Updates regarding leaks in ALSA, bitwise format flags in OS-X, and changes to stopStream / drain flag to avoid hung state in ASIO, DS, OS-X, and Jack APIs.

tags/4.0.11
Gary Scavone Stephen Sinclair 12 years ago
parent
commit
f680bc760b
1 changed files with 36 additions and 17 deletions
  1. +36
    -17
      RtAudio.cpp

+ 36
- 17
RtAudio.cpp View File

@@ -106,6 +106,10 @@ void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) throw()
void RtAudio :: openRtApi( RtAudio::Api api )
{
if (rtapi_)
delete rtapi_;
rtapi_ = 0;
#if defined(__UNIX_JACK__)
if ( api == UNIX_JACK )
rtapi_ = new RtApiJack();
@@ -1080,7 +1084,7 @@ bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
// We'll try higher bit rates first and then work our way down.
std::vector< std::pair<UInt32, UInt32> > physicalFormats;
formatFlags = description.mFormatFlags | kLinearPCMFormatFlagIsFloat & ~kLinearPCMFormatFlagIsSignedInteger;
formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsFloat) & ~kLinearPCMFormatFlagIsSignedInteger;
physicalFormats.push_back( std::pair<Float32, UInt32>( 32, formatFlags ) );
formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
physicalFormats.push_back( std::pair<Float32, UInt32>( 32, formatFlags ) );
@@ -1507,14 +1511,16 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
handle->xrun[1] = false;
}
handle->drainCounter = callback( stream_.userBuffer[0], stream_.userBuffer[1],
stream_.bufferSize, streamTime, status, info->userData );
if ( handle->drainCounter == 2 ) {
int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
stream_.bufferSize, streamTime, status, info->userData );
if ( cbReturnValue == 2 ) {
MUTEX_UNLOCK( &stream_.mutex );
handle->drainCounter = 2;
abortStream();
return SUCCESS;
}
else if ( handle->drainCounter == 1 )
else if ( cbReturnValue == 1 )
handle->drainCounter = 1;
handle->internalDrain = true;
}
@@ -1901,6 +1907,7 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
}
if ( device >= nDevices ) {
jack_client_close( client );
errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!";
error( RtError::INVALID_USE );
}
@@ -2471,15 +2478,17 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
status |= RTAUDIO_INPUT_OVERFLOW;
handle->xrun[1] = false;
}
handle->drainCounter = callback( stream_.userBuffer[0], stream_.userBuffer[1],
stream_.bufferSize, streamTime, status, info->userData );
if ( handle->drainCounter == 2 ) {
int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
stream_.bufferSize, streamTime, status, info->userData );
if ( cbReturnValue == 2 ) {
MUTEX_UNLOCK( &stream_.mutex );
ThreadHandle id;
handle->drainCounter = 2;
pthread_create( &id, NULL, jackStopStream, info );
return SUCCESS;
}
else if ( handle->drainCounter == 1 )
else if ( cbReturnValue == 1 )
handle->drainCounter = 1;
handle->internalDrain = true;
}
@@ -3300,18 +3309,20 @@ bool RtApiAsio :: callbackEvent( long bufferIndex )
status |= RTAUDIO_INPUT_OVERFLOW;
asioXRun = false;
}
handle->drainCounter = callback( stream_.userBuffer[0], stream_.userBuffer[1],
int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
stream_.bufferSize, streamTime, status, info->userData );
if ( handle->drainCounter == 2 ) {
if ( cbReturnValue == 2 ) {
// MUTEX_UNLOCK( &stream_.mutex );
// abortStream();
unsigned threadId;
stopThreadCalled = true;
handle->drainCounter = 2;
stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream,
&stream_.callbackInfo, 0, &threadId );
return SUCCESS;
}
else if ( handle->drainCounter == 1 )
else if ( cbReturnValue == 1 )
handle->drainCounter = 1;
handle->internalDrain = true;
}
@@ -4634,14 +4645,16 @@ void RtApiDs :: callbackEvent()
status |= RTAUDIO_INPUT_OVERFLOW;
handle->xrun[1] = false;
}
handle->drainCounter = callback( stream_.userBuffer[0], stream_.userBuffer[1],
stream_.bufferSize, streamTime, status, info->userData );
if ( handle->drainCounter == 2 ) {
int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
stream_.bufferSize, streamTime, status, info->userData );
if ( cbReturnValue == 2 ) {
// MUTEX_UNLOCK( &stream_.mutex );
handle->drainCounter = 2;
abortStream();
return;
}
else if ( handle->drainCounter == 1 )
else if ( cbReturnValue == 1 )
handle->drainCounter = 1;
handle->internalDrain = true;
}
@@ -4908,7 +4921,7 @@ void RtApiDs :: callbackEvent()
}
}
else { // mode == INPUT
while ( safeReadPointer < endRead ) {
while ( safeReadPointer < endRead && stream_.callbackInfo.isRunning ) {
// See comments for playback.
double millis = (endRead - safeReadPointer) * 1000.0;
millis /= ( formatBytes(stream_.deviceFormat[1]) * stream_.nDeviceChannels[1] * stream_.sampleRate);
@@ -5268,6 +5281,7 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Thus, use the saved results.
if ( stream_.state != STREAM_CLOSED &&
( stream_.device[0] == device || stream_.device[1] == device ) ) {
snd_ctl_close( chandle );
if ( device >= devices_.size() ) {
errorText_ = "RtApiAlsa::getDeviceInfo: device ID was not present before stream was opened.";
error( RtError::WARNING );
@@ -5672,6 +5686,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
}
// If we get here, no supported format was found.
snd_pcm_close( phandle );
errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device " << device << " data format not supported by RtAudio.";
errorText_ = errorStream_.str();
return FAILURE;
@@ -5769,6 +5784,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
// If attempting to setup a duplex stream, the bufferSize parameter
// MUST be the same in both directions!
if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
snd_pcm_close( phandle );
errorStream_ << "RtApiAlsa::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << name << ").";
errorText_ = errorStream_.str();
return FAILURE;
@@ -5855,6 +5871,7 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
apiInfo = (AlsaHandle *) stream_.apiHandle;
}
apiInfo->handles[mode] = phandle;
phandle = 0;
// Allocate necessary internal buffers.
unsigned long bufferBytes;
@@ -5962,6 +5979,8 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
stream_.apiHandle = 0;
}
if ( phandle) snd_pcm_close( phandle );
for ( int i=0; i<2; i++ ) {
if ( stream_.userBuffer[i] ) {
free( stream_.userBuffer[i] );


Loading…
Cancel
Save