added experimental pulseaudio support

master
karlstav 10 years ago
parent c674073d77
commit fb66f9753d
  1. 23
      README.md
  2. 25
      cava.c
  3. 14
      configure.ac
  4. 15
      example_files/config
  5. 64
      input/pulse.c
  6. 4
      input/pulse.h

@ -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.

@ -43,6 +43,10 @@
#include "input/alsa.c"
#endif
#ifdef PULSE
#include "input/pulse.h"
#include "input/pulse.c"
#endif
#include <iniparser.h>
@ -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();

@ -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 ######################

@ -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]

@ -0,0 +1,64 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#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;
}
}
}

@ -0,0 +1,4 @@
//header file for pulse, part of cava.
void* input_pulse(void* data);
Loading…
Cancel
Save