]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm: plug - add automatic conversion for iec958 subframe samples
authorJaroslav Kysela <perex@perex.cz>
Fri, 9 Feb 2024 10:21:04 +0000 (11:21 +0100)
committerJaroslav Kysela <perex@perex.cz>
Fri, 9 Feb 2024 10:21:04 +0000 (11:21 +0100)
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>
configure.ac
include/pcm_plugin.h
src/pcm/pcm_plug.c

index 7a152a4abd205aecfe4cffe3d53a22fa73830a55..3f23830273440193211ec4b9ff8ccff5e3f8b430 100644 (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
index 2d014394a6aa1d49ed4efaeda0261dc530ab262f..f3e8f3b5743410365ca34ba814c5ab846e331f38 100644 (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
  */
index e5a3a18920c4b7527a9409c989375546de6217ec..bd681a9f3c497858795774d2315c33ebb43870ce 100644 (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;