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 <ratio>\tFrame size (default 2) (samplerate will be divided by this number to get frame size same as -c)\n"
70 "\t-f <freq>\tAdd frequency in Hz to detect (use multiple times, if no added 440 Hz will be...)\n"
72 "\t-t <treshold>\tSet treshold (used to hide magnitudes lower than treshold) (defaults -1)\n"
73 "\t-n\t\tPrint integers rather than floats\n"
74 "\t-l\t\tDo not repeat values while still over treshold\n"
75 "\t-b\t\tDo not print first value that will fall under treshold\n"
76 "\t-q\t\tQuiet mode: print only values\n"
78 "\t-?\t\tPrint help\n"
85 "\tsox input.mp3 -b 8 -c 1 -r 8000 -t wav - | %s\n"
86 "\t%s -n -q -l -r 8000 -d 20 -t $tresh -f 697 [-f 770 ...]\n"
88 ,argv
[0],argv
[0],argv
[0]
92 "Frequencies for DTMF decoding:\n"
93 "\t-f 697 -f 770 -f 852 -f 941 -f 1209 -f 1336 -f 1477 -f 1633 -t 10\n"
97 void addfreq(int *freqs
, int freq
) {
99 while(freqs
[i
]!=-1) i
++;
104 int main(int argc
, char ** argv
) {
105 int samplerate
= 8000;
106 int samplecount
= 4000;
112 int freqs
[argc
+1]; freqs
[0]=-1;
115 while ((opt
= getopt(argc
, argv
, "?i:o:a:r:c:d:f:t:nlbq")) != -1) {
118 freopen(optarg
, "r", stdin
);
121 freopen(optarg
, "w", stdout
);
124 freopen(optarg
, "a", stdout
);
127 samplerate
= atoi(optarg
);
130 samplecount
= atoi(optarg
);
133 samplecount
= samplerate
/atoi(optarg
);
136 addfreq(freqs
, atoi(optarg
));
139 treshold
= atoi(optarg
);
160 if(freqs
[0]==-1) addfreq(freqs
, 440);
161 float samples
[samplecount
];
166 "#Detected tone: %d Hz\n"
167 "#Samplerate: %d Hz\n"
168 "#Frame lenght: %d samples\n"
171 ,freqs
[0],samplerate
,samplecount
,treshold
);
175 int i
; for(i
=0;freqs
[i
]!=-1;i
++) {
176 printf("\t%2dHz",freqs
[i
]);
181 char print
=0, printnow
=0, printlast
= 0;
182 while(!feof(stdin
)) {
186 for(i
=0;i
<samplecount
&& !feof(stdin
);i
++) {
187 unsigned char sample
;
188 fread(&sample
,1,1,stdin
);
190 //printf("%d\n", sample);
196 for(i
=0;freqs
[i
]!=-1;i
++) {
197 power
[i
] = goertzel_mag(samplecount
, freqs
[i
], samplerate
, samples
);
199 //Set print true if over treshold or if changed to false (print for the last time after going under treshold)
200 printnow
= power
[i
] > treshold
;
201 print
= !(!repeat
&& printlast
&& !(!printnow
)) && (print
|| printnow
|| (printlast
&& !noreturn
));
203 printlast
= printnow
;
208 printf("%8.2f", position
);
209 for(i
=0;freqs
[i
]!=-1;i
++) {
212 printf("%d",(int)power
[i
]);
214 printf("%.4f",power
[i
]);
221 position
+= ((float)samplecount
/(float)samplerate
);
This page took 0.679295 seconds and 4 git commands to generate.