pcm: plug - add automatic conversion for iec958 subframe samples

As Pavel noted, a possibility to automatically convert standard
linear samples to iec958 subframe format would be handy for latest
Raspberry HDMI driver.

Link: https://lore.kernel.org/alsa-devel/81b0be0a-5ab7-db91-21cb-0c59a55291e9@ivitera.com/
Suggested-by: Pavel Hofman <pavel.hofman@ivitera.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2024-02-09 11:21:04 +01:00
parent 2a736a0d25
commit d8ce72f256
3 changed files with 46 additions and 1 deletions

View file

@ -642,6 +642,9 @@ fi
if test "$build_pcm_alaw" = "yes"; then
AC_DEFINE([BUILD_PCM_PLUGIN_ALAW], "1", [Build PCM alaw plugin])
fi
if test "$build_pcm_iec958" = "yes"; then
AC_DEFINE([BUILD_PCM_PLUGIN_IEC958], "1", [Build PCM iec958 plugin])
fi
if test "$build_pcm_mmap_emul" = "yes"; then
AC_DEFINE([BUILD_PCM_PLUGIN_MMAP_EMUL], "1", [Build PCM mmap-emul plugin])
fi

View file

@ -133,6 +133,19 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode);
/*
* IEC958 subframe conversion plugin
*/
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,
int hdmi_mode);
int _snd_pcm_iec958_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode);
/*
* Route plugin for linear formats
*/

View file

@ -186,7 +186,8 @@ static const snd_pcm_format_t linear_preferred_formats[] = {
#if defined(BUILD_PCM_PLUGIN_MULAW) || \
defined(BUILD_PCM_PLUGIN_ALAW) || \
defined(BUILD_PCM_PLUGIN_ADPCM)
defined(BUILD_PCM_PLUGIN_ADPCM) || \
defined(BUILD_PCM_PLUGIN_IEC958)
#define BUILD_PCM_NONLINEAR
#endif
@ -201,6 +202,10 @@ static const snd_pcm_format_t nonlinear_preferred_formats[] = {
#ifdef BUILD_PCM_PLUGIN_ADPCM
SND_PCM_FORMAT_IMA_ADPCM,
#endif
#ifdef BUILD_PCM_PLUGIN_IEC958
SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
#endif
};
#endif
@ -490,6 +495,18 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
}
#endif
#ifdef BUILD_PCM_PLUGIN_IEC958
static int iec958_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_format_t sformat, snd_pcm_t *slave,
int close_slave)
{
unsigned char preamble_vals[3] = {
0x08, 0x02, 0x04 /* Z, X, Y */
};
return snd_pcm_iec958_open(pcmp, name, sformat, slave, close_slave, NULL, preamble_vals, 0);
}
#endif
static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_plug_params_t *clt, snd_pcm_plug_params_t *slv)
{
snd_pcm_plug_t *plug = pcm->private_data;
@ -526,6 +543,12 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
case SND_PCM_FORMAT_IMA_ADPCM:
f = snd_pcm_adpcm_open;
break;
#endif
#ifdef BUILD_PCM_PLUGIN_IEC958
case SND_PCM_FORMAT_IEC958_SUBFRAME_LE:
case SND_PCM_FORMAT_IEC958_SUBFRAME_BE:
f = iec958_open;
break;
#endif
default:
#ifdef BUILD_PCM_PLUGIN_LFLOAT
@ -566,6 +589,12 @@ static int snd_pcm_plug_change_format(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm_p
case SND_PCM_FORMAT_IMA_ADPCM:
f = snd_pcm_adpcm_open;
break;
#endif
#ifdef BUILD_PCM_PLUGIN_IEC958
case SND_PCM_FORMAT_IEC958_SUBFRAME_LE:
case SND_PCM_FORMAT_IEC958_SUBFRAME_BE:
f = iec958_open;
break;
#endif
default:
return -EINVAL;