X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=RtAudio.cpp;h=0b952f02ec8812c169d3eb17d1ca5c94ae151070;hb=4ee8b95d791a54aca593ad24d4eabbaac90355c0;hp=9ebe49dbb793809ddc89c53bbf509fb5eceaa0ea;hpb=706a281ea84117da2e1afb32e82ed824fc787268;p=rtaudio.git diff --git a/RtAudio.cpp b/RtAudio.cpp index 9ebe49d..0b952f0 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -45,6 +45,7 @@ #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) { @@ -3860,138 +3866,141 @@ private: // 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 works best with conversions between one rate and its multiple. -void convertBufferWasapi(char* outBuffer, - const char* inBuffer, - const unsigned int& channelCount, - const unsigned int& inSampleRate, - const unsigned int& outSampleRate, - const unsigned int& inSampleCount, - unsigned int& outSampleCount, - const RtAudioFormat& format) -{ - // 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); - - // if inSampleRate is a multiple of outSampleRate (or vice versa) there's no need to interpolate - if (floor(sampleRatio) == sampleRatio || floor(sampleRatioInv) == sampleRatioInv) +void convertBufferWasapi( char* outBuffer, + const char* inBuffer, + const unsigned int& channelCount, + const unsigned int& inSampleRate, + const unsigned int& outSampleRate, + const unsigned int& inSampleCount, + unsigned int& outSampleCount, + const RtAudioFormat& format ) +{ + // 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 ) std::roundf( inSampleCount * sampleRatio ); + + // if inSampleRate is a multiple of outSampleRate (or vice versa) there's no need to interpolate + if ( floor( sampleRatio ) == sampleRatio || floor( sampleRatioInv ) == sampleRatioInv ) + { + // frame-by-frame, copy each relative input sample into it's corresponding output sample + for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ ) { - // 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; - - 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; - } + unsigned int inSample = ( unsigned int ) inSampleFraction; - // jump to next in sample - inSampleFraction += sampleStep; - } + 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 + } + 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++ ) { - // 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; - - switch (format) - { - case RTAUDIO_SINT8: - { - for (unsigned int channel = 0; channel < channelCount; channel++) - { - char fromSample = ((char*)inBuffer)[(inSample * channelCount) + channel]; - char toSample = ((char*)inBuffer)[((inSample + 1) * channelCount) + channel]; - float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction)); - ((char*)outBuffer)[(outSample * channelCount) + channel] = fromSample + (char)sampleDiff; - } - break; - } - case RTAUDIO_SINT16: - { - for (unsigned int channel = 0; channel < channelCount; channel++) - { - short fromSample = ((short*)inBuffer)[(inSample * channelCount) + channel]; - short toSample = ((short*)inBuffer)[((inSample + 1) * channelCount) + channel]; - float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction)); - ((short*)outBuffer)[(outSample * channelCount) + channel] = fromSample + (short)sampleDiff; - } - break; - } - case RTAUDIO_SINT24: - { - for (unsigned int channel = 0; channel < channelCount; channel++) - { - int fromSample = ((S24*)inBuffer)[(inSample * channelCount) + channel].asInt(); - int toSample = ((S24*)inBuffer)[((inSample + 1) * channelCount) + channel].asInt(); - float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction)); - ((S24*)outBuffer)[(outSample * channelCount) + channel] = fromSample + (int)sampleDiff; - } - break; - } - case RTAUDIO_SINT32: - { - for (unsigned int channel = 0; channel < channelCount; channel++) - { - int fromSample = ((int*)inBuffer)[(inSample * channelCount) + channel]; - int toSample = ((int*)inBuffer)[((inSample + 1) * channelCount) + channel]; - float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction)); - ((int*)outBuffer)[(outSample * channelCount) + channel] = fromSample + (int)sampleDiff; - } - break; - } - case RTAUDIO_FLOAT32: - { - for (unsigned int channel = 0; channel < channelCount; channel++) - { - float fromSample = ((float*)inBuffer)[(inSample * channelCount) + channel]; - float toSample = ((float*)inBuffer)[((inSample + 1) * channelCount) + channel]; - float sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction)); - ((float*)outBuffer)[(outSample * channelCount) + channel] = fromSample + sampleDiff; - } - break; - } - case RTAUDIO_FLOAT64: - { - for (unsigned int channel = 0; channel < channelCount; channel++) - { - double fromSample = ((double*)inBuffer)[(inSample * channelCount) + channel]; - double toSample = ((double*)inBuffer)[((inSample + 1) * channelCount) + channel]; - double sampleDiff = (toSample - fromSample) * (inSampleFraction - floor(inSampleFraction)); - ((double*)outBuffer)[(outSample * channelCount) + channel] = fromSample + sampleDiff; - } - break; - } - } + 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; } + } } //----------------------------------------------------------------------------- @@ -5280,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 @@ -5360,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. @@ -8780,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; @@ -9108,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();