Skip to content

Commit 7b58f6e

Browse files
committed
added auto pulseaudio source mode
setting source to 'auto' (also the default pulse source now) automatically finds the monitor interface of the defualt sink this will in most cases be most usefull people who has manualy specified the old default value: 'defualt' will now get an error message.
1 parent be2947b commit 7b58f6e

File tree

5 files changed

+110
-18
lines changed

5 files changed

+110
-18
lines changed

cava.c

+17-7
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ double smoothDef[64] = {0.8, 0.8, 1, 1, 0.8, 0.8, 1, 0.8, 0.8, 1, 1, 0.8,
7575
double *smooth = smoothDef;
7676
int smcount = 64;
7777
struct audio_data audio;
78-
int im = 1;
78+
int im = 0;
7979
int om = 1;
8080
int mode = 1;
8181
int col = 6;
@@ -211,7 +211,7 @@ FILE *fp;
211211
}
212212
if (strcmp(inputMethod, "pulse") == 0) {
213213
im = 3;
214-
audio.source = (char *)iniparser_getstring(ini, "input:source", NULL);
214+
audio.source = (char *)iniparser_getstring(ini, "input:source", "auto");
215215
}
216216

217217
}
@@ -234,6 +234,9 @@ void validate_config()
234234
}
235235
if (strcmp(inputMethod, "pulse") == 0) {
236236
im = 3;
237+
#ifdef PULSE
238+
if (strcmp(audio.source, "auto") == 0) getPulseDefaultSink((void*)&audio);
239+
#endif
237240
#ifndef PULSE
238241
fprintf(stderr,
239242
"cava was built without pulseaudio support, install pulseaudio dev files and run make clean && ./configure && make again\n");
@@ -242,21 +245,28 @@ void validate_config()
242245

243246
}
244247
if (im == 0) {
248+
#ifdef PULSE
249+
fprintf(stderr,
250+
"input method '%s' is not supported, supported methods are: 'pulse', 'alsa' and 'fifo'\n",
251+
inputMethod);
252+
#endif
253+
#ifndef PULSE
245254
#ifdef ALSA
246255
fprintf(stderr,
247-
"input method %s is not supported, supported methods are: 'alsa' and 'fifo'\n",
256+
"input method '%s' is not supported, supported methods are: 'alsa' and 'fifo'\n",
248257
inputMethod);
249258
#endif
259+
#endif
250260
#ifndef ALSA
251261
fprintf(stderr,
252-
"input method %s is not supported, supported methods are: 'fifo'\n",
262+
"input method '%s' is not supported, supported methods are: 'fifo'\n",
253263
inputMethod);
254264
#endif
255265
exit(EXIT_FAILURE);
256266
}
257267

258268
// validate: output method
259-
if (strcmp(outputMethod, "ncurses") == 0) {
269+
if (strcmp(outputMethod, "ncurses") == 0) {
260270
om = 1;
261271
#ifndef NCURSES
262272
fprintf(stderr,
@@ -392,7 +402,7 @@ static bool directory_exists(const char * path) {
392402

393403
#endif
394404

395-
int * separate_freq_bands(fftw_complex out[M / 2 + 1][2], int bars, int lcf[200], int hcf[200], float k[200], int channel) {
405+
int * separate_freq_bands(fftw_complex out[M / 2 + 1][2], int bars, int lcf[200], int hcf[200], float k[200], int channel) {
396406
int o,i;
397407
float peak[201];
398408
static int fl[200];
@@ -475,7 +485,7 @@ int main(int argc, char **argv)
475485

476486
// general: define variables
477487
pthread_t p_thread;
478-
int thr_id GCC_UNUSED;
488+
int thr_id GCC_UNUSED;
479489
int modes = 3; // amount of smoothing modes
480490
float fc[200];
481491
float fre[200];

example_files/config

+6-6
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@
3737
# method of capturing audio, supported input methods are: 'pulse', 'alsa' or 'fifo'.
3838
# Defaults to 'alsa'
3939
#
40-
# for pulseaudio 'source' wil be the source. Default: 'NULL', which uses system default source
41-
# all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them
42-
# but the default, might be your microphone, try the command 'pacmd list-sources' to find the right one
43-
# you can change source here to the name of your prefered device, or cahnge your default pulseaudio source by running
44-
# 'pacmd set-default-source NAME|#N'
40+
# All input methods uses the same config variable 'source'
41+
# to define where it should get the audio.
42+
#
43+
# for pulseaudio 'source' wil be the source. Default: 'auto', which uses the monitor source of the default sink
44+
# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them)
4545
#
4646
# for alsa 'source' will be the capture device. Default: 'hw:Loopback,1'
4747
# for fifo 'source' will be the path to fifo-file. Default: '/tmp/mpd.fifo'
@@ -52,7 +52,7 @@
5252
; source = /tmp/mpd.fifo
5353

5454
; method = pulse
55-
; source = NULL
55+
; source = auto
5656

5757

5858

input/fifo.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ struct audio_data {
44
int audio_out_l[2048];
55
int format;
66
unsigned int rate ;
7-
char *source; //alsa device, fifo path or pulse source
7+
char *source ; //alsa device, fifo path or pulse source
88
int im; //input mode alsa, fifo or pulse
99
int channels;
1010
int terminate; // shared variable used to terminate audio thread

input/pulse.c

+85-4
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,97 @@
44
#include <errno.h>
55
#include <pulse/simple.h>
66
#include <pulse/error.h>
7+
#include <pulse/pulseaudio.h>
78
#define BUFSIZE 1024
89

10+
void getPulseDefaultSink(void* data) {
11+
12+
struct audio_data *audio = (struct audio_data *)data;
13+
pa_mainloop_api *mainloop_api;
14+
pa_context *pulseaudio_context;
15+
pa_mainloop *m_pulseaudio_mainloop;
16+
int ret;
17+
18+
19+
void cb(__attribute__((unused)) pa_context *pulseaudio_context,const pa_server_info *i,__attribute__((unused)) void *userdata){
20+
21+
//getting default sink name
22+
audio->source = malloc(sizeof(char) * 1024);
23+
strcpy(audio->source,i->default_sink_name);
24+
25+
//appending .monitor suufix
26+
audio->source = strcat(audio->source, ".monitor");
27+
28+
//quiting mainloop
29+
pa_mainloop_quit(m_pulseaudio_mainloop, 0);
30+
}
31+
32+
33+
void pulseaudio_context_state_callback(__attribute__((unused)) pa_context *c,
34+
void *userdata) {
35+
36+
//make sure loop is ready
37+
switch (pa_context_get_state(pulseaudio_context))
38+
{
39+
case PA_CONTEXT_UNCONNECTED:
40+
//printf("UNCONNECTED\n");
41+
break;
42+
case PA_CONTEXT_CONNECTING:
43+
//printf("CONNECTING\n");
44+
break;
45+
case PA_CONTEXT_AUTHORIZING:
46+
//printf("AUTHORIZING\n");
47+
break;
48+
case PA_CONTEXT_SETTING_NAME:
49+
//printf("ETTING_NAM\n");
50+
break;
51+
case PA_CONTEXT_READY://extract default sink name
52+
//printf("READY\n");
53+
pa_operation_unref(pa_context_get_server_info(
54+
pulseaudio_context, cb, userdata));
55+
break;
56+
case PA_CONTEXT_FAILED:
57+
//printf("FAILED\n");
58+
break;
59+
case PA_CONTEXT_TERMINATED:
60+
//printf("TERMINATED\n");
61+
break;
62+
}
63+
}
64+
65+
66+
67+
// Create a mainloop API and connection to the default server
68+
m_pulseaudio_mainloop = pa_mainloop_new();
69+
70+
mainloop_api = pa_mainloop_get_api(m_pulseaudio_mainloop);
71+
pulseaudio_context = pa_context_new(mainloop_api, "cava device list");
72+
73+
// This function connects to the pulse server
74+
pa_context_connect(pulseaudio_context, NULL, PA_CONTEXT_NOFLAGS,
75+
NULL);
76+
77+
78+
//This function defines a callback so the server will tell us its state.
79+
pa_context_set_state_callback(pulseaudio_context,
80+
pulseaudio_context_state_callback,
81+
NULL);
82+
83+
//starting a mainloop to get default sink
84+
if (pa_mainloop_run(m_pulseaudio_mainloop, &ret) < 0)
85+
{
86+
printf("Could not open pulseaudio mainloop to "
87+
"find default device name: %d",
88+
ret);
89+
}
90+
91+
}
92+
993
void* input_pulse(void* data)
1094
{
1195

1296
struct audio_data *audio = (struct audio_data *)data;
13-
1497
int i, n;
15-
1698
int16_t buf[BUFSIZE / 2];
1799

18100
/* The sample type to use */
@@ -29,8 +111,7 @@ void* input_pulse(void* data)
29111
pa_simple *s = NULL;
30112
int error;
31113

32-
/* Create the recording stream */
33-
if (!(s = pa_simple_new(NULL, "cava", PA_STREAM_RECORD, audio-> source, "audio for cava", &ss, NULL, &pb, &error))) {
114+
if (!(s = pa_simple_new(NULL, "cava", PA_STREAM_RECORD, audio->source, "audio for cava", &ss, NULL, &pb, &error))) {
34115
fprintf(stderr, __FILE__": Could not open pulseaudio source: %s, %s. To find a list of your pulseaudio sources run 'pacmd list-sources'\n",audio->source, pa_strerror(error));
35116
exit(EXIT_FAILURE);
36117
}

input/pulse.h

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//header file for pulse, part of cava.
22

33
void* input_pulse(void* data);
4+
void getPulseDefaultSink();
45

0 commit comments

Comments
 (0)