* - (channel mix F64)
* - pack from F64
*/
-#define DOUBLE_INTERMEDIATE_FORMAT(ctx) \
- (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (ctx->in.finfo) || \
- !GST_AUDIO_FORMAT_INFO_IS_INTEGER (ctx->out.finfo) || \
- (ctx->ns != NOISE_SHAPING_NONE))
-
-static inline gboolean
-check_default (AudioConvertCtx * ctx, const GstAudioFormatInfo * fmt)
-{
- if (!DOUBLE_INTERMEDIATE_FORMAT (ctx)) {
- return GST_AUDIO_FORMAT_INFO_FORMAT (fmt) == GST_AUDIO_FORMAT_S32;
- } else {
- return GST_AUDIO_FORMAT_INFO_FORMAT (fmt) == GST_AUDIO_FORMAT_F64;
- }
-}
-
gboolean
audio_convert_prepare_context (AudioConvertCtx * ctx, GstAudioInfo * in,
- GstAudioInfo * out, GstAudioConvertDithering dither,
- GstAudioConvertNoiseShaping ns)
+ GstAudioInfo * out, GstAudioDitherMethod dither,
+ GstAudioNoiseShapingMethod ns)
{
gint in_depth, out_depth;
GstChannelMixFlags flags;
* source depth. */
if (out_depth <= 20 && (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (in->finfo)
|| in_depth >= out_depth)) {
- ctx->dither = dither;
- ctx->ns = ns;
+ dither = dither;
+ ns = ns;
GST_INFO ("using dither %d and noise shaping %d", dither, ns);
} else {
- ctx->dither = DITHER_NONE;
- ctx->ns = NOISE_SHAPING_NONE;
+ dither = GST_AUDIO_DITHER_NONE;
+ ns = GST_AUDIO_NOISE_SHAPING_NONE;
GST_INFO ("using no dither and noise shaping");
}
/* Use simple error feedback when output sample rate is smaller than
* 32000 as the other methods might move the noise to audible ranges */
- if (ctx->ns > NOISE_SHAPING_ERROR_FEEDBACK && out->rate < 32000)
- ctx->ns = NOISE_SHAPING_ERROR_FEEDBACK;
+ if (ns > GST_AUDIO_NOISE_SHAPING_ERROR_FEEDBACK && out->rate < 32000)
+ ns = GST_AUDIO_NOISE_SHAPING_ERROR_FEEDBACK;
flags =
GST_AUDIO_INFO_IS_UNPOSITIONED (in) ?
ctx->mix = gst_channel_mix_new (flags, in->channels, in->position,
out->channels, out->position);
+ if (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (ctx->in.finfo) ||
+ !GST_AUDIO_FORMAT_INFO_IS_INTEGER (ctx->out.finfo) ||
+ (ns != GST_AUDIO_NOISE_SHAPING_NONE))
+ ctx->mix_format = GST_AUDIO_FORMAT_F64;
+ else
+ ctx->mix_format = GST_AUDIO_FORMAT_S32;
+
/* if one formats is float/double or we use noise shaping use double as
* intermediate format and switch mixing */
- if (DOUBLE_INTERMEDIATE_FORMAT (ctx)) {
+ if (ctx->mix_format == GST_AUDIO_FORMAT_F64) {
GST_INFO ("use float mixing");
- ctx->mix_format = GST_AUDIO_FORMAT_F64;
if (ctx->in.finfo->unpack_format != GST_AUDIO_FORMAT_F64) {
ctx->convert = audio_convert_orc_s32_to_double;
GST_INFO ("convert input to F64");
}
} else {
GST_INFO ("use int mixing");
- ctx->mix_format = GST_AUDIO_FORMAT_S32;
/* check if input needs to be unpacked to intermediate format */
ctx->in_default =
GST_AUDIO_FORMAT_INFO_FORMAT (in->finfo) == GST_AUDIO_FORMAT_S32;
/* check if channel mixer is passthrough */
ctx->mix_passthrough = gst_channel_mix_is_passthrough (ctx->mix);
- ctx->quant_default = check_default (ctx, out->finfo);
+ ctx->quant_default =
+ GST_AUDIO_FORMAT_INFO_FORMAT (out->finfo) == ctx->mix_format;
GST_INFO ("in default %d, mix passthrough %d, out default %d",
ctx->in_default, ctx->mix_passthrough, ctx->out_default);
GST_INFO ("scale out %d", ctx->out_scale);
- gst_audio_quantize_setup (ctx);
+ ctx->quant = gst_audio_quantize_new (dither, ns, 0, ctx->mix_format,
+ out->channels, ctx->out_scale);
return TRUE;
{
g_return_val_if_fail (ctx != NULL, FALSE);
- gst_audio_quantize_free (ctx);
+ if (ctx->quant)
+ gst_audio_quantize_free (ctx->quant);
if (ctx->mix)
gst_channel_mix_free (ctx->mix);
ctx->mix = NULL;
out_width = GST_AUDIO_FORMAT_INFO_WIDTH (ctx->out.finfo);
/* find biggest temp buffer size */
- size = (DOUBLE_INTERMEDIATE_FORMAT (ctx)) ? sizeof (gdouble)
+ size = (ctx->mix_format == GST_AUDIO_FORMAT_F64) ? sizeof (gdouble)
: sizeof (gint32);
if (!ctx->in_default)
else
outbuf = tmpbuf;
- ctx->quantize (ctx, src, outbuf, samples);
+ gst_audio_quantize_samples (ctx->quant, src, samples);
+
+ outbuf = src;
}
if (!ctx->out_default) {
#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)
-/**
- * GstAudioConvertDithering:
- * @DITHER_NONE: No dithering
- * @DITHER_RPDF: Rectangular dithering
- * @DITHER_TPDF: Triangular dithering (default)
- * @DITHER_TPDF_HF: High frequency triangular dithering
- *
- * Set of available dithering methods when converting audio.
- */
-typedef enum
-{
- DITHER_NONE = 0,
- DITHER_RPDF,
- DITHER_TPDF,
- DITHER_TPDF_HF
-} GstAudioConvertDithering;
-
-/**
- * GstAudioConvertNoiseShaping:
- * @NOISE_SHAPING_NONE: No noise shaping (default)
- * @NOISE_SHAPING_ERROR_FEEDBACK: Error feedback
- * @NOISE_SHAPING_SIMPLE: Simple 2-pole noise shaping
- * @NOISE_SHAPING_MEDIUM: Medium 5-pole noise shaping
- * @NOISE_SHAPING_HIGH: High 8-pole noise shaping
- *
- * Set of available noise shaping methods
- */
-typedef enum
-{
- NOISE_SHAPING_NONE = 0,
- NOISE_SHAPING_ERROR_FEEDBACK,
- NOISE_SHAPING_SIMPLE,
- NOISE_SHAPING_MEDIUM,
- NOISE_SHAPING_HIGH
-} GstAudioConvertNoiseShaping;
-
typedef struct _AudioConvertCtx AudioConvertCtx;
-#if 0
-typedef struct _AudioConvertFmt AudioConvertFmt;
-
-struct _AudioConvertFmt
-{
- /* general caps */
- gboolean is_int;
- gint endianness;
- gint width;
- gint rate;
- gint channels;
- GstAudioChannelPosition *pos;
- gboolean unpositioned_layout;
-
- /* int audio caps */
- gboolean sign;
- gint depth;
-
- gint unit_size;
-};
-#endif
-typedef void (*AudioConvertQuantize) (AudioConvertCtx * ctx, gpointer src,
- gpointer dst, gint count);
typedef void (*AudioConvertToF64) (gdouble *dst, const gint32 *src, gint count);
struct _AudioConvertCtx
GstAudioInfo in;
GstAudioInfo out;
+ GstAudioFormat mix_format;
GstChannelMix *mix;
+ GstAudioQuantize *quant;
gboolean in_default;
gboolean mix_passthrough;
gint tmpbufsize;
gint out_scale;
- GstAudioFormat mix_format;
AudioConvertToF64 convert;
- AudioConvertQuantize quantize;
-
- GstAudioConvertDithering dither;
- GstAudioConvertNoiseShaping ns;
- /* last random number generated per channel for hifreq TPDF dither */
- gpointer last_random;
- /* contains the past quantization errors, error[out_channels][count] */
- gdouble *error_buf;
};
gboolean audio_convert_prepare_context (AudioConvertCtx * ctx,
GstAudioInfo * in, GstAudioInfo * out,
- GstAudioConvertDithering dither, GstAudioConvertNoiseShaping ns);
+ GstAudioDitherMethod dither, GstAudioNoiseShapingMethod ns);
gboolean audio_convert_get_sizes (AudioConvertCtx * ctx, gint samples,
gint * srcsize, gint * dstsize);
if (gtype == 0) {
static const GEnumValue values[] = {
- {DITHER_NONE, "No dithering",
+ {GST_AUDIO_DITHER_NONE, "No dithering",
"none"},
- {DITHER_RPDF, "Rectangular dithering", "rpdf"},
- {DITHER_TPDF, "Triangular dithering (default)", "tpdf"},
- {DITHER_TPDF_HF, "High frequency triangular dithering", "tpdf-hf"},
+ {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}
};
if (gtype == 0) {
static const GEnumValue values[] = {
- {NOISE_SHAPING_NONE, "No noise shaping (default)",
+ {GST_AUDIO_NOISE_SHAPING_NONE, "No noise shaping (default)",
"none"},
- {NOISE_SHAPING_ERROR_FEEDBACK, "Error feedback", "error-feedback"},
- {NOISE_SHAPING_SIMPLE, "Simple 2-pole noise shaping", "simple"},
- {NOISE_SHAPING_MEDIUM, "Medium 5-pole noise shaping", "medium"},
- {NOISE_SHAPING_HIGH, "High 8-pole noise shaping", "high"},
+ {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}
};
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, DITHER_TPDF,
+ GST_TYPE_AUDIO_CONVERT_DITHERING, 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, NOISE_SHAPING_NONE,
+ GST_TYPE_AUDIO_CONVERT_NOISE_SHAPING, GST_AUDIO_NOISE_SHAPING_NONE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_pad_template (element_class,
static void
gst_audio_convert_init (GstAudioConvert * this)
{
- this->dither = DITHER_TPDF;
- this->ns = NOISE_SHAPING_NONE;
+ 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);
#include <gst/gst.h>
#include <string.h>
#include <math.h>
-#include "audioconvert.h"
#include "gstaudioconvertorc.h"
#include "gstaudioquantize.h"
#include "gstfastrandom.h"
+typedef void (*QuantizeFunc) (GstAudioQuantize * quant, gpointer src,
+ gpointer dst, gint count);
+
+struct _GstAudioQuantize
+{
+ GstAudioDitherMethod dither;
+ GstAudioNoiseShapingMethod ns;
+ GstAudioQuantizeFlags flags;
+ GstAudioFormat format;
+ guint channels;
+ guint quantizer;
+
+ /* last random number generated per channel for hifreq TPDF dither */
+ gpointer last_random;
+ /* contains the past quantization errors, error[out_channels][count] */
+ gdouble *error_buf;
+
+ QuantizeFunc quantize;
+};
+
#define MAKE_QUANTIZE_FUNC_NAME(name) \
gst_audio_quantize_quantize_##name
#define MAKE_QUANTIZE_FUNC_I(name, DITHER_INIT_FUNC, ADD_DITHER_FUNC, \
ROUND_FUNC) \
static void \
-MAKE_QUANTIZE_FUNC_NAME (name) (AudioConvertCtx *ctx, gint32 *src, \
+MAKE_QUANTIZE_FUNC_NAME (name) (GstAudioQuantize *quant, gint32 *src, \
gint32 *dst, gint count) \
{ \
- gint scale = ctx->out_scale; \
- gint channels = ctx->out.channels; \
+ gint scale = quant->quantizer; \
+ gint channels = quant->channels; \
gint chan_pos; \
\
if (scale > 0) { \
ADD_NS_FUNC, ADD_DITHER_FUNC, \
UPDATE_ERROR_FUNC) \
static void \
-MAKE_QUANTIZE_FUNC_NAME (name) (AudioConvertCtx *ctx, gdouble *src, \
+MAKE_QUANTIZE_FUNC_NAME (name) (GstAudioQuantize *quant, gdouble *src, \
gint32 *dst, gint count) \
{ \
- gint scale = ctx->out_scale; \
- gint channels = ctx->out.channels; \
+ gint scale = quant->quantizer; \
+ gint channels = quant->channels; \
gint chan_pos; \
gdouble tmp, d, factor = (1U<<(32-scale-1)); \
\
#define INIT_DITHER_TPDF_HF_I() \
gint32 rand; \
gint32 dither = (1<<(scale-1)); \
- gint32 *last_random = (gint32 *) ctx->last_random, tmp_rand;
+ gint32 *last_random = (gint32 *) quant->last_random, tmp_rand;
#define ADD_DITHER_TPDF_HF_I() \
tmp_rand = RANDOM_INT_DITHER(dither); \
#define INIT_DITHER_TPDF_HF_F() \
gdouble rand; \
gdouble dither = 1.0/(1U<<(32 - scale)); \
- gdouble *last_random = (gdouble *) ctx->last_random, tmp_rand;
+ gdouble *last_random = (gdouble *) quant->last_random, tmp_rand;
#define ADD_DITHER_TPDF_HF_F() \
tmp_rand = gst_fast_random_double_range (- dither, dither); \
#define INIT_NS_ERROR_FEEDBACK() \
gdouble orig; \
- gdouble *errors = ctx->error_buf;
+ gdouble *errors = quant->error_buf;
#define ADD_NS_ERROR_FEEDBACK() \
orig = tmp; \
#define INIT_NS_SIMPLE() \
gdouble orig; \
- gdouble *errors = ctx->error_buf, cur_error;
+ gdouble *errors = quant->error_buf, cur_error;
#define ADD_NS_SIMPLE() \
cur_error = errors[chan_pos*2] - 0.5 * errors[chan_pos*2 + 1]; \
#define INIT_NS_MEDIUM() \
gdouble orig; \
- gdouble *errors = ctx->error_buf, cur_error; \
+ gdouble *errors = quant->error_buf, cur_error; \
int j;
#define ADD_NS_MEDIUM() \
#define INIT_NS_HIGH() \
gdouble orig; \
- gdouble *errors = ctx->error_buf, cur_error; \
+ gdouble *errors = quant->error_buf, cur_error; \
int j;
#define ADD_NS_HIGH() \
MAKE_QUANTIZE_FUNC_F (float_tpdf_hf_high, INIT_DITHER_TPDF_HF_F, INIT_NS_HIGH,
ADD_NS_HIGH, ADD_DITHER_TPDF_HF_F, UPDATE_ERROR_HIGH);
-static const AudioConvertQuantize quantize_funcs[] = {
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (int_none_none),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (int_rpdf_none),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (int_tpdf_none),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (int_tpdf_hf_none),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_none),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_error_feedback),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_simple),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_medium),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_none_high),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_none),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_error_feedback),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_simple),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_medium),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_high),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_none),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_error_feedback),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_simple),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_medium),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_high),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_none),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_error_feedback),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_simple),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_medium),
- (AudioConvertQuantize) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_high)
+static const QuantizeFunc quantize_funcs[] = {
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (int_none_none),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (int_rpdf_none),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (int_tpdf_none),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (int_tpdf_hf_none),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_none_none),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_none_error_feedback),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_none_simple),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_none_medium),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_none_high),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_none),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_error_feedback),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_simple),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_medium),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_rpdf_high),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_none),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_error_feedback),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_simple),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_medium),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_high),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_none),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_error_feedback),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_simple),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_medium),
+ (QuantizeFunc) MAKE_QUANTIZE_FUNC_NAME (float_tpdf_hf_high)
};
static void
-gst_audio_quantize_setup_noise_shaping (AudioConvertCtx * ctx)
+gst_audio_quantize_setup_noise_shaping (GstAudioQuantize * quant)
{
- switch (ctx->ns) {
- case NOISE_SHAPING_HIGH:{
- ctx->error_buf = g_new0 (gdouble, ctx->out.channels * 8);
+ switch (quant->ns) {
+ case GST_AUDIO_NOISE_SHAPING_HIGH:{
+ quant->error_buf = g_new0 (gdouble, quant->channels * 8);
break;
}
- case NOISE_SHAPING_MEDIUM:{
- ctx->error_buf = g_new0 (gdouble, ctx->out.channels * 5);
+ case GST_AUDIO_NOISE_SHAPING_MEDIUM:{
+ quant->error_buf = g_new0 (gdouble, quant->channels * 5);
break;
}
- case NOISE_SHAPING_SIMPLE:{
- ctx->error_buf = g_new0 (gdouble, ctx->out.channels * 2);
+ case GST_AUDIO_NOISE_SHAPING_SIMPLE:{
+ quant->error_buf = g_new0 (gdouble, quant->channels * 2);
break;
}
- case NOISE_SHAPING_ERROR_FEEDBACK:
- ctx->error_buf = g_new0 (gdouble, ctx->out.channels);
+ case GST_AUDIO_NOISE_SHAPING_ERROR_FEEDBACK:
+ quant->error_buf = g_new0 (gdouble, quant->channels);
break;
- case NOISE_SHAPING_NONE:
+ case GST_AUDIO_NOISE_SHAPING_NONE:
default:
- ctx->error_buf = NULL;
+ quant->error_buf = NULL;
break;
}
return;
}
static void
-gst_audio_quantize_free_noise_shaping (AudioConvertCtx * ctx)
+gst_audio_quantize_setup_dither (GstAudioQuantize * quant)
{
- switch (ctx->ns) {
- case NOISE_SHAPING_HIGH:
- case NOISE_SHAPING_MEDIUM:
- case NOISE_SHAPING_SIMPLE:
- case NOISE_SHAPING_ERROR_FEEDBACK:
- case NOISE_SHAPING_NONE:
- default:
+ switch (quant->dither) {
+ case GST_AUDIO_DITHER_TPDF_HF:
+ quant->last_random = g_new0 (gdouble, quant->channels);
break;
- }
-
- g_free (ctx->error_buf);
- ctx->error_buf = NULL;
- return;
-}
-
-static void
-gst_audio_quantize_setup_dither (AudioConvertCtx * ctx)
-{
- switch (ctx->dither) {
- case DITHER_TPDF_HF:
- if (GST_AUDIO_FORMAT_INFO_IS_INTEGER (ctx->out.finfo))
- ctx->last_random = g_new0 (gint32, ctx->out.channels);
- else
- ctx->last_random = g_new0 (gdouble, ctx->out.channels);
+ case GST_AUDIO_DITHER_RPDF:
+ case GST_AUDIO_DITHER_TPDF:
+ quant->last_random = NULL;
break;
- case DITHER_RPDF:
- case DITHER_TPDF:
- ctx->last_random = NULL;
- break;
- case DITHER_NONE:
+ case GST_AUDIO_DITHER_NONE:
default:
- ctx->last_random = NULL;
+ quant->last_random = NULL;
break;
}
return;
}
static void
-gst_audio_quantize_free_dither (AudioConvertCtx * ctx)
+gst_audio_quantize_setup_quantize_func (GstAudioQuantize * quant)
{
- g_free (ctx->last_random);
+ gint index = 0;
- return;
+ if (quant->ns == GST_AUDIO_NOISE_SHAPING_NONE
+ && quant->format == GST_AUDIO_FORMAT_S32) {
+ index += quant->dither;
+ } else {
+ g_assert (quant->format == GST_AUDIO_FORMAT_F64);
+
+ index += 4 + (5 * quant->dither);
+ index += quant->ns;
+ }
+ quant->quantize = quantize_funcs[index];
}
-static void
-gst_audio_quantize_setup_quantize_func (AudioConvertCtx * ctx)
+/**
+ * gst_audio_quantize_new:
+ * @dither: a #GstAudioDitherMethod
+ * @ns: a #GstAudioNoiseShapingMethod
+ * @flags: #GstAudioQuantizeFlags
+ * @format: the #GstAudioFormat of the samples
+ * @channels: the amount of channels in the samples
+ * @quantizer: the quantizer to use
+ *
+ * Create a new quantizer object with the given parameters.
+ *
+ * Returns: a new #GstAudioQuantize. Free with gst_audio_quantize_free().
+ */
+GstAudioQuantize *
+gst_audio_quantize_new (GstAudioDitherMethod dither,
+ GstAudioNoiseShapingMethod ns, GstAudioQuantizeFlags flags,
+ GstAudioFormat format, guint channels, guint quantizer)
{
- gint index = 0;
+ GstAudioQuantize *quant;
- if (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (ctx->out.finfo)) {
- ctx->quantize = NULL;
- return;
- }
+ quant = g_slice_new0 (GstAudioQuantize);
+ quant->dither = dither;
+ quant->ns = ns;
+ quant->flags = flags;
+ quant->format = format;
+ quant->channels = channels;
+ quant->quantizer = quantizer;
- if (ctx->ns == NOISE_SHAPING_NONE
- && GST_AUDIO_FORMAT_INFO_IS_INTEGER (ctx->in.finfo)) {
- index += ctx->dither;
- } else {
- index += 4 + (5 * ctx->dither);
- index += ctx->ns;
- }
+ gst_audio_quantize_setup_dither (quant);
+ gst_audio_quantize_setup_noise_shaping (quant);
+ gst_audio_quantize_setup_quantize_func (quant);
- ctx->quantize = quantize_funcs[index];
+ return quant;
}
-gboolean
-gst_audio_quantize_setup (AudioConvertCtx * ctx)
+/**
+ * gst_audio_quantize_free:
+ * @quant: a #GstAudioQuantize
+ *
+ * Free a #GstAudioQuantize.
+ */
+void
+gst_audio_quantize_free (GstAudioQuantize * quant)
{
- gst_audio_quantize_setup_dither (ctx);
- gst_audio_quantize_setup_noise_shaping (ctx);
- gst_audio_quantize_setup_quantize_func (ctx);
+ g_free (quant->error_buf);
+ g_free (quant->last_random);
- return TRUE;
+ g_slice_free (GstAudioQuantize, quant);
}
void
-gst_audio_quantize_free (AudioConvertCtx * ctx)
+gst_audio_quantize_samples (GstAudioQuantize * quant,
+ gpointer data, guint samples)
{
- gst_audio_quantize_free_dither (ctx);
- gst_audio_quantize_free_noise_shaping (ctx);
+ quant->quantize (quant, data, data, samples);
}