Follow the standard test with that script, just tell speaker-test to use period size at multiple of 24 audio frames (e.g. 85ms for 48k). The goal is to have periods aligned to 192 audio samples (= HDMI audio block).
Not yet, sorry I've been a bit busy. Am I expecting this test to cause swapping? Or to show no swapping when any other period size will have swapping (and therefore confirm your hypothesis about the problem)?
The goal is to make writes at multiples of 192 samples which is length of the HDMI audio block. IIUC then an xrun at that write size should keep the audio block at standard 192 samples. Maybe the HDMI receiver does not work nicely with shorter audio blocks, even if they are properly aligned to 8 channels (which they should be as all writes are aligned to audio frames). I do not know, it's just a test. But it's important to check the actual period length in the hw_params file.
(Sorry for tardy response.)Can you try the xruns in speaker-test with period set at multiples of 24 frames
Using "-r 48000 -p 85000" does not fix, nor even improve the channel swap problem.
(I checked that "period_size: 4080" and "buffer_size: 16320")
Thanks a lot, that's an important result. Then IUUC the channel misalignment is not caused by different lengths of HDMI audio block when recovering from xruns.
Please can you make a test like https://forums.raspberrypi.com/viewtopic.php?t=364156&start=25#p2192855 and check the dumped output file for discrepancies at xruns?
Code:
gordoste@raspberrypi:~ $ (while true; do for CH in '\x01' '\x02' '\x03' '\x04' '\x05' '\x06' '\x07' '\x08' ; do echo -n -e $CH; echo -n -e '\x00\x00'; done; done ) | aplay -v -c 8 -f S24_3LE -r 48000 -D testiec
Playing raw data 'stdin' : Signed 24 bit Little Endian in 3bytes, Rate 48000 Hz, Channels 8
IEC958 subframe conversion PCM (IEC958_SUBFRAME_LE)
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S24_3LE
subformat : STD
channels : 8
rate : 48000
exact rate : 48000 (48000/1)
msbits : 24
buffer_size : 16384
period_size : 4096
period_time : 85333
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 4096
period_event : 0
start_threshold : 16384
stop_threshold : 16384
silence_threshold: 0
silence_size : 0
boundary : 4611686018427387904
Slave: File PCM (file=/tmp/out.raw)
Final file PCM (file=/tmp/out.raw)
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : IEC958_SUBFRAME_LE
subformat : STD
channels : 8
rate : 48000
exact rate : 48000 (48000/1)
msbits : 24
buffer_size : 16384
period_size : 4096
period_time : 85333
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 4096
period_event : 0
start_threshold : 16384
stop_threshold : 16384
silence_threshold: 0
silence_size : 0
boundary : 4611686018427387904
Slave: Hardware PCM card 1 'vc4-hdmi-1' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : IEC958_SUBFRAME_LE
subformat : STD
channels : 8
rate : 48000
exact rate : 48000 (48000/1)
msbits : 24
buffer_size : 16384
period_size : 4096
period_time : 85333
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 4096
period_event : 0
start_threshold : 16384
stop_threshold : 16384
silence_threshold: 0
silence_size : 0
boundary : 4611686018427387904
appl_ptr : 0
hw_ptr : 0
underrun!!! (at least 603.243 ms long)
Status:
state : XRUN
trigger_time: 120109.856139
tstamp : 0.000000
delay : 0
avail : 16400
avail_max : 16400
underrun!!! (at least 601.405 ms long)
Status:
state : XRUN
trigger_time: 120113.642725
tstamp : 0.000000
delay : 0
avail : 16400
avail_max : 16400
underrun!!! (at least 607.963 ms long)
Status:
state : XRUN
trigger_time: 120117.431007
tstamp : 0.000000
delay : 0
avail : 16400
avail_max : 16400
underrun!!! (at least 606.215 ms long)
Status:
state : XRUN
trigger_time: 120121.231995
tstamp : 0.000000
delay : 0
avail : 16400
avail_max : 16400
^CAborted by signal Interrupt...
I didn't need to nice aplay or anything to cause the xruns, perhaps file output of alsa couldn't keep up. They happen regularly every 4 seconds.
The first few samples look similar to yours (the '80' varies to c0 and 40 at various times):
Code:
gordoste@raspberrypi:/tmp $ xxd -c32 -g1 out.raw | head
00000000: 18 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
00000020: 12 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
00000040: 12 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
00000060: 12 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
00000080: 12 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
000000a0: 12 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
000000c0: 12 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
000000e0: 12 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
00000100: 12 00 00 80 24 00 00 80 34 00 00 00 44 00 00 80 54 00 00 00 64 00 00 00 74 00 00 80 84 00 00 80 ....$...4...D...T...d...t.......
00000120: 12 00 00 40 24 00 00 40 34 00 00 c0 44 00 00 40 54 00 00 c0 64 00 00 c0 74 00 00 40 84 00 00 40 ...@$..@4...D..@T...d...t..@...@
The command
Code:
xxd -c 32 -g 1 /tmp/out.raw | grep -v "54 00 00"
Returns no output which seems to indicate no sample shifting though.
Last edited:
Maybe your storage is too slow to store the out file (can be stored to a tmpfs mount instead), maybe the CPU is too weak to generate the samples - top would show.
Does your xxd output look OK? Just store to file or pipe to less. Why that specific grep?
Does your xxd output look OK? Just store to file or pipe to less. Why that specific grep?
See my edit for the reason I chose that grep... I randomly selected channel 5 to see if it ever gets corrupted.
I changed the .asoundrc to send the file to /run/user/1000/out.raw but it still gets the under-runs. I am using an SD card.
Code:
gordoste@raspberrypi:/tmp $ df -k
Filesystem 1K-blocks Used Available Use% Mounted on
udev 1669488 0 1669488 0% /dev
tmpfs 388432 1452 386980 1% /run
/dev/mmcblk0p2 60798236 13946012 43743904 25% /
tmpfs 1942148 420 1941728 1% /dev/shm
tmpfs 5120 24 5096 1% /run/lock
/dev/mmcblk0p1 522232 74268 447964 15% /boot/firmware
tmpfs 388428 36 388392 1% /run/user/1000
/dev/sda1 7798784 842256 6956528 11% /media/gordoste/ESD-USB
tmpfs 388428 36 388392 1% /run/user/106
gordoste@raspberrypi:/tmp $ id
uid=1000(gordoste) gid=1000(gordoste) groups=1000(gordoste),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),102(input),105(render),106(netdev),115(lpadmin),993(gpio),994(i2c),995(spi)
I changed the .asoundrc to send the file to /run/user/1000/out.raw but it still gets the under-runs. I am using an SD card.
Does top show that the bash command can keep up generating the samples? If not, you can generate some block of samples into a file and cat that file in an endless loop.
I am not sure your grep can detect the corruption. IMO storing the output to less and scrolling through the list may show issues fast. Also what needs to be checked are the 18 every 192 lines, at best even at xrun. Maybe setting period size e.g. to 6144 (i.e. multiple of 192 frames).
I am not sure your grep can detect the corruption. IMO storing the output to less and scrolling through the list may show issues fast. Also what needs to be checked are the 18 every 192 lines, at best even at xrun. Maybe setting period size e.g. to 6144 (i.e. multiple of 192 frames).
I'm going to assume it can't keep up, because it would need to run 768,000 echo commands every second (48000 * 8 * 2). I will try generating a file later tonight.
Shell scripts often have bottlenecks due to too much process spawning. Here's a perl script to do this in a single process:
I then modified the script by the user oozmay from the thread on the RPi forums, placing the command
where it had speaker-test.
Here is an example of the output running under sh -x:
After 14 under-runs I terminated it and was left with a 222MB output file. xxd output generates nearly 7 million lines... too many for manual scanning.
Here is the command I used to automatically scan the output and flag any improper data:
In case you aren't up on perl regexps, it checks that every 32-bit block looks like 0xN?0000?0 where N is the channel number.
Code:
#!perl
while (1) { print "\001\0\0\002\0\0\003\0\0\004\0\0\005\0\0\006\0\0\007\0\0\010\0\0"; }
exit 0;
Code:
perl ~/test.pl | aplay -c8 -r48000 -fS24_3LE -D testiec &
Here is an example of the output running under sh -x:
Code:
sh -x test_chan_swap.sh
+ trap killall background EXIT
+ perl /home/gordoste/test.pl+ bgpid=15972
+ true
+ sleep 10
+ aplay -c8 -r48000 -fS24_3LE -Dtestiec
Playing raw data 'stdin' : Signed 24 bit Little Endian in 3bytes, Rate 48000 Hz, Channels 8
+ echo Forcing x-run...
Forcing x-run...
+ kill -STOP 15972
+ sleep 0.5
+ kill -CONT 15972
+ true
+ sleep 10
underrun!!! (at least 227.306 ms long)
+ echo Forcing x-run...
Forcing x-run...
+ kill -STOP 15972
+ sleep 0.5
+ kill -CONT 15972
+ true
+ sleep 10
underrun!!! (at least 237.979 ms long)
+ echo Forcing x-run...
Forcing x-run...
+ kill -STOP 15972
+ sleep 0.5
+ kill -CONT 15972
+ true
+ sleep 10
underrun!!! (at least 238.469 ms long)
+ echo Forcing x-run...
Forcing x-run...
After 14 under-runs I terminated it and was left with a 222MB output file. xxd output generates nearly 7 million lines... too many for manual scanning.
Here is the command I used to automatically scan the output and flag any improper data:
Code:
gordoste@raspberrypi:~ $ xxd -c32 -g4 /run/user/1000/out.raw | perl -lne '{print unless m/^[0-9a-f]{8}: 1[0-9a-f]0000[0-9a-f]0 2[0-9a-f]0000[0-9a-f]0 3[0-9a-f]0000[0-9a-f]0 4[0-9a-f]0000[0-9a-f]0 5[0-9a-f]0000[0-9a-f]0 6[0-9a-f]0000[0-9a-f]0 7[0-9a-f]0000[0-9a-f]0 8[0-9a-f]0000[0-9a-f]0 \s\S+$/}'
Kudos to your clever automation commands! Did you discover any discrepancy in the stream?
Last edited:
- Home
- Source & Line
- PC Based
- camillaDSP: How to monitor and control audio channel mapping to HDMI?