--- /dev/null
+#!/bin/bash
+#This is sample implementation of DTMF decoder using my C implementation of Goertzel Algorithm
+#This is not very efficient or precise, it's just proof of concept
+#Usage example: arecord 2>/dev/null | ./dtmf.sh
+
+tresh=3
+last='';
+./goertzel -i -q -r 8000 -s 400 -t $tresh -f 697 -f 770 -f 852 -f 941 -f 1209 -f 1336 -f 1477 -f 1633 | while read line; do
+ #echo "$line";
+
+ #Get time
+ pos="$(echo "$line" | cut -f 1)";
+
+ #Get values for each tone
+ a="$(echo "$line" | cut -f 2)";
+ b="$(echo "$line" | cut -f 3)";
+ c="$(echo "$line" | cut -f 4)";
+ d="$(echo "$line" | cut -f 5)";
+ e="$(echo "$line" | cut -f 6)";
+ f="$(echo "$line" | cut -f 7)";
+ g="$(echo "$line" | cut -f 8)";
+ h="$(echo "$line" | cut -f 9)";
+
+ #Compare values to treshold
+ test $a -gt $tresh && a=true || a=false
+ test $b -gt $tresh && b=true || b=false
+ test $c -gt $tresh && c=true || c=false
+ test $d -gt $tresh && d=true || d=false
+ test $e -gt $tresh && e=true || e=false
+ test $f -gt $tresh && f=true || f=false
+ test $g -gt $tresh && g=true || g=false
+ test $h -gt $tresh && h=true || h=false
+
+ #echo "$pos: $a $b $c $d $e $f $g $h";
+ state="$a$b$c$d$e$f$g$h";
+
+ #Test if tones changed since last time
+ #echo test "$state" != "$last"
+ test "$state" != "$last" && {
+
+ #DTMF Table
+ $a && {
+ $e && echo -n '1'
+ $f && echo -n '2'
+ $g && echo -n '3'
+ $h && echo -n 'A'
+ }
+ $b && {
+ $e && echo -n '4'
+ $f && echo -n '5'
+ $g && echo -n '6'
+ $h && echo -n 'B'
+ }
+ $c && {
+ $e && echo -n '7'
+ $f && echo -n '8'
+ $g && echo -n '9'
+ $h && echo -n 'C'
+ }
+ $d && {
+ $e && echo -n '*'
+ $f && echo -n '0'
+ $g && echo '#'
+ $h && echo -n 'D'
+ }
+
+ }
+
+ last="$state"
+
+done
#include <stdio.h>
#include <math.h>
+#include <getopt.h>
+
/*
Usage examples
arecord | ./goertzel
sox input.mp3 -b 8 -c 1 -r 8000 -t wav - | ./goertzel
+
+ Arguments for DTMF decoding:
+ -f 697 -f 770 -f 852 -f 941 -f 1209 -f 1336 -f 1477 -f 1633 -t 10
*/
float goertzel_mag(int numSamples,int TARGET_FREQUENCY,int SAMPLING_RATE, float* data)
return magnitude;
}
-int main() {
+void print_help(char ** argv) {
+ printf("help me %s\n", argv[0]);
+}
+
+void addfreq(int *freqs, int freq) {
+ int i = 0;
+ while(freqs[i]!=-1) i++;
+ freqs[i]=freq;
+ freqs[i+1]=-1;
+}
+
+int main(int argc, char ** argv) {
/*
int samples[] = {0,1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1};
int samplecount = 18;
int samplerate = 8000;
int samplecount = 4000;
+ int treshold = -1;
+ char noreturn = 0;
+ char integers=0;
+ char verbose=1;
+ int freqs[argc+1]; freqs[0]=-1;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "?r:s:f:t:iqn")) != -1) {
+ switch (opt) {
+ case 'r':
+ samplerate = atoi(optarg);
+ break;
+ case 's':
+ samplecount = atoi(optarg);
+ break;
+ case 'f':
+ addfreq(freqs, atoi(optarg));
+ break;
+ case 't':
+ treshold = atoi(optarg);
+ break;
+ case 'i':
+ integers = 1;
+ break;
+ case 'n':
+ noreturn = 1;
+ break;
+ case 'q':
+ verbose = 0;
+ break;
+ case '?':
+ print_help(argv);
+ return 0;
+ break;
+ }
+ }
+
+ if(freqs[0]==-1) addfreq(freqs, 440);
float samples[samplecount];
float position = 0;
- fprintf(stderr,"Position (Secs)\tMagnitude\n");
+
+ if(verbose) {
+ fprintf(stderr,
+ "#Detected tone: %d Hz\n"
+ "#Samplerate: %d Hz\n"
+ "#Frame lenght: %d samples\n"
+ "#Treshold: %d\n"
+ "#\n"
+ ,freqs[0],samplerate,samplecount,treshold);
+ fflush(stderr);
+
+ printf("#Position");
+ int i; for(i=0;freqs[i]!=-1;i++) {
+ printf("\t%2dHz",freqs[i]);
+ }
+ puts("");
+ }
+
+ char print=0, printnow=0, printlast = 0;
while(!feof(stdin)) {
int i;
+
+ //Sample data
for(i=0;i<samplecount && !feof(stdin);i++) {
unsigned char sample;
fread(&sample,1,1,stdin);
samples[i]=sample;
//printf("%d\n", sample);
}
+
+ //Apply goertzel
+ float power[argc];
+ print=0;
+ for(i=0;freqs[i]!=-1;i++) {
+ power[i] = goertzel_mag(samplecount, freqs[i], samplerate, samples);
+
+ //Set print true if over treshold or if changed to false (print for the last time after going under treshold)
+ printnow = power[i] > treshold;
+ print = print || printnow || (printlast && !noreturn);
+ }
+ printlast = printnow;
+ fflush(stdout);
+
+ //Print data
+ if(print) {
+ printf("%8.2f", position);
+ for(i=0;freqs[i]!=-1;i++) {
+ printf("\t");
+ if(integers)
+ printf("%d",(int)power[i]);
+ else
+ printf("%.4f",power[i]);
+ }
+ puts("");
+ fflush(stdout);
+ }
+
+ //Increase time
position += ((float)samplecount/(float)samplerate);
- float power = goertzel_mag(samplecount, 440, samplerate, samples);
- printf("%f\t%f\n", position, power);
}
}