summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorhm <hm@FreeBSD.org>1999-03-07 17:09:03 +0000
committerhm <hm@FreeBSD.org>1999-03-07 17:09:03 +0000
commitd3cdfce5f6a0a4d9c1806d24c9a9bd5e5ee676a6 (patch)
tree4651172a60edd6afc0f607f4e3ec4adeb513a676 /usr.sbin
parent36b481d4f3a44d80e63d9ab230c89bdc520fb8c2 (diff)
downloadFreeBSD-src-d3cdfce5f6a0a4d9c1806d24c9a9bd5e5ee676a6.zip
FreeBSD-src-d3cdfce5f6a0a4d9c1806d24c9a9bd5e5ee676a6.tar.gz
add the dtmfdecode program (added to i4b with 0.71.00) to the i4b userland
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/i4b/Makefile2
-rw-r--r--usr.sbin/i4b/dtmfdecode/Makefile15
-rw-r--r--usr.sbin/i4b/dtmfdecode/README44
-rw-r--r--usr.sbin/i4b/dtmfdecode/dtmfdecode.161
-rw-r--r--usr.sbin/i4b/dtmfdecode/dtmfdecode.c158
5 files changed, 279 insertions, 1 deletions
diff --git a/usr.sbin/i4b/Makefile b/usr.sbin/i4b/Makefile
index 3c12d78..c1d71e7 100644
--- a/usr.sbin/i4b/Makefile
+++ b/usr.sbin/i4b/Makefile
@@ -1,4 +1,4 @@
SUBDIR = isdntrace isdndebug isdnd alawulaw man isdntest \
- isdntel isdntelctl isdnmonitor isdndecode
+ isdntel isdntelctl isdnmonitor isdndecode dtmfdecode
.include <bsd.subdir.mk>
diff --git a/usr.sbin/i4b/dtmfdecode/Makefile b/usr.sbin/i4b/dtmfdecode/Makefile
new file mode 100644
index 0000000..e814285
--- /dev/null
+++ b/usr.sbin/i4b/dtmfdecode/Makefile
@@ -0,0 +1,15 @@
+#---------------------------------------------------------------------------
+#
+# $Id: Makefile,v 1.1 1999/02/15 19:13:47 hm Exp $
+#
+# last edit-date: [Mon Feb 15 20:04:40 1999]
+#
+#---------------------------------------------------------------------------
+
+PROG = dtmfdecode
+SRC = dtmfdecode.c
+LDADD += -lm
+CFLAGS += -Wall -g -DDEBUG
+MAN1 = dtmfdecode.1
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/i4b/dtmfdecode/README b/usr.sbin/i4b/dtmfdecode/README
new file mode 100644
index 0000000..d25cbd2
--- /dev/null
+++ b/usr.sbin/i4b/dtmfdecode/README
@@ -0,0 +1,44 @@
+
+ [Note: the version included in i4b does not output any data you can
+ plot, but will just print the values of the tones it detected. -hm]
+
+
+Poul-Henning Kamp wrote:
+------------------------
+
+I remember that somebody asked about this long time ago, so I sat
+down and hacked a digital filter for that.
+
+The following piece of code will read a ".g711a" file, and output
+9 columns of data. The first is the linear value of the sample,
+the other 8 are strength of the 8 DTMF tones.
+
+Try to run the "beep.g711a" file from i4b through it, and plot the
+output columns with gnuplot. It seems Hellmuth pressed a '1' :-)
+
+The implementation is a recursive resonance filter, actually 8 of
+them, one for each frequency, done in floating point. With a little
+attention to rounding, it can be done just as good, and much faster
+in integer math, in fact 16 bit should be enough, but may not be
+faster than 32bit.
+
+The "POLRAD" quantity determines the resonance width of the filters,
+if you make it too low, it will confuse tones and recognize them
+where they are not. If you make it too high (never, ever >= 1.0!)
+it will take longer to react and maybe not catch a slightly offbeat
+tone. If you set it above or equal to 1.0 you get a tone generator.
+
+This could also be a good basis for a 300Baud FSK modem emulation.
+
+It seems that the .g711a files are bit-flipped, therefore the flip[]
+array trick in this code. The alaw->linear converter is lifted from
+sox.
+
+Now, who writes the answering-machine to end all answering machines
+for i4b ?
+
+Poul-Henning
+--
+Poul-Henning Kamp FreeBSD coreteam member
+phk@FreeBSD.ORG "Real hackers run -current on their laptop."
+"ttyv0" -- What UNIX calls a $20K state-of-the-art, 3D, hi-res color terminal
diff --git a/usr.sbin/i4b/dtmfdecode/dtmfdecode.1 b/usr.sbin/i4b/dtmfdecode/dtmfdecode.1
new file mode 100644
index 0000000..64c6fb3
--- /dev/null
+++ b/usr.sbin/i4b/dtmfdecode/dtmfdecode.1
@@ -0,0 +1,61 @@
+.\"
+.\" Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: dtmfdecode.1,v 1.1 1999/02/15 19:13:47 hm Exp $
+.\"
+.\" last edit-date: [Mon Feb 15 20:11:30 1999]
+.\"
+.\"
+.Dd February, 15 1999
+.Dt dtmfdecode 1
+.Sh NAME
+.Nm dtmfdecode
+.Nd decodes DTMF tones from i4b .g711a files
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+.Nm dtmfdecode
+is part of the isdn4bsd package and is used to detect DTMF tones in the
+audio stream.
+.Pp
+It reads audio G.711 A-Law coded data from stdin and outputs the detected
+numbers values as ASCII charcters to stdout.
+.Pp
+
+.Sh EXAMPLES
+The command:
+.Bd -literal -offset indent
+dtmfdecode < beep.g711a
+.Ed
+.Pp
+will print a "1" to stdout.
+
+.Sh STANDARDS
+ITU Recommendations G.711
+
+.Sh AUTHOR
+The
+.Nm
+utility was written by Poul-Henning Kamp, phk@freebsd.org. This man page
+was written by Hellmuth Michaelis, hm@freebsd.org.
diff --git a/usr.sbin/i4b/dtmfdecode/dtmfdecode.c b/usr.sbin/i4b/dtmfdecode/dtmfdecode.c
new file mode 100644
index 0000000..2b53fa6
--- /dev/null
+++ b/usr.sbin/i4b/dtmfdecode/dtmfdecode.c
@@ -0,0 +1,158 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $Id: dtmfdecode.c,v 1.1 1999/02/15 19:13:47 hm Exp $
+ *
+ * Extract DTMF signalling from a .g711a file from ISDN4BSD
+ *
+ * A-Law to linear conversion from the sox package.
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+/*
+ * g711.c
+ *
+ * u-law, A-law and linear PCM conversions.
+ */
+#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
+#define QUANT_MASK (0xf) /* Quantization field mask. */
+#define NSEGS (8) /* Number of A-law segments. */
+#define SEG_SHIFT (4) /* Left shift for segment number. */
+#define SEG_MASK (0x70) /* Segment field mask. */
+
+/*
+ * alaw2linear() - Convert an A-law value to 16-bit linear PCM
+ *
+ */
+int
+alaw2linear(a_val)
+ unsigned char a_val;
+{
+ int t;
+ int seg;
+
+ a_val ^= 0x55;
+
+ t = (a_val & QUANT_MASK) << 4;
+ seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
+ switch (seg) {
+ case 0:
+ t += 8;
+ break;
+ case 1:
+ t += 0x108;
+ break;
+ default:
+ t += 0x108;
+ t <<= seg - 1;
+ }
+ return ((a_val & SIGN_BIT) ? t : -t);
+}
+
+int flip[256];
+
+double dtmf[8] = {697, 770, 852, 941, 1209, 1336, 1477, 1633};
+double p1[8];
+
+/* This is the Q of the filter (pole radius). must be less than 1.0 */
+#define POLRAD .99
+
+#define P2 (POLRAD*POLRAD)
+
+#define NNN 100
+
+char key [256];
+
+int
+main(int argc, char **argv)
+{
+ int i, j, kk, nn, s, so = 0;
+ double x, a[8], b[8], c[8], d[8], e[8], f[8], g[8], h[8], k[8], l[8], m[8], n[8], y[8];
+
+
+ for (kk = 0; kk < 8; kk++) {
+ y[kk] = g[kk] = k[kk] = 0.0;
+ p1[kk] = (-cos(2 * 3.141592 * dtmf[kk] / 8000.0));
+ }
+
+ for (i=0;i<256;i++) {
+ key[i] = '\0';
+ flip[i] = (i & 1) << 7;
+ flip[i] |= (i & 2) << 5;
+ flip[i] |= (i & 4) << 3;
+ flip[i] |= (i & 8) << 1;
+ flip[i] |= (i & 16) >> 1;
+ flip[i] |= (i & 32) << 3;
+ flip[i] |= (i & 64) << 5;
+ flip[i] |= (i & 128) << 7;
+ }
+
+ key[0x00] = '\0';
+ key[0x11] = '1';
+ key[0x12] = '4';
+ key[0x14] = '7';
+ key[0x18] = '*';
+
+ key[0x21] = '2';
+ key[0x22] = '5';
+ key[0x24] = '8';
+ key[0x28] = '0';
+
+ key[0x41] = '3';
+ key[0x42] = '6';
+ key[0x44] = '9';
+ key[0x48] = '#';
+
+ key[0x81] = 'A';
+ key[0x82] = 'B';
+ key[0x84] = 'C';
+ key[0x88] = 'D';
+
+ x = 0.0;
+ nn = 0;
+ while ((i = getchar()) != EOF) {
+ i = flip[i];
+ j = alaw2linear(i);
+
+ x = j / 32768.0;
+ s = 0;
+ for(kk = 0; kk < 8; kk++) {
+ a[kk] = x;
+ h[kk] = g[kk];
+ l[kk] = k[kk];
+
+ b[kk] = a[kk] - l[kk];
+ c[kk] = P2 * b[kk];
+ d[kk] = a[kk] + c[kk];
+ e[kk] = d[kk] - h[kk];
+ f[kk] = p1[kk] * e[kk];
+ g[kk] = f[kk] + d[kk];
+ k[kk] = h[kk] + f[kk];
+ m[kk] = l[kk] + c[kk];
+ n[kk] = a[kk] - m[kk];
+
+ y[kk] += (fabs(n[kk]) - y[kk]) / 20.0;
+ if (y[kk] > .1)
+ s |= 1 << kk;
+ }
+ if (s != so)
+ nn = 0;
+ else
+ nn++;
+ if (nn == NNN) {
+ if (key[s])
+ putchar(key[s]);
+ }
+ so = s;
+ }
+ printf("\n");
+ return (0);
+}
OpenPOWER on IntegriCloud