[linux-audio-user] sub $200 sound card recommendations

Martin Habets errandir_news at mph.eclipse.co.uk
Thu Oct 13 05:45:15 EDT 2005


On Wed, Oct 12, 2005 at 01:06:59PM -0400, Paul Davis wrote:
> > The UA-25 uses S24_3LE. See the link for a jack patch that kindof swaps
> > the bytes, but it leaves byte 4 empty. Hence samples loose their sign plus
> > more.
> > Shouldn't the jack buffer convert the samples to a full 32 bit value?
> > How are applications suposed to know how many bits are valid in the
> > jack_port_buffer?
> 
> that is a meaningless question. all audio within the JACK graph is 32
> bit float audio. there is no access to h/w-native data formats from
> within the graph: only the backend has access to them, and that is where
> the patch takes effect.

Your answer to my first question makes my second one void indeed. Still
thanks for answering my first one :)

> if the patch does not work correctly, we need to know (as does its
> author).

Well, I'm still working on a final fix. What I have attached corrects the
buffer for the S24_3LE mode. Before this fix -1 from the device (0xffffff)
became 0x00ffffff (large positive number) in the buffer. With the patch
it is 0xffffffff, i.e. -1 as it should be.
I created a very similar patch  for 'arecord -vv', which is in alsa cvs now.
I'll post a final jack fix to jackit-devel, and probably append it to the
sf entry. But there's still plenty of testing to do before that.

-- 
Martin

--- memops.c.patched	2005-10-10 23:33:02.000000000 +0100
+++ memops.c	2005-10-12 18:01:55.000000000 +0100
@@ -30,6 +30,7 @@
 #include <memory.h>
 #include <stdlib.h>
 #include <limits.h>
+#include <endian.h>
 
 #include <jack/memops.h>
 
@@ -443,16 +444,22 @@
 		x |= (unsigned char)(src[1]);
 		x <<= 8;
 		x |= (unsigned char)(src[2]);
-		x <<= 8;
+		/* Correct sign bit and the rest of the top byte */
+		if (src[0] & 0x80) {
+			x |= 0xff << 24;
+		}
 #elif __BYTE_ORDER == __BIG_ENDIAN
 		x = (unsigned char)(src[2]);
 		x <<= 8;
 		x |= (unsigned char)(src[1]);
 		x <<= 8;
 		x |= (unsigned char)(src[0]);
-		x <<= 8;
+		/* Correct sign bit and the rest of the top byte */
+		if (src[2] & 0x80) {
+			x |= 0xff << 24;
+		}
 #endif
-		*dst = (x >> 8) / SAMPLE_MAX_24BIT;
+		*dst = x / SAMPLE_MAX_24BIT;
 		dst++;
 		src += src_skip;
 	}



More information about the Linux-audio-user mailing list