]> code.delx.au - pulseaudio/commitdiff
Merge branch 'master' into master-tx
authorLennart Poettering <lennart@poettering.net>
Mon, 8 Sep 2008 14:25:16 +0000 (17:25 +0300)
committerLennart Poettering <lennart@poettering.net>
Mon, 8 Sep 2008 14:25:16 +0000 (17:25 +0300)
27 files changed:
man/pacat.1.xml.in
man/pulse-daemon.conf.5.xml.in
src/Makefile.am
src/daemon/cpulimit.c
src/daemon/daemon-conf.c
src/daemon/daemon-conf.h
src/daemon/daemon.conf.in
src/daemon/main.c
src/map-file
src/modules/module-alsa-sink.c
src/modules/module-alsa-source.c
src/pulse/channelmap.c
src/pulse/channelmap.h
src/pulse/context.c
src/pulse/internal.h
src/pulsecore/core-util.c
src/pulsecore/core-util.h
src/pulsecore/core.c
src/pulsecore/core.h
src/pulsecore/lock-autospawn.c [moved from src/pulse/lock-autospawn.c with 100% similarity]
src/pulsecore/lock-autospawn.h [moved from src/pulse/lock-autospawn.h with 100% similarity]
src/pulsecore/resampler.c
src/pulsecore/resampler.h
src/pulsecore/sink-input.c
src/pulsecore/source-output.c
src/tests/lock-autospawn-test.c
src/utils/pacat.c

index 7b0d72b963c4fe2e2577ccfc1b63cd60cda56881..68a3a12a57b9c64a4d9e9c9984a956e9c1d7d879 100644 (file)
@@ -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>
index 50e24559c3c0b371e92219b6c360055324dbccec..ed158dfa06ee024e9ae87da83a7b272e0185eab9 100644 (file)
@@ -105,6 +105,16 @@ USA.
       matching only.</p>
     </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
@@ -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>
index a20c7c458e3e3ba4cc10953bf4ddc22ca9e18cc6..1663d66d965244a26a6a2176463e0f6a6c2895bc 100644 (file)
@@ -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
index 59552828502cd8781fe8e7887aa71ccca874794d..a909600e9fd8dc38cadd68d86161e5e318094142 100644 (file)
@@ -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 */
 }
index 40e0a170f397f86588def7d86b913afaf9cc5415..77da3f7ebabea395019eb57403d4d8120bc18255 100644 (file)
@@ -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);
index c42984f99ccca13d8455ae4240ae7d44ad831092..309a142850def4ade658ed2e7b67ae585224c29d 100644 (file)
@@ -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,
index 33b1d61d9a4ff3eb441da4d2efc33e8763d78824..ea09fe09c6fbd7dd1937ece47f4230fa7290a38d 100644 (file)
@@ -47,6 +47,7 @@
 
 ; resample-method = speex-float-3
 ; disable-remixing = no
+; disable-lfe-remixing = yes
 
 ; no-cpu-limit = no
 
index c8eda398d81dc6596c1f0851f26685b95fec4ce8..a9e8ed4626afc94fa85e82c467a1a832106fd6bf 100644 (file)
@@ -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;
 
index b6d3b63d45a8a5eda5d4f306dba5300c08e0621c..67a5ee36db16052fed514d43351b81f7a67c0277 100644 (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;
index e3f9a5ffc61a64bfb06885124eeb4d69d5d22b68..6f0d783026ab9bc476834c6088df58759286d691 100644 (file)
@@ -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;
     }
 
index 54ffde57bab7322135e06588aee628f45e91af9a..fca05006170553db8ad32ed2a9741c08130b7eef 100644 (file)
@@ -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;
     }
 
index 1766e7291eb5c5fc84376bcd76f7d2d0f4d3604d..373087515c0a12d04018155cb2db128a26dc1ddf 100644 (file)
@@ -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;
+}
index f9086d1961b0f919921c9088035a167585b04bb7..d2dd6f8f917ed4f3f3fd583795a2de1e9b9bb633 100644 (file)
@@ -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
index f1aa49873743b3bdf6d5a0bba8249298a9e8a83b..154e5faf6e4b82297f0d722a9f554260e04e8807 100644 (file)
@@ -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;
             }
-
         }
     }
 
index 9167bf1b4a7202f256cddbf91e675087c0096ad9..5fe4210e1177dc751062d046f15578ccec87e320 100644 (file)
@@ -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;
index ad00f4f43519c4904fcb3e45e625470fe014ddbc..3e5ea492defa1234bbf6ec220c4732c68b89ab81 100644 (file)
@@ -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);
 }
index c9e307f5da131ea2efb5ee691ed5a5cb02c7a83d..df8ce3f85c95e2b6815b3879e69e107f1c6d28b9 100644 (file)
@@ -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
index b9f04b68883ea5b13ea090b202e33197686218c4..bd956ae0b5b287198a3873e865bca53681b42e73 100644 (file)
@@ -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);
 }
 
index eb7684185a2348243a3cf0d6d0e95e31dea9d950..fb4490f2fc0a5386484ce5e948c770e69add4f80 100644 (file)
@@ -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;
index 45cd68c1cf051c20181ec05331274677f306fb0f..0ae029b3fda8169bc1a60d6040f594dbdaa5bfa4 100644 (file)
@@ -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 */
index 5e302a9b953112dfa30696e873447bce8bf37fdc..87110cc2dd90d5527e6007d205ff929332d494f3 100644 (file)
@@ -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(
index 7d80242f44ea5e0eb6ac85f36b51528a1f62f3a1..326a7e2ce1651c6ace61eacffff0701805e99848 100644 (file)
@@ -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;
         }
index 5df950a87d22e7e7b5281af2ce012382f210b45d..d76f6e4e94bda85889b046a4dcd7e4aa4e121383 100644 (file)
@@ -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;
         }
index cb3dc87c847b5ec81effedd2a02562548409f77c..80cfda6aa6e4520279968ed9ffabe9003afcebe4 100644 (file)
@@ -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) {
index c1826d7b455996741609c153225bf20cdf31d101..99df5b9eb3370c3f2db4da25676947ac502629d7 100644 (file)
@@ -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;