summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/pacat.1.xml.in6
-rw-r--r--man/pulse-daemon.conf.5.xml.in16
-rw-r--r--src/Makefile.am9
-rw-r--r--src/daemon/cpulimit.c2
-rw-r--r--src/daemon/daemon-conf.c36
-rw-r--r--src/daemon/daemon-conf.h1
-rw-r--r--src/daemon/daemon.conf.in1
-rw-r--r--src/daemon/main.c12
-rw-r--r--src/map-file2
-rw-r--r--src/modules/module-alsa-sink.c2
-rw-r--r--src/modules/module-alsa-source.c2
-rw-r--r--src/pulse/channelmap.c22
-rw-r--r--src/pulse/channelmap.h9
-rw-r--r--src/pulse/context.c318
-rw-r--r--src/pulse/internal.h3
-rw-r--r--src/pulsecore/core-util.c8
-rw-r--r--src/pulsecore/core-util.h1
-rw-r--r--src/pulsecore/core.c2
-rw-r--r--src/pulsecore/core.h1
-rw-r--r--src/pulsecore/lock-autospawn.c (renamed from src/pulse/lock-autospawn.c)0
-rw-r--r--src/pulsecore/lock-autospawn.h (renamed from src/pulse/lock-autospawn.h)0
-rw-r--r--src/pulsecore/resampler.c8
-rw-r--r--src/pulsecore/resampler.h7
-rw-r--r--src/pulsecore/sink-input.c3
-rw-r--r--src/pulsecore/source-output.c3
-rw-r--r--src/tests/lock-autospawn-test.c2
-rw-r--r--src/utils/pacat.c9
27 files changed, 223 insertions, 262 deletions
diff --git a/man/pacat.1.xml.in b/man/pacat.1.xml.in
index 7b0d72b9..68a3a12a 100644
--- a/man/pacat.1.xml.in
+++ b/man/pacat.1.xml.in
@@ -108,9 +108,11 @@ USA.
<optdesc><p>Capture or play back audio with the specified sample
format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
- <opt>s16be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
+ <opt>s16be</opt>, <opt>s32le</opt>,
+ <opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
<opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
- the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
+ the CPU the
+ formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
<opt>float32ne</opt>, <opt>float32re</opt> (for native,
resp. reverse endian) are available as aliases. Defaults to
s16ne.</p></optdesc>
diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index 50e24559..ed158dfa 100644
--- a/man/pulse-daemon.conf.5.xml.in
+++ b/man/pulse-daemon.conf.5.xml.in
@@ -106,6 +106,16 @@ USA.
</option>
<option>
+ <p><opt>disable-lfe-remixing=</opt> When upmixing or downmixing
+ ignore LFE channels. When this option is on the output LFE
+ channel will only get a signal when an input LFE channel is
+ available as well. If no input LFE channel is available the
+ output LFE channel will always be 0. If no output LFE channel is
+ available the signal on the input LFE channel will be
+ ignored.</p>
+ </option>
+
+ <option>
<p><opt>use-pid-file=</opt> Create a PID file in
<file>/tmp/pulse-$USER/pid</file>. Of this is enabled you may
use commands like <opt>--kill</opt> or <opt>--check</opt>. If
@@ -319,9 +329,11 @@ USA.
<option>
<p><opt>default-sample-format=</opt> The default sampling
format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
- <opt>s16be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
+ <opt>s16be</opt>, <opt>s32le</opt>,
+ <opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
<opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
- the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
+ the CPU the
+ formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
<opt>float32ne</opt>, <opt>float32re</opt> (for native,
resp. reverse endian) are available as aliases.</p>
</option>
diff --git a/src/Makefile.am b/src/Makefile.am
index a20c7c45..1663d66d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -541,8 +541,7 @@ libpulse_la_SOURCES = \
pulse/xmalloc.c pulse/xmalloc.h \
pulse/proplist.c pulse/proplist.h \
pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
- pulse/i18n.c pulse/i18n.h \
- pulse/lock-autospawn.c pulse/lock-autospawn.h
+ pulse/i18n.c pulse/i18n.h
# Internal stuff that is shared with libpulsecore
libpulse_la_SOURCES += \
@@ -740,8 +739,7 @@ libpulsecore_la_SOURCES = \
pulse/volume.c pulse/volume.h \
pulse/xmalloc.c pulse/xmalloc.h \
pulse/proplist.c pulse/proplist.h \
- pulse/i18n.c pulse/i18n.h \
- pulse/lock-autospawn.c pulse/lock-autospawn.h
+ pulse/i18n.c pulse/i18n.h
# Pure core stuff (some are shared in libpulse though).
libpulsecore_la_SOURCES += \
@@ -811,6 +809,7 @@ libpulsecore_la_SOURCES += \
pulsecore/start-child.c pulsecore/start-child.h \
pulsecore/envelope.c pulsecore/envelope.h \
pulsecore/proplist-util.c pulsecore/proplist-util.h \
+ pulsecore/lock-autospawn.c pulsecore/lock-autospawn.h \
$(PA_THREAD_OBJS)
if OS_IS_WIN32
@@ -1625,7 +1624,7 @@ update-ffmpeg:
update-map-file:
( echo "PULSE_0 {" ; \
echo "global:" ; \
- ctags -I PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
+ ctags -I PA_GCC_MALLOC,PA_GCC_ALLOC_SIZE2,PA_GCC_ALLOC_SIZE,PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
echo "local:" ; \
echo "*;" ; \
echo "};" ) > $(srcdir)/map-file
diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c
index 59552828..a909600e 100644
--- a/src/daemon/cpulimit.c
+++ b/src/daemon/cpulimit.c
@@ -167,6 +167,8 @@ static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags
pa_assert(e == io_event);
pa_assert(fd == the_pipe[0]);
+ pa_log("Recevied request to terminate due to CPU overload.");
+
pa_read(the_pipe[0], &c, sizeof(c), NULL);
m->quit(m, 1); /* Quit the main loop */
}
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 40e0a170..77da3f7e 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -76,6 +76,7 @@ static const pa_daemon_conf default_conf = {
.log_level = PA_LOG_NOTICE,
.resample_method = PA_RESAMPLER_AUTO,
.disable_remixing = FALSE,
+ .disable_lfe_remixing = TRUE,
.config_file = NULL,
.use_pid_file = TRUE,
.system_instance = FALSE,
@@ -426,6 +427,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
{ "default-fragment-size-msec", parse_fragment_size_msec, NULL },
{ "nice-level", parse_nice_level, NULL },
{ "disable-remixing", pa_config_parse_bool, NULL },
+ { "disable-lfe-remixing", pa_config_parse_bool, NULL },
{ "load-default-script-file", pa_config_parse_bool, NULL },
#ifdef HAVE_SYS_RESOURCE_H
{ "rlimit-fsize", parse_rlimit, NULL },
@@ -490,66 +492,67 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
table[24].data = c;
table[25].data = c;
table[26].data = &c->disable_remixing;
- table[27].data = &c->load_default_script_file;
+ table[27].data = &c->disable_lfe_remixing;
+ table[28].data = &c->load_default_script_file;
#ifdef HAVE_SYS_RESOURCE_H
- table[28].data = &c->rlimit_fsize;
- table[29].data = &c->rlimit_data;
- table[30].data = &c->rlimit_stack;
- table[31].data = &c->rlimit_as;
- table[32].data = &c->rlimit_core;
- table[33].data = &c->rlimit_nofile;
- table[34].data = &c->rlimit_as;
+ table[29].data = &c->rlimit_fsize;
+ table[30].data = &c->rlimit_data;
+ table[31].data = &c->rlimit_stack;
+ table[32].data = &c->rlimit_as;
+ table[33].data = &c->rlimit_core;
+ table[34].data = &c->rlimit_nofile;
+ table[35].data = &c->rlimit_as;
#ifdef RLIMIT_NPROC
- table[35].data = &c->rlimit_nproc;
+ table[36].data = &c->rlimit_nproc;
#endif
#ifdef RLIMIT_MEMLOCK
#ifndef RLIMIT_NPROC
#error "Houston, we have a numbering problem!"
#endif
- table[36].data = &c->rlimit_memlock;
+ table[37].data = &c->rlimit_memlock;
#endif
#ifdef RLIMIT_LOCKS
#ifndef RLIMIT_MEMLOCK
#error "Houston, we have a numbering problem!"
#endif
- table[37].data = &c->rlimit_locks;
+ table[38].data = &c->rlimit_locks;
#endif
#ifdef RLIMIT_SIGPENDING
#ifndef RLIMIT_LOCKS
#error "Houston, we have a numbering problem!"
#endif
- table[38].data = &c->rlimit_sigpending;
+ table[39].data = &c->rlimit_sigpending;
#endif
#ifdef RLIMIT_MSGQUEUE
#ifndef RLIMIT_SIGPENDING
#error "Houston, we have a numbering problem!"
#endif
- table[39].data = &c->rlimit_msgqueue;
+ table[40].data = &c->rlimit_msgqueue;
#endif
#ifdef RLIMIT_NICE
#ifndef RLIMIT_MSGQUEUE
#error "Houston, we have a numbering problem!"
#endif
- table[40].data = &c->rlimit_nice;
+ table[41].data = &c->rlimit_nice;
#endif
#ifdef RLIMIT_RTPRIO
#ifndef RLIMIT_NICE
#error "Houston, we have a numbering problem!"
#endif
- table[41].data = &c->rlimit_rtprio;
+ table[42].data = &c->rlimit_rtprio;
#endif
#ifdef RLIMIT_RTTIME
#ifndef RLIMIT_RTTIME
#error "Houston, we have a numbering problem!"
#endif
- table[42].data = &c->rlimit_rttime;
+ table[43].data = &c->rlimit_rttime;
#endif
#endif
@@ -661,6 +664,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf_printf(s, "log-level = %s\n", log_level_to_string[c->log_level]);
pa_strbuf_printf(s, "resample-method = %s\n", pa_resample_method_to_string(c->resample_method));
pa_strbuf_printf(s, "disable-remixing = %s\n", pa_yes_no(c->disable_remixing));
+ pa_strbuf_printf(s, "disable-lfe-remixing = %s\n", pa_yes_no(c->disable_lfe_remixing));
pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
index c42984f9..309a1428 100644
--- a/src/daemon/daemon-conf.h
+++ b/src/daemon/daemon-conf.h
@@ -66,6 +66,7 @@ typedef struct pa_daemon_conf {
no_cpu_limit,
disable_shm,
disable_remixing,
+ disable_lfe_remixing,
load_default_script_file,
disallow_exit;
int exit_idle_time,
diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
index 33b1d61d..ea09fe09 100644
--- a/src/daemon/daemon.conf.in
+++ b/src/daemon/daemon.conf.in
@@ -47,6 +47,7 @@
; resample-method = speex-float-3
; disable-remixing = no
+; disable-lfe-remixing = yes
; no-cpu-limit = no
diff --git a/src/daemon/main.c b/src/daemon/main.c
index c8eda398..a9e8ed46 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -65,8 +65,8 @@
#include <pulse/timeval.h>
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
-#include <pulse/lock-autospawn.h>
+#include <pulsecore/lock-autospawn.h>
#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
#include <pulsecore/core.h>
@@ -778,8 +778,15 @@ int main(int argc, char *argv[]) {
pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
+ pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
+ s = pa_uname_string();
+ pa_log_debug(_("Running on host: %s"), s);
+ pa_xfree(s);
+
+ pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
+
#ifdef HAVE_VALGRIND_MEMCHECK_H
pa_log_debug(_("Compiled with Valgrind support: yes"));
#else
@@ -792,8 +799,6 @@ int main(int argc, char *argv[]) {
pa_log_debug(_("Optimized build: no"));
#endif
- pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
-
if (!(s = pa_machine_id())) {
pa_log(_("Failed to get machine ID"));
goto finish;
@@ -864,6 +869,7 @@ int main(int argc, char *argv[]) {
c->realtime_priority = conf->realtime_priority;
c->realtime_scheduling = !!conf->realtime_scheduling;
c->disable_remixing = !!conf->disable_remixing;
+ c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
c->running_as_daemon = !!conf->daemonize;
c->disallow_exit = conf->disallow_exit;
diff --git a/src/map-file b/src/map-file
index b6d3b63d..67a5ee36 100644
--- a/src/map-file
+++ b/src/map-file
@@ -9,6 +9,7 @@ pa_browser_unref;
pa_bytes_per_second;
pa_bytes_snprint;
pa_bytes_to_usec;
+pa_channel_map_compatible;
pa_channel_map_equal;
pa_channel_map_init;
pa_channel_map_init_auto;
@@ -98,6 +99,7 @@ pa_context_unref;
pa_cvolume_avg;
pa_cvolume_channels_equal_to;
pa_cvolume_equal;
+pa_cvolume_max;
pa_cvolume_remap;
pa_cvolume_set;
pa_cvolume_snprint;
diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c
index e3f9a5ff..6f0d7830 100644
--- a/src/modules/module-alsa-sink.c
+++ b/src/modules/module-alsa-sink.c
@@ -1241,7 +1241,7 @@ int pa__init(pa_module*m) {
}
if (use_tsched && !pa_rtclock_hrtimer()) {
- pa_log("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
+ pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
use_tsched = FALSE;
}
diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c
index 54ffde57..fca05006 100644
--- a/src/modules/module-alsa-source.c
+++ b/src/modules/module-alsa-source.c
@@ -1073,7 +1073,7 @@ int pa__init(pa_module*m) {
}
if (use_tsched && !pa_rtclock_hrtimer()) {
- pa_log("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
+ pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
use_tsched = FALSE;
}
diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 1766e729..37308751 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -198,6 +198,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
pa_assert(m);
pa_assert(channels > 0);
pa_assert(channels <= PA_CHANNELS_MAX);
+ pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
pa_channel_map_init(m);
@@ -287,9 +288,6 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
case PA_CHANNEL_MAP_AUX: {
unsigned i;
- if (channels >= PA_CHANNELS_MAX)
- return NULL;
-
for (i = 0; i < channels; i++)
m->map[i] = PA_CHANNEL_POSITION_AUX0 + i;
@@ -391,7 +389,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
default:
- return NULL;
+ pa_assert_not_reached();
}
}
@@ -401,6 +399,7 @@ pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels,
pa_assert(m);
pa_assert(channels > 0);
pa_assert(channels <= PA_CHANNELS_MAX);
+ pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
pa_channel_map_init(m);
@@ -489,7 +488,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
pa_assert(rmap);
pa_assert(s);
- memset(&map, 0, sizeof(map));
+ pa_channel_map_init(&map);
if (strcmp(s, "stereo") == 0) {
map.channels = 2;
@@ -552,11 +551,16 @@ int pa_channel_map_valid(const pa_channel_map *map) {
if (map->channels <= 0 || map->channels > PA_CHANNELS_MAX)
return 0;
- for (c = 0; c < map->channels; c++) {
-
- if (map->map[c] < 0 ||map->map[c] >= PA_CHANNEL_POSITION_MAX)
+ for (c = 0; c < map->channels; c++)
+ if (map->map[c] < 0 || map->map[c] >= PA_CHANNEL_POSITION_MAX)
return 0;
- }
return 1;
}
+
+int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) {
+ pa_assert(map);
+ pa_assert(ss);
+
+ return map->channels == ss->channels;
+}
diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h
index f9086d19..d2dd6f8f 100644
--- a/src/pulse/channelmap.h
+++ b/src/pulse/channelmap.h
@@ -157,6 +157,9 @@ typedef enum pa_channel_map_def {
PA_CHANNEL_MAP_OSS,
/**< The default channel mapping used by OSS as defined in the OSS 4.0 API specs */
+ /**< Upper limit of valid channel mapping definitions */
+ PA_CHANNEL_MAP_DEF_MAX,
+
PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF
/**< The default channel map */
} pa_channel_map_def_t;
@@ -211,9 +214,13 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s);
/** Compare two channel maps. Return 1 if both match. */
int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE;
-/** Return non-zero of the specified channel map is considered valid */
+/** Return non-zero if the specified channel map is considered valid */
int pa_channel_map_valid(const pa_channel_map *map) PA_GCC_PURE;
+/** Return non-zero if the specified channel map is compatible with
+ * the specified sample spec. \since 0.9.12 */
+int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) PA_GCC_PURE;
+
PA_C_DECL_END
#endif
diff --git a/src/pulse/context.c b/src/pulse/context.c
index f1aa4987..154e5faf 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -54,7 +54,6 @@
#include <pulse/utf8.h>
#include <pulse/util.h>
#include <pulse/i18n.h>
-#include <pulse/lock-autospawn.h>
#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
@@ -98,26 +97,6 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
[PA_COMMAND_EXTENSION] = pa_command_extension
};
-
-static void unlock_autospawn(pa_context *c) {
- pa_assert(c);
-
- if (c->autospawn_fd >= 0) {
-
- if (c->autospawn_locked)
- pa_autospawn_lock_release();
-
- if (c->autospawn_event)
- c->mainloop->io_free(c->autospawn_event);
-
- pa_autospawn_lock_done(FALSE);
- }
-
- c->autospawn_locked = FALSE;
- c->autospawn_fd = -1;
- c->autospawn_event = NULL;
-}
-
static void context_free(pa_context *c);
pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
@@ -180,9 +159,6 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
c->do_shm = FALSE;
c->do_autospawn = FALSE;
- c->autospawn_fd = -1;
- c->autospawn_locked = FALSE;
- c->autospawn_event = NULL;
memset(&c->spawn_api, 0, sizeof(c->spawn_api));
#ifndef MSG_NOSIGNAL
@@ -252,8 +228,6 @@ static void context_free(pa_context *c) {
context_unlink(c);
- unlock_autospawn(c);
-
if (c->record_streams)
pa_dynarray_free(c->record_streams, NULL, NULL);
if (c->playback_streams)
@@ -577,31 +551,89 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
pa_context_unref(c);
}
-static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
+static char *get_old_legacy_runtime_dir(void) {
+ char *p, u[128];
+ struct stat st;
-#ifndef OS_IS_WIN32
+ if (!pa_get_user_name(u, sizeof(u)))
+ return NULL;
-static int context_connect_spawn(pa_context *c) {
- pid_t pid;
- int status, r;
- int fds[2] = { -1, -1} ;
- pa_iochannel *io;
+ p = pa_sprintf_malloc("/tmp/pulse-%s", u);
- if (getuid() == 0)
- return -1;
+ if (stat(p, &st) < 0) {
+ pa_xfree(p);
+ return NULL;
+ }
- pa_context_ref(c);
+ if (st.st_uid != getuid()) {
+ pa_xfree(p);
+ return NULL;
+ }
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
- pa_log_error(_("socketpair(): %s"), pa_cstrerror(errno));
- pa_context_fail(c, PA_ERR_INTERNAL);
- goto fail;
+ return p;
+}
+
+static char *get_very_old_legacy_runtime_dir(void) {
+ char *p, h[128];
+ struct stat st;
+
+ if (!pa_get_home_dir(h, sizeof(h)))
+ return NULL;
+
+ p = pa_sprintf_malloc("%s/.pulse", h);
+
+ if (stat(p, &st) < 0) {
+ pa_xfree(p);
+ return NULL;
+ }
+
+ if (st.st_uid != getuid()) {
+ pa_xfree(p);
+ return NULL;
+ }
+
+ return p;
+}
+
+
+static pa_strlist *prepend_per_user(pa_strlist *l) {
+ char *ufn;
+ static char *legacy_dir;
+
+ /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
+ if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
+ char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
+ l = pa_strlist_prepend(l, p);
+ pa_xfree(p);
+ pa_xfree(legacy_dir);
+ }
+
+ /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
+ if ((legacy_dir = get_old_legacy_runtime_dir())) {
+ char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
+ l = pa_strlist_prepend(l, p);
+ pa_xfree(p);
+ pa_xfree(legacy_dir);
}
- pa_make_fd_cloexec(fds[0]);
+ /* The per-user instance */
+ if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
+ l = pa_strlist_prepend(l, ufn);
+ pa_xfree(ufn);
+ }
+
+ return l;
+}
- pa_make_socket_low_delay(fds[0]);
- pa_make_socket_low_delay(fds[1]);
+#ifndef OS_IS_WIN32
+
+static int context_autospawn(pa_context *c) {
+ pid_t pid;
+ int status, r;
+
+ pa_log_debug("Trying to autospawn...");
+
+ pa_context_ref(c);
if (c->spawn_api.prefork)
c->spawn_api.prefork();
@@ -617,31 +649,22 @@ static int context_connect_spawn(pa_context *c) {
} else if (!pid) {
/* Child */
- char t[128];
const char *state = NULL;
#define MAX_ARGS 64
const char * argv[MAX_ARGS+1];
int n;
- char *f;
-
- pa_close_all(fds[1], -1);
-
- f = pa_sprintf_malloc("%i", fds[1]);
- pa_set_env("PULSE_PASSED_FD", f);
- pa_xfree(f);
if (c->spawn_api.atfork)
c->spawn_api.atfork();
+ pa_close_all(-1);
+
/* Setup argv */
n = 0;
argv[n++] = c->conf->daemon_binary;
- argv[n++] = "--daemonize=yes";
-
- pa_snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]);
- argv[n++] = strdup(t);
+ argv[n++] = "--start";
while (n < MAX_ARGS) {
char *a;
@@ -661,14 +684,13 @@ static int context_connect_spawn(pa_context *c) {
/* Parent */
- pa_assert_se(pa_close(fds[1]) == 0);
- fds[1] = -1;
-
- r = waitpid(pid, &status, 0);
-
if (c->spawn_api.postfork)
c->spawn_api.postfork();
+ do {
+ r = waitpid(pid, &status, 0);
+ } while (r < 0 && errno == EINTR);
+
if (r < 0) {
pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
@@ -678,21 +700,11 @@ static int context_connect_spawn(pa_context *c) {
goto fail;
}
- c->is_local = TRUE;
-
- unlock_autospawn(c);
-
- io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
- setup_context(c, io);
-
pa_context_unref(c);
return 0;
fail:
- pa_close_pipe(fds);
-
- unlock_autospawn(c);
pa_context_unref(c);
@@ -701,6 +713,8 @@ fail:
#endif /* OS_IS_WIN32 */
+static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
+
static int try_next_connection(pa_context *c) {
char *u = NULL;
int r = -1;
@@ -718,8 +732,18 @@ static int try_next_connection(pa_context *c) {
#ifndef OS_IS_WIN32
if (c->do_autospawn) {
- r = context_connect_spawn(c);
- goto finish;
+
+ if ((r = context_autospawn(c)) < 0)
+ goto finish;
+
+ /* Autospawn only once */
+ c->do_autospawn = FALSE;
+
+ /* Connect only to per-user sockets this time */
+ c->server_list = prepend_per_user(c->server_list);
+
+ /* Retry connection */
+ continue;
}
#endif
@@ -774,91 +798,12 @@ static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userd
goto finish;
}
- unlock_autospawn(c);
setup_context(c, io);
finish:
pa_context_unref(c);
}
-static void autospawn_cb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
- pa_context *c = userdata;
- int k;
-
- pa_assert(a);
- pa_assert(e);
- pa_assert(fd >= 0);
- pa_assert(events == PA_IO_EVENT_INPUT);
- pa_assert(c);
- pa_assert(e == c->autospawn_event);
- pa_assert(fd == c->autospawn_fd);
-
- pa_context_ref(c);
-
- /* Check whether we can get the lock right now*/
- if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) {
- pa_context_fail(c, PA_ERR_ACCESS);
- goto finish;
- }
-
- if (k > 0) {
- /* So we got it, rock on! */
- c->autospawn_locked = TRUE;
- try_next_connection(c);
-
- c->mainloop->io_free(c->autospawn_event);
- c->autospawn_event = NULL;
- }
-
-finish:
-
- pa_context_unref(c);
-}
-
-static char *get_old_legacy_runtime_dir(void) {
- char *p, u[128];
- struct stat st;
-
- if (!pa_get_user_name(u, sizeof(u)))
- return NULL;
-
- p = pa_sprintf_malloc("/tmp/pulse-%s", u);
-
- if (stat(p, &st) < 0) {
- pa_xfree(p);
- return NULL;
- }
-
- if (st.st_uid != getuid()) {
- pa_xfree(p);
- return NULL;
- }
-
- return p;
-}
-
-static char *get_very_old_legacy_runtime_dir(void) {
- char *p, h[128];
- struct stat st;
-
- if (!pa_get_home_dir(h, sizeof(h)))
- return NULL;
-
- p = pa_sprintf_malloc("%s/.pulse", h);
-
- if (stat(p, &st) < 0) {
- pa_xfree(p);
- return NULL;
- }
-
- if (st.st_uid != getuid()) {
- pa_xfree(p);
- return NULL;
- }
-
- return p;
-}
-
int pa_context_connect(
pa_context *c,
const char *server,
@@ -888,11 +833,11 @@ int pa_context_connect(
}
} else {
- char *d, *ufn;
- static char *legacy_dir;
+ char *d;
/* Prepend in reverse order */
+ /* Follow the X display */
if ((d = getenv("DISPLAY"))) {
char *e;
d = pa_xstrdup(d);
@@ -905,70 +850,27 @@ int pa_context_connect(
pa_xfree(d);
}
- c->server_list = pa_strlist_prepend(c->server_list, "tcp6:localhost");
- c->server_list = pa_strlist_prepend(c->server_list, "tcp4:localhost");
+ /* Add TCP/IP on the localhost */
+ c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
+ c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
- /* The system wide instance */
+ /* The system wide instance via PF_LOCAL */
c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
- /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
- if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
- char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
- c->server_list = pa_strlist_prepend(c->server_list, p);
- pa_xfree(p);
- pa_xfree(legacy_dir);
- }
+ /* The user instance via PF_LOCAL */
+ c->server_list = prepend_per_user(c->server_list);
- /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
- if ((legacy_dir = get_old_legacy_runtime_dir())) {
- char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
- c->server_list = pa_strlist_prepend(c->server_list, p);
- pa_xfree(p);
- pa_xfree(legacy_dir);
- }
-
- /* The per-user instance */
- if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
- c->server_list = pa_strlist_prepend(c->server_list, ufn);
- pa_xfree(ufn);
- }
-
- /* Wrap the connection attempts in a single transaction for sane autospawn locking */
+ /* Set up autospawning */
if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
- int k;
-
- pa_assert(c->autospawn_fd < 0);
- pa_assert(!c->autospawn_locked);
- /* Start the locking procedure */
- if ((c->autospawn_fd = pa_autospawn_lock_init()) < 0) {
- pa_context_fail(c, PA_ERR_ACCESS);
- goto finish;
- }
-
- if (api)
- c->spawn_api = *api;
-
- c->do_autospawn = TRUE;
-
- /* Check whether we can get the lock right now*/
- if ((k = pa_autospawn_lock_acquire(FALSE)) < 0) {
- pa_context_fail(c, PA_ERR_ACCESS);
- goto finish;
- }
-
- if (k > 0)
- /* So we got it, rock on! */
- c->autospawn_locked = TRUE;
+ if (getuid() == 0)
+ pa_log_debug("Not doing autospawn since we are root.");
else {
- /* Hmm, we didn't get it, so let's wait for it */
- c->autospawn_event = c->mainloop->io_new(c->mainloop, c->autospawn_fd, PA_IO_EVENT_INPUT, autospawn_cb, c);
+ c->do_autospawn = TRUE;
- pa_context_set_state(c, PA_CONTEXT_CONNECTING);
- r = 0;
- goto finish;
+ if (api)
+ c->spawn_api = *api;
}
-
}
}
diff --git a/src/pulse/internal.h b/src/pulse/internal.h
index 9167bf1b..5fe4210e 100644
--- a/src/pulse/internal.h
+++ b/src/pulse/internal.h
@@ -78,9 +78,6 @@ struct pa_context {
pa_bool_t do_shm:1;
pa_bool_t do_autospawn:1;
- pa_bool_t autospawn_locked:1;
- int autospawn_fd;
- pa_io_event *autospawn_event;
pa_spawn_api spawn_api;
pa_strlist *server_list;
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index ad00f4f4..3e5ea492 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -42,6 +42,7 @@
#include <dirent.h>
#include <regex.h>
#include <langinfo.h>
+#include <sys/utsname.h>
#ifdef HAVE_STRTOF_L
#include <locale.h>
@@ -2445,5 +2446,12 @@ char *pa_machine_id(void) {
/* If no hostname was set we use the POSIX hostid. It's usually
* the IPv4 address. Mit not be that stable. */
return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
+}
+
+char *pa_uname_string(void) {
+ struct utsname u;
+
+ pa_assert_se(uname(&u) == 0);
+ return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
}
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index c9e307f5..df8ce3f8 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -191,5 +191,6 @@ pa_bool_t pa_in_system_mode(void);
#define pa_streq(a,b) (!strcmp((a),(b)))
char *pa_machine_id(void);
+char *pa_uname_string(void);
#endif
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index b9f04b68..bd956ae0 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -138,6 +138,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {
c->realtime_scheduling = FALSE;
c->realtime_priority = 5;
c->disable_remixing = FALSE;
+ c->disable_lfe_remixing = FALSE;
for (j = 0; j < PA_CORE_HOOK_MAX; j++)
pa_hook_init(&c->hooks[j], c);
@@ -204,6 +205,7 @@ static void exit_callback(pa_mainloop_api*m, pa_time_event *e, const struct time
pa_core *c = userdata;
pa_assert(c->exit_event == e);
+ pa_log_info("We are idle, quitting...");
pa_core_exit(c, TRUE, 0);
}
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index eb768418..fb4490f2 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -124,6 +124,7 @@ struct pa_core {
pa_bool_t running_as_daemon:1;
pa_bool_t realtime_scheduling:1;
pa_bool_t disable_remixing:1;
+ pa_bool_t disable_lfe_remixing:1;
pa_resample_method_t resample_method;
int realtime_priority;
diff --git a/src/pulse/lock-autospawn.c b/src/pulsecore/lock-autospawn.c
index d36b669e..d36b669e 100644
--- a/src/pulse/lock-autospawn.c
+++ b/src/pulsecore/lock-autospawn.c
diff --git a/src/pulse/lock-autospawn.h b/src/pulsecore/lock-autospawn.h
index c04c4bd1..c04c4bd1 100644
--- a/src/pulse/lock-autospawn.h
+++ b/src/pulsecore/lock-autospawn.h
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index 45cd68c1..0ae029b3 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -716,7 +716,11 @@ static void calc_map_table(pa_resampler *r) {
* channels for LFE. */
for (ic = 0; ic < r->i_ss.channels; ic++) {
- r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;
+
+ if (!(r->flags & PA_RESAMPLER_NO_LFE))
+ r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;
+ else
+ r->map_table[oc][ic] = 0;
/* Please note that a channel connected to LFE
* doesn't really count as connected. */
@@ -851,7 +855,7 @@ static void calc_map_table(pa_resampler *r) {
}
}
- if (ic_unconnected_lfe > 0) {
+ if (ic_unconnected_lfe > 0 && !(r->flags & PA_RESAMPLER_NO_LFE)) {
/* OK, so there is an unconnected LFE channel. Let's mix
* it into all channels, with factor 0.375 */
diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h
index 5e302a9b..87110cc2 100644
--- a/src/pulsecore/resampler.h
+++ b/src/pulsecore/resampler.h
@@ -49,9 +49,10 @@ typedef enum pa_resample_method {
} pa_resample_method_t;
typedef enum pa_resample_flags {
- PA_RESAMPLER_VARIABLE_RATE = 1,
- PA_RESAMPLER_NO_REMAP = 2, /* implies NO_REMIX */
- PA_RESAMPLER_NO_REMIX = 4
+ PA_RESAMPLER_VARIABLE_RATE = 0x0001U,
+ PA_RESAMPLER_NO_REMAP = 0x0002U, /* implies NO_REMIX */
+ PA_RESAMPLER_NO_REMIX = 0x0004U,
+ PA_RESAMPLER_NO_LFE = 0x0008U
} pa_resample_flags_t;
pa_resampler* pa_resampler_new(
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 7d80242f..326a7e2c 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -201,7 +201,8 @@ pa_sink_input* pa_sink_input_new(
data->resample_method,
((flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
((flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
- (core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
+ (core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
+ (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
pa_log_warn("Unsupported resampling operation.");
return NULL;
}
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 5df950a8..d76f6e4e 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -171,7 +171,8 @@ pa_source_output* pa_source_output_new(
data->resample_method,
((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
((flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
- (core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
+ (core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
+ (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
pa_log_warn("Unsupported resampling operation.");
return NULL;
}
diff --git a/src/tests/lock-autospawn-test.c b/src/tests/lock-autospawn-test.c
index cb3dc87c..80cfda6a 100644
--- a/src/tests/lock-autospawn-test.c
+++ b/src/tests/lock-autospawn-test.c
@@ -28,7 +28,7 @@
#include <pulsecore/macro.h>
#include <pulsecore/thread.h>
-#include <pulse/lock-autospawn.h>
+#include <pulsecore/lock-autospawn.h>
#include <pulse/util.h>
static void thread_func(void*k) {
diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index c1826d7b..99df5b9e 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -500,7 +500,7 @@ static void help(const char *argv0) {
" --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n"
" --rate=SAMPLERATE The sample rate in Hz (defaults to 44100)\n"
" --format=SAMPLEFORMAT The sample type, one of s16le, s16be, u8, float32le,\n"
- " float32be, ulaw, alaw (defaults to s16ne)\n"
+ " float32be, ulaw, alaw, s32le, s32be (defaults to s16ne)\n"
" --channels=CHANNELS The number of channels, 1 for mono, 2 for stereo\n"
" (defaults to 2)\n"
" --channel-map=CHANNELMAP Channel map to use instead of the default\n"
@@ -695,7 +695,7 @@ int main(int argc, char *argv[]) {
goto quit;
}
- if (channel_map_set && channel_map.channels != sample_spec.channels) {
+ if (channel_map_set && pa_channel_map_compatible(&channel_map, &sample_spec)) {
fprintf(stderr, _("Channel map doesn't match sample specification\n"));
goto quit;
}
@@ -773,7 +773,10 @@ int main(int argc, char *argv[]) {
pa_context_set_state_callback(context, context_state_callback, NULL);
/* Connect the context */
- pa_context_connect(context, server, 0, NULL);
+ if (pa_context_connect(context, server, 0, NULL) < 0) {
+ fprintf(stderr, _("pa_context_connect() failed: %s"), pa_strerror(pa_context_errno(context)));
+ goto quit;
+ }
if (verbose) {
struct timeval tv;