gstreamer/gst/audioconvert/audioconvert.c

328 lines
9.4 KiB
C
Raw Normal View History

/* GStreamer
* Copyright (C) 2005 Wim Taymans <wim at fluendo dot com>
*
* audioconvert.c: Convert audio to different audio formats automatically
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <string.h>
#include "gstchannelmix.h"
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
#include "gstaudioquantize.h"
#include "audioconvert.h"
#include "gstaudioconvertorc.h"
/**
* int -> int
* - unpack S32
* - convert F64
* - (channel mix S32) (channel mix F64)
* - (quantize+dither S32) quantize+dither+ns F64->S32
* - pack from S32
*
* int -> float
* - unpack S32
* - convert F64
* - (channel mix F64)
* - pack from F64
*
* float -> int
* - unpack F64
* - (channel mix F64)
* - quantize+dither+ns F64->S32
* - pack from S32
*
* float -> float
* - unpack F64
* - (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))
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
static inline gboolean
check_default (AudioConvertCtx * ctx, const GstAudioFormatInfo * fmt)
{
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
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,
Add some documentation comments, and some new headers to be scanned. Original commit message from CVS: * docs/plugins/Makefile.am: * docs/plugins/gst-plugins-base-plugins-overrides.txt: * docs/plugins/gst-plugins-base-plugins-sections.txt: * docs/plugins/gst-plugins-base-plugins.args: * docs/plugins/gst-plugins-base-plugins.hierarchy: * docs/plugins/gst-plugins-base-plugins.interfaces: * docs/plugins/gst-plugins-base-plugins.prerequisites: * docs/plugins/inspect/plugin-adder.xml: * docs/plugins/inspect/plugin-alsa.xml: * docs/plugins/inspect/plugin-audioconvert.xml: * docs/plugins/inspect/plugin-audiorate.xml: * docs/plugins/inspect/plugin-audioresample.xml: * docs/plugins/inspect/plugin-audiotestsrc.xml: * docs/plugins/inspect/plugin-cdparanoia.xml: * docs/plugins/inspect/plugin-decodebin.xml: * docs/plugins/inspect/plugin-ffmpegcolorspace.xml: * docs/plugins/inspect/plugin-gdp.xml: * docs/plugins/inspect/plugin-gio.xml: * docs/plugins/inspect/plugin-gnomevfs.xml: * docs/plugins/inspect/plugin-libvisual.xml: * docs/plugins/inspect/plugin-ogg.xml: * docs/plugins/inspect/plugin-pango.xml: * docs/plugins/inspect/plugin-playback.xml: * docs/plugins/inspect/plugin-queue2.xml: * docs/plugins/inspect/plugin-subparse.xml: * docs/plugins/inspect/plugin-tcp.xml: * docs/plugins/inspect/plugin-theora.xml: * docs/plugins/inspect/plugin-typefindfunctions.xml: * docs/plugins/inspect/plugin-uridecodebin.xml: * docs/plugins/inspect/plugin-video4linux.xml: * docs/plugins/inspect/plugin-videorate.xml: * docs/plugins/inspect/plugin-videoscale.xml: * docs/plugins/inspect/plugin-videotestsrc.xml: * docs/plugins/inspect/plugin-volume.xml: * docs/plugins/inspect/plugin-vorbis.xml: * docs/plugins/inspect/plugin-ximagesink.xml: * docs/plugins/inspect/plugin-xvimagesink.xml: * ext/cdparanoia/gstcdparanoiasrc.c: * ext/ogg/gstoggdemux.c: * ext/ogg/gstoggdemux.h: * ext/ogg/gstoggmux.c: * ext/ogg/gstoggmux.h: * gst/audioconvert/audioconvert.c: * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.h: * gst/gdp/gstgdpdepay.h: * gst/gdp/gstgdppay.h: * gst/playback/gstdecodebin.c: * gst/playback/gstdecodebin2.c: * gst/playback/gstplaybin.c: * gst/playback/gstplaybin2.c: * gst/playback/gsturidecodebin.c: * gst/tcp/gstmultifdsink.c: * gst/tcp/gstmultifdsink.h: * gst/tcp/gsttcp.h: Add some documentation comments, and some new headers to be scanned. Rename some internal enum declarations (audioconvert's DitherType and NoiseShapingType, GstUnitType from the TCP elements) to match the documented GObject type names so that the docs pick them up. Name the playbin2 docs markups properly so they get picked up. They'll need renaming back when/if playbin2 becomes playbin. 100% symbol coverage for the plugin docs, booya.
2008-05-22 22:09:16 +00:00
GstAudioConvertNoiseShaping ns)
{
gint in_depth, out_depth;
GstChannelMixFlags flags;
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;
in_depth = GST_AUDIO_FORMAT_INFO_DEPTH (in->finfo);
out_depth = GST_AUDIO_FORMAT_INFO_DEPTH (out->finfo);
GST_INFO ("depth in %d, out %d", in_depth, out_depth);
/* Don't dither or apply noise shaping if target depth is bigger than 20 bits
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
* as DA converters only can do a SNR up to 20 bits in reality.
* Also don't dither or apply noise shaping if target depth is larger than
* source depth. */
if (out_depth <= 20 && (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (in->finfo)
|| in_depth >= out_depth)) {
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
ctx->dither = dither;
ctx->ns = ns;
GST_INFO ("using dither %d and noise shaping %d", dither, ns);
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
} else {
ctx->dither = DITHER_NONE;
ctx->ns = NOISE_SHAPING_NONE;
GST_INFO ("using no dither and noise shaping");
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
}
/* 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)
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
ctx->ns = NOISE_SHAPING_ERROR_FEEDBACK;
flags =
GST_AUDIO_INFO_IS_UNPOSITIONED (in) ?
GST_CHANNEL_MIX_FLAGS_UNPOSITIONED_IN : 0;
flags |=
GST_AUDIO_INFO_IS_UNPOSITIONED (out) ?
GST_CHANNEL_MIX_FLAGS_UNPOSITIONED_OUT : 0;
ctx->mix = gst_channel_mix_new (flags, in->channels, in->position,
out->channels, out->position);
/* if one formats is float/double or we use noise shaping use double as
* intermediate format and switch mixing */
if (DOUBLE_INTERMEDIATE_FORMAT (ctx)) {
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");
}
/* check if input needs to be unpacked to intermediate format */
ctx->in_default =
GST_AUDIO_FORMAT_INFO_FORMAT (in->finfo) == GST_AUDIO_FORMAT_F64;
if (GST_AUDIO_FORMAT_INFO_IS_INTEGER (out->finfo)) {
/* quantization will convert to s32, check if this is our final output format */
ctx->out_default =
GST_AUDIO_FORMAT_INFO_FORMAT (out->finfo) == GST_AUDIO_FORMAT_S32;
} else {
ctx->out_default =
GST_AUDIO_FORMAT_INFO_FORMAT (out->finfo) == GST_AUDIO_FORMAT_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 output is in default format */
ctx->out_default =
GST_AUDIO_FORMAT_INFO_FORMAT (out->finfo) == GST_AUDIO_FORMAT_S32;
}
GST_INFO ("unitsizes: %d -> %d", in->bpf, out->bpf);
/* check if channel mixer is passthrough */
ctx->mix_passthrough = gst_channel_mix_is_passthrough (ctx->mix);
ctx->quant_default = check_default (ctx, out->finfo);
GST_INFO ("in default %d, mix passthrough %d, out default %d",
ctx->in_default, ctx->mix_passthrough, ctx->out_default);
ctx->out_scale =
GST_AUDIO_FORMAT_INFO_IS_INTEGER (out->finfo) ? (32 - out_depth) : 0;
GST_INFO ("scale out %d", ctx->out_scale);
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
gst_audio_quantize_setup (ctx);
return TRUE;
/* ERRORS */
unpositioned:
{
GST_WARNING ("unpositioned channels");
return FALSE;
}
}
gboolean
audio_convert_clean_context (AudioConvertCtx * ctx)
{
g_return_val_if_fail (ctx != NULL, FALSE);
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
gst_audio_quantize_free (ctx);
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 = NULL;
g_free (ctx->tmpbuf);
ctx->tmpbuf = NULL;
ctx->tmpbufsize = 0;
return TRUE;
}
gboolean
audio_convert_get_sizes (AudioConvertCtx * ctx, gint samples, gint * srcsize,
gint * dstsize)
{
g_return_val_if_fail (ctx != NULL, FALSE);
if (srcsize)
*srcsize = samples * ctx->in.bpf;
if (dstsize)
*dstsize = samples * ctx->out.bpf;
return TRUE;
}
gboolean
audio_convert_convert (AudioConvertCtx * ctx, gpointer src,
gpointer dst, gint samples, gboolean src_writable)
{
guint insize, outsize, size;
gpointer outbuf, tmpbuf;
guint intemp = 0, outtemp = 0, biggest;
gint in_width, out_width;
g_return_val_if_fail (ctx != 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;
insize = ctx->in.bpf * samples;
outsize = ctx->out.bpf * samples;
in_width = GST_AUDIO_FORMAT_INFO_WIDTH (ctx->in.finfo);
out_width = GST_AUDIO_FORMAT_INFO_WIDTH (ctx->out.finfo);
/* find biggest temp buffer size */
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
size = (DOUBLE_INTERMEDIATE_FORMAT (ctx)) ? sizeof (gdouble)
: sizeof (gint32);
if (!ctx->in_default)
intemp = gst_util_uint64_scale (insize, size * 8, in_width);
if (!ctx->mix_passthrough || !ctx->quant_default)
outtemp = gst_util_uint64_scale (outsize, size * 8, out_width);
biggest = MAX (intemp, outtemp);
/* see if one of the buffers can be used as temp */
if ((outsize >= biggest) && (ctx->out.bpf <= size))
tmpbuf = dst;
else if ((insize >= biggest) && src_writable && (ctx->in.bpf >= size))
tmpbuf = src;
else {
if (biggest > ctx->tmpbufsize) {
ctx->tmpbuf = g_realloc (ctx->tmpbuf, biggest);
ctx->tmpbufsize = biggest;
}
tmpbuf = ctx->tmpbuf;
}
/* start conversion */
if (!ctx->in_default) {
gpointer t;
/* check if final conversion */
if (!(ctx->quant_default && ctx->mix_passthrough))
outbuf = tmpbuf;
else
outbuf = dst;
/* move samples to the middle of the array so that we can
* convert them in-place */
if (ctx->convert)
t = ((gint32 *) outbuf) + (samples * ctx->in.channels);
else
t = outbuf;
/* unpack to default format */
ctx->in.finfo->unpack_func (ctx->in.finfo, 0, t, src,
samples * ctx->in.channels);
if (ctx->convert)
ctx->convert (outbuf, t, samples * ctx->in.channels);
src = outbuf;
}
if (!ctx->mix_passthrough) {
/* check if final conversion */
if (ctx->quant_default)
outbuf = dst;
else
outbuf = tmpbuf;
/* convert channels */
gst_channel_mix_mix (ctx->mix, ctx->mix_format, ctx->in.layout, src, outbuf,
samples);
src = outbuf;
}
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
/* we only need to quantize if output format is int */
if (GST_AUDIO_FORMAT_INFO_IS_INTEGER (ctx->out.finfo)) {
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
if (ctx->out_default)
outbuf = dst;
else
outbuf = tmpbuf;
gst/audioconvert/: Implement dithering and noise shaping in audioconvert. By default now Original commit message from CVS: * gst/audioconvert/Makefile.am: * gst/audioconvert/audioconvert.c: (audio_convert_get_func_index), (check_default), (audio_convert_prepare_context), (audio_convert_clean_context), (audio_convert_convert): * gst/audioconvert/audioconvert.h: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_dithering_get_type), (gst_audio_convert_ns_get_type), (gst_audio_convert_class_init), (gst_audio_convert_init), (gst_audio_convert_set_caps), (gst_audio_convert_set_property), (gst_audio_convert_get_property): * gst/audioconvert/gstaudioconvert.h: * gst/audioconvert/gstaudioquantize.c: (gst_audio_quantize_setup_noise_shaping), (gst_audio_quantize_free_noise_shaping), (gst_audio_quantize_setup_dither), (gst_audio_quantize_free_dither), (gst_audio_quantize_setup_quantize_func), (gst_audio_quantize_setup), (gst_audio_quantize_free): * gst/audioconvert/gstaudioquantize.h: Implement dithering and noise shaping in audioconvert. By default now TPDF dithering (and no noise shaping) will be used when converting from a higher bit depth to 20 bit depth or smaller, otherwise everything will be as it is now. For the last audioconvert in a pipeline it would make sense to use some kind of noise shaping, enabling it by default for all conversions would give undesired results though. Fixes #360246. * tests/check/elements/audioconvert.c: (setup_audioconvert), (GST_START_TEST): Adjust unit test for the new audioconvert.
2007-06-28 20:37:58 +00:00
ctx->quantize (ctx, src, outbuf, samples);
}
if (!ctx->out_default) {
/* pack default format into dst */
ctx->out.finfo->pack_func (ctx->out.finfo, 0, src, dst,
samples * ctx->out.channels);
}
return TRUE;
}