[MPlayer-users] s32_le (flac) falls back to s16_le instead of s24_3le

Mervin Beng mervinb at mail.com
Tue Aug 3 15:23:12 CEST 2010


(I am not sure how to reply to a thread. Please excuse me. If someone
can give me a pointer, I will do it right next time.)

It was pointed out to me that my first patch to this issue did not
format s24le correctly to s32le. Instead it formatted it down to s16le.

I have added a few lines to ao_alsa.c, and changed two lines in
ao_pulse.c. I believe the fallbacks will now be correct.

- If a card supports s32le and s16le, any 24-bit audio (3-byte or
4-byte) is sent out in s32le.

- If a card supports s24_3le (usb audio cards) and s16le, any 24-bit
audio (3-byte or 4-byte) is sent out in s25_3le.

$ git diff libao2.orig/ libao2/
diff --git a/libao2.orig/ao_alsa.c b/libao2/ao_alsa.c
index 57f0bd0..fa59b7f 100644
--- a/libao2.orig/ao_alsa.c
+++ b/libao2/ao_alsa.c
@@ -512,17 +512,30 @@ static int init(int rate_hz, int channels, int
format, int
       }
 
       /* workaround for nonsupported formats
-        sets default format to S16_LE if the given formats aren't
supported */
+        sets default format to S24_3LE or S16_LE
+        if the given formats aren't supported */
       if ((err = snd_pcm_hw_params_test_format(alsa_handler,
alsa_hwparams,
                                              alsa_format)) < 0)
       {
          mp_msg(MSGT_AO,MSGL_INFO,
                MSGTR_AO_ALSA_FormatNotSupportedByHardware,
af_fmt2str_short(for
-         alsa_format = SND_PCM_FORMAT_S16_LE;
+         if ((err = snd_pcm_hw_params_test_format(alsa_handler,
alsa_hwparams,
+                                             SND_PCM_FORMAT_S32_LE)) ==
0)
+           alsa_format = SND_PCM_FORMAT_S32_LE;
+         else if ((err = snd_pcm_hw_params_test_format(alsa_handler, 
+                                             alsa_hwparams,
+                                             SND_PCM_FORMAT_S24_3LE))
== 0)
+           alsa_format = SND_PCM_FORMAT_S24_3LE;
+         else
+           alsa_format = SND_PCM_FORMAT_S16_LE;
          if (AF_FORMAT_IS_AC3(ao_data.format))
            ao_data.format = AF_FORMAT_AC3_LE;
+         else if (alsa_format == SND_PCM_FORMAT_S32_LE)
+           ao_data.format = AF_FORMAT_S32_LE;
+         else if (alsa_format == SND_PCM_FORMAT_S24_LE)
+           ao_data.format = AF_FORMAT_S24_LE;
          else
-         ao_data.format = AF_FORMAT_S16_LE;
+           ao_data.format = AF_FORMAT_S16_LE;
       }
 
       if ((err = snd_pcm_hw_params_set_format(alsa_handler,
alsa_hwparams,
diff --git a/libao2.orig/ao_pulse.c b/libao2/ao_pulse.c
index a07bf31..6b7fa30 100644
--- a/libao2.orig/ao_pulse.c
+++ b/libao2/ao_pulse.c
@@ -117,8 +117,6 @@ static const struct format_map_s {
     int mp_format;
     pa_sample_format_t pa_format;
 } format_maps[] = {
-    {AF_FORMAT_S16_LE, PA_SAMPLE_S16LE},
-    {AF_FORMAT_S16_BE, PA_SAMPLE_S16BE},
 #ifdef PA_SAMPLE_S32NE
     {AF_FORMAT_S32_LE, PA_SAMPLE_S32LE},
     {AF_FORMAT_S32_BE, PA_SAMPLE_S32BE},
@@ -127,6 +125,8 @@ static const struct format_map_s {
     {AF_FORMAT_FLOAT_LE, PA_SAMPLE_FLOAT32LE},
     {AF_FORMAT_FLOAT_BE, PA_SAMPLE_FLOAT32BE},
 #endif
+    {AF_FORMAT_S16_LE, PA_SAMPLE_S16LE},
+    {AF_FORMAT_S16_BE, PA_SAMPLE_S16BE},
     {AF_FORMAT_U8, PA_SAMPLE_U8},
     {AF_FORMAT_MU_LAW, PA_SAMPLE_ULAW},
     {AF_FORMAT_A_LAW, PA_SAMPLE_ALAW},

Cheers,
Mervin



More information about the MPlayer-users mailing list