Browse Source

Various updates and fixes before 4.0.5 release (GS).

tags/4.0.5
Gary Scavone Stephen Sinclair 16 years ago
parent
commit
ad768de27c
12 changed files with 72 additions and 11 deletions
  1. +54
    -8
      RtAudio.cpp
  2. +1
    -1
      doc/doxygen/compiling.txt
  3. +2
    -0
      doc/doxygen/duplex.txt
  4. +1
    -0
      doc/doxygen/playback.txt
  5. +2
    -0
      doc/doxygen/recording.txt
  6. +1
    -1
      doc/doxygen/tutorial.txt
  7. +2
    -1
      doc/release.txt
  8. +2
    -0
      tests/duplex.cpp
  9. +2
    -0
      tests/playraw.cpp
  10. +1
    -0
      tests/playsaw.cpp
  11. +2
    -0
      tests/record.cpp
  12. +2
    -0
      tests/testall.cpp

+ 54
- 8
RtAudio.cpp View File

@@ -42,6 +42,9 @@

#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <limits.h>

// Static variable definitions.
const unsigned int RtApi::MAX_SAMPLE_RATES = 14;
@@ -1731,9 +1734,15 @@ struct JackHandle {
:client(0), drainCounter(0), internalDrain(false) { ports[0] = 0; ports[1] = 0; xrun[0] = false; xrun[1] = false; }
};

void jackSilentError( const char * ) {};

RtApiJack :: RtApiJack()
{
// Nothing to do here.
#if !defined(__RTAUDIO_DEBUG__)
// Turn off Jack's internal error reporting.
jack_set_error_function( &jackSilentError );
#endif
}

RtApiJack :: ~RtApiJack()
@@ -2306,6 +2315,21 @@ void RtApiJack :: 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 necessary to handle it this way because the
// callbackEvent() function must return before the jack_deactivate()
// function will return.
extern "C" void *jackStopStream( void *ptr )
{
CallbackInfo *info = (CallbackInfo *) ptr;
RtApiJack *object = (RtApiJack *) info->object;

object->stopStream();

pthread_exit( NULL );
}

bool RtApiJack :: callbackEvent( unsigned long nframes )
{
if ( stream_.state == STREAM_STOPPED ) return SUCCESS;
@@ -2325,10 +2349,12 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )

// Check if we were draining the stream and signal is finished.
if ( handle->drainCounter > 3 ) {
if ( handle->internalDrain == false )
pthread_cond_signal( &handle->condition );
if ( handle->internalDrain == true ) {
ThreadHandle id;
pthread_create( &id, NULL, jackStopStream, info );
}
else
stopStream();
pthread_cond_signal( &handle->condition );
return SUCCESS;
}

@@ -2357,7 +2383,8 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
stream_.bufferSize, streamTime, status, info->userData );
if ( handle->drainCounter == 2 ) {
MUTEX_UNLOCK( &stream_.mutex );
abortStream();
ThreadHandle id;
pthread_create( &id, NULL, jackStopStream, info );
return SUCCESS;
}
else if ( handle->drainCounter == 1 )
@@ -3857,7 +3884,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
bufferBytes *= 2;

// Set cooperative level to DSSCL_EXCLUSIVE ... sound stops when window focus changes.
//result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE );
// result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE );
// Set cooperative level to DSSCL_PRIORITY ... sound remains when window focus changes.
result = output->SetCooperativeLevel( hWnd, DSSCL_PRIORITY );
if ( FAILED( result ) ) {
@@ -4023,6 +4050,11 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
// Update wave format structure and buffer information.
waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels;

// If the user wants an even bigger buffer, increase the device buffer size accordingly.
while ( dsPointerLeadTime * 2U > (DWORD) bufferBytes )
bufferBytes *= 2;

// Setup the secondary DS buffer description.
dsBufferSize = bufferBytes;
@@ -4044,6 +4076,20 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
return FAILURE;
}

// Get the buffer size ... might be different from what we specified.
DSCBCAPS dscbcaps;
dscbcaps.dwSize = sizeof( DSCBCAPS );
result = buffer->GetCaps( &dscbcaps );
if ( FAILED( result ) ) {
input->Release();
buffer->Release();
errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsinfo.name << ")!";
errorText_ = errorStream_.str();
return FAILURE;
}

bufferBytes = dscbcaps.dwBufferBytes;

// Lock the capture buffer
LPVOID audioPtr;
DWORD dataLen;
@@ -4483,7 +4529,7 @@ void RtApiDs :: callbackEvent()
// The state might change while waiting on a mutex.
if ( stream_.state == STREAM_STOPPED ) {
MUTEX_UNLOCK( &stream_.mutex );
return SUCCESS;
return;
}

// Invoke user callback to get fresh output data UNLESS we are
@@ -4530,7 +4576,7 @@ void RtApiDs :: callbackEvent()
long bufferBytes;

if ( stream_.mode == DUPLEX && !buffersRolling ) {
assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
//assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );

// It takes a while for the devices to get rolling. As a result,
// there's no guarantee that the capture and write device pointers
@@ -4581,7 +4627,7 @@ void RtApiDs :: callbackEvent()
Sleep( 1 );
}

assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
//assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );

buffersRolling = true;
handle->bufferPointer[0] = ( safeWritePos + handle->dsPointerLeadTime[0] );


+ 1
- 1
doc/doxygen/compiling.txt View File

@@ -2,7 +2,7 @@

\section debug Debugging

If you are having problems getting RtAudio to run on your system, make sure to pass a value of \e true to the RtAudio::showWarnings() function (this is the default setting). A variety of warning messages will be displayed which may help in determining the problem. Also, try using the programs included in the <tt>tests</tt> directory. The program <tt>audioprobe</tt> displays the queried capabilities of all hardware devices found for all APIs compiled. When using the ALSA API, further information can be displayed by defining the preprocessor definition __RTAUDIO_DEBUG__.
If you are having problems getting RtAudio to run on your system, make sure to pass a value of \e true to the RtAudio::showWarnings() function (this is the default setting). A variety of warning messages will be displayed which may help in determining the problem. Also, try using the programs included in the <tt>tests</tt> directory. The program <tt>audioprobe</tt> displays the queried capabilities of all hardware devices found for all APIs compiled. When using the ALSA and JACK APIs, further information can be displayed by defining the preprocessor definition __RTAUDIO_DEBUG__.

\section compile Compiling



+ 2
- 0
doc/doxygen/duplex.txt View File

@@ -5,6 +5,8 @@ Finally, it is easy to use RtAudio for simultaneous audio input/output, or duple
\code
#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>

// Pass-through function.
int inout( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,


+ 1
- 0
doc/doxygen/playback.txt View File

@@ -5,6 +5,7 @@ In this example, we provide a complete program that demonstrates the use of RtAu
\code
#include "RtAudio.h"
#include <iostream>
#include <cstdlib>

// Two-channel sawtooth wave generator.
int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,


+ 2
- 0
doc/doxygen/recording.txt View File

@@ -6,6 +6,8 @@ Using RtAudio for audio input is almost identical to the way it is used for play
\code
#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>

int record( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
double streamTime, RtAudioStreamStatus status, void *userData )


+ 1
- 1
doc/doxygen/tutorial.txt View File

@@ -32,7 +32,7 @@ Devices are now re-enumerated every time the RtAudio::getDeviceCount(), RtAudio:

\section download Download

Latest Release (?? January 2009): <A href="http://www.music.mcgill.ca/~gary/rtaudio/release/rtaudio-4.0.5.tar.gz">Version 4.0.5</A>
Latest Release (29 January 2009): <A href="http://www.music.mcgill.ca/~gary/rtaudio/release/rtaudio-4.0.5.tar.gz">Version 4.0.5</A>

\section documentation Documentation Links



+ 2
- 1
doc/release.txt View File

@@ -2,11 +2,12 @@ RtAudio - a set of C++ classes that provide a common API for realtime audio inpu

By Gary P. Scavone, 2001-2009.

v4.0.5: (?? January 2009)
v4.0.5: (29 January 2009)
- added support in CoreAudio for arbitrary stream channel configurations
- added getStreamSampleRate() function because the actual sample rate can sometimes vary slightly from the specified one (thanks to Theo Veenker)
- added new StreamOptions flag "RTAUDIO_SCHEDULE_REALTIME" and attribute "priority" to StreamOptions (thanks to Theo Veenker)
- replaced usleep(50000) in callbackEvent() by a wait on condition variable which gets signaled in startStream() (thanks to Theo Veenker)
- fix for Jack API when user callback function signals stop or abort calls
- fix to way stream state is changed to avoid infinite loop problem
- fix to int<->float conversion in convertBuffer() (thanks to Theo Veenker)
- bug fix in byteSwapBuffer() (thanks to Stefan Muller Arisona and Theo Veenker)


+ 2
- 0
tests/duplex.cpp View File

@@ -10,6 +10,8 @@

#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>

/*
typedef signed long MY_TYPE;


+ 2
- 0
tests/playraw.cpp View File

@@ -11,6 +11,8 @@

#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>

/*
typedef char MY_TYPE;


+ 1
- 0
tests/playsaw.cpp View File

@@ -10,6 +10,7 @@

#include "RtAudio.h"
#include <iostream>
#include <cstdlib>

/*
typedef signed long MY_TYPE;


+ 2
- 0
tests/record.cpp View File

@@ -11,6 +11,8 @@

#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>

/*
typedef char MY_TYPE;


+ 2
- 0
tests/testall.cpp View File

@@ -10,6 +10,8 @@

#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>

#define BASE_RATE 0.005
#define TIME 1.0


Loading…
Cancel
Save