gst-libs/gst/riff/riff-media.c: Correctly support 4, 6 and 8 channels with normal...
authorSebastian Dröge <slomo@circular-chaos.org>
Tue, 17 Apr 2007 01:56:07 +0000 (01:56 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Tue, 17 Apr 2007 01:56:07 +0000 (01:56 +0000)
Original commit message from CVS:
* gst-libs/gst/riff/riff-media.c: (gst_riff_create_audio_caps):
Correctly support 4, 6 and 8 channels with normal PCM and float
wav files.
Fix the depth and signedness calculation in extensible wav files and
also handle 1, 2, 4, 6, 8 channels here when a file without channel
mask is found.
Add support for float, alaw and mulaw in extensible wav files.
This allows correct playback of all but 5 files from
http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html
(gst_riff_create_audio_template_caps):
Add voxware and float formats to the template caps.

ChangeLog
gst-libs/gst/riff/riff-media.c

index 4c0e8c9..e0d7f8b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2007-04-17  Sebastian Dröge  <slomo@circular-chaos.org>
 
+       * gst-libs/gst/riff/riff-media.c: (gst_riff_create_audio_caps):
+       Correctly support 4, 6 and 8 channels with normal PCM and float
+       wav files.
+
+       Fix the depth and signedness calculation in extensible wav files and
+       also handle 1, 2, 4, 6, 8 channels here when a file without channel
+       mask is found.
+
+       Add support for float, alaw and mulaw in extensible wav files.
+
+       This allows correct playback of all but 5 files from
+       http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html
+       
+       (gst_riff_create_audio_template_caps):
+       Add voxware and float formats to the template caps.     
+
+2007-04-17  Sebastian Dröge  <slomo@circular-chaos.org>
+
        Patch by: Vincent Torri <vtorri at univ-evry dot fr>
 
        * ext/pango/gstclockoverlay.c: (gst_clock_overlay_render_time):
index d765a3f..2db3e63 100644 (file)
@@ -759,6 +759,8 @@ gst_riff_create_audio_caps (guint16 codec_id,
         gint wd = ba * 8 / ch;
         gint ws;
 
+        channels_max = 8;
+
         if (strf->size > 32) {
           GST_WARNING ("invalid depth (%d) of pcm audio, overwriting.",
               strf->size);
@@ -787,6 +789,9 @@ gst_riff_create_audio_caps (guint16 codec_id,
             case 6:
               channel_mask = 0x3f;
               break;
+            case 8:
+              channel_mask = 0xff;
+              break;
             default:
               GST_WARNING ("don't know default layout for %d channels", ch);
               channel_mask = 0;
@@ -827,6 +832,8 @@ gst_riff_create_audio_caps (guint16 codec_id,
         gint ch = strf->channels;
         gint wd = ba * 8 / ch;
 
+        channels_max = 8;
+
         caps = gst_caps_new_simple ("audio/x-raw-float",
             "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
             "channels", G_TYPE_INT, ch, "width", G_TYPE_INT, wd, NULL);
@@ -846,6 +853,9 @@ gst_riff_create_audio_caps (guint16 codec_id,
             case 6:
               channel_mask = 0x3f;
               break;
+            case 8:
+              channel_mask = 0xff;
+              break;
             default:
               GST_WARNING ("don't know default layout for %d channels", ch);
               channel_mask = 0;
@@ -1043,6 +1053,8 @@ gst_riff_create_audio_caps (guint16 codec_id,
       guint32 subformat_guid[4];
       const guint8 *data;
 
+      channels_max = 8;
+
       /* should be at least 22 bytes */
       if (strf_data == NULL || GST_BUFFER_SIZE (strf_data) < 22) {
         GST_WARNING ("WAVE_FORMAT_EXTENSIBLE data size is %d (expected: 22)",
@@ -1071,20 +1083,39 @@ gst_riff_create_audio_caps (guint16 codec_id,
           if (strf != NULL) {
             gint ba = strf->blockalign;
             gint ws = strf->size;
-            gint depth = ws;
+            gint wd = ba * 8 / strf->channels;
 
             if (valid_bits_per_sample != 0)
-              depth = valid_bits_per_sample;
+              ws = valid_bits_per_sample;
 
             caps = gst_caps_new_simple ("audio/x-raw-int",
                 "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
                 "channels", G_TYPE_INT, strf->channels,
-                "width", G_TYPE_INT, (int) (ba * 8 / strf->channels),
-                "depth", G_TYPE_INT, depth,
+                "width", G_TYPE_INT, wd,
+                "depth", G_TYPE_INT, ws,
                 "rate", G_TYPE_INT, strf->rate,
-                "signed", G_TYPE_BOOLEAN, (depth > 8) ? TRUE : FALSE, NULL);
+                "signed", G_TYPE_BOOLEAN, wd != 8, NULL);
+
+            /* If channel_mask == 0 and channels <= 2, 4, 6 or 8 let's
+             * assume default layout as some wav files don't have the
+             * channel mask set */
+
+            if (channel_mask == 0) {
+              switch (strf->channels) {
+                case 4:
+                  channel_mask = 0x33;
+                  break;
+                case 6:
+                  channel_mask = 0x3f;
+                  break;
+                case 8:
+                  channel_mask = 0xff;
+                  break;
+              }
+            }
 
-            if (!gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
+            if ((channel_mask != 0 || strf->channels > 2) &&
+                !gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
               GST_WARNING ("failed to add channel layout");
               gst_caps_unref (caps);
               caps = NULL;
@@ -1097,7 +1128,97 @@ gst_riff_create_audio_caps (guint16 codec_id,
             }
           }
         } else if (subformat_guid[0] == 0x00000003) {
-          GST_DEBUG ("FIXME: handle IEEE float format");
+          GST_DEBUG ("FLOAT");
+          if (strf != NULL) {
+            gint ba = strf->blockalign;
+            gint ws = strf->size;
+            gint wd = ba * 8 / strf->channels;
+
+            if (valid_bits_per_sample != 0)
+              ws = valid_bits_per_sample;
+
+            caps = gst_caps_new_simple ("audio/x-raw-float",
+                "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
+                "channels", G_TYPE_INT, strf->channels,
+                "width", G_TYPE_INT, wd, "rate", G_TYPE_INT, strf->rate, NULL);
+
+            /* If channel_mask == 0 and channels <= 2, 4, 6 or 8 let's
+             * assume default layout as some wav files don't have the
+             * channel mask set */
+
+            if (channel_mask == 0) {
+              switch (strf->channels) {
+                case 4:
+                  channel_mask = 0x33;
+                  break;
+                case 6:
+                  channel_mask = 0x3f;
+                  break;
+                case 8:
+                  channel_mask = 0xff;
+                  break;
+              }
+            }
+
+            if ((channel_mask != 0 || strf->channels > 2) &&
+                !gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
+              GST_WARNING ("failed to add channel layout");
+              gst_caps_unref (caps);
+              caps = NULL;
+            }
+            rate_chan = FALSE;
+
+            if (codec_name) {
+              *codec_name =
+                  g_strdup_printf ("Uncompressed %d-bit IEEE float audio",
+                  strf->size);
+            }
+          }
+        } else if (subformat_guid[0] == 00000006) {
+          GST_DEBUG ("ALAW");
+          if (strf != NULL) {
+            if (strf->size != 8) {
+              GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
+                  strf->size);
+              strf->size = 8;
+              strf->av_bps = 8;
+              strf->blockalign = strf->av_bps * strf->channels;
+            }
+            if (strf->av_bps == 0 || strf->blockalign == 0) {
+              GST_WARNING
+                  ("fixing av_bps (%d) and blockalign (%d) of alaw audio",
+                  strf->av_bps, strf->blockalign);
+              strf->av_bps = strf->size;
+              strf->blockalign = strf->av_bps * strf->channels;
+            }
+          }
+          rate_max = 48000;
+          caps = gst_caps_new_simple ("audio/x-alaw", NULL);
+
+          if (codec_name)
+            *codec_name = g_strdup ("A-law audio");
+        } else if (subformat_guid[0] == 0x00000007) {
+          GST_DEBUG ("MULAW");
+          if (strf != NULL) {
+            if (strf->size != 8) {
+              GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
+                  strf->size);
+              strf->size = 8;
+              strf->av_bps = 8;
+              strf->blockalign = strf->av_bps * strf->channels;
+            }
+            if (strf->av_bps == 0 || strf->blockalign == 0) {
+              GST_WARNING
+                  ("fixing av_bps (%d) and blockalign (%d) of mulaw audio",
+                  strf->av_bps, strf->blockalign);
+              strf->av_bps = strf->size;
+              strf->blockalign = strf->av_bps * strf->channels;
+            }
+          }
+          rate_max = 48000;
+          caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
+          if (codec_name)
+            *codec_name = g_strdup ("Mu-law audio");
         } else if (subformat_guid[0] == 0x00000092) {
           GST_DEBUG ("FIXME: handle DOLBY AC3 SPDIF format");
         }
@@ -1316,7 +1437,9 @@ gst_riff_create_audio_template_caps (void)
     GST_RIFF_WAVE_FORMAT_WMAV1,
     GST_RIFF_WAVE_FORMAT_WMAV2,
     GST_RIFF_WAVE_FORMAT_WMAV3,
-    GST_RIFF_WAVE_FORMAT_SONY_ATRAC3
+    GST_RIFF_WAVE_FORMAT_SONY_ATRAC3,
+    GST_RIFF_WAVE_FORMAT_IEEE_FLOAT,
+    GST_RIFF_WAVE_FORMAT_VOXWARE
         /* FILL ME */
   };
   guint i;