mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-04 09:09:56 +00:00
add the dtmfdecode program (added to i4b with 0.71.00) to the i4b userland
This commit is contained in:
parent
e90bc52dbe
commit
bb7ca167ae
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=44554
@ -1,4 +1,4 @@
|
||||
SUBDIR = isdntrace isdndebug isdnd alawulaw man isdntest \
|
||||
isdntel isdntelctl isdnmonitor isdndecode
|
||||
isdntel isdntelctl isdnmonitor isdndecode dtmfdecode
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
15
usr.sbin/i4b/dtmfdecode/Makefile
Normal file
15
usr.sbin/i4b/dtmfdecode/Makefile
Normal file
@ -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>
|
44
usr.sbin/i4b/dtmfdecode/README
Normal file
44
usr.sbin/i4b/dtmfdecode/README
Normal file
@ -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
|
61
usr.sbin/i4b/dtmfdecode/dtmfdecode.1
Normal file
61
usr.sbin/i4b/dtmfdecode/dtmfdecode.1
Normal file
@ -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.
|
158
usr.sbin/i4b/dtmfdecode/dtmfdecode.c
Normal file
158
usr.sbin/i4b/dtmfdecode/dtmfdecode.c
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user