diff --git a/README.md b/README.md index b2e11e2..04f7960 100644 --- a/README.md +++ b/README.md @@ -58,12 +58,15 @@ Build requirements * [ALSA dev files](http://alsa-project.org/) * [FFTW](http://www.fftw.org/) * [ncursesw dev files](http://www.gnu.org/software/ncurses/) (bundled in ncurses in arch) +* [Pulseaudio dev files](http://freedesktop.org/software/pulseaudio/doxygen/) + +Only FFTW is actually required for CAVA to compile, but for maximum usage and preformance ncurses and pulseaudio and/or alsa dev files are recommended. Not sure how to get the pulseaudio dev files for other distros then debian/ubuntu or if the are bundled in pulseaudio. This can be installed easily in all major distros: Debian/Raspbian: - apt-get install libfftw3-dev libasound2-dev libncursesw5-dev + apt-get install libfftw3-dev libasound2-dev libncursesw5-dev libpulse-dev ArchLinux: @@ -135,7 +138,19 @@ Cava is in [AUR](https://aur.archlinux.org/packages/cava/), but is as of Novembe Capturing audio --------------- -### From loopback device +### From Pulseaudio monitor source (New, easy and experimental!) + +First make sure you have installed pulseaudio dev files and that cava has been built with pulseaudio support. + +If you're lucky all you have to do is to uncomment this line in the config file under input: + + method = pulse + +If nothing happens you might have to use a different source then the default. Look at the config file for help. + +The output is dependent on the volume setting, use the arrow up and down keys to adjust cava to the audio. + +### From ALSA-loopback device 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. @@ -151,7 +166,7 @@ Playing the audio through your Loopback interface makes it possible for cava to 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 combined-sink (easy) First create the loopback device as explained in the section above. @@ -162,7 +177,7 @@ PulseAudio setup can also be done in paprefs (Debian: `sudo apt-get install papr 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, turn down the volume, then select the Simultaneous output again. -#### ALSA (hard) +#### ALSA multi channel (hard) First create the loopback device as explained in the section above. diff --git a/cava.c b/cava.c index f0330b0..996dfa4 100644 --- a/cava.c +++ b/cava.c @@ -43,6 +43,10 @@ #include "input/alsa.c" #endif +#ifdef PULSE +#include "input/pulse.h" +#include "input/pulse.c" +#endif #include @@ -201,6 +205,11 @@ FILE *fp; im = 2; audio.source = (char *)iniparser_getstring(ini, "input:source", "/tmp/mpd.fifo"); } + if (strcmp(inputMethod, "pulse") == 0) { + im = 3; + audio.source = (char *)iniparser_getstring(ini, "input:source", "alsa_output.0.analog-stereo.monitor"); + } + } void validate_config() @@ -219,6 +228,15 @@ void validate_config() if (strcmp(inputMethod, "fifo") == 0) { im = 2; } + if (strcmp(inputMethod, "pulse") == 0) { + im = 3; + #ifndef PULSE + fprintf(stderr, + "cava was built without pulseaudio support, install pulseaudio dev files and run make clean && ./configure && make again\n"); + exit(EXIT_FAILURE); + #endif + + } if (im == 0) { #ifdef ALSA fprintf(stderr, @@ -579,6 +597,13 @@ Options:\n\ audio.rate = 44100; } + #ifdef PULSE + if (im == 3) { + thr_id = pthread_create(&p_thread, NULL, input_pulse, + (void*)&audio); //starting fifomusic listener + audio.rate = 44100; + } + #endif if (highcf > audio.rate / 2) { cleanup(); diff --git a/configure.ac b/configure.ac index dcd9bbc..0f40e6b 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,20 @@ AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes, have_alsa=no) AC_MSG_NOTICE([WARNING: No alsa dev files found building without alsa support]) fi + +dnl ###################### +dnl checking for pulse dev +dnl ###################### +AC_CHECK_LIB(pulse-simple, pa_simple_new, have_pulse=yes, have_pulse=no) + if [[ $have_pulse = "yes" ]] ; then + LIBS="$LIBS -lpulse-simple -lpulse" + CPPFLAGS="$CPPFLAGS -DPULSE" + fi + + if [[ $have_pulse = "no" ]] ; then + AC_MSG_NOTICE([WARNING: No pusleaudio dev files found building without pulseaudio support]) + fi + dnl ###################### dnl checking for math lib dnl ###################### diff --git a/example_files/config b/example_files/config index 6799b2e..3056a56 100644 --- a/example_files/config +++ b/example_files/config @@ -31,12 +31,25 @@ [input] -# method of capturing audio, supported input methods are 'alsa' or 'fifo'. +# method of capturing audio, supported input methods are: 'pulse', 'alsa' or 'fifo'. +# +# for pulseaudio 'source' wil be the source. Default: 'alsa_output.0.analog-stereo.monitor' +# all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them +# if the default doesn't work try the command 'pacmd list-sources' to find the right one +# # for alsa 'source' will be the capture device. Default: 'hw:Loopback,1' # for fifo 'source' will be the path to fifo-file. Default: '/tmp/mpd.fifo' ; method = alsa ; source = hw:Loopback,1 +; method = fifo +; source = /tmp/mpd.fifo + +; method = pulse +; source = alsa_output.0.analog-stereo.monitor + + + [output] diff --git a/input/pulse.c b/input/pulse.c new file mode 100644 index 0000000..287a7f8 --- /dev/null +++ b/input/pulse.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include +#define BUFSIZE 1024 + +void* input_pulse(void* data) +{ + + struct audio_data *audio = (struct audio_data *)data; + + int i, n; + + int16_t buf[BUFSIZE / 2]; + + /* The sample type to use */ + static const pa_sample_spec ss = { + .format = PA_SAMPLE_S16LE, + .rate = 44100, + .channels = 2 + }; + static const pa_buffer_attr pb = { + .maxlength = 1024, + .fragsize = 1024 + }; + + pa_simple *s = NULL; + int error; + + /* Create the recording stream */ + if (!(s = pa_simple_new(NULL, "cava", PA_STREAM_RECORD, audio-> source, "audio for cava", &ss, NULL, &pb, &error))) { + fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); + exit(EXIT_FAILURE); + } + + n = 0; + + while (1) { + /* Record some data ... */ + if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) { + fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error)); + exit(EXIT_FAILURE); + } + + //sorting out channels + + for (i = 0; i < BUFSIZE / 2; i += 2) { + + if (audio->channels == 1) audio->audio_out_l[n] = (buf[i] + buf[i + 1]) / 2; + + //stereo storing channels in buffer + if (audio->channels == 2) { + audio->audio_out_l[n] = buf[i]; + audio->audio_out_r[n] = buf[i + 1]; + } + + n++; + if (n == 2048 - 1)n = 0; + } + } + +} diff --git a/input/pulse.h b/input/pulse.h new file mode 100644 index 0000000..7056841 --- /dev/null +++ b/input/pulse.h @@ -0,0 +1,4 @@ +//header file for pulse, part of cava. + +void* input_pulse(void* data); +