mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-19 13:55:41 +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 "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_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
|
||||
{
|
||||
PROP_PAD_0,
|
||||
|
@ -90,6 +106,9 @@ gst_adder_pad_set_property (GObject * object, guint prop_id,
|
|||
case PROP_PAD_VOLUME:
|
||||
GST_OBJECT_LOCK (pad);
|
||||
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);
|
||||
break;
|
||||
case PROP_PAD_MUTE:
|
||||
|
@ -134,9 +153,6 @@ enum
|
|||
PROP_FILTER_CAPS
|
||||
};
|
||||
|
||||
#define GST_CAT_DEFAULT gst_adder_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
/* elementfactory information */
|
||||
|
||||
#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))
|
||||
gst_object_sync_values (GST_OBJECT (pad), stream_time);
|
||||
|
||||
GST_OBJECT_LOCK (pad);
|
||||
if (pad->mute || pad->volume < G_MINDOUBLE) {
|
||||
had_mute = TRUE;
|
||||
GST_DEBUG_OBJECT (adder, "channel %p: skipping muted pad", collect_data);
|
||||
gst_buffer_unref (inbuf);
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1296,6 +1314,7 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
|||
gapbuf = inbuf;
|
||||
else
|
||||
gst_buffer_unref (inbuf);
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1307,6 +1326,46 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
|||
* only) GAP buffer, it will automatically copy the GAP flag. */
|
||||
outbuf = gst_buffer_make_writable (inbuf);
|
||||
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 {
|
||||
if (!is_gap) {
|
||||
/* 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);
|
||||
|
||||
/* further buffers, need to add them */
|
||||
adder->func ((gpointer) outmap.data, (gpointer) inmap.data,
|
||||
inmap.size / bps);
|
||||
if (pad->volume == 1.0) {
|
||||
adder->func ((gpointer) outmap.data, (gpointer) inmap.data,
|
||||
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);
|
||||
} else {
|
||||
/* skip gap buffer */
|
||||
|
@ -1331,6 +1430,7 @@ gst_adder_collected (GstCollectPads * pads, gpointer user_data)
|
|||
}
|
||||
gst_buffer_unref (inbuf);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
}
|
||||
if (outbuf)
|
||||
gst_buffer_unmap (outbuf, &outmap);
|
||||
|
|
|
@ -104,6 +104,9 @@ struct _GstAdderPad {
|
|||
GstPad parent;
|
||||
|
||||
gdouble volume;
|
||||
gint volume_i32;
|
||||
gint volume_i16;
|
||||
gint volume_i8;
|
||||
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_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_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
|
||||
}
|
||||
|
|
|
@ -54,3 +54,195 @@ addf 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