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~509^2~6027^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c6dea5d09cca67016f9bc8a09e2ef65945c8f8e4;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/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/gstdtmfdetect.c b/gst/dtmf/gstdtmfdetect.c deleted file mode 100644 index 6b53a60..0000000 --- a/gst/dtmf/gstdtmfdetect.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * GStreamer - DTMF Detection - * - * Copyright 2009 Nokia Corporation - * Copyright 2009 Collabora Ltd, - * @author: Olivier Crete - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -/** - * SECTION:element-dtmfdetect - * @short_description: Detects DTMF tones - * - * This element will detect DTMF tones and emit messages. - * - * The message is called "dtmf-event" and has - * the following fields: - * - * - * - * gint type (0-1): - * The application uses this field to specify which of the two methods - * specified in RFC 2833 to use. The value should be 0 for tones and 1 for - * named events. Tones are specified by their frequencies and events are - * specfied by their number. This element can only take events as input. - * Do not confuse with "method" which specified the output. - * - * - * - * - * gint number (0-16): - * The event number. - * - * - * - * - * gint method (2): - * This field will always been 2 (ie sound) from this element. - * - * - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gstdtmfdetect.h" - -#include - -#include - -GST_DEBUG_CATEGORY (dtmf_detect_debug); -#define GST_CAT_DEFAULT (dtmf_detect_debug) - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw, " - "format = (string) \"" GST_AUDIO_NE (S16) "\", " - "rate = (int) 8000, " "channels = (int) 1") - ); - - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/x-raw, " - "format = (string) \"" GST_AUDIO_NE (S16) "\", " - "rate = (int) 8000, " "channels = (int) 1") - ); - -/* signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - PROP_0, -}; - -static gboolean gst_dtmf_detect_set_caps (GstBaseTransform * trans, - GstCaps * incaps, GstCaps * outcaps); -static GstFlowReturn gst_dtmf_detect_transform_ip (GstBaseTransform * trans, - GstBuffer * buf); -static gboolean gst_dtmf_detect_sink_event (GstBaseTransform * trans, - GstEvent * event); - -G_DEFINE_TYPE (GstDtmfDetect, gst_dtmf_detect, GST_TYPE_BASE_TRANSFORM); - -static void -gst_dtmf_detect_class_init (GstDtmfDetectClass * klass) -{ - GstElementClass *gstelement_class; - GstBaseTransformClass *gstbasetransform_class; - - gstelement_class = GST_ELEMENT_CLASS (klass); - gstbasetransform_class = (GstBaseTransformClass *) klass; - - GST_DEBUG_CATEGORY_INIT (dtmf_detect_debug, "dtmfdetect", 0, "dtmfdetect"); - - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&srctemplate)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sinktemplate)); - - gst_element_class_set_static_metadata (gstelement_class, - "DTMF detector element", "Filter/Analyzer/Audio", - "This element detects DTMF tones", - "Olivier Crete "); - - gstbasetransform_class->set_caps = - GST_DEBUG_FUNCPTR (gst_dtmf_detect_set_caps); - gstbasetransform_class->transform_ip = - GST_DEBUG_FUNCPTR (gst_dtmf_detect_transform_ip); - gstbasetransform_class->sink_event = - GST_DEBUG_FUNCPTR (gst_dtmf_detect_sink_event); -} - -static void -gst_dtmf_detect_init (GstDtmfDetect * dtmfdetect) -{ - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (dtmfdetect), TRUE); - gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (dtmfdetect), TRUE); -} - -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); - - return TRUE; -} - - -static GstFlowReturn -gst_dtmf_detect_transform_ip (GstBaseTransform * trans, GstBuffer * buf) -{ - GstDtmfDetect *self = GST_DTMF_DETECT (trans); - gint dtmf_count; - gchar dtmfbuf[MAX_DTMF_DIGITS] = ""; - gint i; - GstMapInfo map; - - if (GST_BUFFER_IS_DISCONT (buf)) - zap_dtmf_detect_init (&self->dtmf_state); - 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_count = zap_dtmf_get (&self->dtmf_state, dtmfbuf, MAX_DTMF_DIGITS); - - if (dtmf_count) - GST_DEBUG_OBJECT (self, "Got %d DTMF events: %s", dtmf_count, dtmfbuf); - else - GST_LOG_OBJECT (self, "Got no DTMF events"); - - gst_buffer_unmap (buf, &map); - - for (i = 0; i < dtmf_count; i++) { - GstMessage *dtmf_message = NULL; - GstStructure *structure; - gint dtmf_payload_event; - - GST_DEBUG_OBJECT (self, "Got DTMF event %c", dtmfbuf[i]); - - switch (dtmfbuf[i]) { - case '0': - dtmf_payload_event = 0; - break; - case '1': - dtmf_payload_event = 1; - break; - case '2': - dtmf_payload_event = 2; - break; - case '3': - dtmf_payload_event = 3; - break; - case '4': - dtmf_payload_event = 4; - break; - case '5': - dtmf_payload_event = 5; - break; - case '6': - dtmf_payload_event = 6; - break; - case '7': - dtmf_payload_event = 7; - break; - case '8': - dtmf_payload_event = 8; - break; - case '9': - dtmf_payload_event = 9; - break; - case '*': - dtmf_payload_event = 10; - break; - case '#': - dtmf_payload_event = 11; - break; - case 'A': - dtmf_payload_event = 12; - break; - case 'B': - dtmf_payload_event = 13; - break; - case 'C': - dtmf_payload_event = 14; - break; - case 'D': - dtmf_payload_event = 15; - break; - default: - continue; - } - - structure = gst_structure_new ("dtmf-event", - "type", G_TYPE_INT, 1, - "number", G_TYPE_INT, dtmf_payload_event, - "method", G_TYPE_INT, 2, NULL); - dtmf_message = gst_message_new_element (GST_OBJECT (self), structure); - gst_element_post_message (GST_ELEMENT (self), dtmf_message); - } - - return GST_FLOW_OK; -} - - -static gboolean -gst_dtmf_detect_sink_event (GstBaseTransform * trans, GstEvent * event) -{ - GstDtmfDetect *self = GST_DTMF_DETECT (trans); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH_STOP: - zap_dtmf_detect_init (&self->dtmf_state); - break; - default: - break; - } - - return GST_BASE_TRANSFORM_CLASS (gst_dtmf_detect_parent_class)->sink_event - (trans, event); -} - - -gboolean -gst_dtmf_detect_plugin_init (GstPlugin * plugin) -{ - return gst_element_register (plugin, "dtmfdetect", - GST_RANK_MARGINAL, GST_TYPE_DTMF_DETECT); -} diff --git a/gst/dtmf/gstdtmfdetect.h b/gst/dtmf/gstdtmfdetect.h deleted file mode 100644 index fa42548..0000000 --- a/gst/dtmf/gstdtmfdetect.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * GStreamer - DTMF Detection - * - * Copyright 2009 Nokia Corporation - * Copyright 2009 Collabora Ltd, - * @author: Olivier Crete - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef __GST_DTMF_DETECT_H__ -#define __GST_DTMF_DETECT_H__ - -#include -#include - -#include "tone_detect.h" - -G_BEGIN_DECLS - -/* #define's don't like whitespacey bits */ -#define GST_TYPE_DTMF_DETECT \ - (gst_dtmf_detect_get_type()) -#define GST_DTMF_DETECT(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), \ - GST_TYPE_DTMF_DETECT,GstDtmfDetect)) -#define GST_DTMF_DETECT_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_DTMF_DETECT,GstDtmfDetectClass)) -#define GST_IS_DTMF_DETECT(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DTMF_DETECT)) -#define GST_IS_DTMF_DETECT_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DTMF_DETECT)) - -typedef struct _GstDtmfDetect GstDtmfDetect; -typedef struct _GstDtmfDetectClass GstDtmfDetectClass; -typedef struct _GstDtmfDetectPrivate GstDtmfDetectPrivate; - -struct _GstDtmfDetect -{ - GstBaseTransform parent; - - dtmf_detect_state_t dtmf_state; -}; - -struct _GstDtmfDetectClass -{ - GstBaseTransformClass parent_class; -}; - -GType gst_dtmf_detect_get_type (void); - -gboolean gst_dtmf_detect_plugin_init (GstPlugin *plugin); - -G_END_DECLS - -#endif /* __GST_DTMF_DETECT_H__ */ 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 ------------------------------------------------------------*/