From c1ab343f02ee04b807087f28b33b4ac279d0fda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Sat, 23 Jul 2016 13:25:25 +0200 Subject: [PATCH] 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 ``` --- drivers/rtaudio/RtAudio.cpp | 74 ++++++++++++++++++------------------- drivers/rtaudio/RtAudio.h | 58 +++++++++++++---------------- drivers/rtaudio/RtError.h | 60 ------------------------------ 3 files changed, 63 insertions(+), 129 deletions(-) delete mode 100644 drivers/rtaudio/RtError.h diff --git a/drivers/rtaudio/RtAudio.cpp b/drivers/rtaudio/RtAudio.cpp index 86981e56d25..04159776f71 100644 --- a/drivers/rtaudio/RtAudio.cpp +++ b/drivers/rtaudio/RtAudio.cpp @@ -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 @@ -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 &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- diff --git a/drivers/rtaudio/RtAudio.h b/drivers/rtaudio/RtAudio.h index 7d45d365297..4392e95f327 100644 --- a/drivers/rtaudio/RtAudio.h +++ b/drivers/rtaudio/RtAudio.h @@ -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 #include @@ -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 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 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 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- diff --git a/drivers/rtaudio/RtError.h b/drivers/rtaudio/RtError.h deleted file mode 100644 index ac5c41498ab..00000000000 --- a/drivers/rtaudio/RtError.h +++ /dev/null @@ -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 -#include -#include - -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