mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
gst/cutter/gstcutter.c: copy calculation code from level; remove use of some audio functions
Original commit message from CVS: * gst/cutter/gstcutter.c: (gst_cutter_chain), (gst_cutter_set_property), (gst_cutter_get_caps): copy calculation code from level; remove use of some audio functions
This commit is contained in:
parent
8f0c1ebdb2
commit
baba27fb18
2 changed files with 69 additions and 32 deletions
|
@ -1,3 +1,10 @@
|
|||
2005-11-22 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* gst/cutter/gstcutter.c: (gst_cutter_chain),
|
||||
(gst_cutter_set_property), (gst_cutter_get_caps):
|
||||
copy calculation code from level; remove use of some audio
|
||||
functions
|
||||
|
||||
2005-11-22 Andy Wingo <wingo@pobox.com>
|
||||
|
||||
* Update for gst_tag_setter API changes.
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
GST_DEBUG_CATEGORY (cutter_debug);
|
||||
#define GST_CAT_DEFAULT cutter_debug
|
||||
|
||||
|
||||
#define CUTTER_DEFAULT_THRESHOLD_LEVEL 0.1
|
||||
#define CUTTER_DEFAULT_THRESHOLD_LENGTH (500 * GST_MSECOND)
|
||||
#define CUTTER_DEFAULT_PRE_LENGTH (200 * GST_MSECOND)
|
||||
|
@ -45,16 +44,24 @@ static GstElementDetails cutter_details = {
|
|||
static GstStaticPadTemplate cutter_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
|
||||
GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS)
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"rate = (int) [ 1, MAX ], "
|
||||
"channels = (int) [ 1, MAX ], "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"width = (int) { 8, 16 }, "
|
||||
"depth = (int) { 8, 16 }, " "signed = (boolean) true")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate cutter_sink_factory =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
|
||||
GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS)
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"rate = (int) [ 1, MAX ], "
|
||||
"channels = (int) [ 1, MAX ], "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"width = (int) { 8, 16 }, "
|
||||
"depth = (int) { 8, 16 }, " "signed = (boolean) true")
|
||||
);
|
||||
|
||||
enum
|
||||
|
@ -75,8 +82,6 @@ static void gst_cutter_get_property (GObject * object, guint prop_id,
|
|||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstFlowReturn gst_cutter_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static double inline gst_cutter_16bit_ms (gint16 * data, guint numsamples);
|
||||
static double inline gst_cutter_8bit_ms (gint8 * data, guint numsamples);
|
||||
|
||||
void gst_cutter_get_caps (GstPad * pad, GstCutter * filter);
|
||||
|
||||
|
@ -171,13 +176,46 @@ gst_cutter_message_new (GstCutter * c, gboolean above, GstClockTime timestamp)
|
|||
return gst_message_new_element (GST_OBJECT (c), s);
|
||||
}
|
||||
|
||||
/* Calculate the Normalized Cumulative Square over a buffer of the given type
|
||||
* and over all channels combined */
|
||||
|
||||
#define DEFINE_CUTTER_CALCULATOR(TYPE, RESOLUTION) \
|
||||
static void inline \
|
||||
gst_cutter_calculate_##TYPE (TYPE * in, guint num, \
|
||||
double *NCS) \
|
||||
{ \
|
||||
register int j; \
|
||||
double squaresum = 0.0; /* square sum of the integer samples */ \
|
||||
register double square = 0.0; /* Square */ \
|
||||
gdouble normalizer; /* divisor to get a [-1.0, 1.0] range */ \
|
||||
\
|
||||
*NCS = 0.0; /* Normalized Cumulative Square */ \
|
||||
\
|
||||
normalizer = (double) (1 << (RESOLUTION * 2)); \
|
||||
\
|
||||
for (j = 0; j < num; j++) \
|
||||
{ \
|
||||
square = ((double) in[j]) * in[j]; \
|
||||
squaresum += square; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
*NCS = squaresum / normalizer; \
|
||||
}
|
||||
|
||||
DEFINE_CUTTER_CALCULATOR (gint16, 15);
|
||||
DEFINE_CUTTER_CALCULATOR (gint8, 7);
|
||||
|
||||
|
||||
static GstFlowReturn
|
||||
gst_cutter_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstCutter *filter;
|
||||
gint16 *in_data;
|
||||
double RMS = 0.0; /* RMS of signal in buffer */
|
||||
double ms = 0.0; /* mean square value of buffer */
|
||||
guint num_samples;
|
||||
gdouble NCS = 0.0; /* Normalized Cumulative Square of buffer */
|
||||
gdouble RMS = 0.0; /* RMS of signal in buffer */
|
||||
gdouble NMS = 0.0; /* Normalized Mean Square of buffer */
|
||||
static gboolean silent_prev = FALSE; /* previous value of silent */
|
||||
GstBuffer *prebuf; /* pointer to a prebuffer element */
|
||||
|
||||
|
@ -204,10 +242,14 @@ gst_cutter_chain (GstPad * pad, GstBuffer * buf)
|
|||
/* calculate mean square value on buffer */
|
||||
switch (filter->width) {
|
||||
case 16:
|
||||
ms = gst_cutter_16bit_ms (in_data, GST_BUFFER_SIZE (buf) / 2);
|
||||
num_samples = GST_BUFFER_SIZE (buf) / 2;
|
||||
gst_cutter_calculate_gint16 (in_data, num_samples, &NCS);
|
||||
NMS = NCS / num_samples;
|
||||
break;
|
||||
case 8:
|
||||
ms = gst_cutter_8bit_ms ((gint8 *) in_data, GST_BUFFER_SIZE (buf));
|
||||
num_samples = GST_BUFFER_SIZE (buf);
|
||||
gst_cutter_calculate_gint8 ((gint8 *) in_data, num_samples, &NCS);
|
||||
NMS = NCS / num_samples;
|
||||
break;
|
||||
default:
|
||||
/* this shouldn't happen */
|
||||
|
@ -217,12 +259,12 @@ gst_cutter_chain (GstPad * pad, GstBuffer * buf)
|
|||
|
||||
silent_prev = filter->silent;
|
||||
|
||||
RMS = sqrt (ms) / (double) filter->max_sample;
|
||||
RMS = sqrt (NMS);
|
||||
/* if RMS below threshold, add buffer length to silent run length count
|
||||
* if not, reset
|
||||
*/
|
||||
GST_LOG_OBJECT (filter, "buffer stats: ms %f, RMS %f, audio length %f",
|
||||
ms, RMS, gst_audio_duration_from_pad_buffer (filter->sinkpad, buf));
|
||||
GST_LOG_OBJECT (filter, "buffer stats: NMS %f, RMS %f, audio length %f",
|
||||
NMS, RMS, gst_audio_duration_from_pad_buffer (filter->sinkpad, buf));
|
||||
if (RMS < filter->threshold_level)
|
||||
filter->silent_run_length +=
|
||||
gst_audio_duration_from_pad_buffer (filter->sinkpad, buf);
|
||||
|
@ -267,13 +309,6 @@ gst_cutter_chain (GstPad * pad, GstBuffer * buf)
|
|||
/* now check if we have to send the new buffer to the internal buffer cache
|
||||
* or to the srcpad */
|
||||
if (filter->silent) {
|
||||
/* we ref it before putting it in the pre_buffer */
|
||||
/* FIXME: we shouldn't probably do this, because the buffer
|
||||
* arrives reffed already; the plugin should just push it
|
||||
* or unref it to make it disappear */
|
||||
/*
|
||||
gst_buffer_ref (buf);
|
||||
*/
|
||||
filter->pre_buffer = g_list_append (filter->pre_buffer, buf);
|
||||
filter->pre_run_length +=
|
||||
gst_audio_duration_from_pad_buffer (filter->sinkpad, buf);
|
||||
|
@ -293,13 +328,8 @@ gst_cutter_chain (GstPad * pad, GstBuffer * buf)
|
|||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static double inline
|
||||
gst_cutter_16bit_ms (gint16 * data, guint num_samples)
|
||||
#include "filter.func"
|
||||
static double inline gst_cutter_8bit_ms (gint8 * data, guint num_samples)
|
||||
#include "filter.func"
|
||||
static void
|
||||
gst_cutter_set_property (GObject * object, guint prop_id,
|
||||
static void
|
||||
gst_cutter_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstCutter *filter;
|
||||
|
@ -309,7 +339,6 @@ gst_cutter_16bit_ms (gint16 * data, guint num_samples)
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_THRESHOLD:
|
||||
/* set the level */
|
||||
filter->threshold_level = g_value_get_double (value);
|
||||
GST_DEBUG ("DEBUG: set threshold level to %f", filter->threshold_level);
|
||||
break;
|
||||
|
@ -319,7 +348,8 @@ gst_cutter_16bit_ms (gint16 * data, guint num_samples)
|
|||
* values in dB < 0 result in values between 0 and 1
|
||||
*/
|
||||
filter->threshold_level = pow (10, g_value_get_double (value) / 20);
|
||||
GST_DEBUG ("DEBUG: set threshold level to %f", filter->threshold_level);
|
||||
GST_DEBUG_OBJECT (filter, "set threshold level to %f",
|
||||
filter->threshold_level);
|
||||
break;
|
||||
case PROP_RUN_LENGTH:
|
||||
/* set the minimum length of the silent run required */
|
||||
|
@ -397,6 +427,6 @@ gst_cutter_get_caps (GstPad * pad, GstCutter * filter)
|
|||
g_assert (caps != NULL);
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
gst_structure_get_int (structure, "width", &filter->width);
|
||||
filter->max_sample = gst_audio_highest_sample_value (pad);
|
||||
filter->max_sample = 1 << (filter->width - 1); /* signed */
|
||||
filter->have_caps = TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue