diff --git a/packages/audio/alsa-lib/patches/alsa-lib-002-iec958-format.patch b/packages/audio/alsa-lib/patches/alsa-lib-002-iec958-format.patch new file mode 100644 index 0000000000..e95be03fb3 --- /dev/null +++ b/packages/audio/alsa-lib/patches/alsa-lib-002-iec958-format.patch @@ -0,0 +1,122 @@ +From a49a9205f24b22f1127cabb02ff65aeaf304f58a Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Tue, 30 Jun 2020 17:34:52 +0200 +Subject: [PATCH] pcm_iec958: set channel status bits according to rate and + format + +This mimics snd_pcm_create_iec958_consumer in the kernel. + +The rate and wordlength bits will only be modified if they are +set to "not indicated", which is now the default if no status +option is used. + +This allows applications to override parameters determined from +the stream or implement channel status bits extensions without +needing to change pcm_iec958 code. + +Signed-off-by: Matthias Reichl +--- + src/pcm/pcm_iec958.c | 80 +++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 76 insertions(+), 4 deletions(-) + +diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c +index 17ade957..a11a0439 100644 +--- a/src/pcm/pcm_iec958.c ++++ b/src/pcm/pcm_iec958.c +@@ -365,9 +365,80 @@ static int snd_pcm_iec958_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params + iec->byteswap = format != SND_PCM_FORMAT_IEC958_SUBFRAME; + } + } +- /* FIXME: needs to adjust status_bits according to the format +- * and sample rate +- */ ++ ++ if ((iec->status[0] & IEC958_AES0_PROFESSIONAL) == 0) { ++ if ((iec->status[3] & IEC958_AES3_CON_FS) == IEC958_AES3_CON_FS_NOTID) { ++ unsigned int rate = 0; ++ unsigned char fs; ++ ++ err = INTERNAL(snd_pcm_hw_params_get_rate)(params, &rate, 0); ++ if (err < 0) ++ rate = 0; ++ ++ switch (rate) { ++ case 22050: ++ fs = IEC958_AES3_CON_FS_22050; ++ break; ++ case 24000: ++ fs = IEC958_AES3_CON_FS_24000; ++ break; ++ case 32000: ++ fs = IEC958_AES3_CON_FS_32000; ++ break; ++ case 44100: ++ fs = IEC958_AES3_CON_FS_44100; ++ break; ++ case 48000: ++ fs = IEC958_AES3_CON_FS_48000; ++ break; ++ case 88200: ++ fs = IEC958_AES3_CON_FS_88200; ++ break; ++ case 96000: ++ fs = IEC958_AES3_CON_FS_96000; ++ break; ++ case 176400: ++ fs = IEC958_AES3_CON_FS_176400; ++ break; ++ case 192000: ++ fs = IEC958_AES3_CON_FS_192000; ++ break; ++ case 768000: ++ fs = IEC958_AES3_CON_FS_768000; ++ break; ++ default: ++ fs = IEC958_AES3_CON_FS_NOTID; ++ break; ++ } ++ ++ iec->status[3] &= ~IEC958_AES3_CON_FS; ++ iec->status[3] |= fs; ++ } ++ ++ if ((iec->status[4] & IEC958_AES4_CON_WORDLEN) == IEC958_AES4_CON_WORDLEN_NOTID) { ++ unsigned char ws; ++ switch (snd_pcm_format_width(format)) { ++ case 16: ++ ws = IEC958_AES4_CON_WORDLEN_20_16; ++ break; ++ case 18: ++ ws = IEC958_AES4_CON_WORDLEN_22_18; ++ break; ++ case 20: ++ ws = IEC958_AES4_CON_WORDLEN_20_16 | IEC958_AES4_CON_MAX_WORDLEN_24; ++ break; ++ case 24: ++ case 32: /* Assume 24-bit width for 32-bit samples. */ ++ ws = IEC958_AES4_CON_WORDLEN_24_20 | IEC958_AES4_CON_MAX_WORDLEN_24; ++ break; ++ default: ++ ws = IEC958_AES4_CON_WORDLEN_NOTID; ++ break; ++ } ++ iec->status[4] &= ~(IEC958_AES4_CON_MAX_WORDLEN_24 | IEC958_AES4_CON_WORDLEN); ++ iec->status[4] |= ws; ++ } ++ } + return 0; + } + +@@ -504,7 +575,8 @@ int snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfo + IEC958_AES0_CON_EMPHASIS_NONE, + IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER, + 0, +- IEC958_AES3_CON_FS_48000 ++ IEC958_AES3_CON_FS_NOTID, /* will be set in hwparams */ ++ IEC958_AES4_CON_WORDLEN_NOTID /* will be set in hwparams */ + }; + + assert(pcmp && slave); +-- +2.20.1 +