From 9168ed8d143a4b2ee5abdc41d06d96371524dc19 Mon Sep 17 00:00:00 2001 From: An Ko Date: Fri, 13 Mar 2015 10:45:23 +0000 Subject: [PATCH 1/6] Make git ignore the compiled file --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea57582 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +cava From a09ae743bdb411bc85cf4173912b74e1f07d674f Mon Sep 17 00:00:00 2001 From: An Ko Date: Fri, 13 Mar 2015 10:46:30 +0000 Subject: [PATCH 2/6] Add clean target to makefile People frequently expect this to exist, so they can remove compiled files for packaging, etc. --- makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/makefile b/makefile index 3e17658..9ce8cd9 100644 --- a/makefile +++ b/makefile @@ -1,2 +1,6 @@ cava: cava.c gcc cava.c -o cava -lasound -lm -lfftw3 -lpthread +clean: + rm cava + +.PHONY: clean From abdeea911522d31e98f80dccfe8cb9ff29653e83 Mon Sep 17 00:00:00 2001 From: An Ko Date: Fri, 13 Mar 2015 11:24:23 +0000 Subject: [PATCH 3/6] README clarifications / corrections This is just a proofreading pass; I tried to change none of the meaning. --- README.md | 190 ++++++++++++++++++++++++++---------------------------- 1 file changed, 92 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index 0c7c023..87ee6fe 100644 --- a/README.md +++ b/README.md @@ -1,178 +1,172 @@ C.A.V.A. -========= -Console-based Audio Visualizer for Alsa +======== + +**C**onsole-based **A**udio **V**isualizer for **A**LSA ![spectrum](http://stavestrand.no/cava6.gif "spectrum") -http://youtu.be/vA4RyatP064 +[Demo video](http://youtu.be/vA4RyatP064) -by [Karl Stavestrand](mailto:karl@stavestrand.no ) +by [Karl Stavestrand](mailto:karl@stavestrand.no) Updates ----------- -9/22/2014 - updated support for fifo (mpd). +------- + +9/22/2014 - Added support for mpd FIFO input. What it is ---------- -C.A.V.A is a bar spectrum analyzer for audio using Alsa for input. The frequency range is limited to 50-12000Hz. I know that the human ear can hear from 20 up to 20,000 Hz (and probably "sense" even higher frequencies). But the frequencies between 50 - 12000Hz seems to me to be the sounds that are most distinguishable. (I do believe telephones used to be limited to as low as 8kHz.) -This is my first actual "published" work and I am not a professional programmer so the source code is probably, by all conventions, a complete mess. +C.A.V.A. is a bar spectrum analyzer for audio using ALSA for input. Its frequency range is limited to 50-12,000Hz. I know that the human ear can hear from 20 up to 20,000 Hz (and probably "sense" even higher frequencies), but the frequencies between 50-12,000Hz seem to me to be the most distinguishable. (I believe telephones used to be limited to as low as 8kHz.) -This program is not intendent to be used for scientific purposes. +This program is not intended for scientific use. -Please excuse all the typos as I am both dyslectic and foreign. +This is my first published code. I am not a professional programmer so the source code is probably, by all conventions, a complete mess. Please excuse all the typos as I am both dyslexic and foreign. -Any tips/comments will be received with much appreciation. +Any tips or comments would be much appreciated. -Build Requirements +Build requirements ------------------ -* alsa dev files: (http://alsa-project.org/) -* FFTW: (http://www.fftw.org/) -Debian/Raspbian users can get this with: -apt-get install libfftw3-dev libasound2-dev +* [ALSA dev files](http://alsa-project.org/) +* [FFTW](http://www.fftw.org/) +Debian/Raspbian users can install this with: + apt-get install libfftw3-dev libasound2-dev -How to get started -------------- -``` -make -``` +Getting started +--------------- + make +Capturing audio +--------------- -Capturing audio straight from output -------------- +### Straight from output -If you want to capture audio straight fom the output (not just mic or line-in), you must first create an alsa loopback interface and then output the audio simultaneously to both the loopback and your normal interface. +If you want to capture audio straight fom the output (not just mic or line-in), you must create an ALSA loopback interface, then output the audio simultaneously to both the loopback and your normal interface. -Here is how to create a loopback interface: +Here is one way to create a loopback interface: - Copy the file "alsa-aloop.conf" to your "/etc/modprobe.d/" directory. You might have to change the index=1 to match your sound setup. Look at "aplay -l" to se what index is available. - Add the line "snd-aloop" to /etc/modules - Run "sudo modprobe snd_aloop" -Hopefully your "aplay -l" should now contain a couple of "Loopback" interfaces. +Hopefully your "aplay -l" should now contain a few "Loopback" interfaces. -Now playing the audio through your Loopback interface will make it possible to capture by it cava, but there will be no sound in your speakers :( +Now playing the audio through your Loopback interface makes it possible for cava to to capture it, but there will be no sound in your speakers. :( -Not to worry! There are (at least) two ways of sending the audio output to the loopback and your actual audio interface at the same time: +Not to worry! There are (at least) two ways of sending the audio output to the loopback *and* your actual audio interface at the same time: -- pulseaudio (easy): +#### PulseAudio (easy) -In the file "/etc/pulse/default.pa" add the line "load-module module-combine-sink" (in pulseaudio versions < 2.0 the module is only called "module-combine"). Then restart pulseaudio. For some reason i had to turn of realtime scheduling in order for this to work on raspberry pi, set "realtime-scheduling = no" in /etc/pulse/daemon.conf. +To `/etc/pulse/default.pa`, add the line `load-module module-combine-sink` (in PulseAudio versions <2.0, the module is only called `module-combine`). Then restart PulseAudio. For some reason, I had to turn off realtime scheduling for this to work on a Raspberry Pi (set `realtime-scheduling = no` in `/etc/pulse/daemon.conf`). -Pulseaudio setup can also be done in paprefs (debain: sudo apt-get install paprefs && paprefs&), the far right tab "Simultaneous Output" and check the box. +PulseAudio setup can also be done in paprefs (Debian: `sudo apt-get install paprefs && paprefs`): In the far right tab check the box "Simultaneous Output". -After that there should be an extra Output in your sound options called "Simultaneous output to..." Note that when using this method if you turn down the volume on the Simultaneous output, this will effect the visualizer. So to avoid this you have to select the actual output then turn down the volume then select the Simultaneous output again. +An extra Output should appear in your sound options called "Simultaneous output to..." Note that when using this method if you turn down the volume on the Simultaneous output, this will effect the visualizer. To avoid this, select the actual output, then turn down the volume, then select the Simultaneous output again. -- alsa (hard): +#### ALSA (hard) -Look at the inculded example file: /etc/asound.cnf. I was able to make this work on my laptop an Asus ux31 running elemetary os. But had no luck with the alsa method on my Rasberry PI with an USB DAC runnig rasbian. The pulseaudio method however works perfectly on my PI. +Look at the inculded example file `example_files/etc/asound.conf`. I was able to make this work on my laptop an Asus UX31 running Elementary OS. I had no luck with the ALSA method on my Rasberry PI with an USB DAC runnig Rasbian. The PulseAudio method however works perfectly on my PI. -Read more about the alsa method [here](http://stackoverflow.com/questions/12984089/capture-playback-on-play-only-sound-card-with-alsa) +Read more about the ALSA method [here](http://stackoverflow.com/questions/12984089/capture-playback-on-play-only-sound-card-with-alsa). +Cava defaults to using the ALSA device `hw:1,1`. If your loopback interface is not on that index, or you want to capture audio from somewhere else, simply pass the `-d` flag with the target. -Cava defaults to "hw:1,1" if your loopback interface is not on that index, or you want to capture audio from somewhere else, simply cahnge this with the -d option. +### From mpd's fifo output -Capturing audio from fifo output (mpd) -------------- -add this lines in mpd: +Add these lines in mpd: -``` -audio_output { - type "fifo" - name "my_fifo" - path "/tmp/mpd.fifo" - format "44100:16:2" -} -``` + audio_output { + type "fifo" + name "my_fifo" + path "/tmp/mpd.fifo" + format "44100:16:2" + } -run cava with: -``` - ~ $ ./cava -i fifo -``` +Run cava with `./cava -i fifo`. -The path of the fifo can be specified with -p. +The path of the fifo can be specified with `-p`. -I had some trouble with sync (the visualizer was before the sound) reducing the alsa buffer in the mpd fixed it: +I had some trouble with sync (the visualizer was ahead of the sound). Reducing the ALSA buffer in mpd fixed it: -``` -audio_output { - type "alsa" - name "My ALSA" - buffer_time "50000" # (50ms) default is 500000 microseconds (0.5 seconds) -} -``` + audio_output { + type "alsa" + name "My ALSA" + buffer_time "50000" # (50ms); default is 500000 microseconds (0.5s) + } -Running via ssh: --------------------- -To run via ssh to external monitor: -``` - ~# ./cava [options] > /dev/console -``` -(must be root to redirect to console, simple sudo is not enouh, run "sudo su" first) +Running via ssh +--------------- +To run via ssh to an external monitor, redirect output to `/dev/console`: + ~# ./cava [options] > /dev/console -A note on fonts: --------------------- -Since the graphics are simply based on characters the preformance is dependent on the font in the terminal. +(You must be root to redirect to console. Simple sudo is not enough: Run `sudo su` first.) -- In ttys: -If you run this in the conosle (tty1-7) the program will change the font to the included "cava.psf" (actually "unifont") this is because that font looks good with this program and beause i had to change the font slightly. -In console fonts it seems that only 256 unicode charachters are suported, probably since theese are bitmap fonts. I could not find a font that had unicode charachters 2581-2587, these are the 1/8 - 7/8 blocks used on the top of each bar to increase resolution. +Font notes +---------- + +Since the graphics are simply based on characters, performance is dependent on the terminal font. -So in cava.psf the charachters 1-7 is actually replaced by unicode charachters 2581-2587. Not to worry, when cava is excited the font is suposed to change. However if you notice that 1-7 is replaced by partial blocks just change the font with "setfont". +### In ttys -Another note on fonts, "setfont" is suposed to return the defualt font, but this usally isn't set and I haven't found another way to get the current font. So what cava does is setting the font to "Lat2-Fixed16" on exit (ctrl+c), this should be included in all mayor distros. I think it reverts to your default at reboot. - -- In terminal emulators: +If you run this in a TTY the program will change the font to the included `cava.psf` (actually a slightly modified "unifont"). -In terminal emulator like xTerm, the font is chosen in the software and cannot be changed by an apliaction. So find your terminal settings and try out diferent fonts, some look pretty crap with the block charachters :( . "FreeMono Bold" and "WenQuanYi Micro Hei Mono" is what I have found to look pretty good, But it still looks much better in the tty. I found out that it looks pretty good in the standard gnome terminal. +In console fonts it seems that only 256 Unicode characters are supported, probably because they are bitmap fonts. I could not find a font with Unicode characters 2581-2587 (the 1/8 - 7/8 blocks used on the top of each bar to increase resolution). -!!warning!! cava also turns of the cursor, it's suposed to turn it back on on exit (ctrl+c), but in case it terminates unexpectedly, run: "setterm -cursor on" to get the cursor back. +So in `cava.psf`, the characters 1-7 are actually replaced by Unicode characters 2581-2587. When cava exits, it changes the font back. If cava exits abnormally and you notice that 1-7 are replaced by partial blocks, just change the font with `setfont`. +Actually, `setfont` is supposed to return the default font, but this usually isn't set. I haven't found another way to get the current font. So cava sets the font to "Lat2-Fixed16" when interrupted. All major distros should have it. It will revert to your default font at reboot. +### In terminal emulators -A note on latency: --------------------- -If you experince an issue with latency (sound before image) in terminal emulator, try to increase the font size. This will reduce the number of charachters that has to be printed out. +In terminal emulators like `xterm`, the font is chosen in the software and cannot be changed by an application. So find your terminal settings and try out different fonts. Some look pretty crap with the block charachters :(. "FreeMono Bold" and "WenQuanYi Micro Hei Mono" look pretty good, but it still looks much better in the TTY. I found out that it looks pretty good with the default `gnome-terminal` settings. -If there is a huge buffer in your audio device, you might experience that cava is actually faster then the audio you heare. This will reduce the experience of the visualization. To fix this you can try to increase the buffer settings in the audio playing software. +Cava also disables the terminal cursor, and turns it back on on exit, but in case it terminates unexpectedly, run `setterm -cursor on` to get it back. + + +Latency notes +------------- + +If you see latency issues (sound before image) in a terminal emulator, try increasing the font size. This will reduce the number of characters that have to be shown. + +If your audio device has a huge buffer, you might experience that cava is actually faster then the audio you hear. This reduces the experience of the visualization. To fix this, you try decreasing the buffer settings in your audio playing software. Usage --------------------- -``` -Usage : ./cava [options] +----- + + Usage : ./cava [options] + + Options: + -b 1..(console columns/2-1) or 200 number of bars in the spectrum (default 25 + fills up the console), program wil auto adjust to maxsize if input is to high) -Options: - -b 1..(console columns/2-1) or 200 number of bars in the spectrum (default 25 + fills up the console), program wil auto adjust to maxsize if input is to high) + -i 'input method' method used for listnening to audio, supports 'alsa' and 'fifo' - -i 'input method' method used for listnening to audio, supports 'alsa' and 'fifo' + -d 'alsa device' name of alsa capture device (default 'hw:1,1') - -d 'alsa device' name of alsa capture device (default 'hw:1,1') + -p 'fifo path' path to fifo (default '/tmp/mpd.fifo') - -p 'fifo path' path to fifo (default '/tmp/mpd.fifo') + -c color suported colors: red, green, yellow, magenta, cyan, white, blue, black (default: cyan) - -c color suported colors: red, green, yellow, magenta, cyan, white, blue, black (default: cyan) + -C backround color supported colors: same as above (default: no change) - -C backround color supported colors: same as above (default: no change) + -s sensitivity % sensitivity in percent, 0 means no respons 100 is normal 50 half 200 double and so forth - -s sensitivity % sensitivity in percent, 0 means no respons 100 is normal 50 half 200 double and so forth + -f framerate max frames per second to be drawn, if you are experiencing high CPU usage, try redcing this (default: 60) - -f framerate max frames per second to be drawn, if you are experiencing high CPU usage, try redcing this (default: 60) -``` -exit with ctrl+c. +Exit with ctrl+c. -If cava quits unexpectedly or is force killed echo must be turned on manualy with "stty -echo". +If cava quits unexpectedly or is force killed, echo must be turned on manually with `stty -echo`. From c93ba7d496e4643be75754e2af84067feb8bc3bc Mon Sep 17 00:00:00 2001 From: An Ko Date: Fri, 13 Mar 2015 11:36:24 +0000 Subject: [PATCH 4/6] Initial pass on clarifying source Some automatic indentation. --- cava.c | 917 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 465 insertions(+), 452 deletions(-) diff --git a/cava.c b/cava.c index 2170313..01587a9 100644 --- a/cava.c +++ b/cava.c @@ -1,22 +1,22 @@ -#include -#include +#include +#include #include #include #include #include #define PI 3.14159265358979323846 -#include -#include -#include +#include +#include +#include #include #include struct sigaction old_action; -int M=2048; +int M = 2048; int shared[2048]; -int debug=0; -int format=-1; -int rate=-1; +int debug = 0; +int format = -1; +int rate = -1; void sigint_handler(int sig_no) @@ -26,7 +26,7 @@ void sigint_handler(int sig_no) system("setterm -cursor on"); system("setterm -blank 10"); system("clear"); - system("stty echo"); + system("stty echo"); printf("CTRL-C pressed -- goodbye\n"); sigaction(SIGINT, &old_action, NULL); kill(0, SIGINT); @@ -36,101 +36,108 @@ void sigint_handler(int sig_no) void* music(void* data) { -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; + 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);//assembling params -snd_pcm_hw_params_any (handle, params);//setting defaults or something -snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);//interleeaved mode right left right left -snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); //trying to set 16bit -snd_pcm_hw_params_set_channels(handle, params, 2);//asuming stereo -val = 44100; -snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);//trying 44100 rate -frames = 256; -snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); //number of frames pr read - -err = snd_pcm_hw_params(handle, params); //atempting to set params -if (err < 0) { - fprintf(stderr, - "unable to set hw parameters: %s\n", - snd_strerror(err)); - exit(1); -} + 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);//assembling params + snd_pcm_hw_params_any (handle, params);//setting defaults or something + snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);//interleeaved mode right left right left + snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); //trying to set 16bit + snd_pcm_hw_params_set_channels(handle, params, 2);//asuming stereo + val = 44100; + snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);//trying 44100 rate + frames = 256; + snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); //number of frames pr read + + err = snd_pcm_hw_params(handle, params); //atempting to set 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 actual format + snd_pcm_hw_params_get_format(params, (snd_pcm_format_t * )&val); //getting actual format //convverting result to number of bits -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 - -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; // frames * bits/8 * 2 channels -buffer = (char *) malloc(size); -radj=format/4;//adjustments for interleaved -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 + 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 + + 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; // frames * bits/8 * 2 channels + buffer = (char *) malloc(size); + radj=format/4;//adjustments for interleaved + 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 using to much cpu.. - //for(o=0;o> 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 using to much cpu.. + //for(o=0;o> 6); - //printf("%d\n",buf[4*q+1]); - if (lo<0)lo=lo+4; - if(tempr>=0)tempr= tempr + lo; - if(tempr<0)tempr= tempr - lo; - - - templ = ( buf[size - 4*q - 3] << 2); - lo = ( buf[size - 4*q - 2] >> 6); - - if(lo<0)lo=lo+4; - if(templ>=0)templ=templ+lo; - else templ=templ-lo; - - //printf("%d\n",((tempr+templ)/2)); - shared[n]=(tempr+templ)/2; - - n++; - if(n==M-1)n=0; + FILE *fp; + + int fifo; + int n=0; + signed char buf[1024]; + int tempr,templ,lo; + int i,q; + int size=1024; + char *path = ((char*)data); + fp = fopen(path,"r"); + + while (1) + { + + fread(&buf, sizeof(char),size,fp); + + for (q=0; q<(size/4); q++) + { + //printf("%d, %d\n",buf[q],buf[q+1]); + + tempr = ( buf[size - 4*q-1] << 2); + lo = ( buf[size - 4*q ] >> 6); + //printf("%d\n",buf[4*q+1]); + if (lo<0)lo=lo+4; + if(tempr>=0)tempr= tempr + lo; + if(tempr<0)tempr= tempr - lo; + + + templ = ( buf[size - 4*q - 3] << 2); + lo = ( buf[size - 4*q - 2] >> 6); + + if(lo<0)lo=lo+4; + if(templ>=0)templ=templ+lo; + else templ=templ-lo; + + //printf("%d\n",((tempr+templ)/2)); + shared[n]=(tempr+templ)/2; + + n++; + if(n==M-1)n=0; } - } - fclose(fp); + } + fclose(fp); } int main(int argc, char **argv) { -pthread_t p_thread; -int thr_id; -char *input = "alsa"; -int im = 1; -char *device = "hw:1,1"; -char *path = "/tmp/mpd.fifo"; -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]; -float f[200]; -int flast[200]; -float peak[201]; -int y[M/2+1]; -long int lpeak,hpeak; -int bands=25; -int sleep=0; -int i, n, o, size, dir, err,bw,width,height,c,rest,virt; -int autoband=1; + pthread_t p_thread; + int thr_id; + char *input = "alsa"; + int im = 1; + char *device = "hw:1,1"; + char *path = "/tmp/mpd.fifo"; + 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]; + float f[200]; + int flast[200]; + float peak[201]; + int y[M/2+1]; + long int lpeak,hpeak; + int bands=25; + int sleep=0; + int i, n, o, size, dir, err,bw,width,height,c,rest,virt; + int autoband=1; //long int peakhist[bands][400]; -float temp; -double sum=0; -struct winsize w; -double in[2*(M/2+1)]; -fftw_complex out[M/2+1][2]; -fftw_plan p; -char *color; -int col = 36; -int bgcol = 0; -int sens = 100; -int move=0; -int fall[200]; -float fpeak[200]; -float k[200]; -float g; -int framerate=60; -char *usage="\nUsage : ./cava [options]\n\nOptions:\n\t-b 1..(console columns/2-1) or 200\t number of bars in the spectrum (default 25 + fills up the console), program wil auto adjust to maxsize if input is to high)\n\n\t-i 'input method'\t\t\t method used for listnening to audio, supports 'alsa' and 'fifo'\n\n\t-d 'alsa device'\t\t\t name of alsa capture device (default 'hw:1,1')\n\n\t-p 'fifo path'\t\t\t\t path to fifo (default '/tmp/mpd.fifo')\n\n\t-c color\t\t\t\t suported colors: red, green, yellow, magenta, cyan, white, blue, black (default: cyan)\n\n\t-C backround color\t\t\t supported colors: same as above (default: no change) \n\n\t-s sensitivity %\t\t\t sensitivity in percent, 0 means no respons 100 is normal 50 half 200 double and so forth\n\n\t-f framerate \t\t\t\t max frames per second to be drawn, if you are experiencing high CPU usage, try redcing this (default: 60)\n\n"; + float temp; + double sum=0; + struct winsize w; + double in[2*(M/2+1)]; + fftw_complex out[M/2+1][2]; + fftw_plan p; + char *color; + int col = 36; + int bgcol = 0; + int sens = 100; + int move=0; + int fall[200]; + float fpeak[200]; + float k[200]; + float g; + int framerate=60; + char *usage="\nUsage : ./cava [options]\n\nOptions:\n\t-b 1..(console columns/2-1) or 200\t number of bars in the spectrum (default 25 + fills up the console), program wil auto adjust to maxsize if input is to high)\n\n\t-i 'input method'\t\t\t method used for listnening to audio, supports 'alsa' and 'fifo'\n\n\t-d 'alsa device'\t\t\t name of alsa capture device (default 'hw:1,1')\n\n\t-p 'fifo path'\t\t\t\t path to fifo (default '/tmp/mpd.fifo')\n\n\t-c color\t\t\t\t suported colors: red, green, yellow, magenta, cyan, white, blue, black (default: cyan)\n\n\t-C backround color\t\t\t supported colors: same as above (default: no change) \n\n\t-s sensitivity %\t\t\t sensitivity in percent, 0 means no respons 100 is normal 50 half 200 double and so forth\n\n\t-f framerate \t\t\t\t max frames per second to be drawn, if you are experiencing high CPU usage, try redcing this (default: 60)\n\n"; //**END INIT -for (i=0;i<200;i++) -{ -flast[i]=0; -fall[i]=0; -fpeak[i]=0; -} -for (i=0;i200)bands=200; - break; - case 'd': - device = optarg; - break; - case 's': - sens = atoi(optarg); - break; - case 'f': - framerate = atoi(optarg); - break; - case 'c': + break; + case 'd': + device = optarg; + break; + case 's': + sens = atoi(optarg); + break; + case 'f': + framerate = atoi(optarg); + break; + case 'c': col=0; - color = optarg; - if(strcmp(color,"black")==0) col=30; - 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) - { + color = optarg; + if(strcmp(color,"black")==0) col=30; + 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 'C': + } + break; + case 'C': bgcol=0; - color = optarg; - if(strcmp(color,"black")==0) bgcol=40; - if(strcmp(color,"red")==0) bgcol=41; - if(strcmp(color,"green")==0) bgcol=42; - if(strcmp(color,"yellow")==0) bgcol=43; - if(strcmp(color,"blue")==0) bgcol=44; - if(strcmp(color,"magenta")==0) bgcol=45; - if(strcmp(color,"cyan")==0) bgcol=46; - if(strcmp(color,"white")==0) bgcol=47; - if(bgcol==0) - { + color = optarg; + if(strcmp(color,"black")==0) bgcol=40; + if(strcmp(color,"red")==0) bgcol=41; + if(strcmp(color,"green")==0) bgcol=42; + if(strcmp(color,"yellow")==0) bgcol=43; + if(strcmp(color,"blue")==0) bgcol=44; + if(strcmp(color,"magenta")==0) bgcol=45; + if(strcmp(color,"cyan")==0) bgcol=46; + if(strcmp(color,"white")==0) bgcol=47; + if(bgcol==0) + { printf("color %s not suprted\n",color); exit(1); - } - break; - case 'h': - printf ("%s",usage); - return 0; - case '?': - printf ("%s",usage); - return 1; - default: - abort (); - } + } + break; + case 'h': + printf ("%s",usage); + return 0; + case '?': + printf ("%s",usage); + 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); + struct sigaction action; + memset(&action, 0, sizeof(action)); + action.sa_handler = &sigint_handler; + sigaction(SIGINT, &action, &old_action); //**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; -int matrix[width][height]; -for(i=0;i(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; + int matrix[width][height]; + for(i=0; i2000) +//**watintg for audio to be ready**// + thr_id = pthread_create(&p_thread, NULL, music,(void*)device); //starting alsamusic listner + while (format==-1||rate==-1) { - if(debug==1)printf("could not get rate and or format, problems with audoi thread? quiting...\n"); - exit(1); + usleep(1000); + n++; + if(n>2000) + { + if(debug==1)printf("could not get rate and or format, problems with audoi thread? quiting...\n"); + exit(1); + } } + if(debug==1)printf("got format: %d and rate %d\n",format,rate); + debug=0; } -if(debug==1)printf("got format: %d and rate %d\n",format,rate); -debug=0; -} -if(im==2) -{ -thr_id = pthread_create(&p_thread, NULL, fifomusic,(void*)path); //starting fifomusic listner -rate=44100; -format=16; -} + if(im==2) + { + thr_id = pthread_create(&p_thread, NULL, fifomusic,(void*)path); //starting fifomusic listner + rate=44100; + format=16; + } //**calculating cutof frequencies**/ -for(n=0;n %f (%d -> %d) \n",n,fc[n-1],fc[n],lcf[n-1],hcf[n-1]);} -} + if(debug==1&&n!=0) { + printf("%d: %f -> %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;n--) + printf("\033[1m"); //setting "bright" color mode, looks cooler... I think + if(bgcol!=0) + printf("\033[%dm",bgcol); + { + for (n=(height); n>=0; n--) { - for (i=0;ihpeak) hpeak=shared[i]; - if(shared[i]hpeak) hpeak=shared[i]; + if(shared[i]peak[o]) peak[o]=y[i]; + y[i]=pow(pow(*out[i][0],2)+pow(*out[i][1],2),0.5); //getting r of compex + if(y[i]>peak[o]) peak[o]=y[i]; } - temp=peak[o]*k[o]*((float)sens/100); //multiplying with k and adjusting to sens settings - if(temp>height)temp=height;//just in case - - //**falloff function**// - if(tempheight)temp=height;//just in case + + //**falloff function**// + if(temp=flast[o]) + else if (temp>=flast[o]) { - f[o]=temp; - fpeak[o]=f[o]; - fall[o]=0; + f[o]=temp; + fpeak[o]=f[o]; + fall[o]=0; + } + + flast[o]=f[o]; //memmory for falloff func + + + if(f[o]<0.125)f[o]=0.125; + 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]); } - flast[o]=f[o]; //memmory for falloff func - - if(f[o]<0.125)f[o]=0.125; - 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 alltime:%f \n",sum);} } - // if(debug==1){ printf("topp overall unfiltered:%f \n",peak[bands]); } - - - //if(debug==1){ printf("topp overall alltime:%f \n",sum);} - } - else//**if in sleep mode wait and continiue**// - { + else//**if in sleep mode wait and continiue**// + { if(debug==1)printf("no sound detected for 3 sec, going to sleep mode\n"); //for (i=0;i<200;i++)flast[i]=0; //zeroing memory no more nesceseary after faloff on pauses //pthread_cancel(thr_id);// this didnt work to well, killing sound thread - usleep(1*1000000);//wait 1 sec, then check sound again. + usleep(1*1000000);//wait 1 sec, then check sound again. continue; - } + } //**DRAWING**// -- put in function file maybe? -if (debug==0) -{ - for (n=(height-1);n>=0;n--) + if (debug==0) { - o=0; - move=rest/2;//center adjustment - //if(rest!=0)printf("\033[%dC",(rest/2));//center adjustment - for (i=0;i=0; n--) { - - //next bar? make a space - if(i!=0&&i%bw==0){ - o++; - if(o1)//color - { + } + else if (f[o]-n>1)//color + { if(matrix[i][n]!=1)//change? - { - if(move!=0)printf("\033[%dC",move); + { + 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) + { + 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(" "); } - 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) - { - 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(" "); - } - matrix[i][n]=2; - } - } - - - } - - printf("\n");//next line - - } + matrix[i][n]=2; + } + } -printf("\033[%dA",height);//backup -usleep((1/(float)framerate)*1000000);//sleeping for set us + } -} + printf("\n");//next line + } + printf("\033[%dA",height);//backup + + usleep((1/(float)framerate)*1000000);//sleeping for set us + + } + + + } + return 0; } -return 0; -} - + From 097e9a3cdc5cf633c75ea22b93df9ce15f92805e Mon Sep 17 00:00:00 2001 From: An Ko Date: Fri, 13 Mar 2015 11:37:44 +0000 Subject: [PATCH 5/6] Remove unnecessary spacing --- cava.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/cava.c b/cava.c index 01587a9..9ffd6c6 100644 --- a/cava.c +++ b/cava.c @@ -18,7 +18,6 @@ int debug = 0; int format = -1; int rate = -1; - void sigint_handler(int sig_no) { printf("\033[0m\n"); @@ -78,7 +77,6 @@ music(void* data) 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 snd_pcm_hw_params_get_period_size(params,&frames, &dir); @@ -142,7 +140,6 @@ music(void* data) } } - //FIFO audio listner void* fifomusic(void* data) @@ -174,7 +171,6 @@ fifomusic(void* data) if(tempr>=0)tempr= tempr + lo; if(tempr<0)tempr= tempr - lo; - templ = ( buf[size - 4*q - 3] << 2); lo = ( buf[size - 4*q - 2] >> 6); @@ -192,7 +188,6 @@ fifomusic(void* data) fclose(fp); } - int main(int argc, char **argv) { pthread_t p_thread; @@ -241,7 +236,6 @@ int main(int argc, char **argv) } for (i=0; i(int)w.ws_col/2-1)bands=(int)w.ws_col/2-1; //handle for user setting to many bars @@ -342,7 +334,6 @@ int main(int argc, char **argv) } bw=width/bands; - g=((float)height/1000)*pow((60/(float)framerate),2.5);//calculating gravity //if no bands are selected it tries to padd the default 20 if there is extra room @@ -352,7 +343,6 @@ int main(int argc, char **argv) rest=(((w.ws_col)-(bw*bands+bands-1))); if(rest<0)rest=0; - printf("hoyde: %d bredde: %d bands:%d bandbredde: %d rest: %d\n",(int)w.ws_row,(int)w.ws_col,bands,bw,rest); n=0; @@ -406,10 +396,8 @@ int main(int argc, char **argv) for(n=0; n%f (%d->%d)peak:%f adjpeak: %f \n",o,fc[o],fc[o+1],lcf[o],hcf[o],peak[o],f[o]); @@ -513,7 +497,6 @@ int main(int argc, char **argv) } // if(debug==1){ printf("topp overall unfiltered:%f \n",peak[bands]); } - //if(debug==1){ printf("topp overall alltime:%f \n",sum);} } else//**if in sleep mode wait and continiue**// @@ -543,7 +526,6 @@ int main(int argc, char **argv) } - //draw color or blank or move+1 if(o Date: Fri, 13 Mar 2015 11:55:45 +0000 Subject: [PATCH 6/6] Auto-format with astyle astyle --style=linux --pad-oper --max-code-length=80 --keep-one-line-blocks --keep-one-line-statements --convert-tabs --remove-comment-prefix cava.c --- cava.c | 507 +++++++++++++++++++++++++++------------------------------ 1 file changed, 244 insertions(+), 263 deletions(-) diff --git a/cava.c b/cava.c index 9ffd6c6..e94ebcb 100644 --- a/cava.c +++ b/cava.c @@ -14,9 +14,9 @@ struct sigaction old_action; int M = 2048; int shared[2048]; -int debug = 0; +int debug = 0; int format = -1; -int rate = -1; +int rate = -1; void sigint_handler(int sig_no) { @@ -41,27 +41,30 @@ music(void* data) 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; + 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("error opening stream: %s\n", snd_strerror(err) ); + else if(debug == 1) { printf("open stream succes\n"); } snd_pcm_hw_params_alloca(¶ms);//assembling params snd_pcm_hw_params_any (handle, params);//setting defaults or something - snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);//interleeaved mode right left right left - snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); //trying to set 16bit + snd_pcm_hw_params_set_access(handle, params, + SND_PCM_ACCESS_RW_INTERLEAVED);//interleeaved mode right left right left + snd_pcm_hw_params_set_format(handle, params, + SND_PCM_FORMAT_S16_LE); //trying to set 16bit snd_pcm_hw_params_set_channels(handle, params, 2);//asuming stereo val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);//trying 44100 rate frames = 256; - snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); //number of frames pr read + snd_pcm_hw_params_set_period_size_near(handle, params, &frames, + &dir); //number of frames pr read err = snd_pcm_hw_params(handle, params); //atempting to set params if (err < 0) { @@ -71,67 +74,68 @@ music(void* data) exit(1); } - snd_pcm_hw_params_get_format(params, (snd_pcm_format_t * )&val); //getting actual format + snd_pcm_hw_params_get_format(params, + (snd_pcm_format_t * )&val); //getting actual format //convverting result to number of bits - if(val<6)format=16; - else if(val>5&&val<10)format=24; - else if(val>9)format=32; + 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 - snd_pcm_hw_params_get_period_size(params,&frames, &dir); + 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; // frames * bits/8 * 2 channels + size = frames * (format / 8) * 2; // frames * bits/8 * 2 channels buffer = (char *) malloc(size); - radj=format/4;//adjustments for interleaved - ladj=format/8; - o=0; + radj = format / 4; //adjustments for interleaved + ladj = format / 8; + o = 0; while(1) { err = snd_pcm_readi(handle, buffer, frames); if (err == -EPIPE) { /* EPIPE means overrun */ - if(debug==1) { + if(debug == 1) { fprintf(stderr, "overrun occurred\n"); } snd_pcm_prepare(handle); } else if (err < 0) { - if(debug==1) { + 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); + 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; + tempr = ((buffer[i + (radj) - 1 ] << + 2)); //using the 10 upper bits this whould give me a vert res of 1024, enough... + lo = ((buffer[i + (radj) - 2] >> 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; + 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; + shared[o] = (tempr + templ) / 2; o++; - if(o==M-1)o=0; + if(o == M - 1)o = 0; //shifing ringbuffer one to the left, this ended up using to much cpu.. //for(o=0;o> 6); + tempr = ( buf[size - 4 * q - 1] << 2); + lo = ( buf[size - 4 * q ] >> 6); //printf("%d\n",buf[4*q+1]); - if (lo<0)lo=lo+4; - if(tempr>=0)tempr= tempr + lo; - if(tempr<0)tempr= tempr - lo; + if (lo < 0)lo = lo + 4; + if(tempr >= 0)tempr = tempr + lo; + if(tempr < 0)tempr = tempr - lo; - templ = ( buf[size - 4*q - 3] << 2); - lo = ( buf[size - 4*q - 2] >> 6); + templ = ( buf[size - 4 * q - 3] << 2); + lo = ( buf[size - 4 * q - 2] >> 6); - if(lo<0)lo=lo+4; - if(templ>=0)templ=templ+lo; - else templ=templ-lo; + if(lo < 0)lo = lo + 4; + if(templ >= 0)templ = templ + lo; + else templ = templ - lo; //printf("%d\n",((tempr+templ)/2)); - shared[n]=(tempr+templ)/2; + shared[n] = (tempr + templ) / 2; n++; - if(n==M-1)n=0; + if(n == M - 1)n = 0; } } fclose(fp); @@ -202,62 +204,61 @@ int main(int argc, char **argv) float f[200]; int flast[200]; float peak[201]; - int y[M/2+1]; - long int lpeak,hpeak; - int bands=25; - int sleep=0; - int i, n, o, size, dir, err,bw,width,height,c,rest,virt; - int autoband=1; + int y[M / 2 + 1]; + long int lpeak, hpeak; + int bands = 25; + int sleep = 0; + int i, n, o, size, dir, err, bw, width, height, c, rest, virt; + int autoband = 1; //long int peakhist[bands][400]; float temp; - double sum=0; + double sum = 0; struct winsize w; - double in[2*(M/2+1)]; - fftw_complex out[M/2+1][2]; + double in[2 * (M / 2 + 1)]; + fftw_complex out[M / 2 + 1][2]; fftw_plan p; char *color; int col = 36; int bgcol = 0; int sens = 100; - int move=0; + int move = 0; int fall[200]; float fpeak[200]; float k[200]; float g; - int framerate=60; - char *usage="\nUsage : ./cava [options]\n\nOptions:\n\t-b 1..(console columns/2-1) or 200\t number of bars in the spectrum (default 25 + fills up the console), program wil auto adjust to maxsize if input is to high)\n\n\t-i 'input method'\t\t\t method used for listnening to audio, supports 'alsa' and 'fifo'\n\n\t-d 'alsa device'\t\t\t name of alsa capture device (default 'hw:1,1')\n\n\t-p 'fifo path'\t\t\t\t path to fifo (default '/tmp/mpd.fifo')\n\n\t-c color\t\t\t\t suported colors: red, green, yellow, magenta, cyan, white, blue, black (default: cyan)\n\n\t-C backround color\t\t\t supported colors: same as above (default: no change) \n\n\t-s sensitivity %\t\t\t sensitivity in percent, 0 means no respons 100 is normal 50 half 200 double and so forth\n\n\t-f framerate \t\t\t\t max frames per second to be drawn, if you are experiencing high CPU usage, try redcing this (default: 60)\n\n"; + int framerate = 60; + char *usage = + "\nUsage : ./cava [options]\n\nOptions:\n\t-b 1..(console columns/2-1) or 200\t number of bars in the spectrum (default 25 + fills up the console), program wil auto adjust to maxsize if input is to high)\n\n\t-i 'input method'\t\t\t method used for listnening to audio, supports 'alsa' and 'fifo'\n\n\t-d 'alsa device'\t\t\t name of alsa capture device (default 'hw:1,1')\n\n\t-p 'fifo path'\t\t\t\t path to fifo (default '/tmp/mpd.fifo')\n\n\t-c color\t\t\t\t suported colors: red, green, yellow, magenta, cyan, white, blue, black (default: cyan)\n\n\t-C backround color\t\t\t supported colors: same as above (default: no change) \n\n\t-s sensitivity %\t\t\t sensitivity in percent, 0 means no respons 100 is normal 50 half 200 double and so forth\n\n\t-f framerate \t\t\t\t max frames per second to be drawn, if you are experiencing high CPU usage, try redcing this (default: 60)\n\n"; //**END INIT - for (i=0; i<200; i++) - { - flast[i]=0; - fall[i]=0; - fpeak[i]=0; + for (i = 0; i < 200; i++) { + flast[i] = 0; + fall[i] = 0; + fpeak[i] = 0; } - for (i=0; i200)bands=200; + autoband = 0; //dont automaticly add bands to fill frame + if (bands > 200)bands = 200; break; case 'd': device = optarg; @@ -269,44 +270,42 @@ int main(int argc, char **argv) framerate = atoi(optarg); break; case 'c': - col=0; + col = 0; color = optarg; - if(strcmp(color,"black")==0) col=30; - 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); + if(strcmp(color, "black") == 0) col = 30; + 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 'C': - bgcol=0; + bgcol = 0; color = optarg; - if(strcmp(color,"black")==0) bgcol=40; - if(strcmp(color,"red")==0) bgcol=41; - if(strcmp(color,"green")==0) bgcol=42; - if(strcmp(color,"yellow")==0) bgcol=43; - if(strcmp(color,"blue")==0) bgcol=44; - if(strcmp(color,"magenta")==0) bgcol=45; - if(strcmp(color,"cyan")==0) bgcol=46; - if(strcmp(color,"white")==0) bgcol=47; - if(bgcol==0) - { - printf("color %s not suprted\n",color); + if(strcmp(color, "black") == 0) bgcol = 40; + if(strcmp(color, "red") == 0) bgcol = 41; + if(strcmp(color, "green") == 0) bgcol = 42; + if(strcmp(color, "yellow") == 0) bgcol = 43; + if(strcmp(color, "blue") == 0) bgcol = 44; + if(strcmp(color, "magenta") == 0) bgcol = 45; + if(strcmp(color, "cyan") == 0) bgcol = 46; + if(strcmp(color, "white") == 0) bgcol = 47; + if(bgcol == 0) { + printf("color %s not suprted\n", color); exit(1); } break; case 'h': - printf ("%s",usage); + printf ("%s", usage); return 0; case '?': - printf ("%s",usage); + printf ("%s", usage); return 1; default: abort (); @@ -321,85 +320,92 @@ int main(int argc, char **argv) //**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; + 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; int matrix[width][height]; - for(i=0; i2000) - { - if(debug==1)printf("could not get rate and or format, problems with audoi thread? quiting...\n"); + if(n > 2000) { + if(debug == 1) + printf("could not get rate and or format, problems with audoi thread? quiting...\n"); exit(1); } } - if(debug==1)printf("got format: %d and rate %d\n",format,rate); - debug=0; + if(debug == 1)printf("got format: %d and rate %d\n", format, rate); + debug = 0; } - if(im==2) - { - thr_id = pthread_create(&p_thread, NULL, fifomusic,(void*)path); //starting fifomusic listner - rate=44100; - format=16; + if(im == 2) { + thr_id = pthread_create(&p_thread, NULL, fifomusic, + (void*)path); //starting fifomusic listner + rate = 44100; + format = 16; } //**calculating cutof frequencies**/ - for(n=0; n %f (%d -> %d) \n",n,fc[n-1],fc[n],lcf[n-1],hcf[n-1]); + if(debug == 1 && n != 0) { + printf("%d: %f -> %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; n--) - { - for (i=0; i= 0; n--) { + for (i = 0; i < width + bands; i++) { printf(" ");//setting backround volor } printf("\n");//setting volor } - printf("\033[%dA",height);//backup + printf("\033[%dA", height); //backup } } //debug=1; //**start main loop**// - while (1) - { - if(debug==1) { + while (1) { + if(debug == 1) { system("clear"); } //**populating input buffer & checking if there is sound**// - lpeak=0; - hpeak=0; - for (i=0; i<(2*(M/2+1)); i++) - { - if(ihpeak) hpeak=shared[i]; - if(shared[i] hpeak) hpeak = shared[i]; + if(shared[i] < lpeak) lpeak = shared[i]; + } else in[i] = 0; // if(debug==1) printf("%d %f\n",i,in[i]); } - peak[bands]=(hpeak+abs(lpeak)); - if (peak[bands]==0)sleep++; - else sleep=0; + peak[bands] = (hpeak + abs(lpeak)); + if (peak[bands] == 0)sleep++; + else sleep = 0; //**if sound for the last 5 sec go ahead with fft**// - if (sleeppeak[o]) peak[o]=y[i]; + for (i = lcf[o]; i <= hcf[o]; i++) { + y[i] = pow(pow(*out[i][0], 2) + pow(*out[i][1], 2), 0.5); //getting r of compex + if(y[i] > peak[o]) peak[o] = y[i]; } - temp=peak[o]*k[o]*((float)sens/100); //multiplying with k and adjusting to sens settings - if(temp>height)temp=height;//just in case + temp = peak[o] * k[o] * ((float)sens / + 100); //multiplying with k and adjusting to sens settings + if(temp > height)temp = height; //just in case //**falloff function**// - if(temp=flast[o]) - { - f[o]=temp; - fpeak[o]=f[o]; - fall[o]=0; + } else if (temp >= flast[o]) { + f[o] = temp; + fpeak[o] = f[o]; + fall[o] = 0; } - flast[o]=f[o]; //memmory for falloff func + flast[o] = f[o]; //memmory for falloff func - if(f[o]<0.125)f[o]=0.125; - 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(f[o] < 0.125)f[o] = 0.125; + 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 alltime:%f \n",sum);} - } - else//**if in sleep mode wait and continiue**// - { - if(debug==1)printf("no sound detected for 3 sec, going to sleep mode\n"); - //for (i=0;i<200;i++)flast[i]=0; //zeroing memory no more nesceseary after faloff on pauses + } else { //**if in sleep mode wait and continiue**// + if(debug == 1)printf("no sound detected for 3 sec, going to sleep mode\n"); + //for (i=0;i<200;i++)flast[i]=0; //zeroing memory no more nesceseary after faloff on pauses //pthread_cancel(thr_id);// this didnt work to well, killing sound thread - usleep(1*1000000);//wait 1 sec, then check sound again. + usleep(1 * 1000000); //wait 1 sec, then check sound again. continue; } //**DRAWING**// -- put in function file maybe? - if (debug==0) - { - for (n=(height-1); n>=0; n--) - { - o=0; - move=rest/2;//center adjustment + if (debug == 0) { + for (n = (height - 1); n >= 0; n--) { + o = 0; + move = rest / 2; //center adjustment //if(rest!=0)printf("\033[%dC",(rest/2));//center adjustment - for (i=0; i1)//color - { - if(matrix[i][n]!=1)//change? - { - if(move!=0)printf("\033[%dC",move); - move=0; + } 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) - { + } 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) { case 1: - if(virt==0)printf("1"); + if(virt == 0)printf("1"); else printf("\u2581"); break; case 2: - if(virt==0)printf("2"); + if(virt == 0)printf("2"); else printf("\u2582"); break; case 3: - if(virt==0)printf("3"); + if(virt == 0)printf("3"); else printf("\u2583"); break; case 4: - if(virt==0)printf("4"); + if(virt == 0)printf("4"); else printf("\u2584"); break; case 5: - if(virt==0)printf("5"); + if(virt == 0)printf("5"); else printf("\u2585"); break; case 6: - if(virt==0)printf("6"); + if(virt == 0)printf("6"); else printf("\u2586"); break; case 7: - if(virt==0)printf("7"); + if(virt == 0)printf("7"); else printf("\u2587"); break; default: printf(" "); } - matrix[i][n]=2; + matrix[i][n] = 2; } } @@ -598,9 +579,9 @@ int main(int argc, char **argv) } - printf("\033[%dA",height);//backup + printf("\033[%dA", height); //backup - usleep((1/(float)framerate)*1000000);//sleeping for set us + usleep((1 / (float)framerate) * 1000000); //sleeping for set us }