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;
}