diff --git a/cava.c b/cava.c index ad0b325..5268db5 100644 --- a/cava.c +++ b/cava.c @@ -11,8 +11,14 @@ #include #include #include +#include struct sigaction old_action; +int M=2048; +int shared[2048]; +int debug=0; +int format=-1; +int rate=-1; void sigint_handler(int sig_no) @@ -27,54 +33,167 @@ void sigint_handler(int sig_no) } -int main(int argc, char **argv) + +void* +music(void* data) { -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 = ((char*)data); +val=44100; +int i, n, o, size, dir, err,lo; +int tempr,templ; +int radj,ladj; + +//**init sound device***// + +if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_CAPTURE , 0) < 0)) + printf("error opening stream: %s\n",snd_strerror(err) ); +else + if(debug==1){ printf("open stream succes\n"); } +snd_pcm_hw_params_alloca(¶ms); +snd_pcm_hw_params_any (handle, params); +snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); +snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); +snd_pcm_hw_params_set_channels(handle, params, 2); +val = 44100; +snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); +frames = 32; +snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); + +err = snd_pcm_hw_params(handle, params); +if (err < 0) { + fprintf(stderr, + "unable to set hw parameters: %s\n", + snd_strerror(err)); + exit(1); +} + +snd_pcm_hw_params_get_format(params, (snd_pcm_format_t * )&val); //getting format + +if(val<6)format=16; +else if(val>5&&val<10)format=24; +else if(val>9)format=32; + + +snd_pcm_hw_params_get_rate( params, &rate, &dir); //getting rate +if(debug==1)printf("detected rate: %d\n",rate); + +snd_pcm_hw_params_get_period_size(params,&frames, &dir); +snd_pcm_hw_params_get_period_time(params, &val, &dir); + +size = frames * (format/8)*2; /* bytes/sample * 2 channels */ +buffer = (char *) malloc(size); +radj=format/4; +ladj=format/8; +o=0; +while(1){ + + err = snd_pcm_readi(handle, buffer, frames); + if (err == -EPIPE) { + /* EPIPE means overrun */ + if(debug==1){ fprintf(stderr, "overrun occurred\n");} + snd_pcm_prepare(handle); + } else if (err < 0) { + if(debug==1){ fprintf(stderr, "error from read: %s\n", + snd_strerror(err));} + } else if (err != (int)frames) { + if(debug==1){ fprintf(stderr, "short read, read %d %d frames\n", err,(int)frames);} + } + + //sorting out one channel and only biggest octet + n=0;//frame counter + for (i=0; i> 6)); + if (lo<0)lo=lo+4; + if(tempr>=0)tempr= tempr + lo; + if(tempr<0)tempr= tempr - lo; + + //other channel + templ=(buffer[i+(ladj)-1] << 2); + lo=(buffer[i+(ladj)-2] >> 6); + if(lo<0)lo=lo+4; + if(templ>=0)templ=templ+lo; + else templ=templ-lo; + + //adding channels and storing it int the buffer + shared[o]=(tempr+templ)/2; + o++; + if(o==M-1)o=0; + + //shifing ringbuffer one to the left, this ended up sing to much cpu.. + //for(o=0;o(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]; +int matrix[width][height]; +for(i=0;i5&&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); - +//**watintg for audio to be ready**// +n=0; +thr_id = pthread_create(&p_thread, NULL, music,(void*)device); //starting music listner +while (format==-1||rate==-1) + { + usleep(1000); + n++; + if(n>2000) + { + printf("could not get rate and or format, problems with audoi thread? quiting...\n"); + exit(1); + } + } +printf("got format: %d and rate %d\n",format,rate); //**calculating cutof frequencies**/ for(n=0;n %f (%d -> %d) \n",n,fc[n-1],fc[n],lcf[n-1],hcf[n-1]);} } +//exit(1); + +//constants to wigh signal to frequency +for(n=0;n=0)x[n+(int)frames*o]= x[n+(int)frames*o] + lo; - if(x[n+(int)frames*o]<0)x[n+(int)frames*o]= x[n+(int)frames*o] - lo; +//**preparing screen**// +if(debug==0){ +virt = system("setfont cava.psf"); +system("setterm -cursor off"); +//resetting console +printf("\033[0m\n"); +system("clear"); + +printf("\033[%dm",col);//setting volor +printf("\033[1m"); //setting "bright" color mode, looks cooler... - //other channel - temp=(buffer[i+(format/8)-1] << 8); - lo=buffer[i+(format/8)-2]; - if(lo<0)lo=lo+255; - if(temp>=0)temp=temp+lo; - else temp=temp-lo; - - //adding channels - x[n+(int)frames*o]=(x[n+(int)frames*o]+temp)/2; - - - if(x[n+(int)frames*o]>hpeak) hpeak=x[o]; - if(x[n+(int)frames*o]hpeak) hpeak=x[i]; - if(x[i]hpeak) hpeak=shared[i]; + if(shared[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...? - + temp=peak[o]*k[o]; //weighing signal to height and frequency - f[o]=((peak[o]*(float)height*log(lcf[o]+hcf[o]+10)*log(lcf[o]+hcf[o]+10))) /(65536*(M/8)*(log(hcf[bands-1]))) ; //weighing signal to height and frequency + + //**falloff function**// + if(temp=flast[o]) + { + f[o]=temp; + fpeak[o]=f[o]; + fall[o]=0; + } - f[o]=f[o]*((float)sens/100); + flast[o]=f[o]; //memmory for falloff func + f[o]=f[o]*((float)sens/100); //adjusting sens if(f[o]>height)f[o]=height;//just in case if(debug==1){ printf("%d: f:%f->%f (%d->%d)peak:%f adjpeak: %f \n",o,fc[o],fc[o+1],lcf[o],hcf[o],peak[o],f[o]);} } - if(debug==1){ printf("topp overall unfiltered:%f \n",peak[bands]); + // 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**// @@ -340,7 +408,8 @@ for(o=0;o(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? + for (i=0;i<200;i++)flast[i]=0; //zeroing memory + usleep(1*200000);//wait 200 msec, then check sound again. continue; } if(debug==1)printf("no sound detected, trying again\n"); @@ -351,33 +420,50 @@ for(o=0;o=0;n--) { - o=0; + o=0; + move=rest/2;//center adjustment + //if(rest!=0)printf("\033[%dC",(rest/2));//center adjustment for (i=0;i1) printf("\u2588");//color + if(f[o]-n<0.125) //blank + { + if(matrix[i][n]!=0)//change? + { + if(move!=0)printf("\033[%dC",move); + move=0; + printf(" "); + } + else move++; //no change, moving along + matrix[i][n]=0; + } + else if (f[o]-n>1)//color + { + if(matrix[i][n]!=1)//change? + { + if(move!=0)printf("\033[%dC",move); + move=0; + printf("\u2588"); + } + else move++; //no change, moving along + matrix[i][n]=1; + } else//top color, finding fraction { + if(move!=0)printf("\033[%dC",move); + move=0; c=((((f[o]-(float)n)-0.125)/0.875*7)+1); switch (c) { @@ -412,17 +498,20 @@ if (debug==0) default: printf(" "); } - } + matrix[i][n]=2; + } } } + printf("\n");//next line - if(rest!=0)printf("\033[%dC",(rest/2));//center adjustment + } printf("\033[%dA",height);//backup +usleep((1/(float)framerate)*1000000);//sleeping for set us } //