#include #include #include #include #include #include #include #include #define PI 3.14159265358979323846 #include #include #include #include struct sigaction old_action; void sigint_handler(int sig_no) { printf("\033[0m\n"); system("setfont /usr/share/consolefonts/Lat2-Fixed16.psf.gz "); system("setterm -cursor on"); system("clear"); printf("CTRL-C pressed -- goodbye\n"); sigaction(SIGINT, &old_action, NULL); kill(0, SIGINT); } int main(int argc, char **argv) { int M=4096; signed char *buffer; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; snd_pcm_uframes_t frames; char *device = "hw:1,1"; float fc[200];//={150.223,297.972,689.062,1470,3150,5512.5,11025,18000}; float fr[200];//={0.00340905,0.0067567,0.015625,0.0333,0.07142857,0.125,0.25,0.4}; int lcf[200], hcf[200]; double f[200]; double x[M]; double peak[201]; float y[M/2+1]; long int lpeak,hpeak; int bands=20; int sleep=0; float h; int i, n, o, size, dir, err,xb,yb,bw,format,rate,width,height,c,rest,virt; int autoband=1; //long int peakhist[bands][400]; double temp; double sum=0; int16_t hi; int q=0; val=44100; int debug=0; struct winsize w; double in[2*(M/2+1)]; fftw_complex out[M/2+1][2]; fftw_plan p; struct timespec start, stop; double accum; char *color; int col = 37; //---------- THIS IS THE END OF INIT, MUST STOP PUTTING INIT BELOW //**arg handler**// while ((c = getopt (argc, argv, "b:d:c:t:B")) != -1) switch (c) { case 'b': bands = atoi(optarg); autoband=0; //dont automaticly add bands to fill frame if (bands>200)bands=200; break; case 'd': device = optarg; break; case 'c': col=0; color = optarg; if(strcmp(color,"red")==0) col=31; if(strcmp(color,"green")==0) col=32; if(strcmp(color,"yellow")==0) col=33; if(strcmp(color,"blue")==0) col=34; if(strcmp(color,"magenta")==0) col=35; if(strcmp(color,"cyan")==0) col=36; if(strcmp(color,"white")==0) col=37; if(col==0) { printf("color %s not suprted\n",color); exit(1); } break; case '?': printf ("\nUsage : ./cava [options]\n\nOptions:\n\t-b 1..(console columns/2-1) or 200, number of bars in the spectrum (default 20 + fills up the console), program wil auto adjust to maxsize if input is to high)\n\n\t-d 'alsa device', name of alsa capture device (default 'hw:1,1')\n\n\t-c color\tsuported colors: red, green, yellow, magenta, cyan, white, blue (default: cyan)\n\n\""); return 1; default: abort (); } //**ctrl c handler**// struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = &sigint_handler; sigaction(SIGINT, &action, &old_action); //**drawing frame**// if(debug==0){ virt = system("setfont cava.psf"); system("setterm -cursor off"); } //getting h*w of term ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); if(bands>(int)w.ws_col/2-1)bands=(int)w.ws_col/2-1; //handle for user setting to many bars height=(int)w.ws_row-1; width=(int)w.ws_col-bands-1; bool matrix[width][height]; bw=width/bands; //if no bands are selected it tries to padd the default 20 if there is extra room if(autoband==1) bands=bands+(((w.ws_col)-(bw*bands+bands-1))/(bw+1)); //checks if there is stil extra room, will use this to center rest=(((w.ws_col)-(bw*bands+bands-1))); if(rest<0)rest=0; //resetting console printf("\033[0m\n"); system("clear"); printf("\033[%dm",col);//setting volor /* if(debug==0){ for(yb=0;yb5&&val<10)format=24; else if(val>9)format=32; size = frames * (format/8)*2; /* bytes/sample * 2 channels */ buffer = (char *) malloc(size); if(debug==1)printf("detected format: %d\n",format); snd_pcm_hw_params_get_rate( params, &rate, &dir); //getting rate if(debug==1)printf("detected rate: %d\n",rate); //**calculating cutof frequencies**/ for(n=0;n %f (%d -> %d) \n",n,fc[n-1],fc[n],lcf[n-1],hcf[n-1]);} } p = fftw_plan_dft_r2c_1d(M, in, *out, FFTW_MEASURE); //planning to rock //**start main loop**// while (1) { /* if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) { perror( "clock gettime" ); exit( EXIT_FAILURE ); } */ //**filling of the buffer**// for(o=0;ohpeak) hpeak=x[o]; if(x[n+(int)frames*o]hpeak) hpeak=x[i]; if(x[i]peak[o]) peak[o]=y[i]; } //if (peak[o]>sum)sum=peak[o]; peakest values are ussaly around 50k but i have seen 113000 //divides on 200 because of complex mplification //mulitplise by log of frequency probably because of eq master cd standard, riaa...? f[o]=((peak[o]*(float)height*log(hcf[o]+10)*log(hcf[o]+10))) /(254*(M/8)*(log(hcf[bands-1]))) ; //weighing signal to height and frequency if(f[o]>height)f[o]=height;//just in case if(debug==1){ printf("%d: f:%f->%f peak:%f adjpeak: %f \n",o,fc[o],fc[o+1],peak[o],f[o]);} } if(debug==1){ printf("topp overall unfiltered:%f \n",peak[bands]); } //if(debug==1){ printf("topp overall alltime:%f \n",sum);} } else//**if no signal don't bother**// { if (sleep>(rate*5)/M)//if no signal for 5 sec, go to sleep mode { if(debug==1)printf("no sound detected for 5 sec, going to sleep mode\n"); usleep(1*1000000);//wait one sec, then check sound again. Maybe break, close and reopen? continue; } if(debug==1)printf("no sound detected, trying again\n"); sleep++; continue; } //**DRAWING**// -- put in function file maybe? if (debug==0) { for (n=(height-1);n>=0;n--) { o=0; for (i=0;i1) printf("\u2588");//color else//top color, finding fraction { c=((((f[o]-(float)n)-0.125)/0.875*7)+1); switch (c) { case 1: if(virt==0)printf("1"); else printf("\u2581"); break; case 2: if(virt==0)printf("2"); else printf("\u2582"); break; case 3: if(virt==0)printf("3"); else printf("\u2583"); break; case 4: if(virt==0)printf("4"); else printf("\u2584"); break; case 5: if(virt==0)printf("5"); else printf("\u2585"); break; case 6: if(virt==0)printf("6"); else printf("\u2586"); break; case 7: if(virt==0)printf("7"); else printf("\u2587"); break; default: printf(" "); } } } } printf("\n\033[%dC",(rest/2));//next line and one to the right } printf("\033[%dA",height);//backup } // //snd_pcm_drain(handle); //snd_pcm_drop(handle); //snd_pcm_close(handle); /* //tried to make this frameramet limit to save cpu.... if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) { perror( "clock gettime" ); exit( EXIT_FAILURE ); } */ //accum = (( stop.tv_sec - start.tv_sec )+ ( stop.tv_nsec - start.tv_nsec ))/1000000; //if(accum<50000&&accum>0)usleep(50000-accum); //16666.666666667 usec = 60 fps //printf("time used: %f\n",accum); } fftw_destroy_plan(p); return 0; }