mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
adder: Add support for per-stream volumes
This commit is contained in:
parent
addb07bc58
commit
a76ade2d78
5 changed files with 2849 additions and 5 deletions
|
@ -49,9 +49,25 @@
|
||||||
#include <string.h> /* strcmp */
|
#include <string.h> /* strcmp */
|
||||||
#include "gstadderorc.h"
|
#include "gstadderorc.h"
|
||||||
|
|
||||||
|
#define GST_CAT_DEFAULT gst_adder_debug
|
||||||
|
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
#define DEFAULT_PAD_VOLUME (1.0)
|
#define DEFAULT_PAD_VOLUME (1.0)
|
||||||
#define DEFAULT_PAD_MUTE (FALSE)
|
#define DEFAULT_PAD_MUTE (FALSE)
|
||||||
|
|
||||||
|
/* some defines for audio processing */
|
||||||
|
/* the volume factor is a range from 0.0 to (arbitrary) VOLUME_MAX_DOUBLE = 10.0
|
||||||
|
* we map 1.0 to VOLUME_UNITY_INT*
|
||||||
|
*/
|
||||||
|
#define VOLUME_UNITY_INT8 8 /* internal int for unity 2^(8-5) */
|
||||||
|
#define VOLUME_UNITY_INT8_BIT_SHIFT 3 /* number of bits to shift for unity */
|
||||||
|
#define VOLUME_UNITY_INT16 2048 /* internal int for unity 2^(16-5) */
|
||||||
|
#define VOLUME_UNITY_INT16_BIT_SHIFT 11 /* number of bits to shift for unity */
|
||||||
|
#define VOLUME_UNITY_INT24 524288 /* internal int for unity 2^(24-5) */
|
||||||
|
#define VOLUME_UNITY_INT24_BIT_SHIFT 19 /* number of bits to shift for unity */
|
||||||
|
#define VOLUME_UNITY_INT32 134217728 /* internal int for unity 2^(32-5) */
|
||||||
|
#define VOLUME_UNITY_INT32_BIT_SHIFT 27
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_PAD_0,
|
PROP_PAD_0,
|
||||||
|
@ -90,6 +106,9 @@ gst_adder_pad_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_PAD_VOLUME:
|
case PROP_PAD_VOLUME:
|
||||||
GST_OBJECT_LOCK (pad);
|
GST_OBJECT_LOCK (pad);
|
||||||
pad->volume = g_value_get_double (value);
|
pad->volume = g_value_get_double (value);
|
||||||
|
pad->volume_i8 = pad->volume * VOLUME_UNITY_INT8;
|
||||||
|
pad->volume_i16 = pad->volume * VOLUME_UNITY_INT16;
|
||||||
|
pad->volume_i32 = pad->volume * VOLUME_UNITY_INT32;
|
||||||
GST_OBJECT_UNLOCK (pad);
|
GST_OBJECT_UNLOCK (pad);
|
||||||
break;
|
break;
|
||||||
case PROP_PAD_MUTE:
|
case PROP_PAD_MUTE:
|
||||||
|
@ -134,9 +153,6 @@ enum
|
||||||
PROP_FILTER_CAPS
|
PROP_FILTER_CAPS
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_CAT_DEFAULT gst_adder_debug
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
|
||||||
|
|
||||||
/* elementfactory information */
|
/* elementfactory information */
|
||||||
|
|
||||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||||
|
@ -1274,10 +1290,12 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
||||||
if (GST_CLOCK_TIME_IS_VALID (stream_time))
|
if (GST_CLOCK_TIME_IS_VALID (stream_time))
|
||||||
gst_object_sync_values (GST_OBJECT (pad), stream_time);
|
gst_object_sync_values (GST_OBJECT (pad), stream_time);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (pad);
|
||||||
if (pad->mute || pad->volume < G_MINDOUBLE) {
|
if (pad->mute || pad->volume < G_MINDOUBLE) {
|
||||||
had_mute = TRUE;
|
had_mute = TRUE;
|
||||||
GST_DEBUG_OBJECT (adder, "channel %p: skipping muted pad", collect_data);
|
GST_DEBUG_OBJECT (adder, "channel %p: skipping muted pad", collect_data);
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
|
GST_OBJECT_UNLOCK (pad);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1296,6 +1314,7 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
||||||
gapbuf = inbuf;
|
gapbuf = inbuf;
|
||||||
else
|
else
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
|
GST_OBJECT_UNLOCK (pad);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1307,6 +1326,46 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
||||||
* only) GAP buffer, it will automatically copy the GAP flag. */
|
* only) GAP buffer, it will automatically copy the GAP flag. */
|
||||||
outbuf = gst_buffer_make_writable (inbuf);
|
outbuf = gst_buffer_make_writable (inbuf);
|
||||||
gst_buffer_map (outbuf, &outmap, GST_MAP_READWRITE);
|
gst_buffer_map (outbuf, &outmap, GST_MAP_READWRITE);
|
||||||
|
|
||||||
|
if (pad->volume != 1.0) {
|
||||||
|
switch (adder->info.finfo->format) {
|
||||||
|
case GST_AUDIO_FORMAT_U8:
|
||||||
|
adder_orc_volume_u8 ((gpointer) outmap.data, pad->volume_i8,
|
||||||
|
outmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_S8:
|
||||||
|
adder_orc_volume_s8 ((gpointer) outmap.data, pad->volume_i8,
|
||||||
|
outmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_U16:
|
||||||
|
adder_orc_volume_u16 ((gpointer) outmap.data, pad->volume_i16,
|
||||||
|
outmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_S16:
|
||||||
|
adder_orc_volume_s16 ((gpointer) outmap.data, pad->volume_i16,
|
||||||
|
outmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_U32:
|
||||||
|
adder_orc_volume_u32 ((gpointer) outmap.data, pad->volume_i32,
|
||||||
|
outmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_S32:
|
||||||
|
adder_orc_volume_s32 ((gpointer) outmap.data, pad->volume_i32,
|
||||||
|
outmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_F32:
|
||||||
|
adder_orc_volume_f32 ((gpointer) outmap.data, pad->volume,
|
||||||
|
outmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_F64:
|
||||||
|
adder_orc_volume_f64 ((gpointer) outmap.data, pad->volume,
|
||||||
|
outmap.size / bps);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!is_gap) {
|
if (!is_gap) {
|
||||||
/* we had a previous output buffer, mix this non-GAP buffer */
|
/* we had a previous output buffer, mix this non-GAP buffer */
|
||||||
|
@ -1322,8 +1381,48 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
||||||
" from data %p", collect_data, inmap.size, inmap.data);
|
" from data %p", collect_data, inmap.size, inmap.data);
|
||||||
|
|
||||||
/* further buffers, need to add them */
|
/* further buffers, need to add them */
|
||||||
|
if (pad->volume == 1.0) {
|
||||||
adder->func ((gpointer) outmap.data, (gpointer) inmap.data,
|
adder->func ((gpointer) outmap.data, (gpointer) inmap.data,
|
||||||
inmap.size / bps);
|
inmap.size / bps);
|
||||||
|
} else {
|
||||||
|
switch (adder->info.finfo->format) {
|
||||||
|
case GST_AUDIO_FORMAT_U8:
|
||||||
|
adder_orc_add_volume_u8 ((gpointer) outmap.data,
|
||||||
|
(gpointer) inmap.data, pad->volume_i8, inmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_S8:
|
||||||
|
adder_orc_add_volume_s8 ((gpointer) outmap.data,
|
||||||
|
(gpointer) inmap.data, pad->volume_i8, inmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_U16:
|
||||||
|
adder_orc_add_volume_u16 ((gpointer) outmap.data,
|
||||||
|
(gpointer) inmap.data, pad->volume_i16, inmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_S16:
|
||||||
|
adder_orc_add_volume_s16 ((gpointer) outmap.data,
|
||||||
|
(gpointer) inmap.data, pad->volume_i16, inmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_U32:
|
||||||
|
adder_orc_add_volume_u32 ((gpointer) outmap.data,
|
||||||
|
(gpointer) inmap.data, pad->volume_i32, inmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_S32:
|
||||||
|
adder_orc_add_volume_s32 ((gpointer) outmap.data,
|
||||||
|
(gpointer) inmap.data, pad->volume_i32, inmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_F32:
|
||||||
|
adder_orc_add_volume_f32 ((gpointer) outmap.data,
|
||||||
|
(gpointer) inmap.data, pad->volume, inmap.size / bps);
|
||||||
|
break;
|
||||||
|
case GST_AUDIO_FORMAT_F64:
|
||||||
|
adder_orc_add_volume_f64 ((gpointer) outmap.data,
|
||||||
|
(gpointer) inmap.data, pad->volume, inmap.size / bps);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
gst_buffer_unmap (inbuf, &inmap);
|
gst_buffer_unmap (inbuf, &inmap);
|
||||||
} else {
|
} else {
|
||||||
/* skip gap buffer */
|
/* skip gap buffer */
|
||||||
|
@ -1331,6 +1430,7 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
||||||
}
|
}
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
}
|
}
|
||||||
|
GST_OBJECT_UNLOCK (pad);
|
||||||
}
|
}
|
||||||
if (outbuf)
|
if (outbuf)
|
||||||
gst_buffer_unmap (outbuf, &outmap);
|
gst_buffer_unmap (outbuf, &outmap);
|
||||||
|
|
|
@ -104,6 +104,9 @@ struct _GstAdderPad {
|
||||||
GstPad parent;
|
GstPad parent;
|
||||||
|
|
||||||
gdouble volume;
|
gdouble volume;
|
||||||
|
gint volume_i32;
|
||||||
|
gint volume_i16;
|
||||||
|
gint volume_i8;
|
||||||
gboolean mute;
|
gboolean mute;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -88,6 +88,22 @@ void adder_orc_add_uint16 (guint16 * ORC_RESTRICT d1, const guint16 * ORC_RESTRI
|
||||||
void adder_orc_add_uint8 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n);
|
void adder_orc_add_uint8 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int n);
|
||||||
void adder_orc_add_float32 (float * ORC_RESTRICT d1, const float * ORC_RESTRICT s1, int n);
|
void adder_orc_add_float32 (float * ORC_RESTRICT d1, const float * ORC_RESTRICT s1, int n);
|
||||||
void adder_orc_add_float64 (double * ORC_RESTRICT d1, const double * ORC_RESTRICT s1, int n);
|
void adder_orc_add_float64 (double * ORC_RESTRICT d1, const double * ORC_RESTRICT s1, int n);
|
||||||
|
void adder_orc_volume_u8 (guint8 * ORC_RESTRICT d1, int p1, int n);
|
||||||
|
void adder_orc_volume_s8 (gint8 * ORC_RESTRICT d1, int p1, int n);
|
||||||
|
void adder_orc_volume_u16 (guint16 * ORC_RESTRICT d1, int p1, int n);
|
||||||
|
void adder_orc_volume_s16 (gint16 * ORC_RESTRICT d1, int p1, int n);
|
||||||
|
void adder_orc_volume_u32 (guint32 * ORC_RESTRICT d1, int p1, int n);
|
||||||
|
void adder_orc_volume_s32 (gint32 * ORC_RESTRICT d1, int p1, int n);
|
||||||
|
void adder_orc_volume_f32 (float * ORC_RESTRICT d1, float p1, int n);
|
||||||
|
void adder_orc_volume_f64 (double * ORC_RESTRICT d1, double p1, int n);
|
||||||
|
void adder_orc_add_volume_u8 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, int p1, int n);
|
||||||
|
void adder_orc_add_volume_s8 (gint8 * ORC_RESTRICT d1, const gint8 * ORC_RESTRICT s1, int p1, int n);
|
||||||
|
void adder_orc_add_volume_u16 (guint16 * ORC_RESTRICT d1, const guint16 * ORC_RESTRICT s1, int p1, int n);
|
||||||
|
void adder_orc_add_volume_s16 (gint16 * ORC_RESTRICT d1, const gint16 * ORC_RESTRICT s1, int p1, int n);
|
||||||
|
void adder_orc_add_volume_u32 (guint32 * ORC_RESTRICT d1, const guint32 * ORC_RESTRICT s1, int p1, int n);
|
||||||
|
void adder_orc_add_volume_s32 (gint32 * ORC_RESTRICT d1, const gint32 * ORC_RESTRICT s1, int p1, int n);
|
||||||
|
void adder_orc_add_volume_f32 (float * ORC_RESTRICT d1, const float * ORC_RESTRICT s1, float p1, int n);
|
||||||
|
void adder_orc_add_volume_f64 (double * ORC_RESTRICT d1, const double * ORC_RESTRICT s1, double p1, int n);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,3 +54,195 @@ addf d1, d1, s1
|
||||||
addd d1, d1, s1
|
addd d1, d1, s1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_volume_u8
|
||||||
|
.dest 1 d1 guint8
|
||||||
|
.param 1 p1
|
||||||
|
.const 1 c1 0x80
|
||||||
|
.temp 2 t1
|
||||||
|
.temp 1 t2
|
||||||
|
|
||||||
|
xorb t2, d1, c1
|
||||||
|
mulsbw t1, t2, p1
|
||||||
|
shrsw t1, t1, 3
|
||||||
|
convssswb t2, t1
|
||||||
|
xorb d1, t2, c1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_volume_s8
|
||||||
|
.dest 1 d1 gint8
|
||||||
|
.param 1 p1
|
||||||
|
.temp 2 t1
|
||||||
|
|
||||||
|
mulsbw t1, d1, p1
|
||||||
|
shrsw t1, t1, 3
|
||||||
|
convssswb d1, t1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_volume_u16
|
||||||
|
.dest 2 d1 guint16
|
||||||
|
.param 2 p1
|
||||||
|
.const 2 c1 0x8000
|
||||||
|
.temp 4 t1
|
||||||
|
.temp 2 t2
|
||||||
|
|
||||||
|
xorw t2, d1, c1
|
||||||
|
mulswl t1, t2, p1
|
||||||
|
shrsl t1, t1, 11
|
||||||
|
convssslw t2, t1
|
||||||
|
xorw d1, t2, c1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_volume_s16
|
||||||
|
.dest 2 d1 gint16
|
||||||
|
.param 2 p1
|
||||||
|
.temp 4 t1
|
||||||
|
|
||||||
|
mulswl t1, d1, p1
|
||||||
|
shrsl t1, t1, 11
|
||||||
|
convssslw d1, t1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_volume_u32
|
||||||
|
.dest 4 d1 guint32
|
||||||
|
.param 4 p1
|
||||||
|
.const 4 c1 0x80000000
|
||||||
|
.temp 8 t1
|
||||||
|
.temp 4 t2
|
||||||
|
|
||||||
|
xorl t2, d1, c1
|
||||||
|
mulslq t1, t2, p1
|
||||||
|
shrsq t1, t1, 27
|
||||||
|
convsssql t2, t1
|
||||||
|
xorl d1, t2, c1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_volume_s32
|
||||||
|
.dest 4 d1 gint32
|
||||||
|
.param 4 p1
|
||||||
|
.temp 8 t1
|
||||||
|
|
||||||
|
mulslq t1, d1, p1
|
||||||
|
shrsq t1, t1, 27
|
||||||
|
convsssql d1, t1
|
||||||
|
|
||||||
|
.function adder_orc_volume_f32
|
||||||
|
.dest 4 d1 float
|
||||||
|
.floatparam 4 p1
|
||||||
|
|
||||||
|
mulf d1, d1, p1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_volume_f64
|
||||||
|
.dest 8 d1 double
|
||||||
|
.doubleparam 8 p1
|
||||||
|
|
||||||
|
muld d1, d1, p1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_add_volume_u8
|
||||||
|
.dest 1 d1 guint8
|
||||||
|
.source 1 s1 guint8
|
||||||
|
.param 1 p1
|
||||||
|
.const 1 c1 0x80
|
||||||
|
.temp 2 t1
|
||||||
|
.temp 1 t2
|
||||||
|
|
||||||
|
xorb t2, s1, c1
|
||||||
|
mulsbw t1, t2, p1
|
||||||
|
shrsw t1, t1, 3
|
||||||
|
convssswb t2, t1
|
||||||
|
xorb t2, t2, c1
|
||||||
|
addusb d1, d1, t2
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_add_volume_s8
|
||||||
|
.dest 1 d1 gint8
|
||||||
|
.source 1 s1 gint8
|
||||||
|
.param 1 p1
|
||||||
|
.temp 2 t1
|
||||||
|
.temp 1 t2
|
||||||
|
|
||||||
|
mulsbw t1, s1, p1
|
||||||
|
shrsw t1, t1, 3
|
||||||
|
convssswb t2, t1
|
||||||
|
addssb d1, d1, t2
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_add_volume_u16
|
||||||
|
.dest 2 d1 guint16
|
||||||
|
.source 2 s1 guint16
|
||||||
|
.param 2 p1
|
||||||
|
.const 2 c1 0x8000
|
||||||
|
.temp 4 t1
|
||||||
|
.temp 2 t2
|
||||||
|
|
||||||
|
xorw t2, s1, c1
|
||||||
|
mulswl t1, t2, p1
|
||||||
|
shrsl t1, t1, 11
|
||||||
|
convssslw t2, t1
|
||||||
|
xorw t2, t2, c1
|
||||||
|
addusw d1, d1, t2
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_add_volume_s16
|
||||||
|
.dest 2 d1 gint16
|
||||||
|
.source 2 s1 gint16
|
||||||
|
.param 2 p1
|
||||||
|
.temp 4 t1
|
||||||
|
.temp 2 t2
|
||||||
|
|
||||||
|
mulswl t1, s1, p1
|
||||||
|
shrsl t1, t1, 11
|
||||||
|
convssslw t2, t1
|
||||||
|
addssw d1, d1, t2
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_add_volume_u32
|
||||||
|
.dest 4 d1 guint32
|
||||||
|
.source 4 s1 guint32
|
||||||
|
.param 4 p1
|
||||||
|
.const 4 c1 0x80000000
|
||||||
|
.temp 8 t1
|
||||||
|
.temp 4 t2
|
||||||
|
|
||||||
|
xorl t2, s1, c1
|
||||||
|
mulslq t1, t2, p1
|
||||||
|
shrsq t1, t1, 27
|
||||||
|
convsssql t2, t1
|
||||||
|
xorl t2, t2, c1
|
||||||
|
addusl d1, d1, t2
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_add_volume_s32
|
||||||
|
.dest 4 d1 gint32
|
||||||
|
.source 4 s1 gint32
|
||||||
|
.param 4 p1
|
||||||
|
.temp 8 t1
|
||||||
|
.temp 4 t2
|
||||||
|
|
||||||
|
mulslq t1, s1, p1
|
||||||
|
shrsq t1, t1, 27
|
||||||
|
convsssql t2, t1
|
||||||
|
addssl d1, d1, t2
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_add_volume_f32
|
||||||
|
.dest 4 d1 float
|
||||||
|
.source 4 s1 float
|
||||||
|
.floatparam 4 p1
|
||||||
|
.temp 4 t1
|
||||||
|
|
||||||
|
mulf t1, s1, p1
|
||||||
|
addf d1, d1, t1
|
||||||
|
|
||||||
|
|
||||||
|
.function adder_orc_add_volume_f64
|
||||||
|
.dest 8 d1 double
|
||||||
|
.source 8 s1 double
|
||||||
|
.doubleparam 8 p1
|
||||||
|
.temp 8 t1
|
||||||
|
|
||||||
|
muld t1, s1, p1
|
||||||
|
addd d1, d1, t1
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue