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 <format>\tSet output format\n"
74 "\t\tf: float (default)\n"
76 "\t\tb: binary (0|1)\n"
77 "\t\tB: Boolean (false|true)\n"
78 "\t-l\t\tDo not repeat values while still over treshold\n"
79 "\t-b\t\tDo not print first value that will fall under treshold\n"
80 "\t-q\t\tQuiet mode: print only values\n"
82 "\t-?\t\tPrint help\n"
89 "\tsox input.mp3 -b 8 -c 1 -r 8000 -t wav - | %s\n"
90 "\t%s -n -q -l -r 8000 -d 20 -t $tresh -f 697 [-f 770 ...]\n"
92 ,argv
[0],argv
[0],argv
[0]
96 "Frequencies for DTMF decoding:\n"
97 "\t-f 697 -f 770 -f 852 -f 941 -f 1209 -f 1336 -f 1477 -f 1633 -t 10\n"
101 void addfreq(int *freqs
, int freq
) {
103 while(freqs
[i
]!=-1) i
++;
108 int main(int argc
, char ** argv
) {
109 int samplerate
= 8000;
110 int samplecount
= 4000;
116 int freqs
[argc
+1]; freqs
[0]=-1;
119 while ((opt
= getopt(argc
, argv
, "?i:o:a:r:c:d:f:t:n:lbq")) != -1) {
122 freopen(optarg
, "r", stdin
);
125 freopen(optarg
, "w", stdout
);
128 freopen(optarg
, "a", stdout
);
131 samplerate
= atoi(optarg
);
134 samplecount
= atoi(optarg
);
137 samplecount
= samplerate
/atoi(optarg
);
140 addfreq(freqs
, atoi(optarg
));
143 treshold
= atoi(optarg
);
164 if(freqs
[0]==-1) addfreq(freqs
, 440);
165 float samples
[samplecount
];
170 "#Detected tone: %d Hz\n"
171 "#Samplerate: %d Hz\n"
172 "#Frame lenght: %d samples\n"
175 ,freqs
[0],samplerate
,samplecount
,treshold
);
179 int i
; for(i
=0;freqs
[i
]!=-1;i
++) {
180 printf("\t%2dHz",freqs
[i
]);
185 char print
=0, printnow
=0, printlast
= 0;
186 while(!feof(stdin
)) {
190 for(i
=0;i
<samplecount
&& !feof(stdin
);i
++) {
191 unsigned char sample
;
192 fread(&sample
,1,1,stdin
);
194 //printf("%d\n", sample);
200 for(i
=0;freqs
[i
]!=-1;i
++) {
201 power
[i
] = goertzel_mag(samplecount
, freqs
[i
], samplerate
, samples
);
203 //Set print true if over treshold or if changed to false (print for the last time after going under treshold)
204 printnow
= power
[i
] > treshold
;
205 print
= !(!repeat
&& printlast
&& !(!printnow
)) && (print
|| printnow
|| (printlast
&& !noreturn
));
207 printlast
= printnow
;
212 printf("%8.2f", position
);
213 for(i
=0;freqs
[i
]!=-1;i
++) {
217 printf("%d",(int)power
[i
]);
220 printf("%d",power
[i
]>treshold
);
223 if(power
[i
]>treshold
) printf("true");
224 else printf("false");
228 printf("%.4f",power
[i
]);
236 position
+= ((float)samplecount
/(float)samplerate
);
This page took 0.404431 seconds and 5 git commands to generate.