f22a1fcb1a911c011008ba7c266e279e46b6e6ef
5 float goertzel_mag(int numSamples
,int TARGET_FREQUENCY
,int SAMPLING_RATE
, float* data
)
9 float omega
,sine
,cosine
,coeff
,q0
,q1
,q2
,magnitude
,real
,imag
;
11 float scalingFactor
= numSamples
/ 2.0;
13 floatnumSamples
= (float) numSamples
;
14 k
= (int) (0.5 + ((floatnumSamples
* TARGET_FREQUENCY
) / SAMPLING_RATE
));
15 omega
= (2.0 * M_PI
* k
) / floatnumSamples
;
23 for(i
=0; i
<numSamples
; i
++)
25 q0
= coeff
* q1
- q2
+ data
[i
];
30 // calculate the real and imaginary results
31 // scaling appropriately
32 real
= (q1
- q2
* cosine
) / scalingFactor
;
33 imag
= (q2
* sine
) / scalingFactor
;
35 magnitude
= sqrtf(real
*real
+ imag
*imag
);
39 void print_help(char ** argv
) {
41 "%s takes raw (wav) audio stream and computes power (or magnitude)\n"
42 "of desired frequencies using Goertzel algorithm for time frames\n"
43 "of fixed length (specified in samples or relative to sample rate).\n"
44 "This can be used in various frequency detection applications\n"
45 "like guitar tuning, DTMF decoding and many others...\n"
47 "http://en.wikipedia.org/wiki/Goertzel_algorithm\n"
49 "Curently only raw unsigned 8bit (u8) mono audio is supported, but\n"
50 "samplerate may vary. You can convert other formats before processing.\n"
52 "On lower samplerates and frame sizes this may perform sub-optimally. Eg.:\n"
53 "When set to detect 440Hz (at 8000Hz samplerate and ~4000 samples)\n"
54 "it actually detects something around 438,3Hz rather than 400Hz...\n"
55 "If you can't increase samplerate way around this is just to increase sensitivity.\n"
62 "\t-i <file>\tInput from file (default STDIN)\n"
63 "\t-o <file>\tOutput to file (default STDOUT)\n"
64 "\t-a <file>\tOutput to file (append) (default STDOUT)\n"
66 "\t-r <samplerate>\tInput samplerate (deault 8000 Hz)\n"
67 "\t-c <count>\tFrame size in samples (default 4000 Samples)\n"
68 "\t-d <divisor>\tFrame size ( count = samplerate/divisor ) (default 2)\n"
70 "\t-f <freq>\tAdd frequency in Hz to detect (use multiple times, default 440 Hz)\n"
72 "\t-n <format>\tSet number output format\n"
73 "\t\tf: float\t23.4223 (default)\n"
74 "\t\ti: integer\t23\n"
75 "\t\tb: binary\t(0|1)\n"
76 "\t\tB: Boolean\t(false|true)\n"
78 "\t-t <treshold>\tSet treshold (used in filter, see -l) (defaults -1)\n"
79 "\t-l <filter>\tSet line filter\n"
80 "\t\tf: Falldown:\tprint only when over treshold or just crossed (default)\n"
81 "\t\tt: Treshold:\tprint only when over treshold\n"
82 "\t\tc: Crossed:\tprint only when treshold crossed\n"
83 "\t-u\t\tInvert\ttreshold (values under treshold will be displayed)\n"
85 "\t-q\t\tQuiet mode: print only values\n"
87 "\t-?\t\tPrint help\n"
94 "\tsox input.mp3 -b 8 -c 1 -r 8000 -t wav - | %s\n"
95 "\t%s -n -q -l -r 8000 -d 20 -t $tresh -f 697 [-f 770 ...]\n"
97 ,argv
[0],argv
[0],argv
[0]
101 "Frequencies for DTMF decoding:\n"
102 "\t-f 697 -f 770 -f 852 -f 941 -f 1209 -f 1336 -f 1477 -f 1633 -t 10\n"
106 void addfreq(int *freqs
, int freq
) {
108 while(freqs
[i
]!=-1) i
++;
113 int main(int argc
, char ** argv
) {
114 int samplerate
= 8000;
115 int samplecount
= 4000;
124 int freqs
[argc
+1]; freqs
[0]=-1;
127 while ((opt
= getopt(argc
, argv
, "?i:o:a:r:c:d:f:t:n:l:uq")) != -1) {
130 freopen(optarg
, "r", stdin
);
133 freopen(optarg
, "w", stdout
);
136 freopen(optarg
, "a", stdout
);
139 samplerate
= atoi(optarg
);
142 samplecount
= atoi(optarg
);
145 samplecount
= samplerate
/atoi(optarg
);
148 addfreq(freqs
, atoi(optarg
));
151 treshold
= atoi(optarg
);
172 if(freqs
[0]==-1) addfreq(freqs
, 440);
173 float samples
[samplecount
];
178 "#Detected tone: %d Hz\n"
179 "#Samplerate: %d Hz\n"
180 "#Frame lenght: %d samples\n"
183 ,freqs
[0],samplerate
,samplecount
,treshold
);
187 int i
; for(i
=0;freqs
[i
]!=-1;i
++) {
188 printf("\t%2dHz",freqs
[i
]);
194 char print
=0, printnow
=0;
195 char laststate
[argc
]; for(i
=0;freqs
[i
]!=-1;i
++) laststate
[i
]=-1;
196 while(!feof(stdin
)) {
199 for(i
=0;i
<samplecount
&& !feof(stdin
);i
++) {
200 unsigned char sample
;
201 fread(&sample
,1,1,stdin
);
203 //printf("%d\n", sample);
209 for(i
=0;freqs
[i
]!=-1;i
++) {
210 power
[i
] = goertzel_mag(samplecount
, freqs
[i
], samplerate
, samples
);
212 //Decide if we will print
213 printnow
= under
? power
[i
] < treshold
: power
[i
] > treshold
; //Is over/under treshold?
215 case 'c': //Print if treshold crossed
216 print
= print
|| (laststate
[i
] != printnow
);
219 case 'f': //Print if over treshold or falled down
220 print
= print
|| (laststate
[i
] != printnow
);
221 case 't': //Print if over treshold
222 print
= print
|| printnow
;
224 laststate
[i
] = printnow
; //Store last state
230 printf("%8.2f", position
);
231 for(i
=0;freqs
[i
]!=-1;i
++) {
235 printf("%d",(int)round(power
[i
]));
238 printf("%d",power
[i
]>treshold
);
241 if(power
[i
]>treshold
) printf("true");
242 else printf("false");
246 printf("%.4f",power
[i
]);
254 position
+= ((float)samplecount
/(float)samplerate
);
This page took 0.448445 seconds and 3 git commands to generate.