<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>
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
<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>
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 += \
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 += \
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
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
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 */
}
.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,
{ "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 },
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
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);
no_cpu_limit,
disable_shm,
disable_remixing,
+ disable_lfe_remixing,
load_default_script_file,
disallow_exit;
int exit_idle_time,
; resample-method = speex-float-3
; disable-remixing = no
+; disable-lfe-remixing = yes
; no-cpu-limit = no
#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>
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
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;
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;
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;
pa_cvolume_avg;
pa_cvolume_channels_equal_to;
pa_cvolume_equal;
+pa_cvolume_max;
pa_cvolume_remap;
pa_cvolume_set;
pa_cvolume_snprint;
}
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;
}
}
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;
}
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);
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;
default:
- return NULL;
+ pa_assert_not_reached();
}
}
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);
pa_assert(rmap);
pa_assert(s);
- memset(&map, 0, sizeof(map));
+ pa_channel_map_init(&map);
if (strcmp(s, "stereo") == 0) {
map.channels = 2;
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;
+}
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;
/** 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
#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>
[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) {
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
context_unlink(c);
- unlock_autospawn(c);
-
if (c->record_streams)
pa_dynarray_free(c->record_streams, NULL, NULL);
if (c->playback_streams)
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();
} 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;
/* 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);
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);
#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;
#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
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,
}
} 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);
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;
}
-
}
}
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;
#include <dirent.h>
#include <regex.h>
#include <langinfo.h>
+#include <sys/utsname.h>
#ifdef HAVE_STRTOF_L
#include <locale.h>
/* 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);
}
#define pa_streq(a,b) (!strcmp((a),(b)))
char *pa_machine_id(void);
+char *pa_uname_string(void);
#endif
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);
pa_core *c = userdata;
pa_assert(c->exit_event == e);
+ pa_log_info("We are idle, quitting...");
pa_core_exit(c, TRUE, 0);
}
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;
* 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. */
}
}
- 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 */
} 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(
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;
}
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;
}
#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) {
" --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"
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;
}
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;