d13a874d9612379d94ca4e07c7de72da16ea7294
5 float goertzel_mag(int numSamples
,float 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
) / (float)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
* cosine
- q2
) / scalingFactor
;
33 imag
= (q1
* 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(float *freqs
, float freq
) {
108 while(freqs
[i
]!=-1) i
++;
113 int main(int argc
, char ** argv
) {
114 int samplerate
= 8000;
115 int samplecount
= 4000;
124 float freqs
[argc
+1]; freqs
[0]=-1;
129 while ((opt
= getopt(argc
, argv
, "?i:o:a:r:c:d:f:t:n:l:uq")) != -1) {
132 freopen(optarg
, "r", stdin
);
135 freopen(optarg
, "w", stdout
);
138 freopen(optarg
, "a", stdout
);
141 samplerate
= atoi(optarg
);
144 samplecount
= atoi(optarg
);
147 samplecount
= samplerate
/atoi(optarg
);
150 sscanf(optarg
,"%f",&floatarg
);
151 addfreq(freqs
, floatarg
);
154 treshold
= atoi(optarg
);
175 if(freqs
[0]==-1) addfreq(freqs
, 440);
176 float samples
[samplecount
];
181 "#Detected tone: %.2f Hz\n"
182 "#Samplerate: %d Hz\n"
183 "#Frame lenght: %d samples\n"
186 ,freqs
[0],samplerate
,samplecount
,treshold
);
190 int i
; for(i
=0;freqs
[i
]!=-1;i
++) {
191 printf("\t%2.0fHz",freqs
[i
]); //TODO: print decimal places
197 char print
=0, printnow
=0;
198 char laststate
[argc
]; for(i
=0;freqs
[i
]!=-1;i
++) laststate
[i
]=-1;
199 while(!feof(stdin
)) {
202 for(i
=0;i
<samplecount
&& !feof(stdin
);i
++) {
203 unsigned char sample
;
204 fread(&sample
,1,1,stdin
);
206 //printf("%d\n", sample);
212 for(i
=0;freqs
[i
]!=-1;i
++) {
213 power
[i
] = goertzel_mag(samplecount
, freqs
[i
], samplerate
, samples
);
215 //Decide if we will print
216 printnow
= under
? power
[i
] < treshold
: power
[i
] > treshold
; //Is over/under treshold?
218 case 'c': //Print if treshold crossed
219 print
= print
|| (laststate
[i
] != printnow
);
222 case 'f': //Print if over treshold or falled down
223 print
= print
|| (laststate
[i
] != printnow
);
224 case 't': //Print if over treshold
225 print
= print
|| printnow
;
227 laststate
[i
] = printnow
; //Store last state
233 printf("%8.2f", position
);
234 for(i
=0;freqs
[i
]!=-1;i
++) {
238 printf("%d",(int)round(power
[i
]));
241 printf("%d",power
[i
]>treshold
);
244 if(power
[i
]>treshold
) printf("true");
245 else printf("false");
249 printf("%7.5f",power
[i
]);
257 position
+= ((float)samplecount
/(float)samplerate
);
This page took 0.974469 seconds and 3 git commands to generate.