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 <filter>\tSet filter\n"
79 "\t\tf: Falldown: print only when over treshold or just falled under (default)\n"
80 "\t\tt: Treshold: print only when over treshold\n"
81 "\t\tc: Crossed: print only when treshold crossed\n"
82 "\t-q\t\tQuiet mode: print only values\n"
84 "\t-?\t\tPrint help\n"
91 "\tsox input.mp3 -b 8 -c 1 -r 8000 -t wav - | %s\n"
92 "\t%s -n -q -l -r 8000 -d 20 -t $tresh -f 697 [-f 770 ...]\n"
94 ,argv
[0],argv
[0],argv
[0]
98 "Frequencies for DTMF decoding:\n"
99 "\t-f 697 -f 770 -f 852 -f 941 -f 1209 -f 1336 -f 1477 -f 1633 -t 10\n"
103 void addfreq(int *freqs
, int freq
) {
105 while(freqs
[i
]!=-1) i
++;
110 int main(int argc
, char ** argv
) {
111 int samplerate
= 8000;
112 int samplecount
= 4000;
117 int freqs
[argc
+1]; freqs
[0]=-1;
120 while ((opt
= getopt(argc
, argv
, "?i:o:a:r:c:d:f:t:n:l:q")) != -1) {
123 freopen(optarg
, "r", stdin
);
126 freopen(optarg
, "w", stdout
);
129 freopen(optarg
, "a", stdout
);
132 samplerate
= atoi(optarg
);
135 samplecount
= atoi(optarg
);
138 samplecount
= samplerate
/atoi(optarg
);
141 addfreq(freqs
, atoi(optarg
));
144 treshold
= atoi(optarg
);
162 if(freqs
[0]==-1) addfreq(freqs
, 440);
163 float samples
[samplecount
];
168 "#Detected tone: %d Hz\n"
169 "#Samplerate: %d Hz\n"
170 "#Frame lenght: %d samples\n"
173 ,freqs
[0],samplerate
,samplecount
,treshold
);
177 int i
; for(i
=0;freqs
[i
]!=-1;i
++) {
178 printf("\t%2dHz",freqs
[i
]);
184 char print
=0, printnow
=0;
185 char laststate
[argc
]; for(i
=0;freqs
[i
]!=-1;i
++) laststate
[i
]=-1;
186 while(!feof(stdin
)) {
189 for(i
=0;i
<samplecount
&& !feof(stdin
);i
++) {
190 unsigned char sample
;
191 fread(&sample
,1,1,stdin
);
193 //printf("%d\n", sample);
199 for(i
=0;freqs
[i
]!=-1;i
++) {
200 power
[i
] = goertzel_mag(samplecount
, freqs
[i
], samplerate
, samples
);
202 //Decide if we will print
203 printnow
= power
[i
] > treshold
; //Is over treshold?
205 case 'c': //Print if treshold crossed
206 print
= print
|| (laststate
[i
] != printnow
);
209 case 'f': //Print if over treshold or falled down
210 print
= print
|| (laststate
[i
] != printnow
);
211 case 't': //Print if over treshold
212 print
= print
|| printnow
;
214 laststate
[i
] = printnow
; //Store last state
220 printf("%8.2f", position
);
221 for(i
=0;freqs
[i
]!=-1;i
++) {
225 printf("%d",(int)power
[i
]);
228 printf("%d",power
[i
]>treshold
);
231 if(power
[i
]>treshold
) printf("true");
232 else printf("false");
236 printf("%.4f",power
[i
]);
244 position
+= ((float)samplecount
/(float)samplerate
);
This page took 0.370371 seconds and 4 git commands to generate.