From: Olivier CrĂȘte Date: Thu, 10 Jan 2013 00:59:16 +0000 (-0500) Subject: dtmf/spandsp: Move dtmfdetect to use libspandsp X-Git-Tag: 1.19.3~507^2~14173 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=81b452ba5ddab5ecffb7be10b8b0a648d9fc1f54;p=platform%2Fupstream%2Fgstreamer.git dtmf/spandsp: Move dtmfdetect to use libspandsp Remove our copy of the tone_detect.c file and use the original from libspandsp. Also move the element to the spandsp plugin. --- diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 90fa720..1269355 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -104,6 +104,8 @@ EXTRA_HFILES = \ $(top_srcdir)/ext/opencv/gsttextoverlay.h \ $(top_srcdir)/ext/rsvg/gstrsvgdec.h \ $(top_srcdir)/ext/rsvg/gstrsvgoverlay.h \ + $(top_srcdir)/ext/spandsp/gstspanplc.h \ + $(top_srcdir)/ext/spandsp/gstdtmfdetect.h \ $(top_srcdir)/ext/sdl/sdlaudiosink.h \ $(top_srcdir)/ext/sdl/sdlvideosink.h \ $(top_srcdir)/ext/timidity/gsttimidity.h \ @@ -128,7 +130,6 @@ EXTRA_HFILES = \ $(top_srcdir)/gst/dccp/gstdccpserversrc.h \ $(top_srcdir)/gst/debugutils/fpsdisplaysink.h \ $(top_srcdir)/gst/dtmf/gstdtmfsrc.h \ - $(top_srcdir)/gst/dtmf/gstdtmfdetect.h \ $(top_srcdir)/gst/dtmf/gstrtpdtmfsrc.h \ $(top_srcdir)/gst/dtmf/gstrtpdtmfdepay.h \ $(top_srcdir)/gst/dvdspu/gstdvdspu.h \ diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt index aa5a395..7feecb7 100644 --- a/docs/plugins/gst-plugins-bad-plugins-sections.txt +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -500,6 +500,7 @@ gst_dtmf_src_plugin_init GstDtmfDetect GstDtmfDetectClass +GstDtmfDetectPrivate GST_TYPE_DTMF_DETECT GST_DTMF_DETECT GST_DTMF_DETECT_CAST diff --git a/ext/spandsp/Makefile.am b/ext/spandsp/Makefile.am index 4658595..bd76a93 100644 --- a/ext/spandsp/Makefile.am +++ b/ext/spandsp/Makefile.am @@ -1,9 +1,10 @@ plugin_LTLIBRARIES = libgstspandsp.la -libgstspandsp_la_SOURCES = gstspandsp.c gstspanplc.c +libgstspandsp_la_SOURCES = gstspandsp.c gstspanplc.c gstdtmfdetect.c libgstspandsp_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(SPANDSP_CFLAGS) -libgstspandsp_la_LIBADD = $(SPANDSP_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) +libgstspandsp_la_LIBADD = $(SPANDSP_LIBS) $(GST_PLUGINS_BASE_LIBS) \ + $(GST_BASE_LIBS) $(GST_LIBS) libgstspandsp_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstspandsp_la_LIBTOOLFLAGS = --tag=disable-static -noinst_HEADERS = gstspanplc.h +noinst_HEADERS = gstspanplc.h gstdtmfdetect.h diff --git a/gst/dtmf/gstdtmfdetect.c b/ext/spandsp/gstdtmfdetect.c similarity index 89% rename from gst/dtmf/gstdtmfdetect.c rename to ext/spandsp/gstdtmfdetect.c index 6b53a60..41966e4 100644 --- a/gst/dtmf/gstdtmfdetect.c +++ b/ext/spandsp/gstdtmfdetect.c @@ -98,6 +98,8 @@ enum PROP_0, }; +static void gst_dtmf_detect_finalize (GObject * object); + static gboolean gst_dtmf_detect_set_caps (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps); static GstFlowReturn gst_dtmf_detect_transform_ip (GstBaseTransform * trans, @@ -110,14 +112,18 @@ G_DEFINE_TYPE (GstDtmfDetect, gst_dtmf_detect, GST_TYPE_BASE_TRANSFORM); static void gst_dtmf_detect_class_init (GstDtmfDetectClass * klass) { + GObjectClass *gobject_class; GstElementClass *gstelement_class; GstBaseTransformClass *gstbasetransform_class; + gobject_class = G_OBJECT_CLASS (klass); gstelement_class = GST_ELEMENT_CLASS (klass); gstbasetransform_class = (GstBaseTransformClass *) klass; GST_DEBUG_CATEGORY_INIT (dtmf_detect_debug, "dtmfdetect", 0, "dtmfdetect"); + gobject_class->finalize = gst_dtmf_detect_finalize; + gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate)); gst_element_class_add_pad_template (gstelement_class, @@ -143,13 +149,32 @@ gst_dtmf_detect_init (GstDtmfDetect * dtmfdetect) gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (dtmfdetect), TRUE); } +static void +gst_dtmf_detect_finalize (GObject * object) +{ + GstDtmfDetect *self = GST_DTMF_DETECT (object); + + if (self->dtmf_state) + dtmf_rx_free (self->dtmf_state); + + G_OBJECT_CLASS (gst_dtmf_detect_parent_class)->finalize (object); +} + +static void +gst_dtmf_detect_state_reset (GstDtmfDetect * self) +{ + if (self->dtmf_state) + dtmf_rx_free (self->dtmf_state); + self->dtmf_state = dtmf_rx_init (NULL, NULL, NULL); +} + static gboolean gst_dtmf_detect_set_caps (GstBaseTransform * trans, GstCaps * incaps, GstCaps * outcaps) { GstDtmfDetect *self = GST_DTMF_DETECT (trans); - zap_dtmf_detect_init (&self->dtmf_state); + gst_dtmf_detect_state_reset (self); return TRUE; } @@ -165,15 +190,15 @@ gst_dtmf_detect_transform_ip (GstBaseTransform * trans, GstBuffer * buf) GstMapInfo map; if (GST_BUFFER_IS_DISCONT (buf)) - zap_dtmf_detect_init (&self->dtmf_state); + gst_dtmf_detect_state_reset (self); if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP)) return GST_FLOW_OK; gst_buffer_map (buf, &map, GST_MAP_READ); - zap_dtmf_detect (&self->dtmf_state, (gint16 *) map.data, map.size / 2, FALSE); + dtmf_rx (self->dtmf_state, (gint16 *) map.data, map.size / 2); - dtmf_count = zap_dtmf_get (&self->dtmf_state, dtmfbuf, MAX_DTMF_DIGITS); + dtmf_count = dtmf_rx_get (self->dtmf_state, dtmfbuf, MAX_DTMF_DIGITS); if (dtmf_count) GST_DEBUG_OBJECT (self, "Got %d DTMF events: %s", dtmf_count, dtmfbuf); @@ -261,7 +286,7 @@ gst_dtmf_detect_sink_event (GstBaseTransform * trans, GstEvent * event) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_STOP: - zap_dtmf_detect_init (&self->dtmf_state); + gst_dtmf_detect_state_reset (self); break; default: break; diff --git a/gst/dtmf/gstdtmfdetect.h b/ext/spandsp/gstdtmfdetect.h similarity index 97% rename from gst/dtmf/gstdtmfdetect.h rename to ext/spandsp/gstdtmfdetect.h index fa42548..e0de5c1 100644 --- a/gst/dtmf/gstdtmfdetect.h +++ b/ext/spandsp/gstdtmfdetect.h @@ -28,7 +28,7 @@ #include #include -#include "tone_detect.h" +#include G_BEGIN_DECLS @@ -54,7 +54,7 @@ struct _GstDtmfDetect { GstBaseTransform parent; - dtmf_detect_state_t dtmf_state; + dtmf_rx_state_t *dtmf_state; }; struct _GstDtmfDetectClass diff --git a/ext/spandsp/gstspandsp.c b/ext/spandsp/gstspandsp.c index 8a05625..0fdce79 100644 --- a/ext/spandsp/gstspandsp.c +++ b/ext/spandsp/gstspandsp.c @@ -25,12 +25,14 @@ #endif #include "gstspanplc.h" +#include "gstdtmfdetect.h" static gboolean plugin_init (GstPlugin * plugin) { return gst_element_register (plugin, "spanplc", - GST_RANK_PRIMARY, GST_TYPE_SPAN_PLC); + GST_RANK_PRIMARY, GST_TYPE_SPAN_PLC) && + gst_dtmf_detect_plugin_init (plugin); } GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, diff --git a/gst/dtmf/Makefile.am b/gst/dtmf/Makefile.am index 00b648f..56eda16 100644 --- a/gst/dtmf/Makefile.am +++ b/gst/dtmf/Makefile.am @@ -1,21 +1,16 @@ plugin_LTLIBRARIES = libgstdtmf.la libgstdtmf_la_SOURCES = gstdtmfsrc.c \ - gstdtmfdetect.c \ gstrtpdtmfsrc.c \ gstrtpdtmfdepay.c \ - tone_detect.c \ gstdtmf.c noinst_HEADERS = gstdtmfsrc.h \ - gstdtmfdetect.h \ gstrtpdtmfsrc.h \ gstrtpdtmfdepay.h \ - gstdtmfcommon.h \ - tone_detect.h + gstdtmfcommon.h -libgstdtmf_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \ - -DEXTERN_BUF -DRTP_SUPPORT +libgstdtmf_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) libgstdtmf_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-@GST_API_VERSION@ \ $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) libgstdtmf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) @@ -33,4 +28,4 @@ Android.mk: Makefile.am $(BUILT_SOURCES) -ldl \ -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \ - > $@ \ No newline at end of file + > $@ diff --git a/gst/dtmf/gstdtmf.c b/gst/dtmf/gstdtmf.c index ddd4058..7fd5ee8 100644 --- a/gst/dtmf/gstdtmf.c +++ b/gst/dtmf/gstdtmf.c @@ -3,7 +3,6 @@ #include "config.h" #endif -#include "gstdtmfdetect.h" #include "gstdtmfsrc.h" #include "gstrtpdtmfsrc.h" #include "gstrtpdtmfdepay.h" @@ -12,9 +11,6 @@ static gboolean plugin_init (GstPlugin * plugin) { - if (!gst_dtmf_detect_plugin_init (plugin)) - return FALSE; - if (!gst_dtmf_src_plugin_init (plugin)) return FALSE; diff --git a/gst/dtmf/tone_detect.c b/gst/dtmf/tone_detect.c deleted file mode 100644 index 73a73ee..0000000 --- a/gst/dtmf/tone_detect.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * DTMF Receiver module, part of: - * BSD Telephony Of Mexico "Zapata" Telecom Library, version 1.10 12/9/01 - * - * Part of the "Zapata" Computer Telephony Technology. - * - * See http://www.bsdtelephony.com.mx - * - * - * The technologies, software, hardware, designs, drawings, scheumatics, board - * layouts and/or artwork, concepts, methodologies (including the use of all - * of these, and that which is derived from the use of all of these), all other - * intellectual properties contained herein, and all intellectual property - * rights have been and shall continue to be expressly for the benefit of all - * mankind, and are perpetually placed in the public domain, and may be used, - * copied, and/or modified by anyone, in any manner, for any legal purpose, - * without restriction. - * - * This module written by Stephen Underwood. - */ - -/* - tone_detect.c - General telephony tone detection, and specific - detection of DTMF. - - Copyright (C) 2001 Steve Underwood - - Despite my general liking of the GPL, I place this code in the - public domain for the benefit of all mankind - even the slimy - ones who might try to proprietize my work and use it to my - detriment. -*/ - -#include -#include -#include -#include -#include -#include "tone_detect.h" - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -//#define USE_3DNOW - -/* Basic DTMF specs: - * - * Minimum tone on = 40ms - * Minimum tone off = 50ms - * Maximum digit rate = 10 per second - * Normal twist <= 8dB accepted - * Reverse twist <= 4dB accepted - * S/N >= 15dB will detect OK - * Attenuation <= 26dB will detect OK - * Frequency tolerance +- 1.5% will detect, +-3.5% will reject - */ - -#define SAMPLE_RATE 8000.0 - -#define DTMF_THRESHOLD 8.0e7 -#define FAX_THRESHOLD 8.0e7 -#define FAX_2ND_HARMONIC 2.0 /* 4dB */ -#define DTMF_NORMAL_TWIST 6.3 /* 8dB */ -#define DTMF_REVERSE_TWIST ((isradio) ? 4.0 : 2.5) /* 4dB normal */ -#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */ -#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */ -#define DTMF_2ND_HARMONIC_ROW ((isradio) ? 1.7 : 2.5) /* 4dB normal */ -#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */ - -static tone_detection_descriptor_t dtmf_detect_row[4]; -static tone_detection_descriptor_t dtmf_detect_col[4]; -static tone_detection_descriptor_t dtmf_detect_row_2nd[4]; -static tone_detection_descriptor_t dtmf_detect_col_2nd[4]; -static tone_detection_descriptor_t fax_detect; -static tone_detection_descriptor_t fax_detect_2nd; - -static float dtmf_row[] = { - 697.0, 770.0, 852.0, 941.0 -}; - -static float dtmf_col[] = { - 1209.0, 1336.0, 1477.0, 1633.0 -}; - -static float fax_freq = 1100.0; - -static char dtmf_positions[] = "123A" "456B" "789C" "*0#D"; - -static void -goertzel_init (goertzel_state_t * s, tone_detection_descriptor_t * t) -{ - s->v2 = s->v3 = 0.0; - s->fac = t->fac; -} - -/*- End of function --------------------------------------------------------*/ - -#if defined(USE_3DNOW) -static inline void -_dtmf_goertzel_update (goertzel_state_t * s, float x[], int samples) -{ - int n; - float v; - int i; - float vv[16]; - - vv[4] = s[0].v2; - vv[5] = s[1].v2; - vv[6] = s[2].v2; - vv[7] = s[3].v2; - vv[8] = s[0].v3; - vv[9] = s[1].v3; - vv[10] = s[2].v3; - vv[11] = s[3].v3; - vv[12] = s[0].fac; - vv[13] = s[1].fac; - vv[14] = s[2].fac; - vv[15] = s[3].fac; - - //v1 = s->v2; - //s->v2 = s->v3; - //s->v3 = s->fac*s->v2 - v1 + x[0]; - - __asm__ __volatile__ (" femms;\n" - " movq 16(%%edx),%%mm2;\n" - " movq 24(%%edx),%%mm3;\n" - " movq 32(%%edx),%%mm4;\n" - " movq 40(%%edx),%%mm5;\n" - " movq 48(%%edx),%%mm6;\n" - " movq 56(%%edx),%%mm7;\n" - " jmp 1f;\n" - " .align 32;\n" - " 1: ;\n" - " prefetch (%%eax);\n" - " movq %%mm3,%%mm1;\n" - " movq %%mm2,%%mm0;\n" - " movq %%mm5,%%mm3;\n" - " movq %%mm4,%%mm2;\n" - " pfmul %%mm7,%%mm5;\n" - " pfmul %%mm6,%%mm4;\n" - " pfsub %%mm1,%%mm5;\n" - " pfsub %%mm0,%%mm4;\n" - " movq (%%eax),%%mm0;\n" - " movq %%mm0,%%mm1;\n" - " punpckldq %%mm0,%%mm1;\n" - " add $4,%%eax;\n" - " pfadd %%mm1,%%mm5;\n" - " pfadd %%mm1,%%mm4;\n" - " dec %%ecx;\n" - " jnz 1b;\n" - " movq %%mm2,16(%%edx);\n" - " movq %%mm3,24(%%edx);\n" - " movq %%mm4,32(%%edx);\n" - " movq %%mm5,40(%%edx);\n" - " femms;\n"::"c" (samples), "a" (x), "d" (vv) - :"memory", "eax", "ecx"); - - s[0].v2 = vv[4]; - s[1].v2 = vv[5]; - s[2].v2 = vv[6]; - s[3].v2 = vv[7]; - s[0].v3 = vv[8]; - s[1].v3 = vv[9]; - s[2].v3 = vv[10]; - s[3].v3 = vv[11]; -} -#endif -/*- End of function --------------------------------------------------------*/ - -void -zap_goertzel_update (goertzel_state_t * s, int16_t x[], int samples) -{ - int i; - float v1; - - for (i = 0; i < samples; i++) { - v1 = s->v2; - s->v2 = s->v3; - s->v3 = s->fac * s->v2 - v1 + x[i]; - } -} - -/*- End of function --------------------------------------------------------*/ - -float -zap_goertzel_result (goertzel_state_t * s) -{ - return s->v3 * s->v3 + s->v2 * s->v2 - s->v2 * s->v3 * s->fac; -} - -/*- End of function --------------------------------------------------------*/ - -void -zap_dtmf_detect_init (dtmf_detect_state_t * s) -{ - int i; - float theta; - - s->hit1 = s->hit2 = 0; - - for (i = 0; i < 4; i++) { - theta = 2.0 * G_PI * (dtmf_row[i] / SAMPLE_RATE); - dtmf_detect_row[i].fac = 2.0 * cos (theta); - - theta = 2.0 * G_PI * (dtmf_col[i] / SAMPLE_RATE); - dtmf_detect_col[i].fac = 2.0 * cos (theta); - - theta = 2.0 * G_PI * (dtmf_row[i] * 2.0 / SAMPLE_RATE); - dtmf_detect_row_2nd[i].fac = 2.0 * cos (theta); - - theta = 2.0 * G_PI * (dtmf_col[i] * 2.0 / SAMPLE_RATE); - dtmf_detect_col_2nd[i].fac = 2.0 * cos (theta); - - goertzel_init (&s->row_out[i], &dtmf_detect_row[i]); - goertzel_init (&s->col_out[i], &dtmf_detect_col[i]); - goertzel_init (&s->row_out2nd[i], &dtmf_detect_row_2nd[i]); - goertzel_init (&s->col_out2nd[i], &dtmf_detect_col_2nd[i]); - - s->energy = 0.0; - } - - /* Same for the fax dector */ - theta = 2.0 * G_PI * (fax_freq / SAMPLE_RATE); - fax_detect.fac = 2.0 * cos (theta); - goertzel_init (&s->fax_tone, &fax_detect); - - /* Same for the fax dector 2nd harmonic */ - theta = 2.0 * G_PI * (fax_freq * 2.0 / SAMPLE_RATE); - fax_detect_2nd.fac = 2.0 * cos (theta); - goertzel_init (&s->fax_tone2nd, &fax_detect_2nd); - - s->current_sample = 0; - s->detected_digits = 0; - s->lost_digits = 0; - s->digits[0] = '\0'; - s->mhit = 0; -} - -/*- End of function --------------------------------------------------------*/ - -int -zap_dtmf_detect (dtmf_detect_state_t * s, - int16_t amp[], int samples, int isradio) -{ - - float row_energy[4]; - float col_energy[4]; - float fax_energy; - float fax_energy_2nd; - float famp; - float v1; - int i; - int j; - int sample; - int best_row; - int best_col; - int hit; - int limit; - - hit = 0; - for (sample = 0; sample < samples; sample = limit) { - /* 102 is optimised to meet the DTMF specs. */ - if ((samples - sample) >= (102 - s->current_sample)) - limit = sample + (102 - s->current_sample); - else - limit = samples; -#if defined(USE_3DNOW) - _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample); - _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample); - _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample); - _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample); - /* XXX Need to fax detect for 3dnow too XXX */ -#warning "Fax Support Broken" -#else - /* The following unrolled loop takes only 35% (rough estimate) of the - time of a rolled loop on the machine on which it was developed */ - for (j = sample; j < limit; j++) { - famp = amp[j]; - - s->energy += famp * famp; - - /* With GCC 2.95, the following unrolled code seems to take about 35% - (rough estimate) as long as a neat little 0-3 loop */ - v1 = s->row_out[0].v2; - s->row_out[0].v2 = s->row_out[0].v3; - s->row_out[0].v3 = s->row_out[0].fac * s->row_out[0].v2 - v1 + famp; - - v1 = s->col_out[0].v2; - s->col_out[0].v2 = s->col_out[0].v3; - s->col_out[0].v3 = s->col_out[0].fac * s->col_out[0].v2 - v1 + famp; - - v1 = s->row_out[1].v2; - s->row_out[1].v2 = s->row_out[1].v3; - s->row_out[1].v3 = s->row_out[1].fac * s->row_out[1].v2 - v1 + famp; - - v1 = s->col_out[1].v2; - s->col_out[1].v2 = s->col_out[1].v3; - s->col_out[1].v3 = s->col_out[1].fac * s->col_out[1].v2 - v1 + famp; - - v1 = s->row_out[2].v2; - s->row_out[2].v2 = s->row_out[2].v3; - s->row_out[2].v3 = s->row_out[2].fac * s->row_out[2].v2 - v1 + famp; - - v1 = s->col_out[2].v2; - s->col_out[2].v2 = s->col_out[2].v3; - s->col_out[2].v3 = s->col_out[2].fac * s->col_out[2].v2 - v1 + famp; - - v1 = s->row_out[3].v2; - s->row_out[3].v2 = s->row_out[3].v3; - s->row_out[3].v3 = s->row_out[3].fac * s->row_out[3].v2 - v1 + famp; - - v1 = s->col_out[3].v2; - s->col_out[3].v2 = s->col_out[3].v3; - s->col_out[3].v3 = s->col_out[3].fac * s->col_out[3].v2 - v1 + famp; - - v1 = s->col_out2nd[0].v2; - s->col_out2nd[0].v2 = s->col_out2nd[0].v3; - s->col_out2nd[0].v3 = - s->col_out2nd[0].fac * s->col_out2nd[0].v2 - v1 + famp; - - v1 = s->row_out2nd[0].v2; - s->row_out2nd[0].v2 = s->row_out2nd[0].v3; - s->row_out2nd[0].v3 = - s->row_out2nd[0].fac * s->row_out2nd[0].v2 - v1 + famp; - - v1 = s->col_out2nd[1].v2; - s->col_out2nd[1].v2 = s->col_out2nd[1].v3; - s->col_out2nd[1].v3 = - s->col_out2nd[1].fac * s->col_out2nd[1].v2 - v1 + famp; - - v1 = s->row_out2nd[1].v2; - s->row_out2nd[1].v2 = s->row_out2nd[1].v3; - s->row_out2nd[1].v3 = - s->row_out2nd[1].fac * s->row_out2nd[1].v2 - v1 + famp; - - v1 = s->col_out2nd[2].v2; - s->col_out2nd[2].v2 = s->col_out2nd[2].v3; - s->col_out2nd[2].v3 = - s->col_out2nd[2].fac * s->col_out2nd[2].v2 - v1 + famp; - - v1 = s->row_out2nd[2].v2; - s->row_out2nd[2].v2 = s->row_out2nd[2].v3; - s->row_out2nd[2].v3 = - s->row_out2nd[2].fac * s->row_out2nd[2].v2 - v1 + famp; - - v1 = s->col_out2nd[3].v2; - s->col_out2nd[3].v2 = s->col_out2nd[3].v3; - s->col_out2nd[3].v3 = - s->col_out2nd[3].fac * s->col_out2nd[3].v2 - v1 + famp; - - v1 = s->row_out2nd[3].v2; - s->row_out2nd[3].v2 = s->row_out2nd[3].v3; - s->row_out2nd[3].v3 = - s->row_out2nd[3].fac * s->row_out2nd[3].v2 - v1 + famp; - - /* Update fax tone */ - v1 = s->fax_tone.v2; - s->fax_tone.v2 = s->fax_tone.v3; - s->fax_tone.v3 = s->fax_tone.fac * s->fax_tone.v2 - v1 + famp; - - v1 = s->fax_tone.v2; - s->fax_tone2nd.v2 = s->fax_tone2nd.v3; - s->fax_tone2nd.v3 = s->fax_tone2nd.fac * s->fax_tone2nd.v2 - v1 + famp; - } -#endif - s->current_sample += (limit - sample); - if (s->current_sample < 102) - continue; - - /* Detect the fax energy, too */ - fax_energy = zap_goertzel_result (&s->fax_tone); - - /* We are at the end of a DTMF detection block */ - /* Find the peak row and the peak column */ - row_energy[0] = zap_goertzel_result (&s->row_out[0]); - col_energy[0] = zap_goertzel_result (&s->col_out[0]); - - for (best_row = best_col = 0, i = 1; i < 4; i++) { - row_energy[i] = zap_goertzel_result (&s->row_out[i]); - if (row_energy[i] > row_energy[best_row]) - best_row = i; - col_energy[i] = zap_goertzel_result (&s->col_out[i]); - if (col_energy[i] > col_energy[best_col]) - best_col = i; - } - hit = 0; - /* Basic signal level test and the twist test */ - if (row_energy[best_row] >= DTMF_THRESHOLD - && - col_energy[best_col] >= DTMF_THRESHOLD - && - col_energy[best_col] < row_energy[best_row] * DTMF_REVERSE_TWIST - && col_energy[best_col] * DTMF_NORMAL_TWIST > row_energy[best_row]) { - /* Relative peak test */ - for (i = 0; i < 4; i++) { - if ((i != best_col - && col_energy[i] * DTMF_RELATIVE_PEAK_COL > - col_energy[best_col]) - || (i != best_row - && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > - row_energy[best_row])) { - break; - } - } - /* ... and second harmonic test */ - if (i >= 4 - && - (row_energy[best_row] + col_energy[best_col]) > 42.0 * s->energy - && - zap_goertzel_result (&s->col_out2nd[best_col]) * - DTMF_2ND_HARMONIC_COL < col_energy[best_col] - && zap_goertzel_result (&s->row_out2nd[best_row]) * - DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) { - hit = dtmf_positions[(best_row << 2) + best_col]; - /* Look for two successive similar results */ - /* The logic in the next test is: - We need two successive identical clean detects, with - something different preceeding it. This can work with - back to back differing digits. More importantly, it - can work with nasty phones that give a very wobbly start - to a digit. */ - if (hit == s->hit3 && s->hit3 != s->hit2) { - s->mhit = hit; - s->digit_hits[(best_row << 2) + best_col]++; - s->detected_digits++; - if (s->current_digits < MAX_DTMF_DIGITS) { - s->digits[s->current_digits++] = hit; - s->digits[s->current_digits] = '\0'; - } else { - s->lost_digits++; - } - } - } - } - if (!hit && (fax_energy >= FAX_THRESHOLD) - && (fax_energy > s->energy * 21.0)) { - fax_energy_2nd = zap_goertzel_result (&s->fax_tone2nd); - if (fax_energy_2nd * FAX_2ND_HARMONIC < fax_energy) { -#if 0 - printf ("Fax energy/Second Harmonic: %f/%f\n", fax_energy, - fax_energy_2nd); -#endif - /* XXX Probably need better checking than just this the energy XXX */ - hit = 'f'; - s->fax_hits++; - } /* Don't reset fax hits counter */ - } else { - if (s->fax_hits > 5) { - s->mhit = 'f'; - s->detected_digits++; - if (s->current_digits < MAX_DTMF_DIGITS) { - s->digits[s->current_digits++] = hit; - s->digits[s->current_digits] = '\0'; - } else { - s->lost_digits++; - } - } - s->fax_hits = 0; - } - s->hit1 = s->hit2; - s->hit2 = s->hit3; - s->hit3 = hit; - /* Reinitialise the detector for the next block */ - for (i = 0; i < 4; i++) { - goertzel_init (&s->row_out[i], &dtmf_detect_row[i]); - goertzel_init (&s->col_out[i], &dtmf_detect_col[i]); - goertzel_init (&s->row_out2nd[i], &dtmf_detect_row_2nd[i]); - goertzel_init (&s->col_out2nd[i], &dtmf_detect_col_2nd[i]); - } - goertzel_init (&s->fax_tone, &fax_detect); - goertzel_init (&s->fax_tone2nd, &fax_detect_2nd); - s->energy = 0.0; - s->current_sample = 0; - } - if ((!s->mhit) || (s->mhit != hit)) { - s->mhit = 0; - return (0); - } - return (hit); -} - -/*- End of function --------------------------------------------------------*/ - -int -zap_dtmf_get (dtmf_detect_state_t * s, char *buf, int max) -{ - if (max > s->current_digits) - max = s->current_digits; - if (max > 0) { - memcpy (buf, s->digits, max); - memmove (s->digits, s->digits + max, s->current_digits - max); - s->current_digits -= max; - } - buf[max] = '\0'; - return max; -} - -/*- End of function --------------------------------------------------------*/ -/*- End of file ------------------------------------------------------------*/ diff --git a/gst/dtmf/tone_detect.h b/gst/dtmf/tone_detect.h deleted file mode 100644 index ce6dddd..0000000 --- a/gst/dtmf/tone_detect.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Header file for DTMF Receiver module, part of: - * BSD Telephony Of Mexico "Zapata" Telecom Library, version 1.10 12/9/01 - * - * Part of the "Zapata" Computer Telephony Technology. - * - * See http://www.bsdtelephony.com.mx - * - * - * The technologies, software, hardware, designs, drawings, scheumatics, board - * layouts and/or artwork, concepts, methodologies (including the use of all - * of these, and that which is derived from the use of all of these), all other - * intellectual properties contained herein, and all intellectual property - * rights have been and shall continue to be expressly for the benefit of all - * mankind, and are perpetually placed in the public domain, and may be used, - * copied, and/or modified by anyone, in any manner, for any legal purpose, - * without restriction. - * - * This module written by Stephen Underwood. - */ -/* - tone_detect.h - General telephony tone detection, and specific - detection of DTMF. - - Copyright (C) 2001 Steve Underwood - - Despite my general liking of the GPL, I place this code in the - public domain for the benefit of all mankind - even the slimy - ones who might try to proprietize my work and use it to my - detriment. -*/ - -#ifndef __TONE_DETECT_H__ -#define __TONE_DETECT_H__ - -#include "_stdint.h" - -#include - -typedef struct -{ - float v2; - float v3; - float fac; -} goertzel_state_t; - -#define MAX_DTMF_DIGITS 128 - -typedef struct -{ - int hit1; - int hit2; - int hit3; - int hit4; - int mhit; - - goertzel_state_t row_out[4]; - goertzel_state_t col_out[4]; - goertzel_state_t row_out2nd[4]; - goertzel_state_t col_out2nd[4]; - goertzel_state_t fax_tone; - goertzel_state_t fax_tone2nd; - float energy; - - int current_sample; - char digits[MAX_DTMF_DIGITS + 1]; - int current_digits; - int detected_digits; - int lost_digits; - int digit_hits[16]; - int fax_hits; -} dtmf_detect_state_t; - -typedef struct -{ - float fac; -} tone_detection_descriptor_t; - -void zap_goertzel_update(goertzel_state_t *s, - gint16 x[], - int samples); -float zap_goertzel_result (goertzel_state_t *s); - -void zap_dtmf_detect_init (dtmf_detect_state_t *s); -int zap_dtmf_detect (dtmf_detect_state_t *s, - gint16 amp[], - int samples, - int isradio); -int zap_dtmf_get (dtmf_detect_state_t *s, - char *buf, - int max); - -#endif /* __TONE_DETECT_H__ */ - -/*- End of file ------------------------------------------------------------*/