#include <string.h>
#include "gstchannelmix.h"
-#include "gstaudioquantize.h"
#include "audioconvert.h"
#include "gstaudioconvertorc.h"
+typedef void (*AudioConvertFunc) (gpointer dst, const gpointer src, gint count);
+
/**
* int/int int/float float/int float/float
*
* quantize S32 S32
* pack S32 F64 S32 F64
*/
+struct _GstAudioConverter
+{
+ GstAudioInfo in;
+ GstAudioInfo out;
+
+ GstStructure *config;
+
+ gboolean in_default;
+
+ AudioConvertFunc convert_in;
+
+ GstAudioFormat mix_format;
+ gboolean mix_passthrough;
+ GstChannelMix *mix;
+
+ AudioConvertFunc convert_out;
+
+ GstAudioQuantize *quant;
+
+ gboolean out_default;
+
+ gboolean passthrough;
+
+ gpointer tmpbuf;
+ gpointer tmpbuf2;
+ gint tmpbufsize;
+};
+
+/*
+static guint
+get_opt_uint (GstAudioConverter * convert, const gchar * opt, guint def)
+{
+ guint res;
+ if (!gst_structure_get_uint (convert->config, opt, &res))
+ res = def;
+ return res;
+}
+*/
+
+static gint
+get_opt_enum (GstAudioConverter * convert, const gchar * opt, GType type,
+ gint def)
+{
+ gint res;
+ if (!gst_structure_get_enum (convert->config, opt, type, &res))
+ res = def;
+ return res;
+}
+
+#define DEFAULT_OPT_DITHER_METHOD GST_AUDIO_DITHER_NONE
+#define DEFAULT_OPT_NOISE_SHAPING_METHOD GST_AUDIO_NOISE_SHAPING_NONE
+#define DEFAULT_OPT_QUANTIZATION 1
+
+#define GET_OPT_DITHER_METHOD(c) get_opt_enum(c, \
+ GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD, \
+ DEFAULT_OPT_DITHER_METHOD)
+#define GET_OPT_NOISE_SHAPING_METHOD(c) get_opt_enum(c, \
+ GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD, GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, \
+ DEFAULT_OPT_NOISE_SHAPING_METHOD)
+#define GET_OPT_QUANTIZATION(c) get_opt_uint(c, \
+ GST_AUDIO_CONVERTER_OPT_QUANTIZATION, DEFAULT_OPT_QUANTIZATION)
+
+static gboolean
+copy_config (GQuark field_id, const GValue * value, gpointer user_data)
+{
+ GstAudioConverter *convert = user_data;
+
+ gst_structure_id_set_value (convert->config, field_id, value);
+
+ return TRUE;
+}
+
+/**
+ * gst_audio_converter_set_config:
+ * @convert: a #GstAudioConverter
+ * @config: (transfer full): a #GstStructure
+ *
+ * Set @config as extra configuraion for @convert.
+ *
+ * If the parameters in @config can not be set exactly, this function returns
+ * %FALSE and will try to update as much state as possible. The new state can
+ * then be retrieved and refined with gst_audio_converter_get_config().
+ *
+ * Look at the #GST_AUDIO_CONVERTER_OPT_* fields to check valid configuration
+ * option and values.
+ *
+ * Returns: %TRUE when @config could be set.
+ */
gboolean
-audio_convert_prepare_context (AudioConvertCtx * ctx, GstAudioInfo * in,
- GstAudioInfo * out, GstAudioDitherMethod dither,
- GstAudioNoiseShapingMethod ns)
+gst_audio_converter_set_config (GstAudioConverter * convert,
+ GstStructure * config)
+{
+ g_return_val_if_fail (convert != NULL, FALSE);
+ g_return_val_if_fail (config != NULL, FALSE);
+
+ gst_structure_foreach (config, copy_config, convert);
+ gst_structure_free (config);
+
+ return TRUE;
+}
+
+/**
+ * gst_audio_converter_get_config:
+ * @convert: a #GstAudioConverter
+ *
+ * Get the current configuration of @convert.
+ *
+ * Returns: a #GstStructure that remains valid for as long as @convert is valid
+ * or until gst_audio_converter_set_config() is called.
+ */
+const GstStructure *
+gst_audio_converter_get_config (GstAudioConverter * convert)
+{
+ g_return_val_if_fail (convert != NULL, NULL);
+
+ return convert->config;
+}
+
+
+/**
+ *
+ */
+GstAudioConverter *
+gst_audio_converter_new (GstAudioInfo * in, GstAudioInfo * out,
+ GstStructure * config)
{
+ GstAudioConverter *convert;
gint in_depth, out_depth;
GstChannelMixFlags flags;
gboolean in_int, out_int;
GstAudioFormat format;
+ GstAudioDitherMethod dither;
+ GstAudioNoiseShapingMethod ns;
- g_return_val_if_fail (ctx != NULL, FALSE);
g_return_val_if_fail (in != NULL, FALSE);
g_return_val_if_fail (out != NULL, FALSE);
- /* first clean the existing context */
- audio_convert_clean_context (ctx);
if ((GST_AUDIO_INFO_CHANNELS (in) != GST_AUDIO_INFO_CHANNELS (out)) &&
(GST_AUDIO_INFO_IS_UNPOSITIONED (in)
|| GST_AUDIO_INFO_IS_UNPOSITIONED (out)))
goto unpositioned;
- ctx->in = *in;
- ctx->out = *out;
+ convert = g_slice_new0 (GstAudioConverter);
+
+ convert->in = *in;
+ convert->out = *out;
+
+ /* default config */
+ convert->config = gst_structure_new_empty ("GstAudioConverter");
+ if (config)
+ gst_audio_converter_set_config (convert, config);
+
+ dither = GET_OPT_DITHER_METHOD (convert);
+ ns = GET_OPT_NOISE_SHAPING_METHOD (convert);
GST_INFO ("unitsizes: %d -> %d", in->bpf, out->bpf);
/* step 1, unpack */
format = in->finfo->unpack_format;
- ctx->in_default = in->finfo->unpack_format == in->finfo->format;
+ convert->in_default = in->finfo->unpack_format == in->finfo->format;
GST_INFO ("unpack format %s to %s",
gst_audio_format_to_string (in->finfo->format),
gst_audio_format_to_string (format));
/* step 2, optional convert from S32 to F64 for channel mix */
if (in_int && !out_int) {
GST_INFO ("convert S32 to F64");
- ctx->convert_in = (AudioConvertFunc) audio_convert_orc_s32_to_double;
+ convert->convert_in = (AudioConvertFunc) audio_convert_orc_s32_to_double;
format = GST_AUDIO_FORMAT_F64;
}
/* step 3, channel mix */
- ctx->mix_format = format;
- ctx->mix = gst_channel_mix_new (flags, in->channels, in->position,
+ convert->mix_format = format;
+ convert->mix = gst_channel_mix_new (flags, in->channels, in->position,
out->channels, out->position);
- ctx->mix_passthrough = gst_channel_mix_is_passthrough (ctx->mix);
+ convert->mix_passthrough = gst_channel_mix_is_passthrough (convert->mix);
GST_INFO ("mix format %s, passthrough %d, in_channels %d, out_channels %d",
- gst_audio_format_to_string (format), ctx->mix_passthrough,
+ gst_audio_format_to_string (format), convert->mix_passthrough,
in->channels, out->channels);
/* step 4, optional convert for quantize */
if (!in_int && out_int) {
GST_INFO ("convert F64 to S32");
- ctx->convert_out = (AudioConvertFunc) audio_convert_orc_double_to_s32;
+ convert->convert_out = (AudioConvertFunc) audio_convert_orc_double_to_s32;
format = GST_AUDIO_FORMAT_S32;
}
/* step 5, optional quantize */
* the rounding correct */
if (out_int && out_depth < 32) {
GST_INFO ("quantize to %d bits, dither %d, ns %d", out_depth, dither, ns);
- ctx->quant = gst_audio_quantize_new (dither, ns, 0, format,
+ convert->quant = gst_audio_quantize_new (dither, ns, 0, format,
out->channels, 1U << (32 - out_depth));
}
/* step 6, pack */
g_assert (out->finfo->unpack_format == format);
- ctx->out_default = format == out->finfo->format;
+ convert->out_default = format == out->finfo->format;
GST_INFO ("pack format %s to %s", gst_audio_format_to_string (format),
gst_audio_format_to_string (out->finfo->format));
/* optimize */
- if (out->finfo->format == in->finfo->format && ctx->mix_passthrough) {
+ if (out->finfo->format == in->finfo->format && convert->mix_passthrough) {
GST_INFO ("same formats and passthrough mixing -> passthrough");
- ctx->passthrough = TRUE;
+ convert->passthrough = TRUE;
}
- return TRUE;
+ return convert;
/* ERRORS */
unpositioned:
{
GST_WARNING ("unpositioned channels");
- return FALSE;
+ return NULL;
}
}
-gboolean
-audio_convert_clean_context (AudioConvertCtx * ctx)
+void
+gst_audio_converter_free (GstAudioConverter * convert)
{
- g_return_val_if_fail (ctx != NULL, FALSE);
-
- if (ctx->quant)
- gst_audio_quantize_free (ctx->quant);
- ctx->quant = NULL;
- if (ctx->mix)
- gst_channel_mix_free (ctx->mix);
- ctx->mix = NULL;
- gst_audio_info_init (&ctx->in);
- gst_audio_info_init (&ctx->out);
- ctx->convert_in = NULL;
- ctx->convert_out = NULL;
-
- g_free (ctx->tmpbuf);
- g_free (ctx->tmpbuf2);
- ctx->tmpbuf = NULL;
- ctx->tmpbuf2 = NULL;
- ctx->tmpbufsize = 0;
+ g_return_if_fail (convert != NULL);
- return TRUE;
+ if (convert->quant)
+ gst_audio_quantize_free (convert->quant);
+ if (convert->mix)
+ gst_channel_mix_free (convert->mix);
+ gst_audio_info_init (&convert->in);
+ gst_audio_info_init (&convert->out);
+
+ g_free (convert->tmpbuf);
+ g_free (convert->tmpbuf2);
+ gst_structure_free (convert->config);
+
+ g_slice_free (GstAudioConverter, convert);
}
gboolean
-audio_convert_get_sizes (AudioConvertCtx * ctx, gint samples, gint * srcsize,
- gint * dstsize)
+gst_audio_converter_get_sizes (GstAudioConverter * convert, gint samples,
+ gint * srcsize, gint * dstsize)
{
- g_return_val_if_fail (ctx != NULL, FALSE);
+ g_return_val_if_fail (convert != NULL, FALSE);
if (srcsize)
- *srcsize = samples * ctx->in.bpf;
+ *srcsize = samples * convert->in.bpf;
if (dstsize)
- *dstsize = samples * ctx->out.bpf;
+ *dstsize = samples * convert->out.bpf;
return TRUE;
}
gboolean
-audio_convert_convert (AudioConvertCtx * ctx, gpointer src,
- gpointer dst, gint samples, gboolean src_writable)
+gst_audio_converter_samples (GstAudioConverter * convert,
+ GstAudioConverterFlags flags, gpointer src, gpointer dst, gint samples)
{
guint size;
gpointer outbuf, tmpbuf, tmpbuf2;
- g_return_val_if_fail (ctx != NULL, FALSE);
+ g_return_val_if_fail (convert != NULL, FALSE);
g_return_val_if_fail (src != NULL, FALSE);
g_return_val_if_fail (dst != NULL, FALSE);
g_return_val_if_fail (samples >= 0, FALSE);
if (samples == 0)
return TRUE;
- if (ctx->passthrough) {
- memcpy (dst, src, samples * ctx->in.bpf);
+ if (convert->passthrough) {
+ memcpy (dst, src, samples * convert->in.bpf);
return TRUE;
}
- size = sizeof (gdouble) * samples * MAX (ctx->in.channels, ctx->out.channels);
+ size =
+ sizeof (gdouble) * samples * MAX (convert->in.channels,
+ convert->out.channels);
- if (size > ctx->tmpbufsize) {
- ctx->tmpbuf = g_realloc (ctx->tmpbuf, size);
- ctx->tmpbuf2 = g_realloc (ctx->tmpbuf2, size);
- ctx->tmpbufsize = size;
+ if (size > convert->tmpbufsize) {
+ convert->tmpbuf = g_realloc (convert->tmpbuf, size);
+ convert->tmpbuf2 = g_realloc (convert->tmpbuf2, size);
+ convert->tmpbufsize = size;
}
- tmpbuf = ctx->tmpbuf;
- tmpbuf2 = ctx->tmpbuf2;
+ tmpbuf = convert->tmpbuf;
+ tmpbuf2 = convert->tmpbuf2;
/* 1. unpack */
- if (!ctx->in_default) {
- if (!ctx->convert_in && ctx->mix_passthrough && !ctx->convert_out
- && !ctx->quant && ctx->out_default)
+ if (!convert->in_default) {
+ if (!convert->convert_in && convert->mix_passthrough
+ && !convert->convert_out && !convert->quant && convert->out_default)
outbuf = dst;
else
outbuf = tmpbuf;
- ctx->in.finfo->unpack_func (ctx->in.finfo,
+ convert->in.finfo->unpack_func (convert->in.finfo,
GST_AUDIO_PACK_FLAG_TRUNCATE_RANGE, outbuf, src,
- samples * ctx->in.channels);
+ samples * convert->in.channels);
src = outbuf;
}
/* 2. optionally convert for mixing */
- if (ctx->convert_in) {
- if (ctx->mix_passthrough && !ctx->convert_out && !ctx->quant
- && ctx->out_default)
+ if (convert->convert_in) {
+ if (convert->mix_passthrough && !convert->convert_out && !convert->quant
+ && convert->out_default)
outbuf = dst;
else if (src == tmpbuf)
outbuf = tmpbuf2;
else
outbuf = tmpbuf;
- ctx->convert_in (outbuf, src, samples * ctx->in.channels);
+ convert->convert_in (outbuf, src, samples * convert->in.channels);
src = outbuf;
}
/* step 3, channel mix if not passthrough */
- if (!ctx->mix_passthrough) {
- if (!ctx->convert_out && !ctx->quant && ctx->out_default)
+ if (!convert->mix_passthrough) {
+ if (!convert->convert_out && !convert->quant && convert->out_default)
outbuf = dst;
else
outbuf = tmpbuf;
- gst_channel_mix_mix (ctx->mix, ctx->mix_format, ctx->in.layout, src, outbuf,
- samples);
+ gst_channel_mix_mix (convert->mix, convert->mix_format, convert->in.layout,
+ src, outbuf, samples);
src = outbuf;
}
/* step 4, optional convert F64 -> S32 for quantize */
- if (ctx->convert_out) {
- if (!ctx->quant && ctx->out_default)
+ if (convert->convert_out) {
+ if (!convert->quant && convert->out_default)
outbuf = dst;
else
outbuf = tmpbuf;
- ctx->convert_out (outbuf, src, samples * ctx->out.channels);
+ convert->convert_out (outbuf, src, samples * convert->out.channels);
src = outbuf;
}
/* step 5, optional quantize */
- if (ctx->quant) {
- if (ctx->out_default)
+ if (convert->quant) {
+ if (convert->out_default)
outbuf = dst;
else
outbuf = tmpbuf;
- gst_audio_quantize_samples (ctx->quant, outbuf, src, samples);
+ gst_audio_quantize_samples (convert->quant, outbuf, src, samples);
src = outbuf;
}
/* step 6, pack */
- if (!ctx->out_default) {
- ctx->out.finfo->pack_func (ctx->out.finfo, 0, src, dst,
- samples * ctx->out.channels);
+ if (!convert->out_default) {
+ convert->out.finfo->pack_func (convert->out.finfo, 0, src, dst,
+ samples * convert->out.channels);
}
return TRUE;
/* GStreamer
* Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
- * audioconvert.h: audio format conversion library
+ * audioconverter.h: audio format conversion library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* Boston, MA 02110-1301, USA.
*/
-#ifndef __AUDIO_CONVERT_H__
-#define __AUDIO_CONVERT_H__
+#ifndef __GST_AUDIO_CONVERTER_H__
+#define __GST_AUDIO_CONVERTER_H__
#include <gst/gst.h>
#include <gst/audio/audio.h>
#include "gstchannelmix.h"
-#include "gstaudioquantize.h"
-GST_DEBUG_CATEGORY_EXTERN (audio_convert_debug);
-#define GST_CAT_DEFAULT (audio_convert_debug)
+typedef struct _GstAudioConverter GstAudioConverter;
-typedef struct _AudioConvertCtx AudioConvertCtx;
-
-typedef void (*AudioConvertFunc) (gpointer dst, const gpointer src, gint count);
-
-struct _AudioConvertCtx
-{
- GstAudioInfo in;
- GstAudioInfo out;
-
- gboolean in_default;
+/**
+ * GST_AUDIO_CONVERTER_OPT_DITHER_METHOD:
+ *
+ * #GST_TYPE_AUDIO_DITHER_METHOD, The dither method to use when
+ * changing bit depth.
+ * Default is #GST_AUDIO_DITHER_NONE.
+ */
+#define GST_AUDIO_CONVERTER_OPT_DITHER_METHOD "GstAudioConverter.dither-method"
- AudioConvertFunc convert_in;
+/**
+ * GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD:
+ *
+ * #GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, The noise shaping method to use
+ * to mask noise from quantization errors.
+ * Default is #GST_AUDIO_NOISE_SHAPING_NONE.
+ */
+#define GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD "GstAudioConverter.noise-shaping-method"
- GstAudioFormat mix_format;
- gboolean mix_passthrough;
- GstChannelMix *mix;
+/**
+ * GST_AUDIO_CONVERTER_OPT_QUANTIZATION:
+ *
+ * #G_TYPE_UINT, The quantization amount. Components will be
+ * quantized to multiples of this value.
+ * Default is 1
+ */
+#define GST_AUDIO_CONVERTER_OPT_QUANTIZATION "GstAudioConverter.quantization"
- AudioConvertFunc convert_out;
- GstAudioQuantize *quant;
+/**
+ * @GST_AUDIO_CONVERTER_FLAG_NONE: no flag
+ * @GST_AUDIO_CONVERTER_FLAG_SOURCE_WRITABLE: the source is writable and can be
+ * used as temporary storage during conversion.
+ *
+ * Extra flags passed to gst_audio_converter_samples().
+ */
+typedef enum {
+ GST_AUDIO_CONVERTER_FLAG_NONE = 0,
+ GST_AUDIO_CONVERTER_FLAG_SOURCE_WRITABLE = (1 << 0)
+} GstAudioConverterFlags;
- gboolean out_default;
+GstAudioConverter * gst_audio_converter_new (GstAudioInfo *in_info,
+ GstAudioInfo *out_info,
+ GstStructure *config);
- gboolean passthrough;
+void gst_audio_converter_free (GstAudioConverter * convert);
- gpointer tmpbuf;
- gpointer tmpbuf2;
- gint tmpbufsize;
-};
+gboolean gst_audio_converter_set_config (GstAudioConverter * convert, GstStructure *config);
+const GstStructure * gst_audio_converter_get_config (GstAudioConverter * convert);
-gboolean audio_convert_prepare_context (AudioConvertCtx * ctx,
- GstAudioInfo * in, GstAudioInfo * out,
- GstAudioDitherMethod dither, GstAudioNoiseShapingMethod ns);
-gboolean audio_convert_get_sizes (AudioConvertCtx * ctx, gint samples,
- gint * srcsize, gint * dstsize);
-gboolean audio_convert_clean_context (AudioConvertCtx * ctx);
+gboolean gst_audio_converter_get_sizes (GstAudioConverter * convert,
+ gint samples,
+ gint * srcsize, gint * dstsize);
-gboolean audio_convert_convert (AudioConvertCtx * ctx, gpointer src,
- gpointer dst, gint samples, gboolean src_writable);
+gboolean gst_audio_converter_samples (GstAudioConverter * convert,
+ GstAudioConverterFlags flags,
+ gpointer src, gpointer dst,
+ gint samples);
-#endif /* __AUDIO_CONVERT_H__ */
+#endif /* __GST_AUDIO_CONVERTER_H__ */
#include "gstaudioconvert.h"
#include "gstchannelmix.h"
-#include "gstaudioquantize.h"
#include "plugin.h"
GST_DEBUG_CATEGORY (audio_convert_debug);
GST_PAD_ALWAYS,
STATIC_CAPS);
-#define GST_TYPE_AUDIO_CONVERT_DITHERING (gst_audio_convert_dithering_get_type ())
-static GType
-gst_audio_convert_dithering_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {GST_AUDIO_DITHER_NONE, "No dithering",
- "none"},
- {GST_AUDIO_DITHER_RPDF, "Rectangular dithering", "rpdf"},
- {GST_AUDIO_DITHER_TPDF, "Triangular dithering (default)", "tpdf"},
- {GST_AUDIO_DITHER_TPDF_HF, "High frequency triangular dithering",
- "tpdf-hf"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioConvertDithering", values);
- }
- return gtype;
-}
-
-#define GST_TYPE_AUDIO_CONVERT_NOISE_SHAPING (gst_audio_convert_ns_get_type ())
-static GType
-gst_audio_convert_ns_get_type (void)
-{
- static GType gtype = 0;
-
- if (gtype == 0) {
- static const GEnumValue values[] = {
- {GST_AUDIO_NOISE_SHAPING_NONE, "No noise shaping (default)",
- "none"},
- {GST_AUDIO_NOISE_SHAPING_ERROR_FEEDBACK, "Error feedback",
- "error-feedback"},
- {GST_AUDIO_NOISE_SHAPING_SIMPLE, "Simple 2-pole noise shaping", "simple"},
- {GST_AUDIO_NOISE_SHAPING_MEDIUM, "Medium 5-pole noise shaping", "medium"},
- {GST_AUDIO_NOISE_SHAPING_HIGH, "High 8-pole noise shaping", "high"},
- {0, NULL, NULL}
- };
-
- gtype = g_enum_register_static ("GstAudioConvertNoiseShaping", values);
- }
- return gtype;
-}
-
/*** TYPE FUNCTIONS ***********************************************************/
static void
g_object_class_install_property (gobject_class, PROP_DITHERING,
g_param_spec_enum ("dithering", "Dithering",
"Selects between different dithering methods.",
- GST_TYPE_AUDIO_CONVERT_DITHERING, GST_AUDIO_DITHER_TPDF,
+ GST_TYPE_AUDIO_DITHER_METHOD, GST_AUDIO_DITHER_TPDF,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_NOISE_SHAPING,
g_param_spec_enum ("noise-shaping", "Noise shaping",
"Selects between different noise shaping methods.",
- GST_TYPE_AUDIO_CONVERT_NOISE_SHAPING, GST_AUDIO_NOISE_SHAPING_NONE,
+ GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, GST_AUDIO_NOISE_SHAPING_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_pad_template (element_class,
{
this->dither = GST_AUDIO_DITHER_TPDF;
this->ns = GST_AUDIO_NOISE_SHAPING_NONE;
- memset (&this->ctx, 0, sizeof (AudioConvertCtx));
gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (this), TRUE);
}
{
GstAudioConvert *this = GST_AUDIO_CONVERT (obj);
- audio_convert_clean_context (&this->ctx);
+ gst_audio_converter_free (this->convert);
G_OBJECT_CLASS (parent_class)->dispose (obj);
}
GST_DEBUG_OBJECT (base, "incaps %" GST_PTR_FORMAT ", outcaps %"
GST_PTR_FORMAT, incaps, outcaps);
+ if (this->convert) {
+ gst_audio_converter_free (this->convert);
+ this->convert = NULL;
+ }
+
if (!gst_audio_info_from_caps (&in_info, incaps))
goto invalid_in;
if (!gst_audio_info_from_caps (&out_info, outcaps))
goto invalid_out;
- if (!audio_convert_prepare_context (&this->ctx, &in_info, &out_info,
- this->dither, this->ns))
+ this->convert = gst_audio_converter_new (&in_info, &out_info,
+ gst_structure_new ("GstAudioConverterConfig",
+ GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD,
+ this->dither,
+ GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD,
+ GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, this->ns, NULL));
+
+ if (this->convert == NULL)
goto no_converter;
+ this->in_info = in_info;
+ this->out_info = out_info;
+
return TRUE;
/* ERRORS */
}
no_converter:
{
- GST_ERROR_OBJECT (base, "could not find converter");
+ GST_ERROR_OBJECT (base, "could not make converter");
return FALSE;
}
}
GstMapInfo srcmap, dstmap;
gint insize, outsize;
gboolean inbuf_writable;
+ GstAudioConverterFlags flags;
gint samples;
/* get amount of samples to convert. */
- samples = gst_buffer_get_size (inbuf) / this->ctx.in.bpf;
+ samples = gst_buffer_get_size (inbuf) / this->in_info.bpf;
/* get in/output sizes, to see if the buffers we got are of correct
* sizes */
- if (!audio_convert_get_sizes (&this->ctx, samples, &insize, &outsize))
+ if (!gst_audio_converter_get_sizes (this->convert, samples, &insize,
+ &outsize))
goto error;
if (insize == 0 || outsize == 0)
goto wrong_size;
/* and convert the samples */
+ flags = 0;
+ if (inbuf_writable)
+ flags |= GST_AUDIO_CONVERTER_FLAG_SOURCE_WRITABLE;
+
if (!GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
- if (!audio_convert_convert (&this->ctx, srcmap.data, dstmap.data,
- samples, inbuf_writable))
+ if (!gst_audio_converter_samples (this->convert, flags, srcmap.data,
+ dstmap.data, samples))
goto convert_error;
} else {
/* Create silence buffer */
- gst_audio_format_fill_silence (this->ctx.out.finfo, dstmap.data, outsize);
+ gst_audio_format_fill_silence (this->out_info.finfo, dstmap.data, outsize);
}
ret = GST_FLOW_OK;
if (base->segment.format == GST_FORMAT_TIME) {
input =
- gst_audio_buffer_clip (input, &base->segment, this->ctx.in.rate,
- this->ctx.in.bpf);
+ gst_audio_buffer_clip (input, &base->segment, this->in_info.rate,
+ this->in_info.bpf);
if (!input)
return GST_FLOW_OK;