X-Git-Url: https://git.harvie.cz/?a=blobdiff_plain;f=c%2Fgoertzel%2Fgoertzel.c;h=96458a5b83c7cc2cacf5bd4536276df77c17221c;hb=8f751717d8307e3aa09fdfee19bed9478b7b16be;hp=f5250a0d11e2740e2a4e9987c0bae928c78796a1;hpb=59934436c41da5c999a065638d2e951a34110b03;p=mirrors%2FPrograms.git diff --git a/c/goertzel/goertzel.c b/c/goertzel/goertzel.c index f5250a0..96458a5 100644 --- a/c/goertzel/goertzel.c +++ b/c/goertzel/goertzel.c @@ -2,25 +2,8 @@ #include #include - -/* - Usage examples - arecord | ./goertzel - sox input.mp3 -b 8 -c 1 -r 8000 -t wav - | ./goertzel - - Arguments for DTMF decoding: - -f 697 -f 770 -f 852 -f 941 -f 1209 -f 1336 -f 1477 -f 1633 -t 10 -*/ - float goertzel_mag(int numSamples,int TARGET_FREQUENCY,int SAMPLING_RATE, float* data) { - /* - On lower samplerates and frame sizes this may perform sub-optimally. Eg.: - When set to detect 440Hz (at 8000Hz samplerate and ~4000 samples) - it actually detects something around 438,3Hz rather than 400Hz... - If you can't increase samplerate way around this is just to increase sensitivity. - */ - int k,i; float floatnumSamples; float omega,sine,cosine,coeff,q0,q1,q2,magnitude,real,imag; @@ -54,7 +37,61 @@ float goertzel_mag(int numSamples,int TARGET_FREQUENCY,int SAMPLING_RATE, float* } void print_help(char ** argv) { - printf("help me %s\n", argv[0]); + printf( + "%s takes raw (wav) audio stream and computes power (or magnitude)\n" + "of desired frequencies using Goertzel algorithm for time frames\n" + "of fixed length (specified in samples or relative to sample rate).\n" + "This can be used in various frequency detection applications\n" + "like guitar tuning, DTMF decoding and many others...\n" + "\n" + "http://en.wikipedia.org/wiki/Goertzel_algorithm\n" + "\n" + "Curently only raw unsigned 8bit (u8) mono audio is supported, but\n" + "samplerate may vary. You can convert other formats before processing.\n" + "\n" + "On lower samplerates and frame sizes this may perform sub-optimally. Eg.:\n" + "When set to detect 440Hz (at 8000Hz samplerate and ~4000 samples)\n" + "it actually detects something around 438,3Hz rather than 400Hz...\n" + "If you can't increase samplerate way around this is just to increase sensitivity.\n" + "\n" + ,argv[0] + ); + + printf( + "Arguments:\n" + "\t-i \tInput from file (default STDIN)\n" + "\t-o \tOutput to file (default STDOUT)\n" + "\t-a \tOutput to file (append) (default STDOUT)\n" + "\n" + "\t-r \tInput samplerate (deault 8000 Hz)\n" + "\t-c \tFrame size in samples (default 4000 Samples)\n" + "\t-d \tFrame size (default 2) (samplerate will be divided by this number to get frame size same as -c)\n" + "\n" + "\t-f \tAdd frequency in Hz to detect (use multiple times, if no added 440 Hz will be...)\n" + "\n" + "\t-t \tSet treshold (used to hide magnitudes lower than treshold) (defaults -1)\n" + "\t-n\t\tPrint integers rather than floats\n" + "\t-l\t\tDo not repeat values while still over treshold\n" + "\t-b\t\tDo not print first value that will fall under treshold\n" + "\t-q\t\tQuiet mode: print only values\n" + "\n" + "\t-?\t\tPrint help\n" + "\n" + ); + + printf( + "Usage examples:\n" + "\tarecord | %s\n" + "\tsox input.mp3 -b 8 -c 1 -r 8000 -t wav - | %s\n" + "\t%s -n -q -l -r 8000 -d 20 -t $tresh -f 697 [-f 770 ...]\n" + "\n" + ,argv[0],argv[0],argv[0] + ); + + printf( + "Frequencies for DTMF decoding:\n" + "\t-f 697 -f 770 -f 852 -f 941 -f 1209 -f 1336 -f 1477 -f 1633 -t 10\n" + ); } void addfreq(int *freqs, int freq) { @@ -65,40 +102,49 @@ void addfreq(int *freqs, int freq) { } int main(int argc, char ** argv) { - /* - int samples[] = {0,1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1}; - int samplecount = 18; - float power = goertzel(samplecount, samples, 1.2, 18); - printf("G: %f\n", power); - */ - int samplerate = 8000; int samplecount = 4000; int treshold = -1; char noreturn = 0; + char repeat = 1; char integers=0; char verbose=1; int freqs[argc+1]; freqs[0]=-1; int opt; - while ((opt = getopt(argc, argv, "?r:s:f:t:iqn")) != -1) { + while ((opt = getopt(argc, argv, "?i:o:a:r:c:d:f:t:nlbq")) != -1) { switch (opt) { + case 'i': + freopen(optarg, "r", stdin); + break; + case 'o': + freopen(optarg, "w", stdout); + break; + case 'a': + freopen(optarg, "a", stdout); + break; case 'r': samplerate = atoi(optarg); break; - case 's': + case 'c': samplecount = atoi(optarg); break; + case 'd': + samplecount = samplerate/atoi(optarg); + break; case 'f': addfreq(freqs, atoi(optarg)); break; case 't': treshold = atoi(optarg); break; - case 'i': + case 'n': integers = 1; break; - case 'n': + case 'l': + repeat = 0; + break; + case 'b': noreturn = 1; break; case 'q': @@ -152,7 +198,7 @@ int main(int argc, char ** argv) { //Set print true if over treshold or if changed to false (print for the last time after going under treshold) printnow = power[i] > treshold; - print = print || printnow || (printlast && !noreturn); + print = !(!repeat && printlast && !(!printnow)) && (print || printnow || (printlast && !noreturn)); } printlast = printnow; fflush(stdout);