X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=RtAudio.cpp;h=0b952f02ec8812c169d3eb17d1ca5c94ae151070;hb=4ee8b95d791a54aca593ad24d4eabbaac90355c0;hp=1dc2f2302399c3d124ea043848c402fcd78de2bb;hpb=2495e750040b59b8f14d1f1ac3fd800a977e22ec;p=rtaudio-cdist.git diff --git a/RtAudio.cpp b/RtAudio.cpp old mode 100755 new mode 100644 index 1dc2f23..0b952f0 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -1,4 +1,4 @@ -/************************************************************************/ +/************************************************************************/ /*! \class RtAudio \brief Realtime audio i/o C++ classes. @@ -10,7 +10,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 @@ -38,13 +38,14 @@ */ /************************************************************************/ -// RtAudio: Version 4.1.1 +// RtAudio: Version 4.1.2 #include "RtAudio.h" #include #include #include #include +#include #include // Static variable definitions. @@ -92,12 +93,12 @@ const unsigned int RtApi::SAMPLE_RATES[] = { // // *************************************************** // -std::string RtAudio :: getVersion( void ) throw() +std::string RtAudio :: getVersion( void ) { return RTAUDIO_VERSION; } -void RtAudio :: getCompiledApi( std::vector &apis ) throw() +void RtAudio :: getCompiledApi( std::vector &apis ) { apis.clear(); @@ -209,7 +210,7 @@ RtAudio :: RtAudio( RtAudio::Api api ) throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) ); } -RtAudio :: ~RtAudio() throw() +RtAudio :: ~RtAudio() { if ( rtapi_ ) delete rtapi_; @@ -427,6 +428,9 @@ void RtApi :: setStreamTime( double time ) if ( time >= 0.0 ) stream_.streamTime = time; +#if defined( HAVE_GETTIMEOFDAY ) + gettimeofday( &stream_.lastTickTimestamp, NULL ); +#endif } unsigned int RtApi :: getStreamSampleRate( void ) @@ -1943,7 +1947,7 @@ struct JackHandle { static void jackSilentError( const char * ) {}; RtApiJack :: RtApiJack() -{ + :shouldAutoconnect_(true) { // Nothing to do here. #if !defined(__RTAUDIO_DEBUG__) // Turn off Jack's internal error reporting. @@ -2354,6 +2358,8 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne // here. if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 ); + if ( options && options->flags & RTAUDIO_JACK_DONT_CONNECT ) shouldAutoconnect_ = false; + return SUCCESS; error: @@ -2443,7 +2449,7 @@ void RtApiJack :: startStream( void ) const char **ports; // Get the list of available ports. - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + if ( shouldAutoconnect_ && (stream_.mode == OUTPUT || stream_.mode == DUPLEX) ) { result = 1; ports = jack_get_ports( handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput); if ( ports == NULL) { @@ -2467,7 +2473,7 @@ void RtApiJack :: startStream( void ) free(ports); } - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { + if ( shouldAutoconnect_ && (stream_.mode == INPUT || stream_.mode == DUPLEX) ) { result = 1; ports = jack_get_ports( handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput ); if ( ports == NULL) { @@ -3859,8 +3865,7 @@ private: // In order to satisfy WASAPI's buffer requirements, we need a means of converting sample rate // between HW and the user. The convertBufferWasapi function is used to perform this conversion // between HwIn->UserIn and UserOut->HwOut during the stream callback loop. -// This sample rate converter favors speed over quality, and works best with conversions between -// one rate and its multiple. +// This sample rate converter works best with conversions between one rate and its multiple. void convertBufferWasapi( char* outBuffer, const char* inBuffer, const unsigned int& channelCount, @@ -3872,40 +3877,129 @@ void convertBufferWasapi( char* outBuffer, { // calculate the new outSampleCount and relative sampleStep float sampleRatio = ( float ) outSampleRate / inSampleRate; + float sampleRatioInv = ( float ) 1 / sampleRatio; float sampleStep = 1.0f / sampleRatio; float inSampleFraction = 0.0f; - outSampleCount = ( unsigned int ) roundf( inSampleCount * sampleRatio ); + outSampleCount = ( unsigned int ) std::roundf( inSampleCount * sampleRatio ); - // frame-by-frame, copy each relative input sample into it's corresponding output sample - for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ ) + // if inSampleRate is a multiple of outSampleRate (or vice versa) there's no need to interpolate + if ( floor( sampleRatio ) == sampleRatio || floor( sampleRatioInv ) == sampleRatioInv ) { - unsigned int inSample = ( unsigned int ) inSampleFraction; - - switch ( format ) + // frame-by-frame, copy each relative input sample into it's corresponding output sample + for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ ) { - case RTAUDIO_SINT8: - memcpy( &( ( char* ) outBuffer )[ outSample * channelCount ], &( ( char* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( char ) ); - break; - case RTAUDIO_SINT16: - memcpy( &( ( short* ) outBuffer )[ outSample * channelCount ], &( ( short* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( short ) ); - break; - case RTAUDIO_SINT24: - memcpy( &( ( S24* ) outBuffer )[ outSample * channelCount ], &( ( S24* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( S24 ) ); - break; - case RTAUDIO_SINT32: - memcpy( &( ( int* ) outBuffer )[ outSample * channelCount ], &( ( int* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( int ) ); - break; - case RTAUDIO_FLOAT32: - memcpy( &( ( float* ) outBuffer )[ outSample * channelCount ], &( ( float* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( float ) ); - break; - case RTAUDIO_FLOAT64: - memcpy( &( ( double* ) outBuffer )[ outSample * channelCount ], &( ( double* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( double ) ); - break; + unsigned int inSample = ( unsigned int ) inSampleFraction; + + switch ( format ) + { + case RTAUDIO_SINT8: + memcpy( &( ( char* ) outBuffer )[ outSample * channelCount ], &( ( char* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( char ) ); + break; + case RTAUDIO_SINT16: + memcpy( &( ( short* ) outBuffer )[ outSample * channelCount ], &( ( short* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( short ) ); + break; + case RTAUDIO_SINT24: + memcpy( &( ( S24* ) outBuffer )[ outSample * channelCount ], &( ( S24* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( S24 ) ); + break; + case RTAUDIO_SINT32: + memcpy( &( ( int* ) outBuffer )[ outSample * channelCount ], &( ( int* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( int ) ); + break; + case RTAUDIO_FLOAT32: + memcpy( &( ( float* ) outBuffer )[ outSample * channelCount ], &( ( float* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( float ) ); + break; + case RTAUDIO_FLOAT64: + memcpy( &( ( double* ) outBuffer )[ outSample * channelCount ], &( ( double* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( double ) ); + break; + } + + // jump to next in sample + inSampleFraction += sampleStep; } + } + else // else interpolate + { + // frame-by-frame, copy each relative input sample into it's corresponding output sample + for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ ) + { + unsigned int inSample = ( unsigned int ) inSampleFraction; + float inSampleDec = inSampleFraction - inSample; + unsigned int frameInSample = inSample * channelCount; + unsigned int frameOutSample = outSample * channelCount; - // jump to next in sample - inSampleFraction += sampleStep; + switch ( format ) + { + case RTAUDIO_SINT8: + { + for ( unsigned int channel = 0; channel < channelCount; channel++ ) + { + char fromSample = ( ( char* ) inBuffer )[ frameInSample + channel ]; + char toSample = ( ( char* ) inBuffer )[ frameInSample + channelCount + channel ]; + char sampleDiff = ( char ) ( ( toSample - fromSample ) * inSampleDec ); + ( ( char* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff; + } + break; + } + case RTAUDIO_SINT16: + { + for ( unsigned int channel = 0; channel < channelCount; channel++ ) + { + short fromSample = ( ( short* ) inBuffer )[ frameInSample + channel ]; + short toSample = ( ( short* ) inBuffer )[ frameInSample + channelCount + channel ]; + short sampleDiff = ( short ) ( ( toSample - fromSample ) * inSampleDec ); + ( ( short* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff; + } + break; + } + case RTAUDIO_SINT24: + { + for ( unsigned int channel = 0; channel < channelCount; channel++ ) + { + int fromSample = ( ( S24* ) inBuffer )[ frameInSample + channel ].asInt(); + int toSample = ( ( S24* ) inBuffer )[ frameInSample + channelCount + channel ].asInt(); + int sampleDiff = ( int ) ( ( toSample - fromSample ) * inSampleDec ); + ( ( S24* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff; + } + break; + } + case RTAUDIO_SINT32: + { + for ( unsigned int channel = 0; channel < channelCount; channel++ ) + { + int fromSample = ( ( int* ) inBuffer )[ frameInSample + channel ]; + int toSample = ( ( int* ) inBuffer )[ frameInSample + channelCount + channel ]; + int sampleDiff = ( int ) ( ( toSample - fromSample ) * inSampleDec ); + ( ( int* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff; + } + break; + } + case RTAUDIO_FLOAT32: + { + for ( unsigned int channel = 0; channel < channelCount; channel++ ) + { + float fromSample = ( ( float* ) inBuffer )[ frameInSample + channel ]; + float toSample = ( ( float* ) inBuffer )[ frameInSample + channelCount + channel ]; + float sampleDiff = ( toSample - fromSample ) * inSampleDec; + ( ( float* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff; + } + break; + } + case RTAUDIO_FLOAT64: + { + for ( unsigned int channel = 0; channel < channelCount; channel++ ) + { + double fromSample = ( ( double* ) inBuffer )[ frameInSample + channel ]; + double toSample = ( ( double* ) inBuffer )[ frameInSample + channelCount + channel ]; + double sampleDiff = ( toSample - fromSample ) * inSampleDec; + ( ( double* ) outBuffer )[ frameOutSample + channel ] = fromSample + sampleDiff; + } + break; + } + } + + // jump to next in sample + inSampleFraction += sampleStep; + } } } @@ -5158,10 +5252,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: @@ -5195,6 +5289,8 @@ Exit: // Various revisions for RtAudio 4.0 by Gary Scavone, April 2007 // Changed device query structure for RtAudio 4.0.7, January 2010 +#include +#include #include #include #include @@ -5275,8 +5371,8 @@ RtApiDs :: RtApiDs() RtApiDs :: ~RtApiDs() { - if ( coInitialized_ ) CoUninitialize(); // balanced call. if ( stream_.state != STREAM_CLOSED ) closeStream(); + if ( coInitialized_ ) CoUninitialize(); // balanced call. } // The DirectSound default output is always the first device. @@ -8071,7 +8167,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 ); @@ -8695,8 +8791,10 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device ) info.nativeFormats |= RTAUDIO_SINT8; if ( mask & AFMT_S32_LE || mask & AFMT_S32_BE ) info.nativeFormats |= RTAUDIO_SINT32; +#ifdef AFMT_FLOAT if ( mask & AFMT_FLOAT ) info.nativeFormats |= RTAUDIO_FLOAT32; +#endif if ( mask & AFMT_S24_LE || mask & AFMT_S24_BE ) info.nativeFormats |= RTAUDIO_SINT24; @@ -9023,7 +9121,7 @@ bool RtApiOss :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned } // Verify the sample rate setup worked. - if ( abs( srate - sampleRate ) > 100 ) { + if ( abs( srate - (int)sampleRate ) > 100 ) { close( fd ); errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support sample rate (" << sampleRate << ")."; errorText_ = errorStream_.str(); @@ -10143,8 +10241,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 ) {