From 28fc1cfcb352d47a17078f3348f8702f221db650 Mon Sep 17 00:00:00 2001 From: Gary Scavone Date: Fri, 21 Sep 2012 19:38:03 +0000 Subject: [PATCH] Various changes for true 24-bit support, changes regarding Jack get_latency, and Linux ALSA realtime threading (gps). --- RtAudio.cpp | 86 ++++++++++++++++++++++++++++++----------------- RtAudio.h | 31 +++++++++++++++++ tests/duplex.cpp | 16 ++++----- tests/playraw.cpp | 4 +++ tests/playsaw.cpp | 20 +++++------ tests/record.cpp | 12 +++---- 6 files changed, 115 insertions(+), 54 deletions(-) diff --git a/RtAudio.cpp b/RtAudio.cpp index 823faaf..8477ef9 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -2094,8 +2094,17 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne // Get the latency of the JACK port. ports = jack_get_ports( client, deviceName.c_str(), NULL, flag ); - if ( ports[ firstChannel ] ) - stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) ); + if ( ports[ firstChannel ] ) { + // Added by Ge Wang + jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency); + // the range (usually the min and max are equal) + jack_latency_range_t latrange; latrange.min = latrange.max = 0; + // get the latency range + jack_port_get_latency_range( jack_port_by_name( client, ports[firstChannel] ), cbmode, &latrange ); + // be optimistic, use the min! + stream_.latency[mode] = latrange.min; + //stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) ); + } free( ports ); // The jack server always uses 32-bit floating-point data. @@ -2708,6 +2717,8 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device ) info.nativeFormats |= RTAUDIO_FLOAT32; else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB ) info.nativeFormats |= RTAUDIO_FLOAT64; + else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB ) + info.nativeFormats |= RTAUDIO_SINT24; if ( info.outputChannels > 0 ) if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true; @@ -2860,6 +2871,10 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne stream_.deviceFormat[mode] = RTAUDIO_FLOAT64; if ( channelInfo.type == ASIOSTFloat64MSB ) stream_.doByteSwap[mode] = true; } + else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB ) { + stream_.deviceFormat[mode] = RTAUDIO_SINT24; + if ( channelInfo.type == ASIOSTInt24MSB ) stream_.doByteSwap[mode] = true; + } if ( stream_.deviceFormat[mode] == 0 ) { drivers.removeCurrentDriver(); @@ -3879,7 +3894,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned // Determine the device buffer size. By default, we'll use the value // defined above (32K), but we will grow it to make allowances for // very large software buffer sizes. - DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE;; + DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE; DWORD dsPointerLeadTime = 0; void *ohandle = 0, *bhandle = 0; @@ -5875,8 +5890,8 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne if ( priority < min ) priority = min; else if ( priority > max ) priority = max; param.sched_priority = priority; - pthread_attr_setschedparam( &attr, ¶m ); pthread_attr_setschedpolicy( &attr, SCHED_RR ); + pthread_attr_setschedparam( &attr, ¶m ); } else pthread_attr_setschedpolicy( &attr, SCHED_OTHER ); @@ -7741,11 +7756,12 @@ unsigned int RtApi :: formatBytes( RtAudioFormat format ) { if ( format == RTAUDIO_SINT16 ) return 2; - else if ( format == RTAUDIO_SINT24 || format == RTAUDIO_SINT32 || - format == RTAUDIO_FLOAT32 ) + else if ( format == RTAUDIO_SINT32 || format == RTAUDIO_FLOAT32 ) return 4; else if ( format == RTAUDIO_FLOAT64 ) return 8; + else if ( format == RTAUDIO_SINT24 ) + return 3; else if ( format == RTAUDIO_SINT8 ) return 1; @@ -7878,11 +7894,11 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info } } else if (info.inFormat == RTAUDIO_SINT24) { - Int32 *in = (Int32 *)inBuffer; + Int24 *in = (Int24 *)inBuffer; scale = 1.0 / 8388607.5; for (unsigned int i=0; i>= 8; + out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] >> 8); + //out[info.outOffset[j]] >>= 8; } in += info.inJump; out += info.outJump; @@ -8162,10 +8178,10 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info } } else if (info.inFormat == RTAUDIO_SINT24) { - Int32 *in = (Int32 *)inBuffer; + Int24 *in = (Int24 *)inBuffer; for (unsigned int i=0; i> 8) & 0x0000ffff); + out[info.outOffset[j]] = (Int16) (in[info.inOffset[j]].asInt() >> 8); } in += info.inJump; out += info.outJump; @@ -8226,10 +8242,10 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info } } else if (info.inFormat == RTAUDIO_SINT24) { - Int32 *in = (Int32 *)inBuffer; + Int24 *in = (Int24 *)inBuffer; for (unsigned int i=0; i> 16) & 0x000000ff); + out[info.outOffset[j]] = (signed char) (in[info.inOffset[j]].asInt() >> 16); } in += info.inJump; out += info.outJump; @@ -8268,9 +8284,9 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info } } - //static inline uint16_t bswap_16(uint16_t x) { return (x>>8) | (x<<8); } - //static inline uint32_t bswap_32(uint32_t x) { return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16)); } - //static inline uint64_t bswap_64(uint64_t x) { return (((unsigned long long)bswap_32(x&0xffffffffull))<<32) | (bswap_32(x>>32)); } +//static inline uint16_t bswap_16(uint16_t x) { return (x>>8) | (x<<8); } +//static inline uint32_t bswap_32(uint32_t x) { return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16)); } +//static inline uint64_t bswap_64(uint64_t x) { return (((unsigned long long)bswap_32(x&0xffffffffull))<<32) | (bswap_32(x>>32)); } void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format ) { @@ -8289,8 +8305,7 @@ void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat ptr += 2; } } - else if ( format == RTAUDIO_SINT24 || - format == RTAUDIO_SINT32 || + else if ( format == RTAUDIO_SINT32 || format == RTAUDIO_FLOAT32 ) { for ( unsigned int i=0; i> 8; + c3[2] = (i & 0x00ff0000) >> 16; + return *this; + } + + S24( const S24& v ) { *this = v; } + S24( const double& d ) { *this = (int) d; } + S24( const float& f ) { *this = (int) f; } + S24( const signed short& s ) { *this = (int) s; } + S24( const char& c ) { *this = (int) c; } + + int asInt() { + int i = c3[0] | (c3[1] << 8) | (c3[2] << 16); + if (i & 0x800000) i |= ~0xffffff; + return i; + } +}; +#pragma pack(pop) + #if defined( HAVE_GETTIMEOFDAY ) #include #endif @@ -655,6 +685,7 @@ protected: :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; } }; + typedef S24 Int24; typedef signed short Int16; typedef signed int Int32; typedef float Float32; diff --git a/tests/duplex.cpp b/tests/duplex.cpp index 9991dcf..2c60aad 100644 --- a/tests/duplex.cpp +++ b/tests/duplex.cpp @@ -14,24 +14,24 @@ #include /* -typedef signed long MY_TYPE; -#define FORMAT RTAUDIO_SINT24 - -typedef char MY_TYPE; +typedef char MY_TYPE; #define FORMAT RTAUDIO_SINT8 */ -typedef signed short MY_TYPE; +typedef signed short MY_TYPE; #define FORMAT RTAUDIO_SINT16 /* -typedef signed long MY_TYPE; +typedef S24 MY_TYPE; +#define FORMAT RTAUDIO_SINT24 + +typedef signed long MY_TYPE; #define FORMAT RTAUDIO_SINT32 -typedef float MY_TYPE; +typedef float MY_TYPE; #define FORMAT RTAUDIO_FLOAT32 -typedef double MY_TYPE; +typedef double MY_TYPE; #define FORMAT RTAUDIO_FLOAT64 */ diff --git a/tests/playraw.cpp b/tests/playraw.cpp index 3b7be76..f57c0b0 100644 --- a/tests/playraw.cpp +++ b/tests/playraw.cpp @@ -26,6 +26,10 @@ typedef signed short MY_TYPE; #define SCALE 32767.0 /* +typedef S24 MY_TYPE; +#define FORMAT RTAUDIO_SINT24 +#define SCALE 8388607.0 + typedef signed int MY_TYPE; #define FORMAT RTAUDIO_SINT32 #define SCALE 2147483647.0 diff --git a/tests/playsaw.cpp b/tests/playsaw.cpp index 2117b54..46ea4fb 100644 --- a/tests/playsaw.cpp +++ b/tests/playsaw.cpp @@ -13,29 +13,29 @@ #include /* -typedef signed long MY_TYPE; -#define FORMAT RTAUDIO_SINT24 -#define SCALE 2147483647.0 - -typedef char MY_TYPE; +typedef char MY_TYPE; #define FORMAT RTAUDIO_SINT8 #define SCALE 127.0 */ -typedef signed short MY_TYPE; +typedef signed short MY_TYPE; #define FORMAT RTAUDIO_SINT16 #define SCALE 32767.0 /* -typedef signed long MY_TYPE; +typedef S24 MY_TYPE; +#define FORMAT RTAUDIO_SINT24 +#define SCALE 8388607.0 + +typedef signed long MY_TYPE; #define FORMAT RTAUDIO_SINT32 #define SCALE 2147483647.0 -typedef float MY_TYPE; +typedef float MY_TYPE; #define FORMAT RTAUDIO_FLOAT32 #define SCALE 1.0 -typedef double MY_TYPE; +typedef double MY_TYPE; #define FORMAT RTAUDIO_FLOAT64 #define SCALE 1.0 */ @@ -163,7 +163,7 @@ int main( int argc, char *argv[] ) oParams.nChannels = channels; oParams.firstChannel = offset; - options.flags |= RTAUDIO_HOG_DEVICE; + options.flags = RTAUDIO_HOG_DEVICE; options.flags |= RTAUDIO_SCHEDULE_REALTIME; #if !defined( USE_INTERLEAVED ) options.flags |= RTAUDIO_NONINTERLEAVED; diff --git a/tests/record.cpp b/tests/record.cpp index e4c7b12..5aa0ef3 100644 --- a/tests/record.cpp +++ b/tests/record.cpp @@ -16,24 +16,24 @@ #include /* -typedef char MY_TYPE; +typedef char MY_TYPE; #define FORMAT RTAUDIO_SINT8 */ -typedef signed short MY_TYPE; +typedef signed short MY_TYPE; #define FORMAT RTAUDIO_SINT16 /* -typedef signed long MY_TYPE; +typedef S24 MY_TYPE; #define FORMAT RTAUDIO_SINT24 -typedef signed long MY_TYPE; +typedef signed long MY_TYPE; #define FORMAT RTAUDIO_SINT32 -typedef float MY_TYPE; +typedef float MY_TYPE; #define FORMAT RTAUDIO_FLOAT32 -typedef double MY_TYPE; +typedef double MY_TYPE; #define FORMAT RTAUDIO_FLOAT64 */ -- 2.30.2