summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Scavone <gary@music.mcgill.ca>2012-05-31 20:21:04 +0000
committerStephen Sinclair <sinclair@music.mcgill.ca>2013-10-11 01:38:30 +0200
commit758cf4789a38b161024f5371fd041b5489cf9921 (patch)
tree789fb49f6d721d177180eece9b59f794c6209831
parentf680bc760bce103406a81053c4d56cd501e95002 (diff)
Updates to RtAudio.cpp,h to fix deadlock in stopping stream (Core API). Other file updates for upcoming release of version 4.0.11.
-rw-r--r--Makefile.in2
-rw-r--r--RtAudio.cpp65
-rw-r--r--RtAudio.h5
-rw-r--r--doc/doxygen/tutorial.txt2
-rw-r--r--doc/release.txt7
-rw-r--r--install2
-rw-r--r--readme4
7 files changed, 61 insertions, 26 deletions
diff --git a/Makefile.in b/Makefile.in
index b627531..c2cdcb1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -8,7 +8,7 @@ OBJECTS = RtAudio.o @objects@
STATIC = librtaudio.a
SHARED = @sharedlib@
-RELEASE = 4.0.10
+RELEASE = 4.0.11
MAJOR = 4
LIBRARIES = $(STATIC) $(SHARED)
diff --git a/RtAudio.cpp b/RtAudio.cpp
index 656be06..47e5804 100644
--- a/RtAudio.cpp
+++ b/RtAudio.cpp
@@ -10,7 +10,7 @@
RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
RtAudio: realtime audio i/o C++ classes
- Copyright (c) 2001-2011 Gary P. Scavone
+ Copyright (c) 2001-2012 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
@@ -38,7 +38,7 @@
*/
/************************************************************************/
-// RtAudio: Version 4.0.10
+// RtAudio: Version 4.0.11
#include "RtAudio.h"
#include <iostream>
@@ -416,6 +416,8 @@ struct CoreHandle {
:deviceBuffer(0), drainCounter(0), internalDrain(false) { nStreams[0] = 1; nStreams[1] = 1; id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; }
};
+ThreadHandle threadId;
+
RtApiCore:: RtApiCore()
{
#if defined( AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER )
@@ -1355,7 +1357,7 @@ void RtApiCore :: startStream( void )
return;
}
- MUTEX_LOCK( &stream_.mutex );
+ //MUTEX_LOCK( &stream_.mutex );
OSStatus result = noErr;
CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
@@ -1385,7 +1387,7 @@ void RtApiCore :: startStream( void )
stream_.state = STREAM_RUNNING;
unlock:
- MUTEX_UNLOCK( &stream_.mutex );
+ //MUTEX_UNLOCK( &stream_.mutex );
if ( result == noErr ) return;
error( RtError::SYSTEM_ERROR );
@@ -1400,12 +1402,14 @@ void RtApiCore :: stopStream( void )
return;
}
+ /*
MUTEX_LOCK( &stream_.mutex );
if ( stream_.state == STREAM_STOPPED ) {
MUTEX_UNLOCK( &stream_.mutex );
return;
}
+ */
OSStatus result = noErr;
CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
@@ -1416,9 +1420,9 @@ void RtApiCore :: stopStream( void )
pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled
}
- MUTEX_UNLOCK( &stream_.mutex );
+ //MUTEX_UNLOCK( &stream_.mutex );
result = AudioDeviceStop( handle->id[0], callbackHandler );
- MUTEX_LOCK( &stream_.mutex );
+ //MUTEX_LOCK( &stream_.mutex );
if ( result != noErr ) {
errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping callback procedure on device (" << stream_.device[0] << ").";
errorText_ = errorStream_.str();
@@ -1428,9 +1432,9 @@ void RtApiCore :: stopStream( void )
if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
- MUTEX_UNLOCK( &stream_.mutex );
+ //MUTEX_UNLOCK( &stream_.mutex );
result = AudioDeviceStop( handle->id[1], callbackHandler );
- MUTEX_LOCK( &stream_.mutex );
+ //MUTEX_LOCK( &stream_.mutex );
if ( result != noErr ) {
errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping input callback procedure on device (" << stream_.device[1] << ").";
errorText_ = errorStream_.str();
@@ -1441,7 +1445,7 @@ void RtApiCore :: stopStream( void )
stream_.state = STREAM_STOPPED;
unlock:
- MUTEX_UNLOCK( &stream_.mutex );
+ //MUTEX_UNLOCK( &stream_.mutex );
if ( result == noErr ) return;
error( RtError::SYSTEM_ERROR );
@@ -1462,11 +1466,26 @@ void RtApiCore :: abortStream( void )
stopStream();
}
+// This function will be called by a spawned thread when the user
+// callback function signals that the stream should be stopped or
+// aborted. It is better to handle it this way because the
+// callbackEvent() function probably should return before the AudioDeviceStop()
+// function is called.
+extern "C" void *coreStopStream( void *ptr )
+{
+ CallbackInfo *info = (CallbackInfo *) ptr;
+ RtApiCore *object = (RtApiCore *) info->object;
+
+ object->stopStream();
+
+ pthread_exit( NULL );
+}
+
bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
const AudioBufferList *inBufferList,
const AudioBufferList *outBufferList )
{
- if ( stream_.state == STREAM_STOPPED ) return SUCCESS;
+ if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
if ( stream_.state == STREAM_CLOSED ) {
errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
error( RtError::WARNING );
@@ -1478,13 +1497,18 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
// Check if we were draining the stream and signal is finished.
if ( handle->drainCounter > 3 ) {
- if ( handle->internalDrain == true )
- stopStream();
+
+ if ( handle->internalDrain == true ) {
+ stream_.state = STREAM_STOPPING;
+ pthread_create( &threadId, NULL, coreStopStream, info );
+ //stopStream();
+ }
else // external call to stopStream()
pthread_cond_signal( &handle->condition );
return SUCCESS;
}
+ /*
MUTEX_LOCK( &stream_.mutex );
// The state might change while waiting on a mutex.
@@ -1492,6 +1516,7 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
MUTEX_UNLOCK( &stream_.mutex );
return SUCCESS;
}
+ */
AudioDeviceID outputDevice = handle->id[0];
@@ -1514,14 +1539,15 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
stream_.bufferSize, streamTime, status, info->userData );
if ( cbReturnValue == 2 ) {
- MUTEX_UNLOCK( &stream_.mutex );
+ //MUTEX_UNLOCK( &stream_.mutex );
handle->drainCounter = 2;
abortStream();
return SUCCESS;
}
- else if ( cbReturnValue == 1 )
+ else if ( cbReturnValue == 1 ) {
handle->drainCounter = 1;
handle->internalDrain = true;
+ }
}
if ( stream_.mode == OUTPUT || ( stream_.mode == DUPLEX && deviceId == outputDevice ) ) {
@@ -1719,7 +1745,7 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
}
unlock:
- MUTEX_UNLOCK( &stream_.mutex );
+ //MUTEX_UNLOCK( &stream_.mutex );
RtApi::tickStreamTime();
return SUCCESS;
@@ -2487,9 +2513,10 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
pthread_create( &id, NULL, jackStopStream, info );
return SUCCESS;
}
- else if ( cbReturnValue == 1 )
+ else if ( cbReturnValue == 1 ) {
handle->drainCounter = 1;
handle->internalDrain = true;
+ }
}
jack_default_audio_sample_t *jackbuffer;
@@ -3321,9 +3348,10 @@ bool RtApiAsio :: callbackEvent( long bufferIndex )
&stream_.callbackInfo, 0, &threadId );
return SUCCESS;
}
- else if ( cbReturnValue == 1 )
+ else if ( cbReturnValue == 1 ) {
handle->drainCounter = 1;
handle->internalDrain = true;
+ }
}
unsigned int nChannels, bufferBytes, i, j;
@@ -4653,9 +4681,10 @@ void RtApiDs :: callbackEvent()
abortStream();
return;
}
- else if ( cbReturnValue == 1 )
+ else if ( cbReturnValue == 1 ) {
handle->drainCounter = 1;
handle->internalDrain = true;
+ }
}
HRESULT result;
diff --git a/RtAudio.h b/RtAudio.h
index 368fda3..d59e6bc 100644
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -10,7 +10,7 @@
RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
RtAudio: realtime audio i/o C++ classes
- Copyright (c) 2001-2011 Gary P. Scavone
+ Copyright (c) 2001-2012 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
@@ -42,7 +42,7 @@
\file RtAudio.h
*/
-// RtAudio: Version 4.0.10
+// RtAudio: Version 4.0.11
#ifndef __RTAUDIO_H
#define __RTAUDIO_H
@@ -599,6 +599,7 @@ protected:
enum StreamState {
STREAM_STOPPED,
+ STREAM_STOPPING,
STREAM_RUNNING,
STREAM_CLOSED = -50
};
diff --git a/doc/doxygen/tutorial.txt b/doc/doxygen/tutorial.txt
index 39cb76a..e33ceec 100644
--- a/doc/doxygen/tutorial.txt
+++ b/doc/doxygen/tutorial.txt
@@ -32,7 +32,7 @@ Devices are now re-enumerated every time the RtAudio::getDeviceCount(), RtAudio:
\section download Download
-Latest Release (30 August 2011): <A href="http://www.music.mcgill.ca/~gary/rtaudio/release/rtaudio-4.0.10.tar.gz">Version 4.0.10</A>
+Latest Release (?? June 2012): <A href="http://www.music.mcgill.ca/~gary/rtaudio/release/rtaudio-4.0.11.tar.gz">Version 4.0.11</A>
\section documentation Documentation Links
diff --git a/doc/release.txt b/doc/release.txt
index a3dab35..e36c3e7 100644
--- a/doc/release.txt
+++ b/doc/release.txt
@@ -1,6 +1,11 @@
RtAudio - a set of C++ classes that provide a common API for realtime audio input/output across Linux (native ALSA, JACK, and OSS), Macintosh OS X (CoreAudio and JACK), and Windows (DirectSound and ASIO) operating systems.
-By Gary P. Scavone, 2001-2011.
+By Gary P. Scavone, 2001-2012.
+
+v4.0.11: (?? June 2012)
+- fixes for memory leaks in ALSA (thanks to Martin Koegler)
+- bitwise format flag fixes in OS-X (Benjamin Schroeder and Stefan Arisona)
+- changes to stopStream / drain flag to avoid hung state in ASIO, DS, OS-X, and Jack APIs (Rasmus Ekman and Carlos Luna)
v4.0.10: (30 August 2011)
- fix for compile bug in Windows DS (counting devices)
diff --git a/install b/install
index 365a527..0e01d12 100644
--- a/install
+++ b/install
@@ -1,6 +1,6 @@
RtAudio - a set of C++ classes which provide a common API for realtime audio input/output across Linux (native ALSA, JACK, and OSS), Macintosh OS X (CoreAudio and JACK), and Windows (DirectSound and ASIO) operating systems.
-By Gary P. Scavone, 2001-2011.
+By Gary P. Scavone, 2001-2012.
To configure and compile (on Unix systems and MinGW):
diff --git a/readme b/readme
index 58052f4..ae73eb2 100644
--- a/readme
+++ b/readme
@@ -1,6 +1,6 @@
RtAudio - a set of C++ classes that provide a common API for realtime audio input/output across Linux (native ALSA, JACK, and OSS), Macintosh OS X (CoreAudio and JACK), and Windows (DirectSound and ASIO) operating systems.
-By Gary P. Scavone, 2001-2011.
+By Gary P. Scavone, 2001-2012.
This distribution of RtAudio contains the following:
@@ -34,7 +34,7 @@ LEGAL AND ETHICAL:
The RtAudio license is similar to the MIT License.
RtAudio: a set of realtime audio i/o C++ classes
- Copyright (c) 2001-2011 Gary P. Scavone
+ Copyright (c) 2001-2012 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files