====== FFTW demo - DTMF decoder ====== Hanging on IRC, we decided to try how fast can I write a DTMF decoder with library FFT. I estimated 30 minutes. Finally, it took me exactly one hour, and the code quality is terrible. Yes, I know that computing these 8 bins from definition would be faster and would not require fftw. Now the whole world sees how I code for competitions where only right output, not the code quality, is evaluated. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include double hamming(int i, int length) { double a, b, w, N1; a = 25.0/46.0; b = 21.0/46.0; N1 = (double)(length-1); w = a - b*cos(2*i*M_PI/N1); return w; } int main(int argc, char **argv) { int i; float* acc; float* fftbuf; int fftsize = 512; acc = (float*) calloc(fftsize * 2, sizeof(float)); fftbuf = (float*) calloc(fftsize * 2, sizeof(float)); /* Setup FFTW */ int N = fftsize; fftwf_complex *fftw_in, *fftw_out; fftwf_plan p; fftw_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * N); fftw_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * N); p = fftwf_plan_dft_1d(N, fftw_in, fftw_out, FFTW_FORWARD, FFTW_ESTIMATE); float * win = malloc(fftsize * sizeof(float)); for(i=0; i max) { max = abs(data[j]); } } mx[i] = max; /*if(i%20 == 1) { printf("max %i\n", max); }*/ } #define sigth1 15000 #define sigth2 10000 #define sigstart 32000 //printf("HERE\n"); int pos = sigstart; while(1) { /* find start of burst */ while(pos++) { // printf("pos %i mx %i\n", pos, mx[pos]); if(mx[pos] > sigth1) { break; } } /* find end of burst */ int endpos = pos+10; while(endpos++) { // printf("endpos %i mx %i\n", endpos, mx[endpos]); if(mx[endpos] < sigth2) { break; } } /* align */ int center = (pos+endpos)/2; int dur = endpos-pos; int start = center-fftsize/2; //printf("len = %i (%i - %i), start %i\n", endpos-pos, pos, endpos, start); /* Read data */ for(i=0; i rout[bins[max1]]) { max1 = i; } } /* vert */ for(int i = 4; i<8; i++) { //printf("%i cmp %f %f\n", i, rout[bins[i]], rout[bins[max2]]); if(rout[bins[i]] > rout[bins[max2]]) { max2 = i; } } max2 -= 4; //printf("%i %i\n", max1, max2); int res[4][4] = {{1, 2, 3, 'A'}, {4, 5, 6, 'B'}, {7, 8, 9, 'C'}, {'*', 0, '#', 'D'} }; int rt = res[max2][max1]; if(rt>10) { printf(" *** %c ***\n", rt); } else { printf(" *** %i ***\n", rt); } pos = endpos+10; } }