diff --git a/packages/audio/alsa-lib/patches/alsa-lib-001-iec958-hbr.patch b/packages/audio/alsa-lib/patches/alsa-lib-001-iec958-hbr.patch new file mode 100644 index 0000000000..50a3b87029 --- /dev/null +++ b/packages/audio/alsa-lib/patches/alsa-lib-001-iec958-hbr.patch @@ -0,0 +1,150 @@ +From 10ee8fad6ac9f66b90454dee0d6c798efd209a05 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Tue, 30 Jun 2020 12:45:54 +0200 +Subject: [PATCH] pcm_iec958: implement HDMI HBR audio formatting + +High bitrate compressed audio data like DTS HD or MAT is usually +packed into 8-channel data. The HDMI specs state this has to be +formatted as a single IEC958 stream, compared to normal multi- +channel PCM data which has to be formatted as parallel IEC958 streams. + +As this single-stream formatting mode may break existing setups that +expect non-PCM multichannel data to be formatted as parallel IEC958 +streams it needs to be explicitly selected by setting the hdmi_mode +option to true. + +The single-stream formatting implementation is prepared to cope with +arbitrary channel counts but only limited testing was done for channel +counts other than 8. + +Signed-off-by: Matthias Reichl +--- + src/pcm/pcm_iec958.c | 37 +++++++++++++++++++++++++++++++++---- + 1 file changed, 33 insertions(+), 4 deletions(-) + +diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c +index 76d3ca7b..17ade957 100644 +--- a/src/pcm/pcm_iec958.c ++++ b/src/pcm/pcm_iec958.c +@@ -63,6 +63,7 @@ struct snd_pcm_iec958 { + unsigned int byteswap; + unsigned char preamble[3]; /* B/M/W or Z/X/Y */ + snd_pcm_fast_ops_t fops; ++ int hdmi_mode; + }; + + enum { PREAMBLE_Z, PREAMBLE_X, PREAMBLE_Y }; +@@ -193,6 +194,10 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec, + unsigned int channel; + int32_t sample = 0; + int counter = iec->counter; ++ int single_stream = iec->hdmi_mode && ++ (iec->status[0] & IEC958_AES0_NONAUDIO) && ++ (channels == 8); ++ int counter_step = single_stream ? ((channels + 1) >> 1) : 1; + for (channel = 0; channel < channels; ++channel) { + const char *src; + uint32_t *dst; +@@ -205,7 +210,12 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec, + src_step = snd_pcm_channel_area_step(src_area); + dst_step = snd_pcm_channel_area_step(dst_area) / sizeof(uint32_t); + frames1 = frames; +- iec->counter = counter; ++ ++ if (single_stream) ++ iec->counter = (counter + (channel >> 1)) % 192; ++ else ++ iec->counter = counter; ++ + while (frames1-- > 0) { + goto *get; + #define GET32_END after +@@ -217,9 +227,11 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec, + *dst = sample; + src += src_step; + dst += dst_step; +- iec->counter++; ++ iec->counter += counter_step; + iec->counter %= 192; + } ++ if (single_stream) /* set counter to ch0 value for next iteration */ ++ iec->counter = (counter + frames * counter_step) % 192; + } + } + #endif /* DOC_HIDDEN */ +@@ -473,6 +485,7 @@ static const snd_pcm_ops_t snd_pcm_iec958_ops = { + * \param close_slave When set, the slave PCM handle is closed with copy PCM + * \param status_bits The IEC958 status bits + * \param preamble_vals The preamble byte values ++ * \param hdmi_mode When set, enable HDMI compliant formatting + * \retval zero on success otherwise a negative error code + * \warning Using of this function might be dangerous in the sense + * of compatibility reasons. The prototype might be freely +@@ -481,7 +494,8 @@ static const snd_pcm_ops_t snd_pcm_iec958_ops = { + int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, + snd_pcm_t *slave, int close_slave, + const unsigned char *status_bits, +- const unsigned char *preamble_vals) ++ const unsigned char *preamble_vals, ++ int hdmi_mode) + { + snd_pcm_t *pcm; + snd_pcm_iec958_t *iec; +@@ -519,6 +533,8 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo + + memcpy(iec->preamble, preamble_vals, 3); + ++ iec->hdmi_mode = hdmi_mode; ++ + err = snd_pcm_new(&pcm, SND_PCM_TYPE_IEC958, name, slave->stream, slave->mode); + if (err < 0) { + free(iec); +@@ -566,9 +582,14 @@ pcm.name { + [preamble.z or preamble.b val] + [preamble.x or preamble.m val] + [preamble.y or preamble.w val] ++ [hdmi_mode true] + } + \endcode + ++When hdmi_mode is true, 8-channel compressed data is ++formatted as 4 contiguous frames of a single IEC958 stream as required ++by the HDMI HBR specification. ++ + \subsection pcm_plugins_iec958_funcref Function reference + +