On 11. 02. 24 15:12, Pavel Hofman wrote:
Hi,I wonder if the pcm_iec958.c correctly sets preambles for multichannel PCM/LPCM. It looks as if coded only for stereo.IIUC the X/Y preambles should alternate for even/odd channels.This check https://github.com/alsa-project/alsa-lib/blob/master/src/pcm/pcm_iec958.c#L122 :if (channel) data |= iec->preamble[PREAMBLE_Y]; /* odd sub frame, 'Y' */ else if (! iec->counter) data |= iec->preamble[PREAMBLE_Z]; /* Block start, 'Z' */ else data |= iec->preamble[PREAMBLE_X]; /* even sub frame, 'X' */IMO the condition should be "if (channel % 2)", because for multichannel only the first even channel ch0 gets Y, and the remaining even channels ch2, ch4, ... get X. This is confirmed by analyzing the generated stream captured with the file plugin.Also I am not sure if counting the subframes for Z preamble in https://github.com/alsa-project/alsa-lib/blob/master/src/pcm/pcm_iec958.c#L182 respects the multichannel. I do not know what "parallel IEC958 streams" mean, how the Z preamble should be placed for PCM multichannel.A) Either it can count all channel pairs sequentially up to 192, i.e. preamble Z after 192 pair of (ch0, ch1), (ch2, ch3),...If so, IMO the incrementation in https://github.com/alsa-project/alsa-lib/blob/master/src/pcm/pcm_iec958.c#L229 should increment by channels/2, not by 1 (which fits for channels=2)B) Or it can count each channel pair separately, i.e. 4 preables Z (for 8ch) in a row after 192 pairs of (ch0+ch1), 192 pairs of (ch2+ch3), etc.If so, IMO the counter should be reset after looping for all channel frames also for PCM, not only for nonaudio/single_stream https://github.com/alsa-project/alsa-lib/blob/master/src/pcm/pcm_iec958.c#L232-L233The reason I am looking at this code are the problems with channel swaps at xrun handling of RPi HDMI https://forums.raspberrypi.com/viewtopic.php?p=2187582#p2187540. I suspect the iec958 plugin does not generate correct multichannel IEC958 stream which confuses the HDMI receiver at the stream recovery.
Hi, IMO the iec958 multichannel functionality could be fixed with =================================================================== diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c--- a/src/pcm/pcm_iec958.c (revision 7e5de6fadd394cbbdd3a8d5d7d15081185b4d774)
+++ b/src/pcm/pcm_iec958.c (date 1707745970448) @@ -119,7 +119,7 @@ data |= 0x80000000; /* Preamble */ - if (channel) + if (channel % 2) data |= iec->preamble[PREAMBLE_Y]; /* odd sub frame, 'Y' */ else if (! iec->counter) data |= iec->preamble[PREAMBLE_Z]; /* Block start, 'Z' */ Test: pcm.testiec { type iec958 slave { pcm out format IEC958_SUBFRAME_LE } } pcm.out { type file file "/tmp/out.raw"ALSA_PLUGIN_DIR=/usr/lib/x86_64-linux-gnu/alsa-lib/ LD_PRELOAD=~/personal-work/alsa-lib/src/.libs/libasound.so aplay -v -D testiec -c 8 -f S32_LE /dev/zero
Then it produces the format as in the attached screenshots from mvciew, i.e. IMO four interleaved IEC958 streams.
Attachment:
Výběr_105.png
Description: PNG image
Attachment:
Výběr_104.png
Description: PNG image