Various changes for true 24-bit support, changes regarding Jack get_latency, and...
authorGary Scavone <gary@music.mcgill.ca>
Fri, 21 Sep 2012 19:38:03 +0000 (19:38 +0000)
committerStephen Sinclair <sinclair@music.mcgill.ca>
Thu, 10 Oct 2013 23:38:31 +0000 (01:38 +0200)
RtAudio.cpp
RtAudio.h
tests/duplex.cpp
tests/playraw.cpp
tests/playsaw.cpp
tests/record.cpp

index 823faafc476436a9275206f2181469e3f5b9ad6a..8477ef995ad7b9d7a77eb4a13bf16d95da7551cb 100644 (file)
@@ -2094,8 +2094,17 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
 \r
   // Get the latency of the JACK port.\r
   ports = jack_get_ports( client, deviceName.c_str(), NULL, flag );\r
-  if ( ports[ firstChannel ] )\r
-    stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) );\r
+  if ( ports[ firstChannel ] ) {\r
+    // Added by Ge Wang\r
+    jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency);\r
+    // the range (usually the min and max are equal)\r
+    jack_latency_range_t latrange; latrange.min = latrange.max = 0;\r
+    // get the latency range\r
+    jack_port_get_latency_range( jack_port_by_name( client, ports[firstChannel] ), cbmode, &latrange );\r
+    // be optimistic, use the min!\r
+    stream_.latency[mode] = latrange.min;\r
+    //stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) );\r
+  }\r
   free( ports );\r
 \r
   // The jack server always uses 32-bit floating-point data.\r
@@ -2708,6 +2717,8 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
     info.nativeFormats |= RTAUDIO_FLOAT32;\r
   else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB )\r
     info.nativeFormats |= RTAUDIO_FLOAT64;\r
+  else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB )\r
+    info.nativeFormats |= RTAUDIO_SINT24;\r
 \r
   if ( info.outputChannels > 0 )\r
     if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true;\r
@@ -2860,6 +2871,10 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
     stream_.deviceFormat[mode] = RTAUDIO_FLOAT64;\r
     if ( channelInfo.type == ASIOSTFloat64MSB ) stream_.doByteSwap[mode] = true;\r
   }\r
+  else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB ) {\r
+    stream_.deviceFormat[mode] = RTAUDIO_SINT24;\r
+    if ( channelInfo.type == ASIOSTInt24MSB ) stream_.doByteSwap[mode] = true;\r
+  }\r
 \r
   if ( stream_.deviceFormat[mode] == 0 ) {\r
     drivers.removeCurrentDriver();\r
@@ -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\r
   // defined above (32K), but we will grow it to make allowances for\r
   // very large software buffer sizes.\r
-  DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE;;\r
+  DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE;\r
   DWORD dsPointerLeadTime = 0;\r
 \r
   void *ohandle = 0, *bhandle = 0;\r
@@ -5875,8 +5890,8 @@ bool RtApiAlsa :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
       if ( priority < min ) priority = min;\r
       else if ( priority > max ) priority = max;\r
       param.sched_priority = priority;\r
-      pthread_attr_setschedparam( &attr, &param );\r
       pthread_attr_setschedpolicy( &attr, SCHED_RR );\r
+      pthread_attr_setschedparam( &attr, &param );\r
     }\r
     else\r
       pthread_attr_setschedpolicy( &attr, SCHED_OTHER );\r
@@ -7741,11 +7756,12 @@ unsigned int RtApi :: formatBytes( RtAudioFormat format )
 {\r
   if ( format == RTAUDIO_SINT16 )\r
     return 2;\r
-  else if ( format == RTAUDIO_SINT24 || format == RTAUDIO_SINT32 ||\r
-            format == RTAUDIO_FLOAT32 )\r
+  else if ( format == RTAUDIO_SINT32 || format == RTAUDIO_FLOAT32 )\r
     return 4;\r
   else if ( format == RTAUDIO_FLOAT64 )\r
     return 8;\r
+  else if ( format == RTAUDIO_SINT24 )\r
+    return 3;\r
   else if ( format == RTAUDIO_SINT8 )\r
     return 1;\r
 \r
@@ -7878,11 +7894,11 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
       }\r
     }\r
     else if (info.inFormat == RTAUDIO_SINT24) {\r
-      Int32 *in = (Int32 *)inBuffer;\r
+      Int24 *in = (Int24 *)inBuffer;\r
       scale = 1.0 / 8388607.5;\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
-          out[info.outOffset[j]] = (Float64) (in[info.inOffset[j]] & 0x00ffffff);\r
+          out[info.outOffset[j]] = (Float64) (in[info.inOffset[j]].asInt());\r
           out[info.outOffset[j]] += 0.5;\r
           out[info.outOffset[j]] *= scale;\r
         }\r
@@ -7956,11 +7972,11 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
       }\r
     }\r
     else if (info.inFormat == RTAUDIO_SINT24) {\r
-      Int32 *in = (Int32 *)inBuffer;\r
+      Int24 *in = (Int24 *)inBuffer;\r
       scale = (Float32) ( 1.0 / 8388607.5 );\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
-          out[info.outOffset[j]] = (Float32) (in[info.inOffset[j]] & 0x00ffffff);\r
+          out[info.outOffset[j]] = (Float32) (in[info.inOffset[j]].asInt());\r
           out[info.outOffset[j]] += 0.5;\r
           out[info.outOffset[j]] *= scale;\r
         }\r
@@ -8027,11 +8043,11 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
         out += info.outJump;\r
       }\r
     }\r
-    else if (info.inFormat == RTAUDIO_SINT24) { // Hmmm ... we could just leave it in the lower 3 bytes\r
-      Int32 *in = (Int32 *)inBuffer;\r
+    else if (info.inFormat == RTAUDIO_SINT24) {\r
+      Int24 *in = (Int24 *)inBuffer;\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
-          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]];\r
+          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]].asInt();\r
           out[info.outOffset[j]] <<= 8;\r
         }\r
         in += info.inJump;\r
@@ -8071,13 +8087,13 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
     }\r
   }\r
   else if (info.outFormat == RTAUDIO_SINT24) {\r
-    Int32 *out = (Int32 *)outBuffer;\r
+    Int24 *out = (Int24 *)outBuffer;\r
     if (info.inFormat == RTAUDIO_SINT8) {\r
       signed char *in = (signed char *)inBuffer;\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
-          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]];\r
-          out[info.outOffset[j]] <<= 16;\r
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] << 16);\r
+          //out[info.outOffset[j]] <<= 16;\r
         }\r
         in += info.inJump;\r
         out += info.outJump;\r
@@ -8087,8 +8103,8 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
       Int16 *in = (Int16 *)inBuffer;\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
-          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]];\r
-          out[info.outOffset[j]] <<= 8;\r
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] << 8);\r
+          //out[info.outOffset[j]] <<= 8;\r
         }\r
         in += info.inJump;\r
         out += info.outJump;\r
@@ -8096,7 +8112,7 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
     }\r
     else if (info.inFormat == RTAUDIO_SINT24) {\r
       // Channel compensation and/or (de)interleaving only.\r
-      Int32 *in = (Int32 *)inBuffer;\r
+      Int24 *in = (Int24 *)inBuffer;\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
           out[info.outOffset[j]] = in[info.inOffset[j]];\r
@@ -8109,8 +8125,8 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
       Int32 *in = (Int32 *)inBuffer;\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
-          out[info.outOffset[j]] = (Int32) in[info.inOffset[j]];\r
-          out[info.outOffset[j]] >>= 8;\r
+          out[info.outOffset[j]] = (Int32) (in[info.inOffset[j]] >> 8);\r
+          //out[info.outOffset[j]] >>= 8;\r
         }\r
         in += info.inJump;\r
         out += info.outJump;\r
@@ -8162,10 +8178,10 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
       }\r
     }\r
     else if (info.inFormat == RTAUDIO_SINT24) {\r
-      Int32 *in = (Int32 *)inBuffer;\r
+      Int24 *in = (Int24 *)inBuffer;\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
-          out[info.outOffset[j]] = (Int16) ((in[info.inOffset[j]] >> 8) & 0x0000ffff);\r
+          out[info.outOffset[j]] = (Int16) (in[info.inOffset[j]].asInt() >> 8);\r
         }\r
         in += info.inJump;\r
         out += info.outJump;\r
@@ -8226,10 +8242,10 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
       }\r
     }\r
     else if (info.inFormat == RTAUDIO_SINT24) {\r
-      Int32 *in = (Int32 *)inBuffer;\r
+      Int24 *in = (Int24 *)inBuffer;\r
       for (unsigned int i=0; i<stream_.bufferSize; i++) {\r
         for (j=0; j<info.channels; j++) {\r
-          out[info.outOffset[j]] = (signed char) ((in[info.inOffset[j]] >> 16) & 0x000000ff);\r
+          out[info.outOffset[j]] = (signed char) (in[info.inOffset[j]].asInt() >> 16);\r
         }\r
         in += info.inJump;\r
         out += info.outJump;\r
@@ -8268,9 +8284,9 @@ void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info
   }\r
 }\r
 \r
-  //static inline uint16_t bswap_16(uint16_t x) { return (x>>8) | (x<<8); }\r
-  //static inline uint32_t bswap_32(uint32_t x) { return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16)); }\r
-  //static inline uint64_t bswap_64(uint64_t x) { return (((unsigned long long)bswap_32(x&0xffffffffull))<<32) | (bswap_32(x>>32)); }\r
+//static inline uint16_t bswap_16(uint16_t x) { return (x>>8) | (x<<8); }\r
+//static inline uint32_t bswap_32(uint32_t x) { return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16)); }\r
+//static inline uint64_t bswap_64(uint64_t x) { return (((unsigned long long)bswap_32(x&0xffffffffull))<<32) | (bswap_32(x>>32)); }\r
 \r
 void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format )\r
 {\r
@@ -8289,8 +8305,7 @@ void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat
       ptr += 2;\r
     }\r
   }\r
-  else if ( format == RTAUDIO_SINT24 ||\r
-            format == RTAUDIO_SINT32 ||\r
+  else if ( format == RTAUDIO_SINT32 ||\r
             format == RTAUDIO_FLOAT32 ) {\r
     for ( unsigned int i=0; i<samples; i++ ) {\r
       // Swap 1st and 4th bytes.\r
@@ -8308,6 +8323,17 @@ void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat
       ptr += 3;\r
     }\r
   }\r
+  else if ( format == RTAUDIO_SINT24 ) {\r
+    for ( unsigned int i=0; i<samples; i++ ) {\r
+      // Swap 1st and 3rd bytes.\r
+      val = *(ptr);\r
+      *(ptr) = *(ptr+2);\r
+      *(ptr+2) = val;\r
+\r
+      // Increment 2 more bytes.\r
+      ptr += 2;\r
+    }\r
+  }\r
   else if ( format == RTAUDIO_FLOAT64 ) {\r
     for ( unsigned int i=0; i<samples; i++ ) {\r
       // Swap 1st and 8th bytes\r
index 31f1fa52b420e981d85ffb9689af8b5ecdcad887..f7251245b74828f6bc64d105bfb057c204442d60 100644 (file)
--- a/RtAudio.h
+++ b/RtAudio.h
@@ -557,6 +557,36 @@ struct CallbackInfo {
 //
 // **************************************************************** //
 
+#pragma pack(push, 1)
+class S24 {
+
+ protected:
+  unsigned char c3[3];
+
+ public:
+  S24() {}
+
+  S24& operator = ( const int& i ) {
+    c3[0] = (i & 0x000000ff);
+    c3[1] = (i & 0x0000ff00) >> 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 <sys/time.h>
 #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;
index 9991dcff201cbceb1fbf501084a4c13114626e30..2c60aada87c182bfd837890d1ae4caccd3a673b8 100644 (file)
 #include <cstring>
 
 /*
-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
 */
 
index 3b7be76bbdaebdffff9e850e3a7e6cf4923118c7..f57c0b0e31023995dc491688698faa88a57ac6f5 100644 (file)
@@ -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
index 2117b5453d7a45ca35a179990e146310221a1db9..46ea4fb7318c535186d3fec4b28599fcd79804ee 100644 (file)
 #include <cstdlib>
 
 /*
-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;
index e4c7b12301b2136b10fa7460e09891d4b5ab8d1e..5aa0ef381232820850f73effb1d670159645b480 100644 (file)
 #include <stdio.h>
 
 /*
-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
 */