RtAudio: Update to upstream version 4.1.2

The only differences we have with the upstream tarball are marked with
`// -GODOT-` comments for clarity. The changes we currently have are
just some defines for cross-platform configuration, and could likely be
moved to the SCons buildsystem (ideally in a sub-environment to avoid
having RtAudio-specific defines pollute the whole build log).

One change for WinRT was not kept, if it is needed it should ideally be
integrated upstream:
```
 #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__)
-#ifdef WINRT_ENABLED
-  #define MUTEX_INITIALIZE(A) InitializeCriticalSectionEx(A, 0, 0)
-#else
   #define MUTEX_INITIALIZE(A) InitializeCriticalSection(A)
-#endif
```
This commit is contained in:
Rémi Verschelde 2016-07-23 13:25:25 +02:00
parent b13f430853
commit c1ab343f02
3 changed files with 63 additions and 129 deletions

View file

@ -1,4 +1,5 @@
#ifdef RTAUDIO_ENABLED
#ifdef RTAUDIO_ENABLED // -GODOT-
/************************************************************************/
/*! \class RtAudio
\brief Realtime audio i/o C++ classes.
@ -11,7 +12,7 @@
RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
RtAudio: realtime audio i/o C++ classes
Copyright (c) 2001-2014 Gary P. Scavone
Copyright (c) 2001-2016 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
@ -39,7 +40,7 @@
*/
/************************************************************************/
// RtAudio: Version 4.1.1
// RtAudio: Version 4.1.2
#include "RtAudio.h"
#include <iostream>
@ -56,11 +57,7 @@ const unsigned int RtApi::SAMPLE_RATES[] = {
};
#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__)
#ifdef WINRT_ENABLED
#define MUTEX_INITIALIZE(A) InitializeCriticalSectionEx(A, 0, 0)
#else
#define MUTEX_INITIALIZE(A) InitializeCriticalSection(A)
#endif
#define MUTEX_DESTROY(A) DeleteCriticalSection(A)
#define MUTEX_LOCK(A) EnterCriticalSection(A)
#define MUTEX_UNLOCK(A) LeaveCriticalSection(A)
@ -139,7 +136,8 @@ void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) throw()
void RtAudio :: openRtApi( RtAudio::Api api )
{
delete rtapi_;
if ( rtapi_ )
delete rtapi_;
rtapi_ = 0;
#if defined(__UNIX_JACK__)
@ -215,7 +213,8 @@ RtAudio :: RtAudio( RtAudio::Api api )
RtAudio :: ~RtAudio() throw()
{
delete rtapi_;
if ( rtapi_ )
delete rtapi_;
}
void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
@ -418,7 +417,7 @@ double RtApi :: getStreamTime( void )
then = stream_.lastTickTimestamp;
return stream_.streamTime +
((now.tv_sec + 0.000001 * now.tv_usec) -
(then.tv_sec + 0.000001 * then.tv_usec));
(then.tv_sec + 0.000001 * then.tv_usec));
#else
return stream_.streamTime;
#endif
@ -1832,7 +1831,7 @@ bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
channelsLeft -= streamChannels;
}
}
if ( stream_.doConvertBuffer[1] ) { // convert from our internal "device" buffer
convertBuffer( stream_.userBuffer[1],
stream_.deviceBuffer,
@ -2719,7 +2718,7 @@ RtApiAsio :: RtApiAsio()
// CoInitialize beforehand, but it must be for appartment threading
// (in which case, CoInitilialize will return S_FALSE here).
coInitialized_ = false;
HRESULT hr = CoInitialize( NULL );
HRESULT hr = CoInitialize( NULL );
if ( FAILED(hr) ) {
errorText_ = "RtApiAsio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)";
error( RtAudioError::WARNING );
@ -3170,7 +3169,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
errorText_ = errorStream_.str();
goto error;
}
buffersAllocated = true;
buffersAllocated = true;
stream_.state = STREAM_STOPPED;
// Set flags for buffer conversion.
@ -3644,13 +3643,13 @@ static long asioMessages( long selector, long value, void* /*message*/, double*
static const char* getAsioErrorString( ASIOError result )
{
struct Messages
struct Messages
{
ASIOError value;
const char*message;
};
static const Messages m[] =
static const Messages m[] =
{
{ ASE_NotPresent, "Hardware input or output is not present or available." },
{ ASE_HWMalfunction, "Hardware is malfunctioning." },
@ -5161,10 +5160,10 @@ void RtApiWasapi::wasapiThread()
// if the callback buffer was pushed renderBuffer reset callbackPulled flag
if ( callbackPushed ) {
callbackPulled = false;
// tick stream time
RtApi::tickStreamTime();
}
// tick stream time
RtApi::tickStreamTime();
}
Exit:
@ -5192,7 +5191,7 @@ Exit:
#if defined(__WINDOWS_DS__) // Windows DirectSound API
// Modified by Robin Davies, October 2005
// - Improvements to DirectX pointer chasing.
// - Improvements to DirectX pointer chasing.
// - Bug fix for non-power-of-two Asio granularity used by Edirol PCR-A30.
// - Auto-call CoInitialize for DSOUND and ASIO platforms.
// Various revisions for RtAudio 4.0 by Gary Scavone, April 2007
@ -5232,7 +5231,7 @@ struct DsHandle {
void *id[2];
void *buffer[2];
bool xrun[2];
UINT bufferPointer[2];
UINT bufferPointer[2];
DWORD dsBufferSize[2];
DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by.
HANDLE condition;
@ -6080,7 +6079,7 @@ void RtApiDs :: startStream()
// Increase scheduler frequency on lesser windows (a side-effect of
// increasing timer accuracy). On greater windows (Win2K or later),
// this is already in effect.
timeBeginPeriod( 1 );
timeBeginPeriod( 1 );
buffersRolling = false;
duplexPrerollBytes = 0;
@ -6401,7 +6400,7 @@ void RtApiDs :: callbackEvent()
}
if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
if ( handle->drainCounter > 1 ) { // write zeros to the output stream
@ -6441,6 +6440,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@ -6467,7 +6467,7 @@ void RtApiDs :: callbackEvent()
}
if ( dsPointerBetween( nextWritePointer, safeWritePointer, currentWritePointer, dsBufferSize )
|| dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) {
|| dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) {
// We've strayed into the forbidden zone ... resync the read pointer.
handle->xrun[0] = true;
nextWritePointer = safeWritePointer + handle->dsPointerLeadTime[0] - bufferBytes;
@ -6541,14 +6541,14 @@ void RtApiDs :: callbackEvent()
if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset
DWORD endRead = nextReadPointer + bufferBytes;
// Handling depends on whether we are INPUT or DUPLEX.
// Handling depends on whether we are INPUT or DUPLEX.
// If we're in INPUT mode then waiting is a good thing. If we're in DUPLEX mode,
// then a wait here will drag the write pointers into the forbidden zone.
//
// In DUPLEX mode, rather than wait, we will back off the read pointer until
// it's in a safe position. This causes dropouts, but it seems to be the only
// practical way to sync up the read and write pointers reliably, given the
// the very complex relationship between phase and increment of the read and write
//
// In DUPLEX mode, rather than wait, we will back off the read pointer until
// it's in a safe position. This causes dropouts, but it seems to be the only
// practical way to sync up the read and write pointers reliably, given the
// the very complex relationship between phase and increment of the read and write
// pointers.
//
// In order to minimize audible dropouts in DUPLEX mode, we will
@ -6599,7 +6599,7 @@ void RtApiDs :: callbackEvent()
error( RtAudioError::SYSTEM_ERROR );
return;
}
if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset
}
}
@ -7809,7 +7809,7 @@ void RtApiAlsa :: stopStream()
AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
if ( apiInfo->synchronized )
if ( apiInfo->synchronized )
result = snd_pcm_drop( handle[0] );
else
result = snd_pcm_drain( handle[0] );
@ -8073,7 +8073,7 @@ static void *alsaCallbackHandler( void *ptr )
bool *isRunning = &info->isRunning;
#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread)
if ( &info->doRealtime ) {
if ( info->doRealtime ) {
pthread_t tID = pthread_self(); // ID of this thread
sched_param prio = { info->priority }; // scheduling priority of thread
pthread_setschedparam( tID, SCHED_RR, &prio );
@ -8277,7 +8277,7 @@ void RtApiPulse::callbackEvent( void )
else
bytes = stream_.nUserChannels[INPUT] * stream_.bufferSize *
formatBytes( stream_.userFormat );
if ( pa_simple_read( pah->s_rec, pulse_in, bytes, &pa_error ) < 0 ) {
errorStream_ << "RtApiPulse::callbackEvent: audio read error, " <<
pa_strerror( pa_error ) << ".";
@ -8525,7 +8525,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
}
break;
case OUTPUT:
pah->s_play = pa_simple_new( NULL, "RtAudio", PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error );
pah->s_play = pa_simple_new( NULL, streamName.c_str(), PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error );
if ( !pah->s_play ) {
errorText_ = "RtApiPulse::probeDeviceOpen: error connecting output to PulseAudio server.";
goto error;
@ -8553,7 +8553,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
stream_.state = STREAM_STOPPED;
return true;
error:
if ( pah && stream_.callbackInfo.isRunning ) {
pthread_cond_destroy( &pah->runnable_cv );
@ -10145,8 +10145,8 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format )
{
register char val;
register char *ptr;
char val;
char *ptr;
ptr = buffer;
if ( format == RTAUDIO_SINT16 ) {
@ -10229,4 +10229,4 @@ void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat
//
// vim: et sts=2 sw=2
#endif
#endif // RTAUDIO_ENABLED -GODOT-

View file

@ -1,26 +1,20 @@
// -GODOT- Start
#ifdef RTAUDIO_ENABLED
#if defined(OSX_ENABLED)
#define __MACOSX_CORE__
#define __MACOSX_CORE__
#elif defined(UNIX_ENABLED)
#define __LINUX_ALSA__
#define __LINUX_ALSA__
#elif defined(WINDOWS_ENABLED)
#if defined(WINRT_ENABLED)
#define __RTAUDIO_DUMMY__
#else
#define __WINDOWS_DS__
#if defined(WINRT_ENABLED)
#define __RTAUDIO_DUMMY__
#else
#define __WINDOWS_DS__
#endif
#endif
#endif
// -GODOT- End
/************************************************************************/
/*! \class RtAudio
@ -34,7 +28,7 @@
RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
RtAudio: realtime audio i/o C++ classes
Copyright (c) 2001-2014 Gary P. Scavone
Copyright (c) 2001-2016 Gary P. Scavone
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
@ -69,7 +63,7 @@
#ifndef __RTAUDIO_H
#define __RTAUDIO_H
#define RTAUDIO_VERSION "4.1.1"
#define RTAUDIO_VERSION "4.1.2"
#include <string>
#include <vector>
@ -135,7 +129,7 @@ static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/mi
open the input and/or output stream device(s) for exclusive use.
Note that this is not possible with all supported audio APIs.
If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
to select realtime scheduling (round-robin) for the callback thread.
If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
@ -239,7 +233,7 @@ class RtAudioError : public std::exception
//! The constructor.
RtAudioError( const std::string& message, Type type = RtAudioError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
//! The destructor.
virtual ~RtAudioError( void ) throw() {}
@ -365,7 +359,7 @@ class RtAudio
open the input and/or output stream device(s) for exclusive use.
Note that this is not possible with all supported audio APIs.
If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
to select realtime scheduling (round-robin) for the callback thread.
The \c priority parameter will only be used if the RTAUDIO_SCHEDULE_REALTIME
flag is set. It defines the thread's realtime priority.
@ -434,7 +428,7 @@ class RtAudio
/*!
This function performs a system query of available devices each time it
is called, thus supporting devices connected \e after instantiation. If
a system error occurs during processing, a warning will be issued.
a system error occurs during processing, a warning will be issued.
*/
unsigned int getDeviceCount( void ) throw();
@ -501,7 +495,7 @@ class RtAudio
from within the callback function.
\param options An optional pointer to a structure containing various
global stream options, including a list of OR'ed RtAudioStreamFlags
and a suggested number of stream buffers that can be used to
and a suggested number of stream buffers that can be used to
control stream latency. More buffers typically result in more
robust performance, though at a cost of greater latency. If a
value of zero is specified, a system-specific median value is
@ -806,7 +800,7 @@ protected:
"warning" message is reported and FAILURE is returned. A
successful probe is indicated by a return value of SUCCESS.
*/
virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options );
@ -898,7 +892,7 @@ public:
private:
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options );
@ -932,7 +926,7 @@ public:
private:
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options );
@ -968,7 +962,7 @@ public:
std::vector<RtAudio::DeviceInfo> devices_;
void saveDeviceInfo( void );
bool coInitialized_;
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options );
@ -1007,7 +1001,7 @@ public:
bool buffersRolling;
long duplexPrerollBytes;
std::vector<struct DsDevice> dsDevices;
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options );
@ -1078,7 +1072,7 @@ public:
std::vector<RtAudio::DeviceInfo> devices_;
void saveDeviceInfo( void );
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options );
@ -1142,7 +1136,7 @@ public:
private:
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options );
@ -1167,7 +1161,7 @@ public:
private:
bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/,
bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/,
unsigned int /*firstChannel*/, unsigned int /*sampleRate*/,
RtAudioFormat /*format*/, unsigned int * /*bufferSize*/,
RtAudio::StreamOptions * /*options*/ ) { return false; }
@ -1186,4 +1180,4 @@ public:
//
// vim: et sts=2 sw=2
#endif
#endif // RTAUDIO_ENABLED -GODOT-

View file

@ -1,60 +0,0 @@
/************************************************************************/
/*! \class RtError
\brief Exception handling class for RtAudio & RtMidi.
The RtError class is quite simple but it does allow errors to be
"caught" by RtError::Type. See the RtAudio and RtMidi
documentation to know which methods can throw an RtError.
*/
/************************************************************************/
#ifndef RTERROR_H
#define RTERROR_H
#include <exception>
#include <iostream>
#include <string>
class RtError : public std::exception
{
public:
//! Defined RtError types.
enum Type {
WARNING, /*!< A non-critical error. */
DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */
UNSPECIFIED, /*!< The default, unspecified error type. */
NO_DEVICES_FOUND, /*!< No devices found on system. */
INVALID_DEVICE, /*!< An invalid device ID was specified. */
MEMORY_ERROR, /*!< An error occured during memory allocation. */
INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
INVALID_USE, /*!< The function was called incorrectly. */
DRIVER_ERROR, /*!< A system driver error occured. */
SYSTEM_ERROR, /*!< A system error occured. */
THREAD_ERROR /*!< A thread error occured. */
};
//! The constructor.
RtError( const std::string& message, Type type = RtError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
//! The destructor.
virtual ~RtError( void ) throw() {}
//! Prints thrown error message to stderr.
virtual void printMessage( void ) throw() { std::cerr << '\n' << message_ << "\n\n"; }
//! Returns the thrown error message type.
virtual const Type& getType(void) throw() { return type_; }
//! Returns the thrown error message string.
virtual const std::string& getMessage(void) throw() { return message_; }
//! Returns the thrown error message as a c-style string.
virtual const char* what( void ) const throw() { return message_.c_str(); }
protected:
std::string message_;
Type type_;
};
#endif