s = gst_caps_get_structure (caps, 0);
/* template ensures 16 or 32 */
gst_structure_get_int (s, "width", &width);
+
+ GST_INFO_OBJECT (vd, "using %s with %d channels and %d bit audio depth",
+ gst_structure_get_name (s), vd->vi.channels, width);
}
gst_caps_unref (caps);
}
vd->width = width >> 3;
+ /* select a copy_samples function, this way we can have specialized versions
+ * for mono/stereo and avoid the depth switch in tremor case */
+ vd->copy_samples = get_copy_sample_func (vd->vi.channels, vd->width);
+
caps = gst_caps_copy (gst_pad_get_pad_template_caps (vd->srcpad));
gst_caps_set_simple (caps, "rate", G_TYPE_INT, vd->vi.rate,
"channels", G_TYPE_INT, vd->vi.channels,
goto wrong_samples;
/* copy samples in buffer */
- copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm, sample_count,
- vd->vi.channels, vd->width);
+ vd->copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm,
+ sample_count, vd->vi.channels, vd->width);
GST_LOG_OBJECT (vd, "setting output size to %d", size);
GST_BUFFER_SIZE (out) = size;
#include "config.h"
#endif
+#include <string.h>
#include "gstvorbisdeclib.h"
#ifndef TREMOR
/* These samples can be outside of the float -1.0 -- 1.0 range, this
* is allowed, downstream elements are supposed to clip */
-void
-copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
+static void
+copy_samples_m (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
gint channels, gint width)
{
- gint i, j;
+ memcpy (out, in[0], samples * sizeof (float));
+}
- g_assert (width == 4);
+static void
+copy_samples_s (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
+ gint channels, gint width)
+{
+#ifdef GST_VORBIS_DEC_SEQUENTIAL
+ memcpy (out, in[0], samples * sizeof (float));
+ out += samples;
+ memcpy (out, in[1], samples * sizeof (float));
+#else
+ gint j;
+
+ for (j = 0; j < samples; j++) {
+ *out++ = in[0][j];
+ *out++ = in[1][j];
+ }
+#endif
+}
+static void
+copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
+ gint channels, gint width)
+{
#ifdef GST_VORBIS_DEC_SEQUENTIAL
+ gint i;
+
for (i = 0; i < channels; i++) {
memcpy (out, in[i], samples * sizeof (float));
out += samples;
}
#else
+ gint i, j;
+
for (j = 0; j < samples; j++) {
for (i = 0; i < channels; i++) {
*out++ = in[i][j];
#endif
}
+CopySampleFunc
+get_copy_sample_func (gint channels, gint width)
+{
+ CopySampleFunc f = NULL;
+
+ g_assert (width == 4);
+
+ switch (channels) {
+ case 1:
+ f = copy_samples_m;
+ break;
+ case 2:
+ f = copy_samples_s;
+ break;
+ default:
+ f = copy_samples;
+ break;
+ }
+
+ return f;
+}
+
#else
/* Taken from Tremor, misc.h */
#endif
static void
-copy_samples_32 (gint32 * out, ogg_int32_t ** in, guint samples, gint channels)
+copy_samples_32_m (vorbis_sample_t * _out, vorbis_sample_t ** _in,
+ guint samples, gint channels, gint width)
{
+ gint32 *out = (gint32 *) _out;
+ ogg_int32_t **in = (ogg_int32_t **) _in;
+ gint j;
+
+ for (j = 0; j < samples; j++) {
+ *out++ = CLIP_TO_15 (in[0][j] >> 9);
+ }
+}
+
+static void
+copy_samples_32_s (vorbis_sample_t * _out, vorbis_sample_t ** _in,
+ guint samples, gint channels, gint width)
+{
+ gint32 *out = (gint32 *) _out;
+ ogg_int32_t **in = (ogg_int32_t **) _in;
+ gint j;
+
+ for (j = 0; j < samples; j++) {
+ *out++ = CLIP_TO_15 (in[0][j] >> 9);
+ *out++ = CLIP_TO_15 (in[1][j] >> 9);
+ }
+}
+
+static void
+copy_samples_32 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples,
+ gint channels, gint width)
+{
+ gint32 *out = (gint32 *) _out;
+ ogg_int32_t **in = (ogg_int32_t **) _in;
gint i, j;
for (j = 0; j < samples; j++) {
}
static void
-copy_samples_16 (gint16 * out, ogg_int32_t ** in, guint samples, gint channels)
+copy_samples_16_m (vorbis_sample_t * _out, vorbis_sample_t ** _in,
+ guint samples, gint channels, gint width)
+{
+ gint16 *out = (gint16 *) _out;
+ ogg_int32_t **in = (ogg_int32_t **) _in;
+ gint j;
+
+ for (j = 0; j < samples; j++) {
+ *out++ = CLIP_TO_15 (in[0][j] >> 9);
+ }
+}
+
+static void
+copy_samples_16_s (vorbis_sample_t * _out, vorbis_sample_t ** _in,
+ guint samples, gint channels, gint width)
+{
+ gint16 *out = (gint16 *) _out;
+ ogg_int32_t **in = (ogg_int32_t **) _in;
+ gint j;
+
+ for (j = 0; j < samples; j++) {
+ *out++ = CLIP_TO_15 (in[0][j] >> 9);
+ *out++ = CLIP_TO_15 (in[1][j] >> 9);
+ }
+}
+
+static void
+copy_samples_16 (vorbis_sample_t * _out, vorbis_sample_t ** _in, guint samples,
+ gint channels, gint width)
{
+ gint16 *out = (gint16 *) _out;
+ ogg_int32_t **in = (ogg_int32_t **) _in;
gint i, j;
for (j = 0; j < samples; j++) {
}
}
-void
-copy_samples (vorbis_sample_t * out, vorbis_sample_t ** in, guint samples,
- gint channels, gint width)
+CopySampleFunc
+get_copy_sample_func (gint channels, gint width)
{
+ CopySampleFunc f = NULL;
+
if (width == 4) {
- copy_samples_32 ((gint32 *) out, in, samples, channels);
+ switch (channels) {
+ case 1:
+ f = copy_samples_32_m;
+ break;
+ case 2:
+ f = copy_samples_32_s;
+ break;
+ default:
+ f = copy_samples_32;
+ break;
+ }
} else if (width == 2) {
- copy_samples_16 ((gint16 *) out, in, samples, channels);
+ switch (channels) {
+ case 1:
+ f = copy_samples_16_m;
+ break;
+ case 2:
+ f = copy_samples_16_s;
+ break;
+ default:
+ f = copy_samples_16;
+ break;
+ }
} else {
g_assert_not_reached ();
}
+ return f;
}
#endif
#define GST_VORBIS_DEC_DESCRIPTION "decode raw vorbis streams to float audio"
#define GST_VORBIS_DEC_SRC_CAPS \
- GST_STATIC_CAPS ("audio/x-raw-float, " "rate = (int) [ 1, MAX ], " \
- "channels = (int) [ 1, 256 ], " "endianness = (int) BYTE_ORDER, " \
+ GST_STATIC_CAPS ("audio/x-raw-float, " \
+ "rate = (int) [ 1, MAX ], " \
+ "channels = (int) [ 1, 256 ], " \
+ "endianness = (int) BYTE_ORDER, " \
"width = (int) 32")
#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (32)
"channels = (int) [ 1, 6 ], " \
"endianness = (int) BYTE_ORDER, " \
"width = (int) { 16, 32 }, " \
- "depth = (int) 16, " "signed = (boolean) true")
+ "depth = (int) 16, " \
+ "signed = (boolean) true")
#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (16)
#endif
-void copy_samples (vorbis_sample_t *out, vorbis_sample_t **in,
+typedef void (*CopySampleFunc)(vorbis_sample_t *out, vorbis_sample_t **in,
guint samples, gint channels, gint width);
+CopySampleFunc get_copy_sample_func (gint channels, gint width);
#endif /* __GST_VORBIS_DEC_LIB_H__ */