i2sbus transfer foo

Johannes Berg johannes at sipsolutions.net
Fri May 19 21:36:52 EST 2006


Sorry for the vague subject :) I don't really know what to say...

Let me introduce some things first. First of all, the i2sbus controllers
Apple has in their mac-io chip are capable of doing (among others we
don't care about) 16-bit transfers in 32x and 64x i2s modes, and 24-bit
transfers in 64x i2s mode. For the latter, the chip requires that the
inputs are actually 32-bit aligned, which means that it's a bit weird
that it doesn't actually transfer all the 32 bits. But that's another
issue, maybe there's a way to make it transfer 32 bits that I don't
know. Or maybe it even does and we just don't have a codec capable of
using or creating data in those remaining 8 bits.

Anyway, let's dive right in, here's a sample capture where I was
capturing an 880Hz sine wave generated with gstreamer on another machine
via a direct cable:

00007910  f8 36 48 00 f7 a1 cc 00  f7 a1 cc 00 f7 2e ea 00  |.6H.............|
00007920  f7 2e ea 00 f6 df 58 00  f6 df 58 00 f6 b4 ee 00  |......X...X.....|
00007930  f6 b4 ee 00 f6 af 78 00  f6 af 78 00 f6 cf 59 00  |......x...x...Y.|

The hexdump above is directly from the DMA memory area, not gone through
alsa, I made a debugfs file that gives me access to the buffer area
straight away.

Let me start arecord again:
$ arecord -r 44100 -f S32_LE -c2 > /tmp/test.wav

Dumping the dma area again yields:
00008680  e4 00 ff bd e4 00 fe 93  22 00 fe 93 22 00 fd 6f  |........"..."..o|
00008690  2b 00 fd 6f 2b 00 fc 55  62 00 fc 55 62 00 fb 49  |+..o+..Ub..Ub..I|
000086a0  76 00 fb 49 76 00 fa 52  49 00 fa 52 49 00 f9 71  |v..Iv..RI..RI..q|
000086b0  1f 00 f9 71 1f 00 f8 aa  2c 00 f8 aa 2c 00 f7 ff  |...q....,...,...|
and a 3rd time:
0000ff60  00 07 3a 12 00 06 6f 77  00 06 6f 77 00 05 89 d9  |..:...ow..ow....|
0000ff70  00 05 89 d9 00 04 8e 73  00 04 8e 73 00 03 80 4a  |.......s...s...J|
0000ff80  00 03 80 4a 00 02 64 b0  00 02 64 b0 00 01 3e c0  |...J..d...d...>.|
0000ff90  00 01 3e c0 00 00 16 65  00 00 16 65 00 fe ea b6  |..>....e...e....|
4th time it's like 3rd, 5th like first, but 6th time:
0000bc60  e8 39 00 00 13 60 00 00  13 60 00 01 3d 96 00 01  |.9...`...`..=...|
0000bc70  3d 96 00 02 63 55 00 02  63 55 00 03 7f f5 00 03  |=...cU..cU......|
0000bc80  7f f5 00 04 8b 73 00 04  8b 73 00 05 87 84 00 05  |.....s...s......|
0000bc90  87 84 00 06 6d cc 00 06  6d cc 00 07 37 ae 00 07  |....m...m...7...|

See the problem?

When I actually manage to have it aligned like in #3 above,
SNDRV_PCM_FORMAT_S24_BE would be correct. And in that case, I once even
got a nice wav file that audacity can downsample to 16 bit and play
properly. But in all other cases I get mangled sound for obvious
reasons.

The correct data layout seems to be the first though, because when I
transfer that *to* the chip for playback (by making i2sbus announce
32bit big-endian format to alsa) I get proper sound with the correct
volume, hence I just changed i2sbus to always announce 16 and 32-bit BE
formats which also no longer mangles sound with gstreamer (except for
clicking every once a while on some streams[1]).

Oh, and note that those 4 cases aren't all possible cases. If you think
about it you'll notice that there are 8 cases because we have two
channels. I think I even mixed them in the dumps above, not sure.

Some looking at snd-powermac code later I now changed the i2sbus code to
do a dbdma-programmed engine stop in hope that would synchronize (as a
comment in snd-powermac implies) but that doesn't seem to be correct
either. I now more often get the first case though not all the time.

I'm out of ideas. I don't have a clue how to get this thing synchronized
properly. If anyone has a solution let me know, otherwise I'll probably
just disable 24-bit recording for good, then at least the chances of
getting sound that makes sense (even if left and right might be
switched) are 1/2 as opposed to 1/4 assuming even distribution... Also,
the question is why this does not happen on playback, or at least so
much less frequently that I haven't seen it yet...

johannes

[1] only happens with gstreamer on some streams, and then only if I use
alsasink without giving it the latency-time option, even if I give it
the default it doesn't click. very strange.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 793 bytes
Desc: This is a digitally signed message part
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20060519/7f04bf25/attachment.pgp>


More information about the Linuxppc-dev mailing list