Skip to content

Commit

Permalink
pcm: plug - add automatic conversion for iec958 subframe samples
Browse files Browse the repository at this point in the history
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/[email protected]/
Suggested-by: Pavel Hofman <[email protected]>
Signed-off-by: Jaroslav Kysela <[email protected]>
  • Loading branch information
perexg committed Feb 9, 2024
1 parent 2a736a0 commit d8ce72f
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions include/pcm_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
31 changes: 30 additions & 1 deletion src/pcm/pcm_plug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit d8ce72f

Please sign in to comment.