removesilence: add threshold property

silence thresold was hardcoded to -60 dB, now it is configurable
using this new property

Closes #63
This commit is contained in:
Nicola Murino 2018-11-26 16:40:01 +01:00
parent e549566969
commit 8978f55886
3 changed files with 38 additions and 5 deletions

View file

@ -52,6 +52,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_remove_silence_debug);
#define MINIMUM_SILENCE_TIME_MIN 0 #define MINIMUM_SILENCE_TIME_MIN 0
#define MINIMUM_SILENCE_TIME_MAX 10000000000 #define MINIMUM_SILENCE_TIME_MAX 10000000000
#define MINIMUM_SILENCE_TIME_DEF 0 #define MINIMUM_SILENCE_TIME_DEF 0
#define DEFAULT_VAD_THRESHOLD -60
/* Filter signals and args */ /* Filter signals and args */
enum enum
@ -65,6 +66,7 @@ enum
PROP_0, PROP_0,
PROP_REMOVE, PROP_REMOVE,
PROP_HYSTERESIS, PROP_HYSTERESIS,
PROP_THRESHOLD,
PROP_SQUASH, PROP_SQUASH,
PROP_SILENT, PROP_SILENT,
PROP_MINIMUM_SILENCE_BUFFERS, 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", "Set the hysteresis (on samples) used on the internal VAD",
1, G_MAXUINT64, DEFAULT_VAD_HYSTERESIS, G_PARAM_READWRITE)); 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_object_class_install_property (gobject_class, PROP_SQUASH,
g_param_spec_boolean ("squash", "Squash", g_param_spec_boolean ("squash", "Squash",
"Set to true to retimestamp buffers when silence is removed and so avoid timestamp gap", "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 static void
gst_remove_silence_init (GstRemoveSilence * filter) 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->remove = FALSE;
filter->squash = FALSE; filter->squash = FALSE;
filter->ts_offset = 0; filter->ts_offset = 0;
@ -221,6 +229,9 @@ gst_remove_silence_set_property (GObject * object, guint prop_id,
case PROP_HYSTERESIS: case PROP_HYSTERESIS:
vad_set_hysteresis (filter->vad, g_value_get_uint64 (value)); vad_set_hysteresis (filter->vad, g_value_get_uint64 (value));
break; break;
case PROP_THRESHOLD:
vad_set_threshold (filter->vad, g_value_get_int (value));
break;
case PROP_SQUASH: case PROP_SQUASH:
filter->squash = g_value_get_boolean (value); filter->squash = g_value_get_boolean (value);
break; break;
@ -252,6 +263,9 @@ gst_remove_silence_get_property (GObject * object, guint prop_id,
case PROP_HYSTERESIS: case PROP_HYSTERESIS:
g_value_set_uint64 (value, vad_get_hysteresis (filter->vad)); g_value_set_uint64 (value, vad_get_hysteresis (filter->vad));
break; break;
case PROP_THRESHOLD:
g_value_set_int (value, vad_get_threshold_as_db (filter->vad));
break;
case PROP_SQUASH: case PROP_SQUASH:
g_value_set_boolean (value, filter->squash); g_value_set_boolean (value, filter->squash);
break; break;

View file

@ -22,11 +22,11 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include <glib.h> #include <glib.h>
#include "vad_private.h" #include "vad_private.h"
#define VAD_POWER_ALPHA 0x0800 /* Q16 */ #define VAD_POWER_ALPHA 0x0800 /* Q16 */
#define VAD_POWER_THRESHOLD 0x000010C7 /* -60 dB (square wave) */
#define VAD_ZCR_THRESHOLD 0 #define VAD_ZCR_THRESHOLD 0
#define VAD_BUFFER_SIZE 256 #define VAD_BUFFER_SIZE 256
@ -59,15 +59,17 @@ struct _vad_s
guint64 hysteresis; guint64 hysteresis;
guint64 vad_samples; guint64 vad_samples;
guint64 vad_power; guint64 vad_power;
guint64 threshold;
long vad_zcr; long vad_zcr;
}; };
VADFilter * VADFilter *
vad_new (guint64 hysteresis) vad_new (guint64 hysteresis, gint threshold)
{ {
VADFilter *vad = malloc (sizeof (VADFilter)); VADFilter *vad = malloc (sizeof (VADFilter));
vad_reset (vad); vad_reset (vad);
vad->hysteresis = hysteresis; vad->hysteresis = hysteresis;
vad_set_threshold (vad, threshold);
return vad; return vad;
} }
@ -99,6 +101,19 @@ vad_get_hysteresis (struct _vad_s *p)
return p->hysteresis; 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 gint
vad_update (struct _vad_s * p, gint16 * data, gint len) 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; ((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; && p->vad_zcr < VAD_ZCR_THRESHOLD) ? VAD_VOICE : VAD_SILENCE;
if (p->vad_state != frame_type) { if (p->vad_state != frame_type) {

View file

@ -35,7 +35,11 @@ void vad_set_hysteresis(VADFilter *p, guint64 hysteresis);
guint64 vad_get_hysteresis(VADFilter *p); 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); void vad_reset(VADFilter *p);