mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
gst/audioconvert/: Support for 64-bit float audio in audioconvert (#339837)
Original commit message from CVS: * gst/audioconvert/audioconvert.c: (float), (double), (audio_convert_get_func_index): * gst/audioconvert/gstaudioconvert.c: (set_structure_widths), (make_lossless_changes): Support for 64-bit float audio in audioconvert (#339837)
This commit is contained in:
parent
6f25185e75
commit
36180a5f3d
3 changed files with 73 additions and 30 deletions
|
@ -1,3 +1,11 @@
|
|||
2007-02-02 Stefan Kost <ensonic@users.sf.net>
|
||||
|
||||
* gst/audioconvert/audioconvert.c: (float), (double),
|
||||
(audio_convert_get_func_index):
|
||||
* gst/audioconvert/gstaudioconvert.c: (set_structure_widths),
|
||||
(make_lossless_changes):
|
||||
Support for 64-bit float audio in audioconvert (#339837)
|
||||
|
||||
2007-02-01 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
Patch by: Holger Wansing <linux wansing-online de>
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
#include "gstchannelmix.h"
|
||||
#include "audioconvert.h"
|
||||
|
||||
/* int to float conversion: int2float(i) = 1 / (2^31-1) * i */
|
||||
/* int to float/double conversion: int2xxx(i) = 1 / (2^31-1) * i */
|
||||
#define INT2FLOAT(i) (4.6566128752457969e-10 * ((gfloat)i))
|
||||
#define INT2DOUBLE(i) (4.6566128752457969e-10 * ((gdouble)i))
|
||||
|
||||
/* sign bit in the intermediate format */
|
||||
#define SIGNED (1U<<31)
|
||||
|
@ -52,7 +53,7 @@ MAKE_UNPACK_FUNC_NAME (name) (gpointer src, gint32 *dst, \
|
|||
} \
|
||||
}
|
||||
|
||||
/* special unpack code for float */
|
||||
/* special unpack code for float/double */
|
||||
static void
|
||||
MAKE_UNPACK_FUNC_NAME (float) (gpointer src, gint32 * dst,
|
||||
gint scale, gint count)
|
||||
|
@ -61,6 +62,21 @@ MAKE_UNPACK_FUNC_NAME (float) (gpointer src, gint32 * dst,
|
|||
gdouble temp;
|
||||
|
||||
for (; count; count--) {
|
||||
/* blow up to 32 bit */
|
||||
temp = (*p++ * 2147483647.0) + 0.5;
|
||||
*dst++ = (gint32) CLAMP (temp, G_MININT32, G_MAXINT32);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
MAKE_UNPACK_FUNC_NAME (double) (gpointer src, gint32 * dst,
|
||||
gint scale, gint count)
|
||||
{
|
||||
gdouble *p = (gdouble *) src;
|
||||
gdouble temp;
|
||||
|
||||
for (; count; count--) {
|
||||
/* blow up to 32 bit */
|
||||
temp = (*p++ * 2147483647.0) + 0.5;
|
||||
*dst++ = (gint32) CLAMP (temp, G_MININT32, G_MAXINT32);
|
||||
}
|
||||
|
@ -109,7 +125,7 @@ MAKE_PACK_FUNC_NAME (name) (gint32 *src, gpointer dst, \
|
|||
} \
|
||||
}
|
||||
|
||||
/* special float pack function */
|
||||
/* special pack code for float/double */
|
||||
static void
|
||||
MAKE_PACK_FUNC_NAME (float) (gint32 * src, gpointer dst, gint scale, gint count)
|
||||
{
|
||||
|
@ -120,6 +136,17 @@ MAKE_PACK_FUNC_NAME (float) (gint32 * src, gpointer dst, gint scale, gint count)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
MAKE_PACK_FUNC_NAME (double) (gint32 * src, gpointer dst, gint scale,
|
||||
gint count)
|
||||
{
|
||||
gdouble *p = (gdouble *) dst;
|
||||
|
||||
for (; count; count--) {
|
||||
*p++ = INT2DOUBLE (*src++);
|
||||
}
|
||||
}
|
||||
|
||||
#define WRITE8(p, v) GST_WRITE_UINT8 (p, v)
|
||||
#define WRITE16_TO_LE(p,v) GST_WRITE_UINT16_LE (p, (guint16)(v))
|
||||
#define WRITE16_TO_BE(p,v) GST_WRITE_UINT16_BE (p, (guint16)(v))
|
||||
|
@ -161,6 +188,7 @@ static AudioConvertUnpack unpack_funcs[] = {
|
|||
MAKE_UNPACK_FUNC_NAME (u32_be),
|
||||
MAKE_UNPACK_FUNC_NAME (s32_be),
|
||||
MAKE_UNPACK_FUNC_NAME (float),
|
||||
MAKE_UNPACK_FUNC_NAME (double),
|
||||
};
|
||||
|
||||
static AudioConvertPack pack_funcs[] = {
|
||||
|
@ -181,6 +209,7 @@ static AudioConvertPack pack_funcs[] = {
|
|||
MAKE_PACK_FUNC_NAME (u32_be),
|
||||
MAKE_PACK_FUNC_NAME (s32_be),
|
||||
MAKE_PACK_FUNC_NAME (float),
|
||||
MAKE_PACK_FUNC_NAME (double),
|
||||
};
|
||||
|
||||
static gint
|
||||
|
@ -193,7 +222,8 @@ audio_convert_get_func_index (AudioConvertFmt * fmt)
|
|||
index += fmt->endianness == G_LITTLE_ENDIAN ? 0 : 2;
|
||||
index += fmt->sign ? 1 : 0;
|
||||
} else {
|
||||
index = 16;
|
||||
/* this is float/double */
|
||||
index = (fmt->width == 32) ? 16 : 17;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
|
|
@ -120,6 +120,11 @@ GST_BOILERPLATE_FULL (GstAudioConvert, gst_audio_convert, GstBaseTransform,
|
|||
|
||||
#define STATIC_CAPS \
|
||||
GST_STATIC_CAPS ( \
|
||||
"audio/x-raw-float, " \
|
||||
"rate = (int) [ 1, MAX ], " \
|
||||
"channels = (int) [ 1, 8 ], " \
|
||||
"endianness = (int) BYTE_ORDER, " \
|
||||
"width = (int) 64;" \
|
||||
"audio/x-raw-float, " \
|
||||
"rate = (int) [ 1, MAX ], " \
|
||||
"channels = (int) [ 1, 8 ], " \
|
||||
|
@ -316,6 +321,30 @@ parse_error:
|
|||
}
|
||||
}
|
||||
|
||||
/* Set widths (a list); multiples of 8 between min and max */
|
||||
static void
|
||||
set_structure_widths (GstStructure * s, int min, int max)
|
||||
{
|
||||
GValue list = { 0 };
|
||||
GValue val = { 0 };
|
||||
int width;
|
||||
|
||||
if (min == max) {
|
||||
gst_structure_set (s, "width", G_TYPE_INT, min, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
g_value_init (&list, GST_TYPE_LIST);
|
||||
g_value_init (&val, G_TYPE_INT);
|
||||
for (width = min; width <= max; width += 8) {
|
||||
g_value_set_int (&val, width);
|
||||
gst_value_list_append_value (&list, &val);
|
||||
}
|
||||
gst_structure_set_value (s, "width", &list);
|
||||
g_value_unset (&val);
|
||||
g_value_unset (&list);
|
||||
}
|
||||
|
||||
/* Modify the structure so that things that must always have a single
|
||||
* value (for float), or can always be losslessly converted (for int), have
|
||||
* appropriate values.
|
||||
|
@ -325,10 +354,10 @@ make_lossless_changes (GstStructure * s, gboolean isfloat)
|
|||
{
|
||||
if (isfloat) {
|
||||
/* float doesn't have a depth or signedness field and only supports a
|
||||
* width of 32 and native endianness */
|
||||
* widths of 32/64 and native endianness */
|
||||
gst_structure_remove_field (s, "depth");
|
||||
gst_structure_remove_field (s, "signed");
|
||||
gst_structure_set (s, "width", G_TYPE_INT, 32, NULL);
|
||||
set_structure_widths (s, 32, 64);
|
||||
gst_structure_set (s, "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);
|
||||
} else {
|
||||
/* int supports either endian, and signed or unsigned. GValues are a pain */
|
||||
|
@ -381,30 +410,6 @@ append_with_other_format (GstCaps * caps, GstStructure * s, gboolean isfloat)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set widths (a list); multiples of 8 between min and max */
|
||||
static void
|
||||
set_structure_widths (GstStructure * s, int min, int max)
|
||||
{
|
||||
GValue list = { 0 };
|
||||
GValue val = { 0 };
|
||||
int width;
|
||||
|
||||
if (min == max) {
|
||||
gst_structure_set (s, "width", G_TYPE_INT, min, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
g_value_init (&list, GST_TYPE_LIST);
|
||||
g_value_init (&val, G_TYPE_INT);
|
||||
for (width = min; width <= max; width += 8) {
|
||||
g_value_set_int (&val, width);
|
||||
gst_value_list_append_value (&list, &val);
|
||||
}
|
||||
gst_structure_set_value (s, "width", &list);
|
||||
g_value_unset (&val);
|
||||
g_value_unset (&list);
|
||||
}
|
||||
|
||||
/* Audioconvert can perform all conversions on audio except for resampling.
|
||||
* However, there are some conversions we _prefer_ not to do. For example, it's
|
||||
* better to convert format (float<->int, endianness, etc) than the number of
|
||||
|
|
Loading…
Reference in a new issue