mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
Merge branch 'master' of git://0pointer.de/pulseaudio
This commit is contained in:
commit
ed7642ebac
20 changed files with 255 additions and 75 deletions
|
|
@ -20,21 +20,6 @@ pulseconfdir=$(sysconfdir)/pulse
|
||||||
CLEANFILES = \
|
CLEANFILES = \
|
||||||
$(noinst_DATA)
|
$(noinst_DATA)
|
||||||
|
|
||||||
dist_man_MANS = \
|
|
||||||
pulseaudio.1 \
|
|
||||||
esdcompat.1 \
|
|
||||||
pax11publish.1 \
|
|
||||||
paplay.1 \
|
|
||||||
pacat.1 \
|
|
||||||
pacmd.1 \
|
|
||||||
pactl.1 \
|
|
||||||
pasuspender.1 \
|
|
||||||
padsp.1 \
|
|
||||||
pabrowse.1 \
|
|
||||||
pulse-daemon.conf.5 \
|
|
||||||
pulse-client.conf.5 \
|
|
||||||
default.pa.5
|
|
||||||
|
|
||||||
noinst_DATA = \
|
noinst_DATA = \
|
||||||
pulseaudio.1.xml \
|
pulseaudio.1.xml \
|
||||||
esdcompat.1.xml \
|
esdcompat.1.xml \
|
||||||
|
|
@ -50,24 +35,39 @@ noinst_DATA = \
|
||||||
pulse-client.conf.5.xml \
|
pulse-client.conf.5.xml \
|
||||||
default.pa.5.xml
|
default.pa.5.xml
|
||||||
|
|
||||||
if BUILD_MANPAGES
|
|
||||||
|
|
||||||
CLEANFILES += \
|
|
||||||
$(dist_man_MANS)
|
|
||||||
|
|
||||||
%.xml: %.xml.in Makefile
|
%.xml: %.xml.in Makefile
|
||||||
sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
|
sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
|
||||||
-e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
|
-e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
|
||||||
-e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
|
-e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
|
||||||
|
|
||||||
%: %.xml Makefile
|
|
||||||
perl $(srcdir)/xmltoman $< > $@ || rm -f $@
|
|
||||||
|
|
||||||
xmllint: $(noinst_DATA)
|
xmllint: $(noinst_DATA)
|
||||||
for f in $(noinst_DATA) ; do \
|
for f in $(noinst_DATA) ; do \
|
||||||
xmllint --noout --valid "$$f" || exit 1 ; \
|
xmllint --noout --valid "$$f" || exit 1 ; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if BUILD_MANPAGES
|
||||||
|
|
||||||
|
dist_man_MANS = \
|
||||||
|
pulseaudio.1 \
|
||||||
|
esdcompat.1 \
|
||||||
|
pax11publish.1 \
|
||||||
|
paplay.1 \
|
||||||
|
pacat.1 \
|
||||||
|
pacmd.1 \
|
||||||
|
pactl.1 \
|
||||||
|
pasuspender.1 \
|
||||||
|
padsp.1 \
|
||||||
|
pabrowse.1 \
|
||||||
|
pulse-daemon.conf.5 \
|
||||||
|
pulse-client.conf.5 \
|
||||||
|
default.pa.5
|
||||||
|
|
||||||
|
CLEANFILES += \
|
||||||
|
$(dist_man_MANS)
|
||||||
|
|
||||||
|
%: %.xml Makefile
|
||||||
|
perl $(srcdir)/xmltoman $< > $@ || rm -f $@
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
|
|
||||||
|
|
@ -648,7 +648,6 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (conf->daemonize) {
|
if (conf->daemonize) {
|
||||||
pid_t child;
|
pid_t child;
|
||||||
int tty_fd;
|
|
||||||
|
|
||||||
if (pa_stdio_acquire() < 0) {
|
if (pa_stdio_acquire() < 0) {
|
||||||
pa_log(_("Failed to acquire stdio."));
|
pa_log(_("Failed to acquire stdio."));
|
||||||
|
|
@ -781,6 +780,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
|
pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
|
||||||
|
|
||||||
|
pa_log_debug(_("Running in VM: %s"), pa_yes_no(pa_running_in_vm()));
|
||||||
|
|
||||||
#ifdef __OPTIMIZE__
|
#ifdef __OPTIMIZE__
|
||||||
pa_log_debug(_("Optimized build: yes"));
|
pa_log_debug(_("Optimized build: yes"));
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ pa_cvolume_get_balance;
|
||||||
pa_cvolume_get_fade;
|
pa_cvolume_get_fade;
|
||||||
pa_cvolume_get_position;
|
pa_cvolume_get_position;
|
||||||
pa_cvolume_inc;
|
pa_cvolume_inc;
|
||||||
|
pa_cvolume_inc_clamp;
|
||||||
pa_cvolume_init;
|
pa_cvolume_init;
|
||||||
pa_cvolume_max;
|
pa_cvolume_max;
|
||||||
pa_cvolume_max_mask;
|
pa_cvolume_max_mask;
|
||||||
|
|
|
||||||
|
|
@ -1712,7 +1712,9 @@ static int option_verify(pa_alsa_option *o) {
|
||||||
{ "input-boost-on", N_("Boost") },
|
{ "input-boost-on", N_("Boost") },
|
||||||
{ "input-boost-off", N_("No Boost") },
|
{ "input-boost-off", N_("No Boost") },
|
||||||
{ "output-amplifier-on", N_("Amplifier") },
|
{ "output-amplifier-on", N_("Amplifier") },
|
||||||
{ "output-amplifier-off", N_("No Amplifier") }
|
{ "output-amplifier-off", N_("No Amplifier") },
|
||||||
|
{ "output-speaker", N_("Speaker") },
|
||||||
|
{ "output-headphones", N_("Headphones") }
|
||||||
};
|
};
|
||||||
|
|
||||||
pa_assert(o);
|
pa_assert(o);
|
||||||
|
|
@ -1770,15 +1772,17 @@ static int element_verify(pa_alsa_element *e) {
|
||||||
|
|
||||||
static int path_verify(pa_alsa_path *p) {
|
static int path_verify(pa_alsa_path *p) {
|
||||||
static const struct description_map well_known_descriptions[] = {
|
static const struct description_map well_known_descriptions[] = {
|
||||||
{ "analog-input", N_("Analog Input") },
|
{ "analog-input", N_("Analog Input") },
|
||||||
{ "analog-input-microphone", N_("Analog Microphone") },
|
{ "analog-input-microphone", N_("Analog Microphone") },
|
||||||
{ "analog-input-linein", N_("Analog Line-In") },
|
{ "analog-input-linein", N_("Analog Line-In") },
|
||||||
{ "analog-input-radio", N_("Analog Radio") },
|
{ "analog-input-radio", N_("Analog Radio") },
|
||||||
{ "analog-input-video", N_("Analog Video") },
|
{ "analog-input-video", N_("Analog Video") },
|
||||||
{ "analog-output", N_("Analog Output") },
|
{ "analog-output", N_("Analog Output") },
|
||||||
{ "analog-output-headphones", N_("Analog Headphones") },
|
{ "analog-output-headphones", N_("Analog Headphones") },
|
||||||
{ "analog-output-lfe-on-mono", N_("Analog Output (LFE)") },
|
{ "analog-output-lfe-on-mono", N_("Analog Output (LFE)") },
|
||||||
{ "analog-output-mono", N_("Analog Mono Output") }
|
{ "analog-output-mono", N_("Analog Mono Output") },
|
||||||
|
{ "analog-output-headphones-2", N_("Analog Headphones 2") },
|
||||||
|
{ "analog-output-speaker", N_("Analog Speaker") }
|
||||||
};
|
};
|
||||||
|
|
||||||
pa_alsa_element *e;
|
pa_alsa_element *e;
|
||||||
|
|
|
||||||
|
|
@ -1698,10 +1698,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_tsched && !pa_rtclock_hrtimer()) {
|
use_tsched = pa_alsa_may_tsched(use_tsched);
|
||||||
pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
|
|
||||||
use_tsched = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
u = pa_xnew0(struct userdata, 1);
|
u = pa_xnew0(struct userdata, 1);
|
||||||
u->core = m->core;
|
u->core = m->core;
|
||||||
|
|
|
||||||
|
|
@ -1541,10 +1541,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_tsched && !pa_rtclock_hrtimer()) {
|
use_tsched = pa_alsa_may_tsched(use_tsched);
|
||||||
pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
|
|
||||||
use_tsched = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
u = pa_xnew0(struct userdata, 1);
|
u = pa_xnew0(struct userdata, 1);
|
||||||
u->core = m->core;
|
u->core = m->core;
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include <pulsecore/once.h>
|
#include <pulsecore/once.h>
|
||||||
#include <pulsecore/thread.h>
|
#include <pulsecore/thread.h>
|
||||||
#include <pulsecore/conf-parser.h>
|
#include <pulsecore/conf-parser.h>
|
||||||
|
#include <pulsecore/core-rtclock.h>
|
||||||
|
|
||||||
#include "alsa-util.h"
|
#include "alsa-util.h"
|
||||||
#include "alsa-mixer.h"
|
#include "alsa-mixer.h"
|
||||||
|
|
@ -1308,3 +1309,26 @@ const char* pa_alsa_strerror(int errnum) {
|
||||||
|
|
||||||
return translated;
|
return translated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pa_bool_t pa_alsa_may_tsched(pa_bool_t want) {
|
||||||
|
|
||||||
|
if (!want)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!pa_rtclock_hrtimer()) {
|
||||||
|
/* We cannot depend on being woken up in time when the timers
|
||||||
|
are inaccurate, so let's fallback to classic IO based playback
|
||||||
|
then. */
|
||||||
|
pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
|
||||||
|
return FALSE; }
|
||||||
|
|
||||||
|
if (pa_running_in_vm()) {
|
||||||
|
/* We cannot depend on being woken up when we ask for in a VM,
|
||||||
|
* so let's fallback to classic IO based playback then. */
|
||||||
|
pa_log_notice("Disabling timer-based scheduling because running inside a VM.");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,4 +142,6 @@ pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm);
|
||||||
|
|
||||||
const char* pa_alsa_strerror(int errnum);
|
const char* pa_alsa_strerror(int errnum);
|
||||||
|
|
||||||
|
pa_bool_t pa_alsa_may_tsched(pa_bool_t want);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -109,3 +109,20 @@ priority = 10
|
||||||
[Option External Amplifier:off]
|
[Option External Amplifier:off]
|
||||||
name = output-amplifier-off
|
name = output-amplifier-off
|
||||||
priority = 0
|
priority = 0
|
||||||
|
|
||||||
|
;;; 'Analog Output'
|
||||||
|
|
||||||
|
[Element Analog Output]
|
||||||
|
enumeration = select
|
||||||
|
|
||||||
|
[Option Analog Output:Speakers]
|
||||||
|
name = output-speaker
|
||||||
|
priority = 10
|
||||||
|
|
||||||
|
[Option Analog Output:Headphones]
|
||||||
|
name = output-headphones
|
||||||
|
priority = 9
|
||||||
|
|
||||||
|
[Option Analog Output:FP Headphones]
|
||||||
|
name = output-headphones
|
||||||
|
priority = 8
|
||||||
|
|
|
||||||
|
|
@ -334,7 +334,7 @@ int pa__init(pa_module*m) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ports = jack_get_ports(u->client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
|
ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput);
|
||||||
|
|
||||||
channels = 0;
|
channels = 0;
|
||||||
for (p = ports; *p; p++)
|
for (p = ports; *p; p++)
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ int pa__init(pa_module*m) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ports = jack_get_ports(u->client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
|
ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsOutput);
|
||||||
|
|
||||||
channels = 0;
|
channels = 0;
|
||||||
for (p = ports; *p; p++)
|
for (p = ports; *p; p++)
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,14 @@ PA_MODULE_AUTHOR("Lennart Poettering");
|
||||||
PA_MODULE_DESCRIPTION("LIRC volume control");
|
PA_MODULE_DESCRIPTION("LIRC volume control");
|
||||||
PA_MODULE_VERSION(PACKAGE_VERSION);
|
PA_MODULE_VERSION(PACKAGE_VERSION);
|
||||||
PA_MODULE_LOAD_ONCE(TRUE);
|
PA_MODULE_LOAD_ONCE(TRUE);
|
||||||
PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name>");
|
PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name> volume_limit=<volume limit> volume_step=<volume change step>");
|
||||||
|
|
||||||
static const char* const valid_modargs[] = {
|
static const char* const valid_modargs[] = {
|
||||||
"config",
|
"config",
|
||||||
"sink",
|
"sink",
|
||||||
"appname",
|
"appname",
|
||||||
|
"volume_limit",
|
||||||
|
"volume_step",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -61,10 +63,10 @@ struct userdata {
|
||||||
char *sink_name;
|
char *sink_name;
|
||||||
pa_module *module;
|
pa_module *module;
|
||||||
float mute_toggle_save;
|
float mute_toggle_save;
|
||||||
|
pa_volume_t volume_limit;
|
||||||
|
pa_volume_t volume_step;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DELTA (PA_VOLUME_NORM/20)
|
|
||||||
|
|
||||||
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
|
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
|
||||||
struct userdata *u = userdata;
|
struct userdata *u = userdata;
|
||||||
char *name = NULL, *code = NULL;
|
char *name = NULL, *code = NULL;
|
||||||
|
|
@ -125,12 +127,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event
|
||||||
|
|
||||||
switch (volchange) {
|
switch (volchange) {
|
||||||
case UP:
|
case UP:
|
||||||
pa_cvolume_inc(&cv, DELTA);
|
pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);
|
||||||
pa_sink_set_volume(s, &cv, TRUE, TRUE);
|
pa_sink_set_volume(s, &cv, TRUE, TRUE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DOWN:
|
case DOWN:
|
||||||
pa_cvolume_dec(&cv, DELTA);
|
pa_cvolume_dec(&cv, u->volume_step);
|
||||||
pa_sink_set_volume(s, &cv, TRUE, TRUE);
|
pa_sink_set_volume(s, &cv, TRUE, TRUE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -170,6 +172,8 @@ fail:
|
||||||
int pa__init(pa_module*m) {
|
int pa__init(pa_module*m) {
|
||||||
pa_modargs *ma = NULL;
|
pa_modargs *ma = NULL;
|
||||||
struct userdata *u;
|
struct userdata *u;
|
||||||
|
pa_volume_t volume_limit = PA_VOLUME_NORM*3/2;
|
||||||
|
pa_volume_t volume_step = PA_VOLUME_NORM/20;
|
||||||
|
|
||||||
pa_assert(m);
|
pa_assert(m);
|
||||||
|
|
||||||
|
|
@ -178,6 +182,16 @@ int pa__init(pa_module*m) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) {
|
||||||
|
pa_log("Failed to parse volume limit");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) {
|
||||||
|
pa_log("Failed to parse volume step");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
m->userdata = u = pa_xnew(struct userdata, 1);
|
m->userdata = u = pa_xnew(struct userdata, 1);
|
||||||
u->module = m;
|
u->module = m;
|
||||||
u->io = NULL;
|
u->io = NULL;
|
||||||
|
|
@ -185,6 +199,8 @@ int pa__init(pa_module*m) {
|
||||||
u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
|
u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
|
||||||
u->lirc_fd = -1;
|
u->lirc_fd = -1;
|
||||||
u->mute_toggle_save = 0;
|
u->mute_toggle_save = 0;
|
||||||
|
u->volume_limit = volume_limit;
|
||||||
|
u->volume_step = volume_step;
|
||||||
|
|
||||||
if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) {
|
if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) {
|
||||||
pa_log("lirc_init() failed.");
|
pa_log("lirc_init() failed.");
|
||||||
|
|
|
||||||
|
|
@ -48,13 +48,15 @@ PA_MODULE_AUTHOR("Lennart Poettering");
|
||||||
PA_MODULE_DESCRIPTION("Multimedia keyboard support via Linux evdev");
|
PA_MODULE_DESCRIPTION("Multimedia keyboard support via Linux evdev");
|
||||||
PA_MODULE_VERSION(PACKAGE_VERSION);
|
PA_MODULE_VERSION(PACKAGE_VERSION);
|
||||||
PA_MODULE_LOAD_ONCE(FALSE);
|
PA_MODULE_LOAD_ONCE(FALSE);
|
||||||
PA_MODULE_USAGE("device=<evdev device> sink=<sink name>");
|
PA_MODULE_USAGE("device=<evdev device> sink=<sink name> volume_limit=<volume limit> volume_step=<volume change step>");
|
||||||
|
|
||||||
#define DEFAULT_DEVICE "/dev/input/event0"
|
#define DEFAULT_DEVICE "/dev/input/event0"
|
||||||
|
|
||||||
static const char* const valid_modargs[] = {
|
static const char* const valid_modargs[] = {
|
||||||
"device",
|
"device",
|
||||||
"sink",
|
"sink",
|
||||||
|
"volume_limit",
|
||||||
|
"volume_step",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -63,10 +65,10 @@ struct userdata {
|
||||||
pa_io_event *io;
|
pa_io_event *io;
|
||||||
char *sink_name;
|
char *sink_name;
|
||||||
pa_module *module;
|
pa_module *module;
|
||||||
|
pa_volume_t volume_limit;
|
||||||
|
pa_volume_t volume_step;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DELTA (PA_VOLUME_NORM/20)
|
|
||||||
|
|
||||||
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
|
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
|
||||||
struct userdata *u = userdata;
|
struct userdata *u = userdata;
|
||||||
|
|
||||||
|
|
@ -120,12 +122,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event
|
||||||
|
|
||||||
switch (volchange) {
|
switch (volchange) {
|
||||||
case UP:
|
case UP:
|
||||||
pa_cvolume_inc(&cv, DELTA);
|
pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);
|
||||||
pa_sink_set_volume(s, &cv, TRUE, TRUE);
|
pa_sink_set_volume(s, &cv, TRUE, TRUE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DOWN:
|
case DOWN:
|
||||||
pa_cvolume_dec(&cv, DELTA);
|
pa_cvolume_dec(&cv, u->volume_step);
|
||||||
pa_sink_set_volume(s, &cv, TRUE, TRUE);
|
pa_sink_set_volume(s, &cv, TRUE, TRUE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -160,6 +162,8 @@ int pa__init(pa_module*m) {
|
||||||
struct input_id input_id;
|
struct input_id input_id;
|
||||||
char name[256];
|
char name[256];
|
||||||
uint8_t evtype_bitmask[EV_MAX/8 + 1];
|
uint8_t evtype_bitmask[EV_MAX/8 + 1];
|
||||||
|
pa_volume_t volume_limit = PA_VOLUME_NORM*3/2;
|
||||||
|
pa_volume_t volume_step = PA_VOLUME_NORM/20;
|
||||||
|
|
||||||
pa_assert(m);
|
pa_assert(m);
|
||||||
|
|
||||||
|
|
@ -168,12 +172,24 @@ int pa__init(pa_module*m) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) {
|
||||||
|
pa_log("Failed to parse volume limit");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) {
|
||||||
|
pa_log("Failed to parse volume step");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
m->userdata = u = pa_xnew(struct userdata, 1);
|
m->userdata = u = pa_xnew(struct userdata, 1);
|
||||||
u->module = m;
|
u->module = m;
|
||||||
u->io = NULL;
|
u->io = NULL;
|
||||||
u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
|
u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
|
||||||
u->fd = -1;
|
u->fd = -1;
|
||||||
u->fd_type = 0;
|
u->fd_type = 0;
|
||||||
|
u->volume_limit = volume_limit;
|
||||||
|
u->volume_step = volume_step;
|
||||||
|
|
||||||
if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) {
|
if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) {
|
||||||
pa_log("Failed to open evdev device: %s", pa_cstrerror(errno));
|
pa_log("Failed to open evdev device: %s", pa_cstrerror(errno));
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ typedef struct pa_ext_device_manager_role_priority_info {
|
||||||
} pa_ext_device_manager_role_priority_info;
|
} pa_ext_device_manager_role_priority_info;
|
||||||
|
|
||||||
/** Stores information about one device in the device database that is
|
/** Stores information about one device in the device database that is
|
||||||
* maintained by module-device-manager. \since 0.9.19 */
|
* maintained by module-device-manager. \since 0.9.20 */
|
||||||
typedef struct pa_ext_device_manager_info {
|
typedef struct pa_ext_device_manager_info {
|
||||||
const char *name; /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */
|
const char *name; /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */
|
||||||
const char *description; /**< The description of the device when it was last seen, if applicable and saved */
|
const char *description; /**< The description of the device when it was last seen, if applicable and saved */
|
||||||
|
|
@ -49,32 +49,32 @@ typedef struct pa_ext_device_manager_info {
|
||||||
pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */
|
pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */
|
||||||
} pa_ext_device_manager_info;
|
} pa_ext_device_manager_info;
|
||||||
|
|
||||||
/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.19 */
|
/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.20 */
|
||||||
typedef void (*pa_ext_device_manager_test_cb_t)(
|
typedef void (*pa_ext_device_manager_test_cb_t)(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
uint32_t version,
|
uint32_t version,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Test if this extension module is available in the server. \since 0.9.19 */
|
/** Test if this extension module is available in the server. \since 0.9.20 */
|
||||||
pa_operation *pa_ext_device_manager_test(
|
pa_operation *pa_ext_device_manager_test(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
pa_ext_device_manager_test_cb_t cb,
|
pa_ext_device_manager_test_cb_t cb,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.19 */
|
/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.20 */
|
||||||
typedef void (*pa_ext_device_manager_read_cb_t)(
|
typedef void (*pa_ext_device_manager_read_cb_t)(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
const pa_ext_device_manager_info *info,
|
const pa_ext_device_manager_info *info,
|
||||||
int eol,
|
int eol,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Read all entries from the device database. \since 0.9.19 */
|
/** Read all entries from the device database. \since 0.9.20 */
|
||||||
pa_operation *pa_ext_device_manager_read(
|
pa_operation *pa_ext_device_manager_read(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
pa_ext_device_manager_read_cb_t cb,
|
pa_ext_device_manager_read_cb_t cb,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Sets the description for a device. \since 0.9.19 */
|
/** Sets the description for a device. \since 0.9.20 */
|
||||||
pa_operation *pa_ext_device_manager_set_device_description(
|
pa_operation *pa_ext_device_manager_set_device_description(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
const char* device,
|
const char* device,
|
||||||
|
|
@ -82,21 +82,21 @@ pa_operation *pa_ext_device_manager_set_device_description(
|
||||||
pa_context_success_cb_t cb,
|
pa_context_success_cb_t cb,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Delete entries from the device database. \since 0.9.19 */
|
/** Delete entries from the device database. \since 0.9.20 */
|
||||||
pa_operation *pa_ext_device_manager_delete(
|
pa_operation *pa_ext_device_manager_delete(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
const char *const s[],
|
const char *const s[],
|
||||||
pa_context_success_cb_t cb,
|
pa_context_success_cb_t cb,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Enable the role-based device-priority routing mode. \since 0.9.19 */
|
/** Enable the role-based device-priority routing mode. \since 0.9.20 */
|
||||||
pa_operation *pa_ext_device_manager_enable_role_device_priority_routing(
|
pa_operation *pa_ext_device_manager_enable_role_device_priority_routing(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
int enable,
|
int enable,
|
||||||
pa_context_success_cb_t cb,
|
pa_context_success_cb_t cb,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Prefer a given device in the priority list. \since 0.9.19 */
|
/** Prefer a given device in the priority list. \since 0.9.20 */
|
||||||
pa_operation *pa_ext_device_manager_reorder_devices_for_role(
|
pa_operation *pa_ext_device_manager_reorder_devices_for_role(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
const char* role,
|
const char* role,
|
||||||
|
|
@ -104,20 +104,20 @@ pa_operation *pa_ext_device_manager_reorder_devices_for_role(
|
||||||
pa_context_success_cb_t cb,
|
pa_context_success_cb_t cb,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Subscribe to changes in the device database. \since 0.9.19 */
|
/** Subscribe to changes in the device database. \since 0.9.20 */
|
||||||
pa_operation *pa_ext_device_manager_subscribe(
|
pa_operation *pa_ext_device_manager_subscribe(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
int enable,
|
int enable,
|
||||||
pa_context_success_cb_t cb,
|
pa_context_success_cb_t cb,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.19 */
|
/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.20 */
|
||||||
typedef void (*pa_ext_device_manager_subscribe_cb_t)(
|
typedef void (*pa_ext_device_manager_subscribe_cb_t)(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
/** Set the subscription callback that is called when
|
/** Set the subscription callback that is called when
|
||||||
* pa_ext_device_manager_subscribe() was called. \since 0.9.19 */
|
* pa_ext_device_manager_subscribe() was called. \since 0.9.20 */
|
||||||
void pa_ext_device_manager_set_subscribe_cb(
|
void pa_ext_device_manager_set_subscribe_cb(
|
||||||
pa_context *c,
|
pa_context *c,
|
||||||
pa_ext_device_manager_subscribe_cb_t cb,
|
pa_ext_device_manager_subscribe_cb_t cb,
|
||||||
|
|
|
||||||
|
|
@ -885,7 +885,7 @@ pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvo
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) {
|
pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit) {
|
||||||
pa_volume_t m;
|
pa_volume_t m;
|
||||||
|
|
||||||
pa_assert(v);
|
pa_assert(v);
|
||||||
|
|
@ -895,14 +895,18 @@ pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) {
|
||||||
|
|
||||||
m = pa_cvolume_max(v);
|
m = pa_cvolume_max(v);
|
||||||
|
|
||||||
if (m >= PA_VOLUME_MAX - inc)
|
if (m >= limit - inc)
|
||||||
m = PA_VOLUME_MAX;
|
m = limit;
|
||||||
else
|
else
|
||||||
m += inc;
|
m += inc;
|
||||||
|
|
||||||
return pa_cvolume_scale(v, m);
|
return pa_cvolume_scale(v, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc){
|
||||||
|
return pa_cvolume_inc_clamp(v, inc, PA_VOLUME_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
|
pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
|
||||||
pa_volume_t m;
|
pa_volume_t m;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -348,6 +348,10 @@ pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, p
|
||||||
* and dest may point to the same structure. \since 0.9.16 */
|
* and dest may point to the same structure. \since 0.9.16 */
|
||||||
pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
|
pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
|
||||||
|
|
||||||
|
/** Increase the volume passed in by 'inc', but not exceeding 'limit'.
|
||||||
|
* The proportions between the channels are kept. \since 0.9.19 */
|
||||||
|
pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit);
|
||||||
|
|
||||||
/** Increase the volume passed in by 'inc'. The proportions between
|
/** Increase the volume passed in by 'inc'. The proportions between
|
||||||
* the channels are kept. \since 0.9.16 */
|
* the channels are kept. \since 0.9.16 */
|
||||||
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
|
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@
|
||||||
#include <pulsecore/strbuf.h>
|
#include <pulsecore/strbuf.h>
|
||||||
#include <pulsecore/usergroup.h>
|
#include <pulsecore/usergroup.h>
|
||||||
#include <pulsecore/strlist.h>
|
#include <pulsecore/strlist.h>
|
||||||
|
#include <pulsecore/cpu-x86.h>
|
||||||
|
|
||||||
#include "core-util.h"
|
#include "core-util.h"
|
||||||
|
|
||||||
|
|
@ -2944,6 +2945,7 @@ int pa_pipe_cloexec(int pipefd[2]) {
|
||||||
|
|
||||||
if (errno != EINVAL && errno != ENOSYS)
|
if (errno != EINVAL && errno != ENOSYS)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((r = pipe(pipefd)) < 0)
|
if ((r = pipe(pipefd)) < 0)
|
||||||
|
|
@ -2965,6 +2967,7 @@ int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||||
|
|
||||||
if (errno != EINVAL && errno != ENOSYS)
|
if (errno != EINVAL && errno != ENOSYS)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((fd = accept(sockfd, addr, addrlen)) < 0)
|
if ((fd = accept(sockfd, addr, addrlen)) < 0)
|
||||||
|
|
@ -3015,3 +3018,93 @@ void pa_nullify_stdfds(void) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *pa_read_line_from_file(const char *fn) {
|
||||||
|
FILE *f;
|
||||||
|
char ln[256] = "", *r;
|
||||||
|
|
||||||
|
if (!(f = pa_fopen_cloexec(fn, "r")))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
r = fgets(ln, sizeof(ln)-1, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (!r) {
|
||||||
|
errno = EIO;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pa_strip_nl(ln);
|
||||||
|
return pa_xstrdup(ln);
|
||||||
|
}
|
||||||
|
|
||||||
|
pa_bool_t pa_running_in_vm(void) {
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
|
||||||
|
/* Both CPUID and DMI are x86 specific interfaces... */
|
||||||
|
|
||||||
|
uint32_t eax = 0x40000000;
|
||||||
|
union {
|
||||||
|
uint32_t sig32[3];
|
||||||
|
char text[13];
|
||||||
|
} sig;
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
const char *const dmi_vendors[] = {
|
||||||
|
"/sys/class/dmi/id/sys_vendor",
|
||||||
|
"/sys/class/dmi/id/board_vendor",
|
||||||
|
"/sys/class/dmi/id/bios_vendor"
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) {
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if ((s = pa_read_line_from_file(dmi_vendors[i]))) {
|
||||||
|
|
||||||
|
if (pa_startswith(s, "QEMU") ||
|
||||||
|
/* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
|
||||||
|
pa_startswith(s, "VMware") ||
|
||||||
|
pa_startswith(s, "VMW") ||
|
||||||
|
pa_startswith(s, "Microsoft Corporation") ||
|
||||||
|
pa_startswith(s, "innotek GmbH") ||
|
||||||
|
pa_startswith(s, "Xen")) {
|
||||||
|
|
||||||
|
pa_xfree(s);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pa_xfree(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* http://lwn.net/Articles/301888/ */
|
||||||
|
pa_zero(sig);
|
||||||
|
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
/* ebx/rbx is being used for PIC! */
|
||||||
|
" push %%"PA_REG_b" \n\t"
|
||||||
|
" cpuid \n\t"
|
||||||
|
" mov %%ebx, %1 \n\t"
|
||||||
|
" pop %%"PA_REG_b" \n\t"
|
||||||
|
|
||||||
|
: "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2])
|
||||||
|
: "0" (eax)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pa_streq(sig.text, "XenVMMXenVMM") ||
|
||||||
|
pa_streq(sig.text, "KVMKVMKVM") ||
|
||||||
|
/* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
|
||||||
|
pa_streq(sig.text, "VMwareVMware") ||
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
|
||||||
|
pa_streq(sig.text, "Microsoft Hv"))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -267,4 +267,7 @@ FILE* pa_fopen_cloexec(const char *path, const char *mode);
|
||||||
|
|
||||||
void pa_nullify_stdfds(void);
|
void pa_nullify_stdfds(void);
|
||||||
|
|
||||||
|
char *pa_read_line_from_file(const char *fn);
|
||||||
|
pa_bool_t pa_running_in_vm(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2631,7 +2631,7 @@ static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint3
|
||||||
pa_tagstruct_put_usec(reply, s->current_monitor_latency);
|
pa_tagstruct_put_usec(reply, s->current_monitor_latency);
|
||||||
pa_tagstruct_put_usec(reply,
|
pa_tagstruct_put_usec(reply,
|
||||||
s->current_source_latency +
|
s->current_source_latency +
|
||||||
pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->sample_spec));
|
pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->source->sample_spec));
|
||||||
pa_tagstruct_put_boolean(reply,
|
pa_tagstruct_put_boolean(reply,
|
||||||
pa_source_get_state(s->source_output->source) == PA_SOURCE_RUNNING &&
|
pa_source_get_state(s->source_output->source) == PA_SOURCE_RUNNING &&
|
||||||
pa_source_output_get_state(s->source_output) == PA_SOURCE_OUTPUT_RUNNING);
|
pa_source_output_get_state(s->source_output) == PA_SOURCE_OUTPUT_RUNNING);
|
||||||
|
|
|
||||||
|
|
@ -717,14 +717,15 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
|
||||||
pa_memchunk rchunk;
|
pa_memchunk rchunk;
|
||||||
pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
|
pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
|
||||||
|
|
||||||
if (nvfs) {
|
|
||||||
pa_memchunk_make_writable(&rchunk, 0);
|
|
||||||
pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
|
/* pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
|
||||||
|
|
||||||
if (rchunk.memblock) {
|
if (rchunk.memblock) {
|
||||||
|
|
||||||
|
if (nvfs) {
|
||||||
|
pa_memchunk_make_writable(&rchunk, 0);
|
||||||
|
pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
|
||||||
|
}
|
||||||
|
|
||||||
pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
|
pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
|
||||||
pa_memblock_unref(rchunk.memblock);
|
pa_memblock_unref(rchunk.memblock);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue