wavpackdec: Add floating point format support
authorVladimir Menshakov <vladimir.menshakov@gmail.com>
Sun, 7 Mar 2021 21:25:01 +0000 (21:25 +0000)
committerSebastian Dröge <sebastian@centricular.com>
Mon, 8 Mar 2021 13:19:57 +0000 (15:19 +0200)
This commit negotiate F32 audio format if MODE_FLOAT used in wavpack file.
Wavpack float mode is always in 32-bit IEEE format.

The following pipeline plays distorted audio if source file is encoded in float mode:
gst-launch-1.0 filesrc ... ! wavpackparse ! wavpackdec ! pulsesink

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/894>

docs/gst_plugins_cache.json
ext/wavpack/gstwavpackdec.c
ext/wavpack/gstwavpackdec.h

index 615c7b9..1b5c909 100644 (file)
                         "presence": "always"
                     },
                     "src": {
-                        "caps": "audio/x-raw:\n         format: S8\n         layout: interleaved\n       channels: [ 1, 8 ]\n           rate: [ 6000, 192000 ]\naudio/x-raw:\n         format: S16LE\n         layout: interleaved\n       channels: [ 1, 8 ]\n           rate: [ 6000, 192000 ]\naudio/x-raw:\n         format: S32LE\n         layout: interleaved\n       channels: [ 1, 8 ]\n           rate: [ 6000, 192000 ]\n",
+                        "caps": "audio/x-raw:\n         format: S8\n         layout: interleaved\n       channels: [ 1, 8 ]\n           rate: [ 6000, 192000 ]\naudio/x-raw:\n         format: S16LE\n         layout: interleaved\n       channels: [ 1, 8 ]\n           rate: [ 6000, 192000 ]\naudio/x-raw:\n         format: S32LE\n         layout: interleaved\n       channels: [ 1, 8 ]\n           rate: [ 6000, 192000 ]\naudio/x-raw:\n         format: F32LE\n         layout: interleaved\n       channels: [ 1, 8 ]\n           rate: [ 6000, 192000 ]\n",
                         "direction": "src",
                         "presence": "always"
                     }
index a87774a..9fc32d8 100644 (file)
@@ -82,6 +82,10 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
         "audio/x-raw, "
         "format = (string) " GST_AUDIO_NE (S32) ", "
         "layout = (string) interleaved, "
+        "channels = (int) [ 1, 8 ], " "rate = (int) [ 6000, 192000 ]; "
+        "audio/x-raw, "
+        "format = (string) " GST_AUDIO_NE (F32) ", "
+        "layout = (string) interleaved, "
         "channels = (int) [ 1, 8 ], " "rate = (int) [ 6000, 192000 ]")
     );
 
@@ -131,6 +135,7 @@ gst_wavpack_dec_reset (GstWavpackDec * dec)
   dec->channel_mask = 0;
   dec->sample_rate = 0;
   dec->depth = 0;
+  dec->mode_float = FALSE;
 }
 
 static void
@@ -208,7 +213,9 @@ gst_wavpack_dec_negotiate (GstWavpackDec * dec)
       break;
     case 24:
     case 32:
-      fmt = _GST_AUDIO_FORMAT_NE (S32);
+      fmt =
+          dec->mode_float ? _GST_AUDIO_FORMAT_NE (F32) :
+          _GST_AUDIO_FORMAT_NE (S32);
       dec->width = 32;
       break;
     default:
@@ -277,7 +284,8 @@ gst_wavpack_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
   WavpackHeader wph;
   int32_t decoded, unpacked_size;
   gboolean format_changed;
-  gint width, depth, i, j, max;
+  gint width, depth, i, j, max, wavpack_mode;
+  gboolean mode_float;
   gint32 *dec_data = NULL;
   guint8 *out_data;
   GstMapInfo map, omap;
@@ -323,10 +331,14 @@ gst_wavpack_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
 
   g_assert (dec->context != NULL);
 
+  wavpack_mode = WavpackGetMode (dec->context);
+  mode_float = (wavpack_mode & MODE_FLOAT) == MODE_FLOAT;
+
   format_changed =
       (dec->sample_rate != WavpackGetSampleRate (dec->context)) ||
       (dec->channels != WavpackGetNumChannels (dec->context)) ||
       (dec->depth != WavpackGetBytesPerSample (dec->context) * 8) ||
+      (dec->mode_float != mode_float) ||
       (dec->channel_mask != WavpackGetChannelMask (dec->context));
 
   if (!gst_pad_has_current_caps (GST_AUDIO_DECODER_SRC_PAD (dec)) ||
@@ -336,6 +348,7 @@ gst_wavpack_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
     dec->sample_rate = WavpackGetSampleRate (dec->context);
     dec->channels = WavpackGetNumChannels (dec->context);
     dec->depth = WavpackGetBytesPerSample (dec->context) * 8;
+    dec->mode_float = mode_float;
 
     channel_mask = WavpackGetChannelMask (dec->context);
     if (channel_mask == 0)
index 3cba002..726e5c2 100644 (file)
@@ -52,6 +52,7 @@ struct _GstWavpackDec
   gint width;
   gint channels;
   gint channel_mask;
+  gboolean mode_float;
 
   gint channel_reorder_map[64];