diff --git a/gst/removesilence/gstremovesilence.c b/gst/removesilence/gstremovesilence.c index c861f29be1..2debf57214 100644 --- a/gst/removesilence/gstremovesilence.c +++ b/gst/removesilence/gstremovesilence.c @@ -52,6 +52,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_remove_silence_debug); #define MINIMUM_SILENCE_TIME_MIN 0 #define MINIMUM_SILENCE_TIME_MAX 10000000000 #define MINIMUM_SILENCE_TIME_DEF 0 +#define DEFAULT_VAD_THRESHOLD -60 /* Filter signals and args */ enum @@ -65,6 +66,7 @@ enum PROP_0, PROP_REMOVE, PROP_HYSTERESIS, + PROP_THRESHOLD, PROP_SQUASH, PROP_SILENT, PROP_MINIMUM_SILENCE_BUFFERS, @@ -132,6 +134,12 @@ gst_remove_silence_class_init (GstRemoveSilenceClass * klass) "Set the hysteresis (on samples) used on the internal VAD", 1, G_MAXUINT64, DEFAULT_VAD_HYSTERESIS, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_THRESHOLD, + g_param_spec_int ("threshold", + "Threshold", + "Set the silence threshold used on the internal VAD in dB", + -70, 70, DEFAULT_VAD_THRESHOLD, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_SQUASH, g_param_spec_boolean ("squash", "Squash", "Set to true to retimestamp buffers when silence is removed and so avoid timestamp gap", @@ -180,7 +188,7 @@ gst_remove_silence_class_init (GstRemoveSilenceClass * klass) static void gst_remove_silence_init (GstRemoveSilence * filter) { - filter->vad = vad_new (DEFAULT_VAD_HYSTERESIS); + filter->vad = vad_new (DEFAULT_VAD_HYSTERESIS, DEFAULT_VAD_THRESHOLD); filter->remove = FALSE; filter->squash = FALSE; filter->ts_offset = 0; @@ -221,6 +229,9 @@ gst_remove_silence_set_property (GObject * object, guint prop_id, case PROP_HYSTERESIS: vad_set_hysteresis (filter->vad, g_value_get_uint64 (value)); break; + case PROP_THRESHOLD: + vad_set_threshold (filter->vad, g_value_get_int (value)); + break; case PROP_SQUASH: filter->squash = g_value_get_boolean (value); break; @@ -252,6 +263,9 @@ gst_remove_silence_get_property (GObject * object, guint prop_id, case PROP_HYSTERESIS: g_value_set_uint64 (value, vad_get_hysteresis (filter->vad)); break; + case PROP_THRESHOLD: + g_value_set_int (value, vad_get_threshold_as_db (filter->vad)); + break; case PROP_SQUASH: g_value_set_boolean (value, filter->squash); break; diff --git a/gst/removesilence/vad_private.c b/gst/removesilence/vad_private.c index 2c495967e6..369e18e6fc 100644 --- a/gst/removesilence/vad_private.c +++ b/gst/removesilence/vad_private.c @@ -22,11 +22,11 @@ #include #include #include +#include #include #include "vad_private.h" #define VAD_POWER_ALPHA 0x0800 /* Q16 */ -#define VAD_POWER_THRESHOLD 0x000010C7 /* -60 dB (square wave) */ #define VAD_ZCR_THRESHOLD 0 #define VAD_BUFFER_SIZE 256 @@ -59,15 +59,17 @@ struct _vad_s guint64 hysteresis; guint64 vad_samples; guint64 vad_power; + guint64 threshold; long vad_zcr; }; VADFilter * -vad_new (guint64 hysteresis) +vad_new (guint64 hysteresis, gint threshold) { VADFilter *vad = malloc (sizeof (VADFilter)); vad_reset (vad); vad->hysteresis = hysteresis; + vad_set_threshold (vad, threshold); return vad; } @@ -99,6 +101,19 @@ vad_get_hysteresis (struct _vad_s *p) return p->hysteresis; } +void +vad_set_threshold (struct _vad_s *p, gint threshold_db) +{ + gint power = (gint) (threshold_db / 10.0); + p->threshold = (guint64) (pow (10, (power)) * 4294967295); +} + +gint +vad_get_threshold_as_db (struct _vad_s *p) +{ + return (gint) (10 * log10 (p->threshold / 4294967295.0)); +} + gint vad_update (struct _vad_s * p, gint16 * data, gint len) { @@ -129,7 +144,7 @@ vad_update (struct _vad_s * p, gint16 * data, gint len) ((sample & 0x8000) != (p->cqueue.base.s[tail] & 0x8000)) ? 1 : -1; } - frame_type = (p->vad_power > VAD_POWER_THRESHOLD + frame_type = (p->vad_power > p->threshold && p->vad_zcr < VAD_ZCR_THRESHOLD) ? VAD_VOICE : VAD_SILENCE; if (p->vad_state != frame_type) { diff --git a/gst/removesilence/vad_private.h b/gst/removesilence/vad_private.h index 08eef627a0..530a38c5e5 100644 --- a/gst/removesilence/vad_private.h +++ b/gst/removesilence/vad_private.h @@ -35,7 +35,11 @@ void vad_set_hysteresis(VADFilter *p, guint64 hysteresis); guint64 vad_get_hysteresis(VADFilter *p); -VADFilter* vad_new(guint64 hysteresis); +void vad_set_threshold(VADFilter *p, gint threshold_db); + +gint vad_get_threshold_as_db(VADFilter *p); + +VADFilter* vad_new(guint64 hysteresis, gint threshold); void vad_reset(VADFilter *p);