From diwic at kemper.freedesktop.org Tue Sep 2 05:41:22 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Tue, 2 Sep 2014 05:41:22 -0700 (PDT) Subject: [pulseaudio-commits] 2 commits - src/daemon src/pulse src/pulsecore src/tests Message-ID: <20140902124122.1C74D76255@kemper.freedesktop.org> src/daemon/caps.c | 2 - src/daemon/main.c | 68 ++++++++++++++++++++-------------------- src/pulse/context.c | 2 - src/pulse/def.h | 2 - src/pulse/error.c | 2 - src/pulsecore/authkey.c | 6 +-- src/pulsecore/esound.h | 2 - src/pulsecore/protocol-esound.c | 2 - src/pulsecore/protocol-native.c | 2 - src/tests/resampler-test.c | 4 +- 10 files changed, 46 insertions(+), 46 deletions(-) New commits: commit 58cffdcfc8674e96e9faeaf726a4b86aebdc427b Author: David Henningsson Date: Tue Sep 2 11:50:39 2014 +0200 Replace "authorization" with "authentication" Since we don't have "limited" clients, a client that authenticates correctly is automatically authorized. However, it's the authentication that can go wrong, rather than the authorization. Buglink: https://bugs.freedesktop.org/show_bug.cgi?id=78566 Signed-off-by: David Henningsson diff --git a/src/pulse/def.h b/src/pulse/def.h index dfc0c10..ee7404d 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -464,7 +464,7 @@ typedef enum pa_error_code { PA_ERR_CONNECTIONREFUSED, /**< Connection refused */ PA_ERR_PROTOCOL, /**< Protocol error */ PA_ERR_TIMEOUT, /**< Timeout */ - PA_ERR_AUTHKEY, /**< No authorization key */ + PA_ERR_AUTHKEY, /**< No authentication key */ PA_ERR_INTERNAL, /**< Internal error */ PA_ERR_CONNECTIONTERMINATED, /**< Connection terminated */ PA_ERR_KILLED, /**< Entity killed */ diff --git a/src/pulse/error.c b/src/pulse/error.c index 751d42a..27b8ec4 100644 --- a/src/pulse/error.c +++ b/src/pulse/error.c @@ -46,7 +46,7 @@ const char*pa_strerror(int error) { [PA_ERR_CONNECTIONREFUSED] = N_("Connection refused"), [PA_ERR_PROTOCOL] = N_("Protocol error"), [PA_ERR_TIMEOUT] = N_("Timeout"), - [PA_ERR_AUTHKEY] = N_("No authorization key"), + [PA_ERR_AUTHKEY] = N_("No authentication key"), [PA_ERR_INTERNAL] = N_("Internal error"), [PA_ERR_CONNECTIONTERMINATED] = N_("Connection terminated"), [PA_ERR_KILLED] = N_("Entity killed"), diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c index 3c5827d..7f91f16 100644 --- a/src/pulsecore/authkey.c +++ b/src/pulsecore/authkey.c @@ -42,7 +42,7 @@ #include "authkey.h" -/* Generate a new authorization key, store it in file fd and return it in *data */ +/* Generate a new authentication key, store it in file fd and return it in *data */ static int generate(int fd, void *ret_data, size_t length) { ssize_t r; @@ -70,7 +70,7 @@ static int generate(int fd, void *ret_data, size_t length) { #define O_BINARY 0 #endif -/* Load an authorization cookie from file fn and store it in data. If +/* Load an authentication cookie from file fn and store it in data. If * the cookie file doesn't exist, create it */ static int load(const char *fn, bool create, void *data, size_t length) { int fd = -1; @@ -156,7 +156,7 @@ int pa_authkey_load(const char *fn, bool create, void *data, size_t length) { return ret; if ((ret = load(p, create, data, length)) < 0) - pa_log_warn("Failed to load authorization key '%s': %s", p, (ret < 0) ? pa_cstrerror(errno) : "File corrupt"); + pa_log_warn("Failed to load authentication key '%s': %s", p, (ret < 0) ? pa_cstrerror(errno) : "File corrupt"); pa_xfree(p); diff --git a/src/pulsecore/esound.h b/src/pulsecore/esound.h index 5d6ec95..5fc91db 100644 --- a/src/pulsecore/esound.h +++ b/src/pulsecore/esound.h @@ -33,7 +33,7 @@ /* maximum size we can write(). Otherwise we might overflow */ #define ESD_MAX_WRITE_SIZE (21 * 4096) -/* length of the authorization key, octets */ +/* length of the authentication key, octets */ #define ESD_KEY_LEN (16) /* default port for the EsounD server */ diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 755109c..a4e0028 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -351,7 +351,7 @@ static int esd_proto_connect(connection *c, esd_proto_t request, const void *dat } if (!c->authorized) { - pa_log("Kicked client with invalid authorization key."); + pa_log("Kicked client with invalid authentication key."); return -1; } diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 93db157..6ec65d6 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2724,7 +2724,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta } if (!success) { - pa_log_warn("Denied access to client with invalid authorization data."); + pa_log_warn("Denied access to client with invalid authentication data."); pa_pstream_send_error(c->pstream, tag, PA_ERR_ACCESS); return; } commit 764da4260a2ab44816d4b1f4c4e709f4684b1b9a Author: David Henningsson Date: Tue Sep 2 12:09:44 2014 +0200 Make all debug/info level messages untranslatable Debug and info messages are primarily meant for developers, rather than end users. Let's save translators' time, and leave them untranslated. Signed-off-by: David Henningsson diff --git a/src/daemon/caps.c b/src/daemon/caps.c index 669d6e2..91c7f95 100644 --- a/src/daemon/caps.c +++ b/src/daemon/caps.c @@ -51,7 +51,7 @@ void pa_drop_root(void) { uid_t uid; gid_t gid; - pa_log_debug(_("Cleaning up privileges.")); + pa_log_debug("Cleaning up privileges."); uid = getuid(); gid = getgid(); diff --git a/src/daemon/main.c b/src/daemon/main.c index 150ce6d..23fb660 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -112,7 +112,7 @@ int __padsp_disabled__ = 7; #endif static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) { - pa_log_info(_("Got signal %s."), pa_sig2str(sig)); + pa_log_info("Got signal %s.", pa_sig2str(sig)); switch (sig) { #ifdef SIGUSR1 @@ -139,7 +139,7 @@ static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void case SIGINT: case SIGTERM: default: - pa_log_info(_("Exiting.")); + pa_log_info("Exiting."); m->quit(m, 1); break; } @@ -166,7 +166,7 @@ static int change_user(void) { return -1; } - pa_log_info(_("Found user '%s' (UID %lu) and group '%s' (GID %lu)."), + pa_log_info("Found user '%s' (UID %lu) and group '%s' (GID %lu).", PA_SYSTEM_USER, (unsigned long) pw->pw_uid, PA_SYSTEM_GROUP, (unsigned long) gr->gr_gid); @@ -244,7 +244,7 @@ static int change_user(void) { if (!getenv("PULSE_STATE_PATH")) pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH); - pa_log_info(_("Successfully changed user to \"" PA_SYSTEM_USER "\".")); + pa_log_info("Successfully changed user to \"" PA_SYSTEM_USER "\"."); return 0; } @@ -270,7 +270,7 @@ static int set_one_rlimit(const pa_rlimit *r, int resource, const char *name) { rl.rlim_cur = rl.rlim_max = r->value; if (setrlimit(resource, &rl) < 0) { - pa_log_info(_("setrlimit(%s, (%u, %u)) failed: %s"), name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno)); + pa_log_info("setrlimit(%s, (%u, %u)) failed: %s", name, (unsigned) r->value, (unsigned) r->value, pa_cstrerror(errno)); return -1; } @@ -584,9 +584,9 @@ int main(int argc, char *argv[]) { } if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) - pa_log_info(_("Daemon not running")); + pa_log_info("Daemon not running"); else { - pa_log_info(_("Daemon running as PID %u"), pid); + pa_log_info("Daemon running as PID %u", pid); retval = 0; } @@ -769,7 +769,7 @@ int main(int argc, char *argv[]) { if (retval) pa_log(_("Daemon startup failed.")); else - pa_log_info(_("Daemon startup successful.")); + pa_log_info("Daemon startup successful."); goto finish; } @@ -886,67 +886,67 @@ int main(int argc, char *argv[]) { pa_set_env_and_record("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); + 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_log_debug("Running on host: %s", s); pa_xfree(s); - pa_log_debug(_("Found %u CPUs."), pa_ncpus()); + pa_log_debug("Found %u CPUs.", pa_ncpus()); - pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE); + 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")); + pa_log_debug("Compiled with Valgrind support: yes"); #else - pa_log_debug(_("Compiled with Valgrind support: no")); + pa_log_debug("Compiled with Valgrind support: no"); #endif - pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind())); + pa_log_debug("Running in valgrind mode: %s", pa_yes_no(pa_in_valgrind())); - pa_log_debug(_("Running in VM: %s"), pa_yes_no(pa_running_in_vm())); + pa_log_debug("Running in VM: %s", pa_yes_no(pa_running_in_vm())); #ifdef __OPTIMIZE__ - pa_log_debug(_("Optimized build: yes")); + pa_log_debug("Optimized build: yes"); #else - pa_log_debug(_("Optimized build: no")); + pa_log_debug("Optimized build: no"); #endif #ifdef NDEBUG - pa_log_debug(_("NDEBUG defined, all asserts disabled.")); + pa_log_debug("NDEBUG defined, all asserts disabled."); #elif defined(FASTPATH) - pa_log_debug(_("FASTPATH defined, only fast path asserts disabled.")); + pa_log_debug("FASTPATH defined, only fast path asserts disabled."); #else - pa_log_debug(_("All asserts enabled.")); + pa_log_debug("All asserts enabled."); #endif if (!(s = pa_machine_id())) { pa_log(_("Failed to get machine ID")); goto finish; } - pa_log_info(_("Machine ID is %s."), s); + pa_log_info("Machine ID is %s.", s); pa_xfree(s); if ((s = pa_session_id())) { - pa_log_info(_("Session ID is %s."), s); + pa_log_info("Session ID is %s.", s); pa_xfree(s); } if (!(s = pa_get_runtime_dir())) goto finish; - pa_log_info(_("Using runtime directory %s."), s); + pa_log_info("Using runtime directory %s.", s); pa_xfree(s); if (!(s = pa_get_state_dir())) goto finish; - pa_log_info(_("Using state directory %s."), s); + pa_log_info("Using state directory %s.", s); pa_xfree(s); - pa_log_info(_("Using modules directory %s."), conf->dl_search_path); + pa_log_info("Using modules directory %s.", conf->dl_search_path); - pa_log_info(_("Running in system mode: %s"), pa_yes_no(pa_in_system_mode())); + pa_log_info("Running in system mode: %s", pa_yes_no(pa_in_system_mode())); if (pa_in_system_mode()) pa_log_warn(_("OK, so you are running PA in system mode. Please note that you most likely shouldn't be doing that.\n" @@ -976,9 +976,9 @@ int main(int argc, char *argv[]) { pa_disable_sigpipe(); if (pa_rtclock_hrtimer()) - pa_log_info(_("Fresh high-resolution timers available! Bon appetit!")); + pa_log_info("Fresh high-resolution timers available! Bon appetit!"); else - pa_log_info(_("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!")); + pa_log_info("Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"); if (conf->lock_memory) { #if defined(HAVE_SYS_MMAN_H) && !defined(__ANDROID__) @@ -1113,13 +1113,13 @@ int main(int argc, char *argv[]) { } #endif - pa_log_info(_("Daemon startup complete.")); + pa_log_info("Daemon startup complete."); retval = 0; if (pa_mainloop_run(mainloop, &retval) < 0) goto finish; - pa_log_info(_("Daemon shutdown initiated.")); + pa_log_info("Daemon shutdown initiated."); finish: #ifdef HAVE_DBUS @@ -1145,7 +1145,7 @@ finish: pa_scache_free_all(c); pa_core_unref(c); - pa_log_info(_("Daemon terminated.")); + pa_log_info("Daemon terminated."); } if (!conf->no_cpu_limit) diff --git a/src/pulse/context.c b/src/pulse/context.c index d572406..8897de0 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -574,7 +574,7 @@ static void setup_context(pa_context *c, pa_iochannel *io) { c->pdispatch = pa_pdispatch_new(c->mainloop, c->use_rtclock, command_table, PA_COMMAND_MAX); if (pa_client_conf_load_cookie(c->conf, cookie, sizeof(cookie)) < 0) - pa_log_info(_("No cookie loaded. Attempting to connect without.")); + pa_log_info("No cookie loaded. Attempting to connect without."); t = pa_tagstruct_command(c, PA_COMMAND_AUTH, &tag); diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c index 566b69f..60345af 100644 --- a/src/tests/resampler-test.c +++ b/src/tests/resampler-test.c @@ -415,8 +415,8 @@ int main(int argc, char *argv[]) { pa_memchunk i, j; pa_usec_t ts; - pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS); - pa_log_debug(_("=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)"), seconds, + pa_log_debug("Compilation CFLAGS: %s", PA_CFLAGS); + pa_log_debug("=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)", seconds, a.rate, a.channels, pa_sample_format_to_string(a.format), b.rate, b.channels, pa_sample_format_to_string(b.format)); From pmeerw at kemper.freedesktop.org Tue Sep 2 10:46:06 2014 From: pmeerw at kemper.freedesktop.org (Peter Meerwald) Date: Tue, 2 Sep 2014 10:46:06 -0700 (PDT) Subject: [pulseaudio-commits] src/daemon Message-ID: <20140902174606.2834776254@kemper.freedesktop.org> src/daemon/caps.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) New commits: commit c6bc835e4572e682c8f09ddc5852ed63da1838d4 Author: Peter Meerwald Date: Mon Sep 1 22:53:29 2014 +0200 daemon: Debian/kFreeBSD 9.2 fails to compile due to caps Debian/kFreeBSD 9.2 comes with sys/capability.h but it is not usable; work around it the patch does several things: * it makes the comment point to the correct bugtracker issue: https://bugs.freedesktop.org/show_bug.cgi?id=72580 * it handles Debian/kFreeBSD the same way as FreeBSD * it logs a warning that capabilities are actually NOT dropped daemon/caps.c: In function ???pa_drop_caps???: daemon/caps.c:93:2: error: #error "Don't know how to do capabilities on your system. Please send a patch." #error "Don't know how to do capabilities on your system. Please send a patch." ^ Makefile:9575: recipe for target 'daemon/pulseaudio-caps.o' failed Signed-off-by: Peter Meerwald diff --git a/src/daemon/caps.c b/src/daemon/caps.c index 91c7f95..9471d3b 100644 --- a/src/daemon/caps.c +++ b/src/daemon/caps.c @@ -86,9 +86,10 @@ void pa_drop_caps(void) { pa_assert_se(cap_clear(caps) == 0); pa_assert_se(cap_set_proc(caps) == 0); pa_assert_se(cap_free(caps) == 0); -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) /* FreeBSD doesn't have this functionality, even though sys/capability.h is - * available. See https://bugs.freedesktop.org/show_bug.cgi?id=73967 */ + * available. See https://bugs.freedesktop.org/show_bug.cgi?id=72580 */ + pa_log_warn("FreeBSD cannot drop extra capabilities, implementation needed."); #else #error "Don't know how to do capabilities on your system. Please send a patch." #endif /* __linux__ */ From pmeerw at kemper.freedesktop.org Wed Sep 3 03:51:50 2014 From: pmeerw at kemper.freedesktop.org (Peter Meerwald) Date: Wed, 3 Sep 2014 03:51:50 -0700 (PDT) Subject: [pulseaudio-commits] src/pulsecore Message-ID: <20140903105150.68B6876254@kemper.freedesktop.org> src/pulsecore/svolume_c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit 5d7b5e509ce3a9a5c17f3ee3cec2eee2979e190f Author: Peter Meerwald Date: Wed Sep 3 02:03:44 2014 +0200 svolume: Make volume pointer parameter const for pa_volume_float32re_c() const obviously missing Signed-off-by: Peter Meerwald diff --git a/src/pulsecore/svolume_c.c b/src/pulsecore/svolume_c.c index eb04973..ad2df18 100644 --- a/src/pulsecore/svolume_c.c +++ b/src/pulsecore/svolume_c.c @@ -117,7 +117,7 @@ static void pa_volume_float32ne_c(float *samples, const float *volumes, unsigned } } -static void pa_volume_float32re_c(float *samples, float *volumes, unsigned channels, unsigned length) { +static void pa_volume_float32re_c(float *samples, const float *volumes, unsigned channels, unsigned length) { unsigned channel; length /= sizeof(float); From pmeerw at kemper.freedesktop.org Thu Sep 4 00:59:10 2014 From: pmeerw at kemper.freedesktop.org (Peter Meerwald) Date: Thu, 4 Sep 2014 00:59:10 -0700 (PDT) Subject: [pulseaudio-commits] src/pulsecore src/tests Message-ID: <20140904075910.EC14B76250@kemper.freedesktop.org> src/pulsecore/endianmacros.h | 23 ++++++++++++----------- src/pulsecore/mix.c | 11 ++++------- src/pulsecore/sample-util.c | 4 ++-- src/pulsecore/sconv-s16le.c | 22 ++++++++-------------- src/pulsecore/svolume_c.c | 4 ++-- src/tests/mix-test.c | 4 ++-- src/tests/resampler-test.c | 4 ++-- 7 files changed, 32 insertions(+), 40 deletions(-) New commits: commit 293a1739e25707c25321d5bc6cd3e2e8aa96a910 Author: Peter Meerwald Date: Tue Sep 2 23:53:09 2014 +0200 endianmacros: Replace borked PA_FLOAT32_SWAP() with PA_READ_FLOAT32RE() / PA_WRITE_FLOAT32RE() building PA with -O0 leads to test failure in mix-test on i386 issue reported by Felipe, see http://lists.freedesktop.org/archives/pulseaudio-discuss/2014-August/021406.html the problem is the value 0xbeffbd7f: when byte-swapped it becomes 0x7fbdffbe and according to IEEE-754 represents a signalling NaN (starting with s111 1111 10, see http://en.wikipedia.org/wiki/NaN) when this value is assigned to a floating point register, it becomes 0x7ffdffbe, representing a quiet NaN (starting with s111 1111 11) -- a signalling NaN is turned into a quiet NaN! so PA_FLOAT32_SWAP(PA_FLOAT32_SWAP(x)) != x for certain values, uhuh! the following test code can be used; due to volatile, it will always demonstrate the issue; without volatile, it depends on the optimization level (i386, 32-bit, gcc 4.9): // snip static inline float PA_FLOAT32_SWAP(float x) { union { float f; uint32_t u; } t; t.f = x; t.u = bswap_32(t.u); return t.f; } int main() { unsigned x = 0xbeffbd7f; volatile float f = PA_FLOAT32_SWAP(*(float *)&x); printf("%08x %08x %08x %f\n", 0xbeffbd7f, *(unsigned *)&f, bswap_32(*(unsigned *)&f), f); } // snip the problem goes away with optimization when no temporary floating point registers are used the proposed solution is to avoid passing swapped floating point data in a float; this is done with new functions PA_READ_FLOAT32RE() and PA_WRITE_FLOAT32RE() which use uint32_t to dereference a pointer and byte-swap the data, hence no temporary float variable is used also delete PA_FLOAT32_TO_LE()/_BE(), not used Signed-off-by: Peter Meerwald Reported-by: Felipe Sateler diff --git a/src/pulsecore/endianmacros.h b/src/pulsecore/endianmacros.h index 4822fc4..2e73136 100644 --- a/src/pulsecore/endianmacros.h +++ b/src/pulsecore/endianmacros.h @@ -71,25 +71,32 @@ static inline void PA_WRITE24LE(uint8_t *p, uint32_t u) { p[0] = (uint8_t) u; } -static inline float PA_FLOAT32_SWAP(float x) { +static inline float PA_READ_FLOAT32RE(const void *p) { union { float f; uint32_t u; } t; - t.f = x; - t.u = PA_UINT32_SWAP(t.u); + t.u = PA_UINT32_SWAP(*(uint32_t *) p); return t.f; } +static inline void PA_WRITE_FLOAT32RE(void *p, float x) { + union { + float f; + uint32_t u; + } t; + + t.f = x; + *(uint32_t *) p = PA_UINT32_SWAP(t.u); +} + #define PA_MAYBE_INT16_SWAP(c,x) ((c) ? PA_INT16_SWAP(x) : (x)) #define PA_MAYBE_UINT16_SWAP(c,x) ((c) ? PA_UINT16_SWAP(x) : (x)) #define PA_MAYBE_INT32_SWAP(c,x) ((c) ? PA_INT32_SWAP(x) : (x)) #define PA_MAYBE_UINT32_SWAP(c,x) ((c) ? PA_UINT32_SWAP(x) : (x)) -#define PA_MAYBE_FLOAT32_SWAP(c,x) ((c) ? PA_FLOAT32_SWAP(x) : (x)) - #ifdef WORDS_BIGENDIAN #define PA_INT16_FROM_LE(x) PA_INT16_SWAP(x) #define PA_INT16_FROM_BE(x) ((int16_t)(x)) @@ -115,9 +122,6 @@ static inline float PA_FLOAT32_SWAP(float x) { #define PA_UINT32_TO_LE(x) PA_UINT32_SWAP(x) #define PA_UINT32_TO_BE(x) ((uint32_t)(x)) - #define PA_FLOAT32_TO_LE(x) PA_FLOAT32_SWAP(x) - #define PA_FLOAT32_TO_BE(x) ((float) (x)) - #define PA_READ24NE(x) PA_READ24BE(x) #define PA_WRITE24NE(x,y) PA_WRITE24BE((x),(y)) @@ -148,9 +152,6 @@ static inline float PA_FLOAT32_SWAP(float x) { #define PA_UINT32_TO_LE(x) ((uint32_t)(x)) #define PA_UINT32_TO_BE(x) PA_UINT32_SWAP(x) - #define PA_FLOAT32_TO_LE(x) ((float) (x)) - #define PA_FLOAT32_TO_BE(x) PA_FLOAT32_SWAP(x) - #define PA_READ24NE(x) PA_READ24LE(x) #define PA_WRITE24NE(x,y) PA_WRITE24LE((x),(y)) diff --git a/src/pulsecore/mix.c b/src/pulsecore/mix.c index 10567d6..03c71f0 100644 --- a/src/pulsecore/mix.c +++ b/src/pulsecore/mix.c @@ -576,17 +576,14 @@ static void pa_mix_float32re_c(pa_mix_info streams[], unsigned nstreams, unsigne for (i = 0; i < nstreams; i++) { pa_mix_info *m = streams + i; - float v, cv = m->linear[channel].f; + float cv = m->linear[channel].f; - if (PA_LIKELY(cv > 0)) { - v = PA_FLOAT32_SWAP(*(float*) m->ptr); - v *= cv; - sum += v; - } + if (PA_LIKELY(cv > 0)) + sum += PA_READ_FLOAT32RE(m->ptr) * cv; m->ptr = (uint8_t*) m->ptr + sizeof(float); } - *data = PA_FLOAT32_SWAP(sum); + PA_WRITE_FLOAT32RE(data, sum); if (PA_UNLIKELY(++channel >= channels)) channel = 0; diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c index dc5c1fd..539f3b8 100644 --- a/src/pulsecore/sample-util.c +++ b/src/pulsecore/sample-util.c @@ -296,9 +296,9 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo for (; n > 0; n--) { float f; - f = PA_FLOAT32_SWAP(*s); + f = PA_READ_FLOAT32RE(s); f = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f); - *d = PA_FLOAT32_SWAP(f); + PA_WRITE_FLOAT32RE(d, f); s = (const float*) ((const uint8_t*) s + sstr); d = (float*) ((uint8_t*) d + dstr); diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c index 45cf972..0c1d16c 100644 --- a/src/pulsecore/sconv-s16le.c +++ b/src/pulsecore/sconv-s16le.c @@ -157,8 +157,7 @@ void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) { for (; n > 0; n--) { int16_t s = *(a++); float k = INT16_FROM(s) * (1.0f / (1 << 15)); - k = PA_FLOAT32_SWAP(k); - *(b++) = k; + PA_WRITE_FLOAT32RE(b++, k); } } @@ -169,8 +168,7 @@ void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) { for (; n > 0; n--) { int32_t s = *(a++); float k = INT32_FROM(s) * (1.0f / (1U << 31)); - k = PA_FLOAT32_SWAP(k); - *(b++) = k; + PA_WRITE_FLOAT32RE(b++, k); } } @@ -180,8 +178,7 @@ void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) { for (; n > 0; n--) { int16_t s; - float v = *(a++); - v = PA_FLOAT32_SWAP(v) * (1 << 15); + float v = PA_READ_FLOAT32RE(a++) * (1 << 15); s = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF); *(b++) = INT16_TO(s); } @@ -193,8 +190,7 @@ void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) { for (; n > 0; n--) { int32_t s; - float v = *(a++); - v = PA_FLOAT32_SWAP(v) * (1U << 31); + float v = PA_READ_FLOAT32RE(a++) * (1U << 31); s = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL); *(b++) = INT32_TO(s); } @@ -325,7 +321,7 @@ void pa_sconv_s24le_to_float32re(unsigned n, const uint8_t *a, float *b) { for (; n > 0; n--) { int32_t s = READ24(a) << 8; float k = s * (1.0f / (1U << 31)); - *b = PA_FLOAT32_SWAP(k); + PA_WRITE_FLOAT32RE(b, k); a += 3; b++; } @@ -337,8 +333,7 @@ void pa_sconv_s24le_from_float32re(unsigned n, const float *a, uint8_t *b) { for (; n > 0; n--) { int32_t s; - float v = *a; - v = PA_FLOAT32_SWAP(v) * (1U << 31); + float v = PA_READ_FLOAT32RE(a) * (1U << 31); s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL); WRITE24(b, ((uint32_t) s) >> 8); a++; @@ -411,7 +406,7 @@ void pa_sconv_s24_32le_to_float32re(unsigned n, const uint32_t *a, float *b) { for (; n > 0; n--) { int32_t s = (int32_t) (UINT32_FROM(*a) << 8); float k = s * (1.0f / (1U << 31)); - *b = PA_FLOAT32_SWAP(k); + PA_WRITE_FLOAT32RE(b, k); a++; b++; } @@ -437,8 +432,7 @@ void pa_sconv_s24_32le_from_float32re(unsigned n, const float *a, uint32_t *b) { for (; n > 0; n--) { int32_t s; - float v = *a; - v = PA_FLOAT32_SWAP(v) * (1U << 31); + float v = PA_READ_FLOAT32RE(a) * (1U << 31); s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL); *b = UINT32_TO(((uint32_t) s) >> 8); a++; diff --git a/src/pulsecore/svolume_c.c b/src/pulsecore/svolume_c.c index ad2df18..2e2db12 100644 --- a/src/pulsecore/svolume_c.c +++ b/src/pulsecore/svolume_c.c @@ -125,9 +125,9 @@ static void pa_volume_float32re_c(float *samples, const float *volumes, unsigned for (channel = 0; length; length--) { float t; - t = PA_FLOAT32_SWAP(*samples); + t = PA_READ_FLOAT32RE(samples); t *= volumes[channel]; - *samples++ = PA_FLOAT32_SWAP(t); + PA_WRITE_FLOAT32RE(samples++, t); if (PA_UNLIKELY(++channel >= channels)) channel = 0; diff --git a/src/tests/mix-test.c b/src/tests/mix-test.c index d5bae13..e95607d 100644 --- a/src/tests/mix-test.c +++ b/src/tests/mix-test.c @@ -150,7 +150,7 @@ static void compare_block(const pa_sample_spec *ss, const pa_memchunk *chunk, in float *u = d; for (i = 0; i < chunk->length / pa_frame_size(ss); i++) { - float uu = PA_MAYBE_FLOAT32_SWAP(ss->format != PA_SAMPLE_FLOAT32NE, *u); + float uu = ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_READ_FLOAT32RE(u); fail_unless(fabsf(uu - *v) <= 1e-6f, NULL); ++u; ++v; @@ -264,7 +264,7 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) { if (ss->format == PA_SAMPLE_FLOAT32RE) { float *u = d; for (i = 0; i < 10; i++) - u[i] = PA_FLOAT32_SWAP(float32ne_result[0][i]); + PA_WRITE_FLOAT32RE(&u[i], float32ne_result[0][i]); } else memcpy(d, float32ne_result[0], sizeof(float32ne_result[0])); diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c index 60345af..f547770 100644 --- a/src/tests/resampler-test.c +++ b/src/tests/resampler-test.c @@ -98,7 +98,7 @@ static void dump_block(const char *label, const pa_sample_spec *ss, const pa_mem float *u = d; for (i = 0; i < chunk->length / pa_frame_size(ss); i++) { - printf("%4.3g ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_FLOAT32_SWAP(*u)); + printf("%4.3g ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_READ_FLOAT32RE(u)); u++; } @@ -222,7 +222,7 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) { if (ss->format == PA_SAMPLE_FLOAT32RE) for (i = 0; i < 10; i++) - u[i] = PA_FLOAT32_SWAP(u[i]); + PA_WRITE_FLOAT32RE(&u[i], u[i]); break; } From tanuk at kemper.freedesktop.org Sun Sep 7 03:52:18 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Sun, 7 Sep 2014 03:52:18 -0700 (PDT) Subject: [pulseaudio-commits] src/cardwidget.cc src/channelwidget.cc src/devicewidget.cc src/mainwindow.cc src/rolewidget.cc src/sinkinputwidget.cc src/sinkwidget.cc src/sourceoutputwidget.cc src/sourcewidget.cc src/streamwidget.cc Message-ID: <20140907105218.CB0DD761EF@kemper.freedesktop.org> src/cardwidget.cc | 1 + src/channelwidget.cc | 1 + src/devicewidget.cc | 1 + src/mainwindow.cc | 6 ++++++ src/rolewidget.cc | 1 + src/sinkinputwidget.cc | 1 + src/sinkwidget.cc | 1 + src/sourceoutputwidget.cc | 1 + src/sourcewidget.cc | 1 + src/streamwidget.cc | 1 + 10 files changed, 15 insertions(+) New commits: commit b2362f2223b1ecc0c92fac9d261d5684f33af06f Author: Hans de Goede Date: Thu Aug 28 12:58:05 2014 +0200 Reference the widget before returning it from ::create methods Widgets (unlike Windows and Dialogs) returned by Gtk::Builder::get_widget* start owned by the GtkBuilder object, the idea being that they will get added to a container before the scope of the GtkBuilder object ends, and it thus automatically gets destroyed. But in the various ::create methods in pavucontrol, a pointer to the widget gets returned, so that it can be added to a cointainer by the caller. However as soon as the ::create method exits the GtkBuilder object owning the widget, and thus also the widget gets destroyed, and we end up returning free-ed memory. This commit fixes this by making all ::create methods take a reference on the widget before returning it, and having all the callers unreference the widget after adding it to a container. https://bugs.freedesktop.org/show_bug.cgi?id=83144 https://bugzilla.redhat.com/show_bug.cgi?id=1133339 Signed-off-by: Hans de Goede diff --git a/src/cardwidget.cc b/src/cardwidget.cc index c79ac6c..28c558d 100644 --- a/src/cardwidget.cc +++ b/src/cardwidget.cc @@ -45,6 +45,7 @@ CardWidget* CardWidget::create() { CardWidget* w; Glib::RefPtr x = Gtk::Builder::create_from_file(GLADE_FILE, "cardWidget"); x->get_widget_derived("cardWidget", w); + w->reference(); return w; } diff --git a/src/channelwidget.cc b/src/channelwidget.cc index 6f59de2..fe94c11 100644 --- a/src/channelwidget.cc +++ b/src/channelwidget.cc @@ -53,6 +53,7 @@ ChannelWidget* ChannelWidget::create() { x->add_from_file(GLADE_FILE, "adjustment1"); x->add_from_file(GLADE_FILE, "channelWidget"); x->get_widget_derived("channelWidget", w); + w->reference(); return w; } diff --git a/src/devicewidget.cc b/src/devicewidget.cc index 1a148ee..813780f 100644 --- a/src/devicewidget.cc +++ b/src/devicewidget.cc @@ -89,6 +89,7 @@ void DeviceWidget::setChannelMap(const pa_channel_map &m, bool can_decibel) { snprintf(text, sizeof(text), "%s", pa_channel_position_to_pretty_string(m.map[i])); cw->channelLabel->set_markup(text); channelsVBox->pack_start(*cw, false, false, 0); + cw->unreference(); } channelWidgets[m.channels-1]->last = true; diff --git a/src/mainwindow.cc b/src/mainwindow.cc index 5a42318..5d205fb 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -300,6 +300,7 @@ void MainWindow::updateCard(const pa_card_info &info) { else { cardWidgets[info.index] = w = CardWidget::create(); cardsVBox->pack_start(*w, false, false, 0); + w->unreference(); w->index = info.index; is_new = true; } @@ -416,6 +417,7 @@ bool MainWindow::updateSink(const pa_sink_info &info) { sinkWidgets[info.index] = w = SinkWidget::create(this); w->setChannelMap(info.channel_map, !!(info.flags & PA_SINK_DECIBEL_VOLUME)); sinksVBox->pack_start(*w, false, false, 0); + w->unreference(); w->index = info.index; w->monitor_index = info.monitor_source; is_new = true; @@ -570,6 +572,7 @@ void MainWindow::updateSource(const pa_source_info &info) { sourceWidgets[info.index] = w = SourceWidget::create(this); w->setChannelMap(info.channel_map, !!(info.flags & PA_SOURCE_DECIBEL_VOLUME)); sourcesVBox->pack_start(*w, false, false, 0); + w->unreference(); w->index = info.index; is_new = true; @@ -686,6 +689,7 @@ void MainWindow::updateSinkInput(const pa_sink_input_info &info) { sinkInputWidgets[info.index] = w = SinkInputWidget::create(this); w->setChannelMap(info.channel_map, true); streamsVBox->pack_start(*w, false, false, 0); + w->unreference(); w->index = info.index; w->clientIndex = info.client; is_new = true; @@ -743,6 +747,7 @@ void MainWindow::updateSourceOutput(const pa_source_output_info &info) { w->setChannelMap(info.channel_map, true); #endif recsVBox->pack_start(*w, false, false, 0); + w->unreference(); w->index = info.index; w->clientIndex = info.client; is_new = true; @@ -838,6 +843,7 @@ bool MainWindow::createEventRoleWidget() { eventRoleWidget = RoleWidget::create(); streamsVBox->pack_start(*eventRoleWidget, false, false, 0); + eventRoleWidget->unreference(); eventRoleWidget->role = "sink-input-by-media-role:event"; eventRoleWidget->setChannelMap(cm, true); diff --git a/src/rolewidget.cc b/src/rolewidget.cc index fd3196c..db07f92 100644 --- a/src/rolewidget.cc +++ b/src/rolewidget.cc @@ -40,6 +40,7 @@ RoleWidget* RoleWidget::create() { RoleWidget* w; Glib::RefPtr x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget"); x->get_widget_derived("streamWidget", w); + w->reference(); return w; } diff --git a/src/sinkinputwidget.cc b/src/sinkinputwidget.cc index b88b718..5a0ba39 100644 --- a/src/sinkinputwidget.cc +++ b/src/sinkinputwidget.cc @@ -43,6 +43,7 @@ SinkInputWidget* SinkInputWidget::create(MainWindow* mainWindow) { Glib::RefPtr x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget"); x->get_widget_derived("streamWidget", w); w->init(mainWindow); + w->reference(); return w; } diff --git a/src/sinkwidget.cc b/src/sinkwidget.cc index 7f4902c..f682cf2 100644 --- a/src/sinkwidget.cc +++ b/src/sinkwidget.cc @@ -82,6 +82,7 @@ SinkWidget* SinkWidget::create(MainWindow* mainWindow) { Glib::RefPtr x = Gtk::Builder::create_from_file(GLADE_FILE, "deviceWidget"); x->get_widget_derived("deviceWidget", w); w->init(mainWindow, "sink"); + w->reference(); return w; } diff --git a/src/sourceoutputwidget.cc b/src/sourceoutputwidget.cc index 827c5a8..4d915b0 100644 --- a/src/sourceoutputwidget.cc +++ b/src/sourceoutputwidget.cc @@ -49,6 +49,7 @@ SourceOutputWidget* SourceOutputWidget::create(MainWindow* mainWindow) { Glib::RefPtr x = Gtk::Builder::create_from_file(GLADE_FILE, "streamWidget"); x->get_widget_derived("streamWidget", w); w->init(mainWindow); + w->reference(); return w; } diff --git a/src/sourcewidget.cc b/src/sourcewidget.cc index 5e4ecf0..fde5333 100644 --- a/src/sourcewidget.cc +++ b/src/sourcewidget.cc @@ -35,6 +35,7 @@ SourceWidget* SourceWidget::create(MainWindow* mainWindow) { Glib::RefPtr x = Gtk::Builder::create_from_file(GLADE_FILE, "deviceWidget"); x->get_widget_derived("deviceWidget", w); w->init(mainWindow, "source"); + w->reference(); return w; } diff --git a/src/streamwidget.cc b/src/streamwidget.cc index 94363ec..e602cce 100644 --- a/src/streamwidget.cc +++ b/src/streamwidget.cc @@ -77,6 +77,7 @@ void StreamWidget::setChannelMap(const pa_channel_map &m, bool can_decibel) { snprintf(text, sizeof(text), "%s", pa_channel_position_to_pretty_string(m.map[i])); cw->channelLabel->set_markup(text); channelsVBox->pack_start(*cw, false, false, 0); + cw->unreference(); } channelWidgets[m.channels-1]->last = true; channelWidgets[m.channels-1]->setBaseVolume(PA_VOLUME_NORM); From tanuk at kemper.freedesktop.org Sun Sep 7 03:59:21 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Sun, 7 Sep 2014 03:59:21 -0700 (PDT) Subject: [pulseaudio-commits] src/pavucontrol.glade Message-ID: <20140907105921.13D0A761EF@kemper.freedesktop.org> src/pavucontrol.glade | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) New commits: commit e83660bbd66a0612f6e7097522812e16062dc1b2 Author: Hans de Goede Date: Fri Aug 29 09:42:04 2014 +0200 Do not instantiate cardwidget, devicewidget and rolewidget with a type of EventBox RoleWidget::create contains: x->get_widget_derived("streamWidget", w); But streamWidget is defined as following in the glade file: Where as RoleWidget is derived from [Minimal]StreamWidget, which is derived from Gtk::VBox, so this is clearly wrong. Adding: printf("rolewidget type: %s\n", g_type_name(G_TYPE_FROM_INSTANCE(w->gobj()))); for debugging shows that this really leads to RoleWidget being instantiated as an EventBox (yet things still work due to sheer luck). This commit fixes this, by putting the streamWidget id at the right level of the hierarchy in the glade file (and likewise for cardWidget and deviceWidget). Signed-off-by: Hans de Goede diff --git a/src/pavucontrol.glade b/src/pavucontrol.glade index 5116632..219f5a2 100644 --- a/src/pavucontrol.glade +++ b/src/pavucontrol.glade @@ -12,12 +12,12 @@ False window1 - + True False False - + True False @@ -202,12 +202,12 @@ False window1 - + True False False - + True False @@ -1331,12 +1331,12 @@ False window1 - + True False False - + True False From tanuk at kemper.freedesktop.org Mon Sep 8 01:26:48 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Mon, 8 Sep 2014 01:26:48 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140908082648.5F3FC761DF@kemper.freedesktop.org> src/modules/alsa/mixer/paths/analog-output-headphones.conf | 1 + src/modules/alsa/mixer/paths/analog-output-lineout.conf | 1 + 2 files changed, 2 insertions(+) New commits: commit 610704d225675d1d112cf1973bde9edb420ec37e Author: Tanu Kaskinen Date: Sun Sep 7 15:20:18 2014 +0300 alsa-mixer: Mark "Line HP Swap" as required-any In the (theoretical) case that no other elements exists but "Line HP Swap", the presence of that element signals that there are headphone and line-out outputs, otherwise there would be nothing to swap. diff --git a/src/modules/alsa/mixer/paths/analog-output-headphones.conf b/src/modules/alsa/mixer/paths/analog-output-headphones.conf index 89d794f..5222c23 100644 --- a/src/modules/alsa/mixer/paths/analog-output-headphones.conf +++ b/src/modules/alsa/mixer/paths/analog-output-headphones.conf @@ -77,6 +77,7 @@ override-map.2 = all-left,all-right [Element Line HP Swap] switch = on +required-any = any ; This profile path is intended to control the first headphones, not ; the second headphones. But it should not hurt if we leave the second diff --git a/src/modules/alsa/mixer/paths/analog-output-lineout.conf b/src/modules/alsa/mixer/paths/analog-output-lineout.conf index d5e24b1..40af699 100644 --- a/src/modules/alsa/mixer/paths/analog-output-lineout.conf +++ b/src/modules/alsa/mixer/paths/analog-output-lineout.conf @@ -82,6 +82,7 @@ volume = off [Element Line HP Swap] switch = off +required-any = any ; This profile path is intended to control the default output, not the ; headphones. But it should not hurt if we leave the headphone jack From tanuk at kemper.freedesktop.org Mon Sep 8 03:02:07 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Mon, 8 Sep 2014 03:02:07 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140908100207.8CB3F761DF@kemper.freedesktop.org> src/modules/bluetooth/bluez5-util.c | 14 ++++++++------ src/modules/bluetooth/bluez5-util.h | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) New commits: commit 4e041f7b36bb614705e3487b3a415ccb7a97407c Author: Luiz Augusto von Dentz Date: Mon Sep 8 12:14:42 2014 +0300 bluetooth: Add pa_bluetooth_transport_set_state diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 93677b4..01e1ce3 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -167,7 +167,7 @@ static const char *transport_state_to_string(pa_bluetooth_transport_state_t stat return "invalid"; } -static void transport_state_changed(pa_bluetooth_transport *t, pa_bluetooth_transport_state_t state) { +void pa_bluetooth_transport_set_state(pa_bluetooth_transport *t, pa_bluetooth_transport_state_t state) { bool old_any_connected; pa_assert(t); @@ -183,6 +183,8 @@ static void transport_state_changed(pa_bluetooth_transport *t, pa_bluetooth_tran t->state = state; if (state == PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED) t->device->transports[t->profile] = NULL; + else + t->device->transports[t->profile] = t; pa_hook_fire(&t->device->discovery->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t); @@ -191,7 +193,7 @@ static void transport_state_changed(pa_bluetooth_transport *t, pa_bluetooth_tran } void pa_bluetooth_transport_put(pa_bluetooth_transport *t) { - transport_state_changed(t, PA_BLUETOOTH_TRANSPORT_STATE_IDLE); + pa_bluetooth_transport_set_state(t, PA_BLUETOOTH_TRANSPORT_STATE_IDLE); } void pa_bluetooth_transport_free(pa_bluetooth_transport *t) { @@ -328,7 +330,7 @@ static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter return; } - transport_state_changed(t, state); + pa_bluetooth_transport_set_state(t, state); } break; @@ -412,7 +414,7 @@ static void device_free(pa_bluetooth_device *d) { if (!(t = d->transports[i])) continue; - transport_state_changed(t, PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED); + pa_bluetooth_transport_set_state(t, PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED); pa_bluetooth_transport_free(t); } @@ -1270,7 +1272,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), r, NULL)); dbus_message_unref(r); - d->transports[p] = t = pa_bluetooth_transport_new(d, sender, path, p, config, size); + t = pa_bluetooth_transport_new(d, sender, path, p, config, size); t->acquire = bluez5_transport_acquire_cb; t->release = bluez5_transport_release_cb; pa_bluetooth_transport_put(t); @@ -1433,7 +1435,7 @@ static DBusMessage *endpoint_clear_configuration(DBusConnection *conn, DBusMessa if ((t = pa_hashmap_get(y->transports, path))) { pa_log_debug("Clearing transport %s profile %s", t->path, pa_bluetooth_profile_to_string(t->profile)); - transport_state_changed(t, PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED); + pa_bluetooth_transport_set_state(t, PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED); pa_bluetooth_transport_free(t); } diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index 67377e9..5bcab16 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -112,6 +112,7 @@ void pa_bluetooth_backend_free(pa_bluetooth_backend *b); pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path, pa_bluetooth_profile_t p, const uint8_t *config, size_t size); +void pa_bluetooth_transport_set_state(pa_bluetooth_transport *t, pa_bluetooth_transport_state_t state); void pa_bluetooth_transport_put(pa_bluetooth_transport *t); void pa_bluetooth_transport_free(pa_bluetooth_transport *t); From tanuk at kemper.freedesktop.org Mon Sep 8 03:22:37 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Mon, 8 Sep 2014 03:22:37 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140908102237.B2C0F761DF@kemper.freedesktop.org> src/modules/bluetooth/bluez5-util.c | 4 ++++ src/modules/bluetooth/bluez5-util.h | 1 + 2 files changed, 5 insertions(+) New commits: commit 19180345fa583c7a8d237e3726d8e66755db8d4e Author: Luiz Augusto von Dentz Date: Mon Sep 8 12:14:43 2014 +0300 bluetooth: Add pa_bluetooth_transport_unlink diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 01e1ce3..efe87d3 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -196,6 +196,10 @@ void pa_bluetooth_transport_put(pa_bluetooth_transport *t) { pa_bluetooth_transport_set_state(t, PA_BLUETOOTH_TRANSPORT_STATE_IDLE); } +void pa_bluetooth_transport_unlink(pa_bluetooth_transport *t) { + pa_bluetooth_transport_set_state(t, PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED); +} + void pa_bluetooth_transport_free(pa_bluetooth_transport *t) { pa_assert(t); diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index 5bcab16..d41bf28 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -114,6 +114,7 @@ pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const void pa_bluetooth_transport_set_state(pa_bluetooth_transport *t, pa_bluetooth_transport_state_t state); void pa_bluetooth_transport_put(pa_bluetooth_transport *t); +void pa_bluetooth_transport_unlink(pa_bluetooth_transport *t); void pa_bluetooth_transport_free(pa_bluetooth_transport *t); bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d); From diwic at kemper.freedesktop.org Mon Sep 8 04:05:53 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Mon, 8 Sep 2014 04:05:53 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140908110553.32D3E761DF@kemper.freedesktop.org> src/modules/alsa/alsa-mixer.c | 61 +++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 9 deletions(-) New commits: commit b8656afe4ae470fa0207278b2205467f9ca1f01d Author: David Henningsson Date: Tue Sep 2 16:11:53 2014 +0200 alsa-mixer: Improve workaround for Valgrind's false warnings Valgrind is not correctly handling ALSA TLV syscalls, which leads to false warnings, looking like this: "Conditional jump or move depends on uninitialised value(s)" Unfortunately, alsa-lib itself also uses these values which valgrind falsely believe are uninitialized, so not all warnings are removed, but this is what we can do from PA until the valgrind bug is fixed. Signed-off-by: David Henningsson diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index ead601a..201f835 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -50,6 +50,58 @@ #include "alsa-mixer.h" #include "alsa-util.h" +#ifdef HAVE_VALGRIND_MEMCHECK_H +/* These macros are workarounds for a bug in valgrind, which is not handling the + * ALSA TLV syscalls correctly. See + * http://valgrind.10908.n7.nabble.com/Missing-ioctl-for-SNDRV-CTL-IOCTL-TLV-READ-td42711.html */ + +static inline int vgfix_get_capture_dB(snd_mixer_elem_t *a, snd_mixer_selem_channel_id_t b, long *c) { + int r = snd_mixer_selem_get_capture_dB(a, b, c); + VALGRIND_MAKE_MEM_DEFINED(c, sizeof(*c)); + return r; +} + +static inline int vgfix_get_playback_dB(snd_mixer_elem_t *a, snd_mixer_selem_channel_id_t b, long *c) { + int r = snd_mixer_selem_get_playback_dB(a, b, c); + VALGRIND_MAKE_MEM_DEFINED(c, sizeof(*c)); + return r; +} + +static inline int vgfix_ask_capture_vol_dB(snd_mixer_elem_t *a, long b, long *c) { + int r = snd_mixer_selem_ask_capture_vol_dB(a, b, c); + VALGRIND_MAKE_MEM_DEFINED(c, sizeof(*c)); + return r; +} + +static inline int vgfix_ask_playback_vol_dB(snd_mixer_elem_t *a, long b, long *c) { + int r = snd_mixer_selem_ask_playback_vol_dB(a, b, c); + VALGRIND_MAKE_MEM_DEFINED(c, sizeof(*c)); + return r; +} + +static inline int vgfix_get_capture_dB_range(snd_mixer_elem_t *a, long *b, long *c) { + int r = snd_mixer_selem_get_capture_dB_range(a, b, c); + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(*b)); + VALGRIND_MAKE_MEM_DEFINED(c, sizeof(*c)); + return r; +} + +static inline int vgfix_get_playback_dB_range(snd_mixer_elem_t *a, long *b, long *c) { + int r = snd_mixer_selem_get_playback_dB_range(a, b, c); + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(*b)); + VALGRIND_MAKE_MEM_DEFINED(c, sizeof(*c)); + return r; +} + +#define snd_mixer_selem_get_capture_dB(a, b, c) vgfix_get_capture_dB(a, b, c) +#define snd_mixer_selem_get_playback_dB(a, b, c) vgfix_get_playback_dB(a, b, c) +#define snd_mixer_selem_ask_capture_vol_dB(a, b, c) vgfix_ask_capture_vol_dB(a, b, c) +#define snd_mixer_selem_ask_playback_vol_dB(a, b, c) vgfix_ask_playback_vol_dB(a, b, c) +#define snd_mixer_selem_get_capture_dB_range(a, b, c) vgfix_get_capture_dB_range(a, b, c) +#define snd_mixer_selem_get_playback_dB_range(a, b, c) vgfix_get_playback_dB_range(a, b, c) + +#endif + static int setting_select(pa_alsa_setting *s, snd_mixer_t *m); struct description_map { @@ -1001,10 +1053,6 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann if (r < 0) continue; -#ifdef HAVE_VALGRIND_MEMCHECK_H - VALGRIND_MAKE_MEM_DEFINED(&value, sizeof(value)); -#endif - f = from_alsa_dB(value); } else { @@ -1517,11 +1565,6 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) { } if (e->has_dB) { -#ifdef HAVE_VALGRIND_MEMCHECK_H - VALGRIND_MAKE_MEM_DEFINED(&min_dB, sizeof(min_dB)); - VALGRIND_MAKE_MEM_DEFINED(&max_dB, sizeof(max_dB)); -#endif - e->min_dB = ((double) min_dB) / 100.0; e->max_dB = ((double) max_dB) / 100.0; From diwic at kemper.freedesktop.org Mon Sep 8 04:51:20 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Mon, 8 Sep 2014 04:51:20 -0700 (PDT) Subject: [pulseaudio-commits] src/pulsecore Message-ID: <20140908115120.9FA54761DF@kemper.freedesktop.org> src/pulsecore/core-util.c | 8 ++++++++ 1 file changed, 8 insertions(+) New commits: commit 076601ee28a442868ba4ab92a6f379190f6fa0ab Author: David Henningsson Date: Tue Nov 12 07:52:48 2013 +0100 core-util: Fail if XDG_RUNTIME_DIR belongs to someone else Usually, PA will use the PULSE_SERVER X11 property instead of using XDG_RUNTIME_DIR, so this environment variable does not matter. If this property is not available, or if one is using the pacmd cli protocol, the client will go ahead and call pa_make_secure_dir on XDG_RUNTIME_DIR/pulse. This will either fail (if you're another regular user), or succeed (if you're root). Both scenarios are bad - failing will cause the connection to fail, and succeeding is even worse, as it can cause *other* connections to fail (as the directory ownership has changed). Instead fail and complain loudly. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=83007 Signed-off-by: David Henningsson diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index d7a95d6..6b7cd35 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -1816,6 +1816,14 @@ char *pa_get_runtime_dir(void) { /* Use the XDG standard for the runtime directory. */ d = getenv("XDG_RUNTIME_DIR"); if (d) { + struct stat st; + if (stat(d, &st) == 0 && st.st_uid != getuid()) { + pa_log(_("XDG_RUNTIME_DIR (%s) is not owned by us (uid %d), but by uid %d! " + "(This could e g happen if you try to connect to a non-root PulseAudio as a root user, over the native protocol. Don't do that.)"), + d, getuid(), st.st_uid); + goto fail; + } + k = pa_sprintf_malloc("%s" PA_PATH_SEP "pulse", d); if (pa_make_secure_dir(k, m, (uid_t) -1, (gid_t) -1, true) < 0) { From diwic at kemper.freedesktop.org Wed Sep 10 01:00:09 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Wed, 10 Sep 2014 01:00:09 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140910080009.38EC276255@kemper.freedesktop.org> src/modules/alsa/mixer/paths/analog-output-headphones.conf | 8 ++++++++ src/modules/alsa/mixer/paths/analog-output-speaker.conf | 4 ++++ 2 files changed, 12 insertions(+) New commits: commit 594da41d07edcebc5fd319388852a66cc3f12ace Author: Sjoerd Simons Date: Sun Aug 31 20:11:21 2014 +0200 alsa-mixer: recognize Dock headphone jack Recognize the Dock headphone jack in the same way the normal & front headphone jacks are detected. Reviewed-by: David Henningsson diff --git a/src/modules/alsa/mixer/paths/analog-output-headphones.conf b/src/modules/alsa/mixer/paths/analog-output-headphones.conf index 5222c23..a41d41f 100644 --- a/src/modules/alsa/mixer/paths/analog-output-headphones.conf +++ b/src/modules/alsa/mixer/paths/analog-output-headphones.conf @@ -25,6 +25,14 @@ description-key = analog-output-headphones [Properties] device.icon_name = audio-headphones +[Jack Dock Headphone] +required-any = any + +[Jack Dock Headphone Phantom] +required-any = any +state.plugged = unknown +state.unplugged = unknown + [Jack Front Headphone] required-any = any diff --git a/src/modules/alsa/mixer/paths/analog-output-speaker.conf b/src/modules/alsa/mixer/paths/analog-output-speaker.conf index d79fad1..f708e61 100644 --- a/src/modules/alsa/mixer/paths/analog-output-speaker.conf +++ b/src/modules/alsa/mixer/paths/analog-output-speaker.conf @@ -29,6 +29,10 @@ device.icon_name = audio-speakers state.plugged = no state.unplugged = unknown +[Jack Dock Headphone] +state.plugged = no +state.unplugged = unknown + [Jack Front Headphone] state.plugged = no state.unplugged = unknown From diwic at kemper.freedesktop.org Wed Sep 10 01:46:14 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Wed, 10 Sep 2014 01:46:14 -0700 (PDT) Subject: [pulseaudio-commits] src/map-file src/pulse src/pulsecore Message-ID: <20140910084614.3B8C776255@kemper.freedesktop.org> src/map-file | 1 + src/pulse/stream.c | 18 +++++++++++++++--- src/pulse/stream.h | 11 +++++++++++ src/pulsecore/memblock.c | 14 ++++++++++++-- src/pulsecore/memblock.h | 4 ++-- 5 files changed, 41 insertions(+), 7 deletions(-) New commits: commit 78ca8cfc966d7ea56cab43ee1ef40cafd1fa30b5 Author: Lukasz Marek Date: Tue Apr 15 02:08:23 2014 +0200 Client API: Add pa_stream_write_ext_free() function. New function allows to pass data pointer that is a member of the outer structure that need to be freed too when data is not needed anymore. Signed-off-by: Lukasz Marek diff --git a/src/map-file b/src/map-file index dc36fdc..5159829 100644 --- a/src/map-file +++ b/src/map-file @@ -330,6 +330,7 @@ pa_stream_update_sample_rate; pa_stream_update_timing_info; pa_stream_writable_size; pa_stream_write; +pa_stream_write_ext_free; pa_strerror; pa_sw_cvolume_divide; pa_sw_cvolume_divide_scalar; diff --git a/src/pulse/stream.c b/src/pulse/stream.c index 8e35c29..3c04c42 100644 --- a/src/pulse/stream.c +++ b/src/pulse/stream.c @@ -1464,11 +1464,12 @@ int pa_stream_cancel_write( return 0; } -int pa_stream_write( +int pa_stream_write_ext_free( pa_stream *s, const void *data, size_t length, pa_free_cb_t free_cb, + void *free_cb_data, int64_t offset, pa_seek_mode_t seek) { @@ -1519,7 +1520,7 @@ int pa_stream_write( chunk.index = 0; if (free_cb && !pa_pstream_get_shm(s->context->pstream)) { - chunk.memblock = pa_memblock_new_user(s->context->mempool, (void*) t_data, t_length, free_cb, 1); + chunk.memblock = pa_memblock_new_user(s->context->mempool, (void*) t_data, t_length, free_cb, free_cb_data, 1); chunk.length = t_length; } else { void *d; @@ -1544,7 +1545,7 @@ int pa_stream_write( } if (free_cb && pa_pstream_get_shm(s->context->pstream)) - free_cb((void*) data); + free_cb(free_cb_data); } /* This is obviously wrong since we ignore the seeking index . But @@ -1591,6 +1592,17 @@ int pa_stream_write( return 0; } +int pa_stream_write( + pa_stream *s, + const void *data, + size_t length, + pa_free_cb_t free_cb, + int64_t offset, + pa_seek_mode_t seek) { + + return pa_stream_write_ext_free(s, data, length, free_cb, (void*) data, offset, seek); +} + int pa_stream_peek(pa_stream *s, const void **data, size_t *length) { pa_assert(s); pa_assert(PA_REFCNT_VALUE(s) >= 1); diff --git a/src/pulse/stream.h b/src/pulse/stream.h index 7ceb569..bc17143 100644 --- a/src/pulse/stream.h +++ b/src/pulse/stream.h @@ -554,6 +554,17 @@ int pa_stream_write( int64_t offset, /**< Offset for seeking, must be 0 for upload streams */ pa_seek_mode_t seek /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */); +/** Function does exactly the same as pa_stream_write() with the difference + * that free_cb_data is passed to free_cb instead of data. \since 6.0 */ +int pa_stream_write_ext_free( + pa_stream *p /**< The stream to use */, + const void *data /**< The data to write */, + size_t nbytes /**< The length of the data to write in bytes */, + pa_free_cb_t free_cb /**< A cleanup routine for the data or NULL to request an internal copy */, + void *free_cb_data /**< Argument passed to free_cb function */, + int64_t offset /**< Offset for seeking, must be 0 for upload streams */, + pa_seek_mode_t seek /**< Seek mode, must be PA_SEEK_RELATIVE for upload streams */); + /** Read the next fragment from the buffer (for recording streams). * If there is data at the current read index, \a data will point to * the actual data and \a nbytes will contain the size of the data in diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c index 5ef2aa9..f57b106 100644 --- a/src/pulsecore/memblock.c +++ b/src/pulsecore/memblock.c @@ -83,6 +83,8 @@ struct pa_memblock { struct { /* If type == PA_MEMBLOCK_USER this points to a function for freeing this memory block */ pa_free_cb_t free_cb; + /* If type == PA_MEMBLOCK_USER this is passed as free_cb argument */ + void *free_cb_data; } user; struct { @@ -402,7 +404,13 @@ pa_memblock *pa_memblock_new_fixed(pa_mempool *p, void *d, size_t length, bool r } /* No lock necessary */ -pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, pa_free_cb_t free_cb, bool read_only) { +pa_memblock *pa_memblock_new_user( + pa_mempool *p, + void *d, + size_t length, + pa_free_cb_t free_cb, + void *free_cb_data, + bool read_only) { pa_memblock *b; pa_assert(p); @@ -425,6 +433,7 @@ pa_memblock *pa_memblock_new_user(pa_mempool *p, void *d, size_t length, pa_free pa_atomic_store(&b->please_signal, 0); b->per_type.user.free_cb = free_cb; + b->per_type.user.free_cb_data = free_cb_data; stat_add(b); return b; @@ -536,7 +545,7 @@ static void memblock_free(pa_memblock *b) { switch (b->type) { case PA_MEMBLOCK_USER : pa_assert(b->per_type.user.free_cb); - b->per_type.user.free_cb(pa_atomic_ptr_load(&b->data)); + b->per_type.user.free_cb(b->per_type.user.free_cb_data); /* Fall through */ @@ -670,6 +679,7 @@ static void memblock_make_local(pa_memblock *b) { /* Humm, not enough space in the pool, so lets allocate the memory with malloc() */ b->per_type.user.free_cb = pa_xfree; pa_atomic_ptr_store(&b->data, pa_xmemdup(pa_atomic_ptr_load(&b->data), b->length)); + b->per_type.user.free_cb_data = pa_atomic_ptr_load(&b->data); b->type = PA_MEMBLOCK_USER; b->read_only = false; diff --git a/src/pulsecore/memblock.h b/src/pulsecore/memblock.h index d60f3c3..9ce88ca 100644 --- a/src/pulsecore/memblock.h +++ b/src/pulsecore/memblock.h @@ -85,10 +85,10 @@ pa_memblock *pa_memblock_new(pa_mempool *, size_t length); pa_memblock *pa_memblock_new_pool(pa_mempool *, size_t length); /* Allocate a new memory block of type PA_MEMBLOCK_USER */ -pa_memblock *pa_memblock_new_user(pa_mempool *, void *data, size_t length, pa_free_cb_t free_cb, bool read_only); +pa_memblock *pa_memblock_new_user(pa_mempool *, void *data, size_t length, pa_free_cb_t free_cb, void *free_cb_data, bool read_only); /* A special case of pa_memblock_new_user: take a memory buffer previously allocated with pa_xmalloc() */ -#define pa_memblock_new_malloced(p,data,length) pa_memblock_new_user(p, data, length, pa_xfree, 0) +#define pa_memblock_new_malloced(p,data,length) pa_memblock_new_user(p, data, length, pa_xfree, data, 0) /* Allocate a new memory block of type PA_MEMBLOCK_FIXED */ pa_memblock *pa_memblock_new_fixed(pa_mempool *, void *data, size_t length, bool read_only); From diwic at kemper.freedesktop.org Wed Sep 10 02:29:01 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Wed, 10 Sep 2014 02:29:01 -0700 (PDT) Subject: [pulseaudio-commits] 2 commits - configure.ac Message-ID: <20140910092901.BFD3476255@kemper.freedesktop.org> configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) New commits: commit fcfaa77fe77a2e97d7ae56d0ee6bbb26201d87d7 Author: David Henningsson Date: Wed Sep 10 11:28:45 2014 +0200 configure: Fix spelling of "backend" Signed-off-by: David Henningsson diff --git a/configure.ac b/configure.ac index e1e2572..f13ddb0 100644 --- a/configure.ac +++ b/configure.ac @@ -1511,7 +1511,7 @@ echo " Enable D-Bus: ${ENABLE_DBUS} Enable BlueZ 4: ${ENABLE_BLUEZ_4} Enable BlueZ 5: ${ENABLE_BLUEZ_5} - headset backed: ${BLUETOOTH_HEADSET_BACKEND} + headset backend: ${BLUETOOTH_HEADSET_BACKEND} Enable udev: ${ENABLE_UDEV} Enable HAL->udev compat: ${ENABLE_HAL_COMPAT} Enable systemd login: ${ENABLE_SYSTEMD} commit f782155da5404b336facf02cb3ad6da9a873db54 Author: Wim Taymans Date: Mon Sep 8 11:15:55 2014 +0200 configure: fix headset check diff --git a/configure.ac b/configure.ac index 7b56210..e1e2572 100644 --- a/configure.ac +++ b/configure.ac @@ -1037,7 +1037,7 @@ else BLUETOOTH_HEADSET_BACKEND=$with_bluetooth_headset_backend fi -AS_IF([test "x$BLUETOOTH_HEADSET_BACKEND" != "xofono && "test "x$BLUETOOTH_HEADSET_BACKEND" != "xnull"], +AS_IF([test "x$BLUETOOTH_HEADSET_BACKEND" != "xofono" && test "x$BLUETOOTH_HEADSET_BACKEND" != "xnull"], [AC_MSG_ERROR([*** Invalid Bluetooth Headset backend])]) AC_SUBST(BLUETOOTH_HEADSET_BACKEND) From tanuk at kemper.freedesktop.org Wed Sep 10 03:27:21 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Wed, 10 Sep 2014 03:27:21 -0700 (PDT) Subject: [pulseaudio-commits] 2 commits - src/modules Message-ID: <20140910102721.36DA076255@kemper.freedesktop.org> src/modules/bluetooth/backend-null.c | 2 +- src/modules/bluetooth/backend-ofono.c | 4 +++- src/modules/bluetooth/bluez5-util.c | 8 +++++++- src/modules/bluetooth/bluez5-util.h | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) New commits: commit f508b34b8bec101b20e454e6852e57eb9dec5a0c Author: Luiz Augusto von Dentz Date: Wed Sep 10 11:48:23 2014 +0200 bluetooth: Add discovery to pa_bluetooth_backend_new diff --git a/src/modules/bluetooth/backend-null.c b/src/modules/bluetooth/backend-null.c index f8a145b..6e621a7 100644 --- a/src/modules/bluetooth/backend-null.c +++ b/src/modules/bluetooth/backend-null.c @@ -27,7 +27,7 @@ #include "bluez5-util.h" -pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c) { +pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discovery *y) { pa_log_debug("Bluetooth Headset Backend API support disabled"); return NULL; } diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index bf0db47..99ff09d 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -54,6 +54,7 @@ struct pa_bluetooth_backend { pa_core *core; + pa_bluetooth_discovery *discovery; pa_dbus_connection *connection; }; @@ -104,7 +105,7 @@ static DBusHandlerResult hf_audio_agent_handler(DBusConnection *c, DBusMessage * return DBUS_HANDLER_RESULT_HANDLED; } -pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c) { +pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discovery *y) { pa_bluetooth_backend *backend; DBusError err; static const DBusObjectPathVTable vtable_hf_audio_agent = { @@ -115,6 +116,7 @@ pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c) { backend = pa_xnew0(pa_bluetooth_backend, 1); backend->core = c; + backend->discovery = y; dbus_error_init(&err); diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 97862d5..8bb57f4 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -896,7 +896,7 @@ static void get_managed_objects_reply(DBusPendingCall *pending, void *userdata) y->objects_listed = true; if (!y->backend) - y->backend = pa_bluetooth_backend_new(y->core); + y->backend = pa_bluetooth_backend_new(y->core, y); finish: dbus_message_unref(r); diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index d41bf28..8db4a17 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -106,7 +106,7 @@ struct pa_bluetooth_adapter { bool valid; }; -pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c); +pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discovery *y); void pa_bluetooth_backend_free(pa_bluetooth_backend *b); pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path, commit 5c2ed8abedd55141101829c4b2069ad5aa5498f4 Author: Luiz Augusto von Dentz Date: Mon Sep 8 13:35:33 2014 +0300 bluetooth: Only create backend instance once objects are listed This makes sure the devices are discovered before the backend start creating new transports. diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index efe87d3..97862d5 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -895,6 +895,9 @@ static void get_managed_objects_reply(DBusPendingCall *pending, void *userdata) y->objects_listed = true; + if (!y->backend) + y->backend = pa_bluetooth_backend_new(y->core); + finish: dbus_message_unref(r); @@ -947,6 +950,10 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us pa_hashmap_remove_all(y->devices); pa_hashmap_remove_all(y->adapters); y->objects_listed = false; + if (y->backend) { + pa_bluetooth_backend_free(y->backend); + y->backend = NULL; + } } if (new_owner && *new_owner) { @@ -1597,7 +1604,6 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { endpoint_init(y, PA_BLUETOOTH_PROFILE_A2DP_SINK); endpoint_init(y, PA_BLUETOOTH_PROFILE_A2DP_SOURCE); - y->backend = pa_bluetooth_backend_new(c); get_managed_objects(y); From pmeerw at kemper.freedesktop.org Wed Sep 10 10:40:07 2014 From: pmeerw at kemper.freedesktop.org (Peter Meerwald) Date: Wed, 10 Sep 2014 10:40:07 -0700 (PDT) Subject: [pulseaudio-commits] 14 commits - src/.gitignore src/Makefile.am src/daemon src/pulsecore src/tests Message-ID: <20140910174007.3B1CA76254@kemper.freedesktop.org> src/.gitignore | 6 src/Makefile.am | 38 + src/daemon/main.c | 13 src/pulsecore/cpu.c | 38 + src/pulsecore/cpu.h | 6 src/pulsecore/mix.c | 8 src/pulsecore/remap.c | 14 src/tests/cpu-mix-test.c | 226 +++++++++++ src/tests/cpu-remap-test.c | 436 +++++++++++++++++++++ src/tests/cpu-sconv-test.c | 265 ++++++++++++ src/tests/cpu-test.c | 877 ------------------------------------------- src/tests/cpu-volume-test.c | 249 ++++++++++++ src/tests/mix-special-test.c | 326 --------------- 13 files changed, 1273 insertions(+), 1229 deletions(-) New commits: commit eed6d95f490d9efd5d593074ed67e61c5426f59b Author: Peter Meerwald Date: Wed Apr 23 17:47:26 2014 +0200 tests: Remove mix-special-test code has been moved to cpu-mix-test Signed-off-by: Peter Meerwald diff --git a/src/.gitignore b/src/.gitignore index a90c7dc..5ca8013 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -55,7 +55,6 @@ mainloop-test-glib mcalign-test memblockq-test memblock-test -mix-special-test mix-test once-test pacat-simple diff --git a/src/Makefile.am b/src/Makefile.am index 2ff4967..8d49af3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -249,8 +249,7 @@ TESTS_default = \ cpu-sconv-test \ cpu-volume-test \ lock-autospawn-test \ - mult-s16-test \ - mix-special-test + mult-s16-test TESTS_norun = \ ipacl-test \ @@ -538,11 +537,6 @@ mult_s16_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la li mult_s16_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) mult_s16_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) -mix_special_test_SOURCES = tests/mix-special-test.c tests/runtime-test-util.h -mix_special_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la libpulsecommon- at PA_MAJORMINOR@.la -mix_special_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) -mix_special_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) - rtstutter_SOURCES = tests/rtstutter.c rtstutter_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la libpulsecommon- at PA_MAJORMINOR@.la rtstutter_CFLAGS = $(AM_CFLAGS) diff --git a/src/tests/mix-special-test.c b/src/tests/mix-special-test.c deleted file mode 100644 index 08ac812..0000000 --- a/src/tests/mix-special-test.c +++ /dev/null @@ -1,326 +0,0 @@ -/*** - This file is part of PulseAudio. - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "runtime-test-util.h" - -static void acquire_mix_streams(pa_mix_info streams[], unsigned nstreams) { - unsigned i; - - for (i = 0; i < nstreams; i++) - streams[i].ptr = pa_memblock_acquire_chunk(&streams[i].chunk); -} - -static void release_mix_streams(pa_mix_info streams[], unsigned nstreams) { - unsigned i; - - for (i = 0; i < nstreams; i++) - pa_memblock_release(streams[i].chunk.memblock); -} - -/* special case: mix 2 s16ne streams, 1 channel each */ -static void pa_mix2_ch1_s16ne(pa_mix_info streams[], int16_t *data, unsigned length) { - const int16_t *ptr0 = streams[0].ptr; - const int16_t *ptr1 = streams[1].ptr; - - const int32_t cv0 = streams[0].linear[0].i; - const int32_t cv1 = streams[1].linear[0].i; - - length /= sizeof(int16_t); - - for (; length > 0; length--) { - int32_t sum; - - sum = pa_mult_s16_volume(*ptr0++, cv0); - sum += pa_mult_s16_volume(*ptr1++, cv1); - - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); - *data++ = sum; - } -} - -/* special case: mix 2 s16ne streams, 2 channels each */ -static void pa_mix2_ch2_s16ne(pa_mix_info streams[], int16_t *data, unsigned length) { - const int16_t *ptr0 = streams[0].ptr; - const int16_t *ptr1 = streams[1].ptr; - - length /= sizeof(int16_t) * 2; - - for (; length > 0; length--) { - int32_t sum; - - sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[0].i); - sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[0].i); - - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); - *data++ = sum; - - sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[1].i); - sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[1].i); - - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); - *data++ = sum; - } -} - -/* special case: mix 2 s16ne streams */ -static void pa_mix2_s16ne(pa_mix_info streams[], unsigned channels, int16_t *data, unsigned length) { - const int16_t *ptr0 = streams[0].ptr; - const int16_t *ptr1 = streams[1].ptr; - unsigned channel = 0; - - length /= sizeof(int16_t); - - for (; length > 0; length--) { - int32_t sum; - - sum = pa_mult_s16_volume(*ptr0++, streams[0].linear[channel].i); - sum += pa_mult_s16_volume(*ptr1++, streams[1].linear[channel].i); - - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); - *data++ = sum; - - if (PA_UNLIKELY(++channel >= channels)) - channel = 0; - } -} - -/* special case: mix s16ne streams, 2 channels each */ -static void pa_mix_ch2_s16ne(pa_mix_info streams[], unsigned nstreams, int16_t *data, unsigned length) { - - length /= sizeof(int16_t) * 2; - - for (; length > 0; length--) { - int32_t sum0 = 0, sum1 = 0; - unsigned i; - - for (i = 0; i < nstreams; i++) { - pa_mix_info *m = streams + i; - int32_t cv0 = m->linear[0].i; - int32_t cv1 = m->linear[1].i; - - sum0 += pa_mult_s16_volume(*((int16_t*) m->ptr), cv0); - m->ptr = (uint8_t*) m->ptr + sizeof(int16_t); - - sum1 += pa_mult_s16_volume(*((int16_t*) m->ptr), cv1); - m->ptr = (uint8_t*) m->ptr + sizeof(int16_t); - } - - *data++ = PA_CLAMP_UNLIKELY(sum0, -0x8000, 0x7FFF); - *data++ = PA_CLAMP_UNLIKELY(sum1, -0x8000, 0x7FFF); - } -} - -static void pa_mix_generic_s16ne(pa_mix_info streams[], unsigned nstreams, unsigned channels, int16_t *data, unsigned length) { - unsigned channel = 0; - - length /= sizeof(int16_t); - - for (; length > 0; length--) { - int32_t sum = 0; - unsigned i; - - for (i = 0; i < nstreams; i++) { - pa_mix_info *m = streams + i; - int32_t cv = m->linear[channel].i; - - if (PA_LIKELY(cv > 0)) - sum += pa_mult_s16_volume(*((int16_t*) m->ptr), cv); - m->ptr = (uint8_t*) m->ptr + sizeof(int16_t); - } - - sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF); - *data++ = sum; - - if (PA_UNLIKELY(++channel >= channels)) - channel = 0; - } -} - -#define SAMPLES 1028 -#define TIMES 1000 -#define TIMES2 100 - -START_TEST (mix_special_1ch_test) { - int16_t samples0[SAMPLES]; - int16_t samples1[SAMPLES]; - int16_t out[SAMPLES]; - int16_t out_ref[SAMPLES]; - pa_mempool *pool; - pa_memchunk c0, c1; - pa_mix_info m[2]; - unsigned nsamples = SAMPLES; - - fail_unless((pool = pa_mempool_new(false, 0)) != NULL, NULL); - - pa_random(samples0, nsamples * sizeof(int16_t)); - c0.memblock = pa_memblock_new_fixed(pool, samples0, nsamples * sizeof(int16_t), false); - c0.length = pa_memblock_get_length(c0.memblock); - c0.index = 0; - - pa_random(samples1, nsamples * sizeof(int16_t)); - c1.memblock = pa_memblock_new_fixed(pool, samples1, nsamples * sizeof(int16_t), false); - c1.length = pa_memblock_get_length(c1.memblock); - c1.index = 0; - - m[0].chunk = c0; - m[0].volume.channels = 1; - m[0].volume.values[0] = PA_VOLUME_NORM; - m[0].linear[0].i = 0x5555; - - m[1].chunk = c1; - m[1].volume.channels = 1; - m[1].volume.values[0] = PA_VOLUME_NORM; - m[1].linear[0].i = 0x6789; - - PA_RUNTIME_TEST_RUN_START("mix s16 generic 1 channel", TIMES, TIMES2) { - acquire_mix_streams(m, 2); - pa_mix_generic_s16ne(m, 2, 1, out_ref, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - } PA_RUNTIME_TEST_RUN_STOP - - PA_RUNTIME_TEST_RUN_START("mix s16 2 streams 1 channel", TIMES, TIMES2) { - acquire_mix_streams(m, 2); - pa_mix2_ch1_s16ne(m, out, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - } PA_RUNTIME_TEST_RUN_STOP - - fail_unless(memcmp(out, out_ref, nsamples * sizeof(int16_t)) == 0); - - pa_memblock_unref(c0.memblock); - pa_memblock_unref(c1.memblock); - - pa_mempool_free(pool); -} -END_TEST - -START_TEST (mix_special_2ch_test) { - int16_t samples0[SAMPLES*2]; - int16_t samples1[SAMPLES*2]; - int16_t out[SAMPLES*2]; - int16_t out_ref[SAMPLES*2]; - int i; - pa_mempool *pool; - pa_memchunk c0, c1; - pa_mix_info m[2]; - unsigned nsamples = SAMPLES * 2; - - fail_unless((pool = pa_mempool_new(false, 0)) != NULL, NULL); - - pa_random(samples0, nsamples * sizeof(int16_t)); - c0.memblock = pa_memblock_new_fixed(pool, samples0, nsamples * sizeof(int16_t), false); - c0.length = pa_memblock_get_length(c0.memblock); - c0.index = 0; - - pa_random(samples1, nsamples * sizeof(int16_t)); - c1.memblock = pa_memblock_new_fixed(pool, samples1, nsamples * sizeof(int16_t), false); - c1.length = pa_memblock_get_length(c1.memblock); - c1.index = 0; - - m[0].chunk = c0; - m[0].volume.channels = 2; - for (i = 0; i < m[0].volume.channels; i++) { - m[0].volume.values[i] = PA_VOLUME_NORM; - m[0].linear[i].i = 0x5555; - } - - m[1].chunk = c1; - m[1].volume.channels = 2; - for (i = 0; i < m[1].volume.channels; i++) { - m[1].volume.values[i] = PA_VOLUME_NORM; - m[1].linear[i].i = 0x6789; - } - - PA_RUNTIME_TEST_RUN_START("mix s16 generic 2 channels", TIMES, TIMES2) { - acquire_mix_streams(m, 2); - pa_mix_generic_s16ne(m, 2, 2, out_ref, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - } PA_RUNTIME_TEST_RUN_STOP - - PA_RUNTIME_TEST_RUN_START("mix s16 2 channels", TIMES, TIMES2) { - acquire_mix_streams(m, 2); - pa_mix_ch2_s16ne(m, 2, out, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - } PA_RUNTIME_TEST_RUN_STOP - - fail_unless(memcmp(out, out_ref, nsamples * sizeof(int16_t)) == 0); - - PA_RUNTIME_TEST_RUN_START("mix s16 2 streams", TIMES, TIMES2) { - acquire_mix_streams(m, 2); - pa_mix2_s16ne(m, 2, out, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - } PA_RUNTIME_TEST_RUN_STOP - - fail_unless(memcmp(out, out_ref, nsamples * sizeof(int16_t)) == 0); - - PA_RUNTIME_TEST_RUN_START("mix s16 2 streams 2 channels", TIMES, TIMES2) { - acquire_mix_streams(m, 2); - pa_mix2_ch2_s16ne(m, out, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - } PA_RUNTIME_TEST_RUN_STOP - - fail_unless(memcmp(out, out_ref, nsamples * sizeof(int16_t)) == 0); - - pa_memblock_unref(c0.memblock); - pa_memblock_unref(c1.memblock); - - pa_mempool_free(pool); -} -END_TEST - -int main(int argc, char *argv[]) { - int failed = 0; - Suite *s; - TCase *tc; - SRunner *sr; - - if (!getenv("MAKE_CHECK")) - pa_log_set_level(PA_LOG_DEBUG); - - s = suite_create("Mix-special"); - tc = tcase_create("mix-special 1ch"); - tcase_add_test(tc, mix_special_1ch_test); - tcase_set_timeout(tc, 120); - suite_add_tcase(s, tc); - tc = tcase_create("mix-special 2ch"); - tcase_add_test(tc, mix_special_2ch_test); - tcase_set_timeout(tc, 120); - suite_add_tcase(s, tc); - - sr = srunner_create(s); - srunner_run_all(sr, CK_NORMAL); - failed = srunner_ntests_failed(sr); - srunner_free(sr); - - return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -} commit f8fe25e8df583e37401b5c324a693f360d801052 Author: Peter Meerwald Date: Wed Apr 23 23:48:17 2014 +0200 tests: Use float constants in cpu-sconv-test Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-sconv-test.c b/src/tests/cpu-sconv-test.c index 4e7848d..428ebe0 100644 --- a/src/tests/cpu-sconv-test.c +++ b/src/tests/cpu-sconv-test.c @@ -94,8 +94,8 @@ static void run_conv_test_s16_to_float( bool correct, bool perf) { - PA_DECLARE_ALIGNED(8, float, f[SAMPLES]) = { 0 }; - PA_DECLARE_ALIGNED(8, float, f_ref[SAMPLES]) = { 0 }; + PA_DECLARE_ALIGNED(8, float, f[SAMPLES]) = { 0.0f }; + PA_DECLARE_ALIGNED(8, float, f_ref[SAMPLES]) = { 0.0f }; PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]); float *floats, *floats_ref; int16_t *samples; @@ -114,7 +114,7 @@ static void run_conv_test_s16_to_float( func(nsamples, samples, floats); for (i = 0; i < nsamples; i++) { - if (fabsf(floats[i] - floats_ref[i]) > 0.0001) { + if (fabsf(floats[i] - floats_ref[i]) > 0.0001f) { pa_log_debug("Correctness test failed: align=%d", align); pa_log_debug("%d: %.24f != %.24f (%d)\n", i, floats[i], floats_ref[i], samples[i]); fail(); commit ce9318fb72a3f5a1fdb81287313fc8cd295ab11b Author: Peter Meerwald Date: Tue Apr 22 19:12:28 2014 +0200 tests: Add ARM NEON test code to cpu-remap-test Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-remap-test.c b/src/tests/cpu-remap-test.c index dccb571..4ee5e00 100644 --- a/src/tests/cpu-remap-test.c +++ b/src/tests/cpu-remap-test.c @@ -327,6 +327,75 @@ START_TEST (remap_sse2_test) { END_TEST #endif /* defined (__i386__) || defined (__amd64__) */ +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) +START_TEST (remap_neon_test) { + pa_cpu_arm_flag_t flags = 0; + pa_init_remap_func_t init_func, orig_init_func; + + pa_cpu_get_arm_flags(&flags); + if (!(flags & PA_CPU_ARM_NEON)) { + pa_log_info("NEON not supported. Skipping"); + return; + } + + orig_init_func = pa_get_init_remap_func(); + pa_remap_func_init_neon(flags); + init_func = pa_get_init_remap_func(); + + pa_log_debug("Checking NEON remap (float, mono->stereo)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false); + pa_log_debug("Checking NEON remap (float, mono->4-channel)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 4, false); + + pa_log_debug("Checking NEON remap (s16, mono->stereo)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false); + pa_log_debug("Checking NEON remap (s16, mono->4-channel)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 4, false); + + pa_log_debug("Checking NEON remap (float, stereo->mono)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2, 1, false); + pa_log_debug("Checking NEON remap (float, 4-channel->mono)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 1, false); + + pa_log_debug("Checking NEON remap (s16, stereo->mono)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2, 1, false); + pa_log_debug("Checking NEON remap (s16, 4-channel->mono)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 1, false); + + pa_log_debug("Checking NEON remap (float, 4-channel->4-channel)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 4, false); + pa_log_debug("Checking NEON remap (s16, 4-channel->4-channel)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 4, false); +} +END_TEST + +START_TEST (rearrange_neon_test) { + pa_cpu_arm_flag_t flags = 0; + pa_init_remap_func_t init_func, orig_init_func; + + pa_cpu_get_arm_flags(&flags); + if (!(flags & PA_CPU_ARM_NEON)) { + pa_log_info("NEON not supported. Skipping"); + return; + } + + orig_init_func = pa_get_init_remap_func(); + pa_remap_func_init_neon(flags); + init_func = pa_get_init_remap_func(); + + pa_log_debug("Checking NEON remap (float, stereo rearrange)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 2, 2, true); + pa_log_debug("Checking NEON remap (s16, stereo rearrange)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 2, 2, true); + + pa_log_debug("Checking NEON remap (float, 4-channel rearrange)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 4, 4, true); + pa_log_debug("Checking NEON remap (s16, 4-channel rearrange)"); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 4, 4, true); +} +END_TEST +#endif + int main(int argc, char *argv[]) { int failed = 0; Suite *s; @@ -344,11 +413,17 @@ int main(int argc, char *argv[]) { tcase_add_test(tc, remap_mmx_test); tcase_add_test(tc, remap_sse2_test); #endif +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) + tcase_add_test(tc, remap_neon_test); +#endif tcase_set_timeout(tc, 120); suite_add_tcase(s, tc); tc = tcase_create("rearrange"); tcase_add_test(tc, rearrange_special_test); +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) + tcase_add_test(tc, rearrange_neon_test); +#endif tcase_set_timeout(tc, 120); suite_add_tcase(s, tc); commit d8be5cbf8b16363b410d655956ccf6f57ff21529 Author: Peter Meerwald Date: Wed Apr 23 16:52:39 2014 +0200 tests: Add rearrange remapping test cases to cpu-remap-test Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-remap-test.c b/src/tests/cpu-remap-test.c index c0a6a64..dccb571 100644 --- a/src/tests/cpu-remap-test.c +++ b/src/tests/cpu-remap-test.c @@ -147,7 +147,8 @@ static void setup_remap_channels( pa_remap_t *m, pa_sample_format_t f, unsigned in_channels, - unsigned out_channels) { + unsigned out_channels, + bool rearrange) { unsigned i, o; @@ -155,10 +156,19 @@ static void setup_remap_channels( m->i_ss.channels = in_channels; m->o_ss.channels = out_channels; - for (o = 0; o < out_channels; o++) { - for (i = 0; i < in_channels; i++) { - m->map_table_f[o][i] = 1.0f / in_channels; - m->map_table_i[o][i] = 0x10000 / in_channels; + if (rearrange) { + for (o = 0; o < out_channels; o++) { + for (i = 0; i < in_channels; i++) { + m->map_table_f[o][i] = (o == i) ? 1.0f : 0.0f; + m->map_table_i[o][i] = (o == i) ? 0x10000 : 0; + } + } + } else { + for (o = 0; o < out_channels; o++) { + for (i = 0; i < in_channels; i++) { + m->map_table_f[o][i] = 1.0f / in_channels; + m->map_table_i[o][i] = 0x10000 / in_channels; + } } } } @@ -201,14 +211,15 @@ static void remap_init_test_channels( pa_init_remap_func_t orig_init_func, pa_sample_format_t f, unsigned in_channels, - unsigned out_channels) { + unsigned out_channels, + bool rearrange) { pa_remap_t remap_orig, remap_func; - setup_remap_channels(&remap_orig, f, in_channels, out_channels); + setup_remap_channels(&remap_orig, f, in_channels, out_channels, rearrange); orig_init_func(&remap_orig); - setup_remap_channels(&remap_func, f, in_channels, out_channels); + setup_remap_channels(&remap_func, f, in_channels, out_channels, rearrange); init_func(&remap_func); remap_test_channels(&remap_func, &remap_orig); @@ -217,19 +228,20 @@ static void remap_init_test_channels( static void remap_init2_test_channels( pa_sample_format_t f, unsigned in_channels, - unsigned out_channels) { + unsigned out_channels, + bool rearrange) { pa_cpu_info cpu_info = { PA_CPU_UNDEFINED, {}, false }; pa_remap_t remap_orig, remap_func; cpu_info.force_generic_code = true; pa_remap_func_init(&cpu_info); - setup_remap_channels(&remap_orig, f, in_channels, out_channels); + setup_remap_channels(&remap_orig, f, in_channels, out_channels, rearrange); pa_init_remap_func(&remap_orig); cpu_info.force_generic_code = false; pa_remap_func_init(&cpu_info); - setup_remap_channels(&remap_func, f, in_channels, out_channels); + setup_remap_channels(&remap_func, f, in_channels, out_channels, rearrange); pa_init_remap_func(&remap_func); remap_test_channels(&remap_func, &remap_orig); @@ -237,24 +249,37 @@ static void remap_init2_test_channels( START_TEST (remap_special_test) { pa_log_debug("Checking special remap (float, mono->stereo)"); - remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 2); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 2, false); pa_log_debug("Checking special remap (float, mono->4-channel)"); - remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 4); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 4, false); pa_log_debug("Checking special remap (s16, mono->stereo)"); - remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 2); + remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 2, false); pa_log_debug("Checking special remap (s16, mono->4-channel)"); - remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 4); + remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 4, false); pa_log_debug("Checking special remap (float, stereo->mono)"); - remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 2, 1); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 2, 1, false); pa_log_debug("Checking special remap (float, 4-channel->mono)"); - remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 4, 1); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 4, 1, false); pa_log_debug("Checking special remap (s16, stereo->mono)"); - remap_init2_test_channels(PA_SAMPLE_S16NE, 2, 1); + remap_init2_test_channels(PA_SAMPLE_S16NE, 2, 1, false); pa_log_debug("Checking special remap (s16, 4-channel->mono)"); - remap_init2_test_channels(PA_SAMPLE_S16NE, 4, 1); + remap_init2_test_channels(PA_SAMPLE_S16NE, 4, 1, false); +} +END_TEST + +START_TEST (rearrange_special_test) { + pa_log_debug("Checking special remap (s16, stereo rearrange)"); + remap_init2_test_channels(PA_SAMPLE_S16NE, 2, 2, true); + pa_log_debug("Checking special remap (float, stereo rearrange)"); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 2, 2, true); + + pa_log_debug("Checking special remap (s16, 4-channel rearrange)"); + remap_init2_test_channels(PA_SAMPLE_S16NE, 4, 4, true); + pa_log_debug("Checking special remap (float, 4-channel rearrange)"); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 4, 4, true); } END_TEST @@ -273,10 +298,10 @@ START_TEST (remap_mmx_test) { orig_init_func = pa_get_init_remap_func(); pa_remap_func_init_mmx(flags); init_func = pa_get_init_remap_func(); - remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false); pa_log_debug("Checking MMX remap (s16, mono->stereo)"); - remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false); } END_TEST @@ -294,10 +319,10 @@ START_TEST (remap_sse2_test) { orig_init_func = pa_get_init_remap_func(); pa_remap_func_init_sse(flags); init_func = pa_get_init_remap_func(); - remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2, false); pa_log_debug("Checking SSE2 remap (s16, mono->stereo)"); - remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2, false); } END_TEST #endif /* defined (__i386__) || defined (__amd64__) */ @@ -322,6 +347,11 @@ int main(int argc, char *argv[]) { tcase_set_timeout(tc, 120); suite_add_tcase(s, tc); + tc = tcase_create("rearrange"); + tcase_add_test(tc, rearrange_special_test); + tcase_set_timeout(tc, 120); + suite_add_tcase(s, tc); + sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); failed = srunner_ntests_failed(sr); commit c68c9f3aa2d79e0377710f6c34ef62ec9f8198ca Author: Peter Meerwald Date: Wed Apr 23 22:18:34 2014 +0200 tests: Add to remapping special case code tests to cpu-remap-test Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-remap-test.c b/src/tests/cpu-remap-test.c index fa7633d..c0a6a64 100644 --- a/src/tests/cpu-remap-test.c +++ b/src/tests/cpu-remap-test.c @@ -214,6 +214,50 @@ static void remap_init_test_channels( remap_test_channels(&remap_func, &remap_orig); } +static void remap_init2_test_channels( + pa_sample_format_t f, + unsigned in_channels, + unsigned out_channels) { + + pa_cpu_info cpu_info = { PA_CPU_UNDEFINED, {}, false }; + pa_remap_t remap_orig, remap_func; + + cpu_info.force_generic_code = true; + pa_remap_func_init(&cpu_info); + setup_remap_channels(&remap_orig, f, in_channels, out_channels); + pa_init_remap_func(&remap_orig); + + cpu_info.force_generic_code = false; + pa_remap_func_init(&cpu_info); + setup_remap_channels(&remap_func, f, in_channels, out_channels); + pa_init_remap_func(&remap_func); + + remap_test_channels(&remap_func, &remap_orig); +} + +START_TEST (remap_special_test) { + pa_log_debug("Checking special remap (float, mono->stereo)"); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 2); + pa_log_debug("Checking special remap (float, mono->4-channel)"); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 1, 4); + + pa_log_debug("Checking special remap (s16, mono->stereo)"); + remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 2); + pa_log_debug("Checking special remap (s16, mono->4-channel)"); + remap_init2_test_channels(PA_SAMPLE_S16NE, 1, 4); + + pa_log_debug("Checking special remap (float, stereo->mono)"); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 2, 1); + pa_log_debug("Checking special remap (float, 4-channel->mono)"); + remap_init2_test_channels(PA_SAMPLE_FLOAT32NE, 4, 1); + + pa_log_debug("Checking special remap (s16, stereo->mono)"); + remap_init2_test_channels(PA_SAMPLE_S16NE, 2, 1); + pa_log_debug("Checking special remap (s16, 4-channel->mono)"); + remap_init2_test_channels(PA_SAMPLE_S16NE, 4, 1); +} +END_TEST + #if defined (__i386__) || defined (__amd64__) START_TEST (remap_mmx_test) { pa_cpu_x86_flag_t flags = 0; @@ -270,6 +314,7 @@ int main(int argc, char *argv[]) { s = suite_create("CPU"); tc = tcase_create("remap"); + tcase_add_test(tc, remap_special_test); #if defined (__i386__) || defined (__amd64__) tcase_add_test(tc, remap_mmx_test); tcase_add_test(tc, remap_sse2_test); commit 7ae700941c17724a2308873854782c6093656c75 Author: Peter Meerwald Date: Wed Apr 23 22:18:05 2014 +0200 tests: Reorganize cpu-remap-test program Make run_remap_test() support up to 8 input and output channels. Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-remap-test.c b/src/tests/cpu-remap-test.c index eef5532..fa7633d 100644 --- a/src/tests/cpu-remap-test.c +++ b/src/tests/cpu-remap-test.c @@ -24,47 +24,54 @@ #include #include +#include #include #include #include #include "runtime-test-util.h" -#define SAMPLES 1028 +#define SAMPLES 1027 #define TIMES 1000 #define TIMES2 100 -static void run_remap_test_mono_stereo_float( +static void run_remap_test_float( pa_remap_t *remap_func, pa_remap_t *remap_orig, int align, bool correct, bool perf) { - PA_DECLARE_ALIGNED(8, float, s_ref[SAMPLES*2]) = { 0 }; - PA_DECLARE_ALIGNED(8, float, s[SAMPLES*2]) = { 0 }; - PA_DECLARE_ALIGNED(8, float, m[SAMPLES]); - float *stereo, *stereo_ref; - float *mono; - int i, nsamples; + PA_DECLARE_ALIGNED(8, float, out_buf_ref[SAMPLES*8]) = { 0.0f, }; + PA_DECLARE_ALIGNED(8, float, out_buf[SAMPLES*8]) = { 0.0f, }; + PA_DECLARE_ALIGNED(8, float, in_buf[SAMPLES*8]); + float *out, *out_ref; + float *in; + unsigned n_ic = remap_func->i_ss.channels; + unsigned n_oc = remap_func->o_ss.channels; + unsigned i, nsamples; + + pa_assert(n_ic >= 1 && n_ic <= 8); + pa_assert(n_oc >= 1 && n_oc <= 8); /* Force sample alignment as requested */ - stereo = s + (8 - align); - stereo_ref = s_ref + (8 - align); - mono = m + (8 - align); + out = out_buf + (8 - align); + out_ref = out_buf_ref + (8 - align); + in = in_buf + (8 - align); nsamples = SAMPLES - (8 - align); - for (i = 0; i < nsamples; i++) - mono[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f); + for (i = 0; i < nsamples * n_ic; i++) + in[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f); if (correct) { - remap_orig->do_remap(remap_orig, stereo_ref, mono, nsamples); - remap_func->do_remap(remap_func, stereo, mono, nsamples); + remap_orig->do_remap(remap_orig, out_ref, in, nsamples); + remap_func->do_remap(remap_func, out, in, nsamples); - for (i = 0; i < nsamples * 2; i++) { - if (fabsf(stereo[i] - stereo_ref[i]) > 0.0001f) { + for (i = 0; i < nsamples * n_oc; i++) { + if (fabsf(out[i] - out_ref[i]) > 0.0001f) { pa_log_debug("Correctness test failed: align=%d", align); - pa_log_debug("%d: %.24f != %.24f (%.24f)\n", i, stereo[i], stereo_ref[i], mono[i]); + pa_log_debug("%d: %.24f != %.24f\n", i, + out[i], out_ref[i]); fail(); } } @@ -74,45 +81,50 @@ static void run_remap_test_mono_stereo_float( pa_log_debug("Testing remap performance with %d sample alignment", align); PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - remap_func->do_remap(remap_func, stereo, mono, nsamples); + remap_func->do_remap(remap_func, out, in, nsamples); } PA_RUNTIME_TEST_RUN_STOP PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - remap_orig->do_remap(remap_orig, stereo_ref, mono, nsamples); + remap_orig->do_remap(remap_orig, out_ref, in, nsamples); } PA_RUNTIME_TEST_RUN_STOP } } -static void run_remap_test_mono_stereo_s16( +static void run_remap_test_s16( pa_remap_t *remap_func, pa_remap_t *remap_orig, int align, bool correct, bool perf) { - PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES*2]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES*2]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, m[SAMPLES]); - int16_t *stereo, *stereo_ref; - int16_t *mono; - int i, nsamples; + PA_DECLARE_ALIGNED(8, int16_t, out_buf_ref[SAMPLES*8]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, out_buf[SAMPLES*8]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, in_buf[SAMPLES*8]); + int16_t *out, *out_ref; + int16_t *in; + unsigned n_ic = remap_func->i_ss.channels; + unsigned n_oc = remap_func->o_ss.channels; + unsigned i, nsamples; + + pa_assert(n_ic >= 1 && n_ic <= 8); + pa_assert(n_oc >= 1 && n_oc <= 8); /* Force sample alignment as requested */ - stereo = s + (8 - align); - stereo_ref = s_ref + (8 - align); - mono = m + (8 - align); + out = out_buf + (8 - align); + out_ref = out_buf_ref + (8 - align); + in = in_buf + (8 - align); nsamples = SAMPLES - (8 - align); - pa_random(mono, nsamples * sizeof(int16_t)); + pa_random(in, nsamples * n_ic * sizeof(int16_t)); if (correct) { - remap_orig->do_remap(remap_orig, stereo_ref, mono, nsamples); - remap_func->do_remap(remap_func, stereo, mono, nsamples); + remap_orig->do_remap(remap_orig, out_ref, in, nsamples); + remap_func->do_remap(remap_func, out, in, nsamples); - for (i = 0; i < nsamples * 2; i++) { - if (abs(stereo[i] - stereo_ref[i]) > 1) { + for (i = 0; i < nsamples * n_oc; i++) { + if (abs(out[i] - out_ref[i]) > 3) { pa_log_debug("Correctness test failed: align=%d", align); - pa_log_debug("%d: %d != %d (%d)\n", i, stereo[i], stereo_ref[i], mono[i]); + pa_log_debug("%d: %d != %d\n", i, out[i], out_ref[i]); fail(); } } @@ -122,74 +134,84 @@ static void run_remap_test_mono_stereo_s16( pa_log_debug("Testing remap performance with %d sample alignment", align); PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - remap_func->do_remap(remap_orig, stereo, mono, nsamples); + remap_func->do_remap(remap_func, out, in, nsamples); } PA_RUNTIME_TEST_RUN_STOP PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - remap_func->do_remap(remap_func, stereo_ref, mono, nsamples); + remap_orig->do_remap(remap_orig, out_ref, in, nsamples); } PA_RUNTIME_TEST_RUN_STOP } } -static void setup_remap_mono_stereo(pa_remap_t *m, pa_sample_format_t f) { +static void setup_remap_channels( + pa_remap_t *m, + pa_sample_format_t f, + unsigned in_channels, + unsigned out_channels) { + + unsigned i, o; + m->format = f; - m->i_ss.channels = 1; - m->o_ss.channels = 2; - m->map_table_f[0][0] = 1.0f; - m->map_table_f[1][0] = 1.0f; - m->map_table_i[0][0] = 0x10000; - m->map_table_i[1][0] = 0x10000; -} + m->i_ss.channels = in_channels; + m->o_ss.channels = out_channels; -static void remap_test_mono_stereo_float( - pa_init_remap_func_t init_func, - pa_init_remap_func_t orig_init_func) { + for (o = 0; o < out_channels; o++) { + for (i = 0; i < in_channels; i++) { + m->map_table_f[o][i] = 1.0f / in_channels; + m->map_table_i[o][i] = 0x10000 / in_channels; + } + } +} - pa_remap_t remap_orig, remap_func; +static void remap_test_channels( + pa_remap_t *remap_func, pa_remap_t *remap_orig) { - setup_remap_mono_stereo(&remap_orig, PA_SAMPLE_FLOAT32NE); - orig_init_func(&remap_orig); - if (!remap_orig.do_remap) { + if (!remap_orig->do_remap) { pa_log_warn("No reference remapping function, abort test"); return; } - setup_remap_mono_stereo(&remap_func, PA_SAMPLE_FLOAT32NE); - init_func(&remap_func); - if (!remap_func.do_remap || remap_func.do_remap == remap_orig.do_remap) { + if (!remap_func->do_remap || remap_func->do_remap == remap_orig->do_remap) { pa_log_warn("No remapping function, abort test"); return; } - run_remap_test_mono_stereo_float(&remap_func, &remap_orig, 0, true, false); - run_remap_test_mono_stereo_float(&remap_func, &remap_orig, 1, true, false); - run_remap_test_mono_stereo_float(&remap_func, &remap_orig, 2, true, false); - run_remap_test_mono_stereo_float(&remap_func, &remap_orig, 3, true, true); + pa_assert(remap_func->format == remap_orig->format); + + switch (remap_func->format) { + case PA_SAMPLE_FLOAT32NE: + run_remap_test_float(remap_func, remap_orig, 0, true, false); + run_remap_test_float(remap_func, remap_orig, 1, true, false); + run_remap_test_float(remap_func, remap_orig, 2, true, false); + run_remap_test_float(remap_func, remap_orig, 3, true, true); + break; + case PA_SAMPLE_S16NE: + run_remap_test_s16(remap_func, remap_orig, 0, true, false); + run_remap_test_s16(remap_func, remap_orig, 1, true, false); + run_remap_test_s16(remap_func, remap_orig, 2, true, false); + run_remap_test_s16(remap_func, remap_orig, 3, true, true); + break; + default: + pa_assert_not_reached(); + } } -static void remap_test_mono_stereo_s16( +static void remap_init_test_channels( pa_init_remap_func_t init_func, - pa_init_remap_func_t orig_init_func) { + pa_init_remap_func_t orig_init_func, + pa_sample_format_t f, + unsigned in_channels, + unsigned out_channels) { pa_remap_t remap_orig, remap_func; - setup_remap_mono_stereo(&remap_orig, PA_SAMPLE_S16NE); + setup_remap_channels(&remap_orig, f, in_channels, out_channels); orig_init_func(&remap_orig); - if (!remap_orig.do_remap) { - pa_log_warn("No reference remapping function, abort test"); - return; - } + setup_remap_channels(&remap_func, f, in_channels, out_channels); init_func(&remap_func); - if (!remap_func.do_remap || remap_func.do_remap == remap_orig.do_remap) { - pa_log_warn("No remapping function, abort test"); - return; - } - run_remap_test_mono_stereo_s16(&remap_func, &remap_orig, 0, true, false); - run_remap_test_mono_stereo_s16(&remap_func, &remap_orig, 1, true, false); - run_remap_test_mono_stereo_s16(&remap_func, &remap_orig, 2, true, false); - run_remap_test_mono_stereo_s16(&remap_func, &remap_orig, 3, true, true); + remap_test_channels(&remap_func, &remap_orig); } #if defined (__i386__) || defined (__amd64__) @@ -207,10 +229,10 @@ START_TEST (remap_mmx_test) { orig_init_func = pa_get_init_remap_func(); pa_remap_func_init_mmx(flags); init_func = pa_get_init_remap_func(); - remap_test_mono_stereo_float(init_func, orig_init_func); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2); pa_log_debug("Checking MMX remap (s16, mono->stereo)"); - remap_test_mono_stereo_s16(init_func, orig_init_func); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2); } END_TEST @@ -228,10 +250,10 @@ START_TEST (remap_sse2_test) { orig_init_func = pa_get_init_remap_func(); pa_remap_func_init_sse(flags); init_func = pa_get_init_remap_func(); - remap_test_mono_stereo_float(init_func, orig_init_func); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_FLOAT32NE, 1, 2); pa_log_debug("Checking SSE2 remap (s16, mono->stereo)"); - remap_test_mono_stereo_s16(init_func, orig_init_func); + remap_init_test_channels(init_func, orig_init_func, PA_SAMPLE_S16NE, 1, 2); } END_TEST #endif /* defined (__i386__) || defined (__amd64__) */ commit 8f4897e162415a54ef926774889ba8f99fee9a1c Author: Peter Meerwald Date: Wed Apr 23 23:22:58 2014 +0200 tests: Use remap function passed in remap struct Cleanup and add function to setup remap struct Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-remap-test.c b/src/tests/cpu-remap-test.c index 4b8ddd7..eef5532 100644 --- a/src/tests/cpu-remap-test.c +++ b/src/tests/cpu-remap-test.c @@ -35,9 +35,8 @@ #define TIMES2 100 static void run_remap_test_mono_stereo_float( - pa_remap_t *remap, - pa_do_remap_func_t func, - pa_do_remap_func_t orig_func, + pa_remap_t *remap_func, + pa_remap_t *remap_orig, int align, bool correct, bool perf) { @@ -59,11 +58,11 @@ static void run_remap_test_mono_stereo_float( mono[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f); if (correct) { - orig_func(remap, stereo_ref, mono, nsamples); - func(remap, stereo, mono, nsamples); + remap_orig->do_remap(remap_orig, stereo_ref, mono, nsamples); + remap_func->do_remap(remap_func, stereo, mono, nsamples); for (i = 0; i < nsamples * 2; i++) { - if (fabsf(stereo[i] - stereo_ref[i]) > 0.0001) { + if (fabsf(stereo[i] - stereo_ref[i]) > 0.0001f) { pa_log_debug("Correctness test failed: align=%d", align); pa_log_debug("%d: %.24f != %.24f (%.24f)\n", i, stereo[i], stereo_ref[i], mono[i]); fail(); @@ -75,19 +74,18 @@ static void run_remap_test_mono_stereo_float( pa_log_debug("Testing remap performance with %d sample alignment", align); PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - func(remap, stereo, mono, nsamples); + remap_func->do_remap(remap_func, stereo, mono, nsamples); } PA_RUNTIME_TEST_RUN_STOP PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - orig_func(remap, stereo_ref, mono, nsamples); + remap_orig->do_remap(remap_orig, stereo_ref, mono, nsamples); } PA_RUNTIME_TEST_RUN_STOP } } static void run_remap_test_mono_stereo_s16( - pa_remap_t *remap, - pa_do_remap_func_t func, - pa_do_remap_func_t orig_func, + pa_remap_t *remap_func, + pa_remap_t *remap_orig, int align, bool correct, bool perf) { @@ -108,8 +106,8 @@ static void run_remap_test_mono_stereo_s16( pa_random(mono, nsamples * sizeof(int16_t)); if (correct) { - orig_func(remap, stereo_ref, mono, nsamples); - func(remap, stereo, mono, nsamples); + remap_orig->do_remap(remap_orig, stereo_ref, mono, nsamples); + remap_func->do_remap(remap_func, stereo, mono, nsamples); for (i = 0; i < nsamples * 2; i++) { if (abs(stereo[i] - stereo_ref[i]) > 1) { @@ -124,81 +122,74 @@ static void run_remap_test_mono_stereo_s16( pa_log_debug("Testing remap performance with %d sample alignment", align); PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - func(remap, stereo, mono, nsamples); + remap_func->do_remap(remap_orig, stereo, mono, nsamples); } PA_RUNTIME_TEST_RUN_STOP PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - orig_func(remap, stereo_ref, mono, nsamples); + remap_func->do_remap(remap_func, stereo_ref, mono, nsamples); } PA_RUNTIME_TEST_RUN_STOP } } +static void setup_remap_mono_stereo(pa_remap_t *m, pa_sample_format_t f) { + m->format = f; + m->i_ss.channels = 1; + m->o_ss.channels = 2; + m->map_table_f[0][0] = 1.0f; + m->map_table_f[1][0] = 1.0f; + m->map_table_i[0][0] = 0x10000; + m->map_table_i[1][0] = 0x10000; +} + static void remap_test_mono_stereo_float( pa_init_remap_func_t init_func, pa_init_remap_func_t orig_init_func) { - pa_remap_t remap; - pa_do_remap_func_t orig_func, func; - - remap.format = PA_SAMPLE_FLOAT32NE; - remap.i_ss.channels = 1; - remap.o_ss.channels = 2; - remap.map_table_f[0][0] = 1.0; - remap.map_table_f[1][0] = 1.0; - remap.map_table_i[0][0] = 0x10000; - remap.map_table_i[1][0] = 0x10000; - orig_init_func(&remap); - orig_func = remap.do_remap; - if (!orig_func) { + pa_remap_t remap_orig, remap_func; + + setup_remap_mono_stereo(&remap_orig, PA_SAMPLE_FLOAT32NE); + orig_init_func(&remap_orig); + if (!remap_orig.do_remap) { pa_log_warn("No reference remapping function, abort test"); return; } - init_func(&remap); - func = remap.do_remap; - if (!func || func == orig_func) { + setup_remap_mono_stereo(&remap_func, PA_SAMPLE_FLOAT32NE); + init_func(&remap_func); + if (!remap_func.do_remap || remap_func.do_remap == remap_orig.do_remap) { pa_log_warn("No remapping function, abort test"); return; } - run_remap_test_mono_stereo_float(&remap, func, orig_func, 0, true, false); - run_remap_test_mono_stereo_float(&remap, func, orig_func, 1, true, false); - run_remap_test_mono_stereo_float(&remap, func, orig_func, 2, true, false); - run_remap_test_mono_stereo_float(&remap, func, orig_func, 3, true, true); + run_remap_test_mono_stereo_float(&remap_func, &remap_orig, 0, true, false); + run_remap_test_mono_stereo_float(&remap_func, &remap_orig, 1, true, false); + run_remap_test_mono_stereo_float(&remap_func, &remap_orig, 2, true, false); + run_remap_test_mono_stereo_float(&remap_func, &remap_orig, 3, true, true); } static void remap_test_mono_stereo_s16( pa_init_remap_func_t init_func, pa_init_remap_func_t orig_init_func) { - pa_remap_t remap; - pa_do_remap_func_t orig_func, func; - - remap.format = PA_SAMPLE_S16NE; - remap.i_ss.channels = 1; - remap.o_ss.channels = 2; - remap.map_table_f[0][0] = 1.0; - remap.map_table_f[1][0] = 1.0; - remap.map_table_i[0][0] = 0x10000; - remap.map_table_i[1][0] = 0x10000; - orig_init_func(&remap); - orig_func = remap.do_remap; - if (!orig_func) { + pa_remap_t remap_orig, remap_func; + + setup_remap_mono_stereo(&remap_orig, PA_SAMPLE_S16NE); + orig_init_func(&remap_orig); + if (!remap_orig.do_remap) { pa_log_warn("No reference remapping function, abort test"); return; } - init_func(&remap); - func = remap.do_remap; - if (!func || func == orig_func) { + init_func(&remap_func); + if (!remap_func.do_remap || remap_func.do_remap == remap_orig.do_remap) { pa_log_warn("No remapping function, abort test"); return; } - run_remap_test_mono_stereo_s16(&remap, func, orig_func, 0, true, false); - run_remap_test_mono_stereo_s16(&remap, func, orig_func, 1, true, false); - run_remap_test_mono_stereo_s16(&remap, func, orig_func, 2, true, false); - run_remap_test_mono_stereo_s16(&remap, func, orig_func, 3, true, true); + run_remap_test_mono_stereo_s16(&remap_func, &remap_orig, 0, true, false); + run_remap_test_mono_stereo_s16(&remap_func, &remap_orig, 1, true, false); + run_remap_test_mono_stereo_s16(&remap_func, &remap_orig, 2, true, false); + run_remap_test_mono_stereo_s16(&remap_func, &remap_orig, 3, true, true); } #if defined (__i386__) || defined (__amd64__) commit 173649e4f740621566aeefce3c9819284efb1812 Author: Peter Meerwald Date: Wed Apr 23 22:49:14 2014 +0200 tests: Add ARM NEON test code to cpu-mix-test Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-mix-test.c b/src/tests/cpu-mix-test.c index ab53c6c..181a767 100644 --- a/src/tests/cpu-mix-test.c +++ b/src/tests/cpu-mix-test.c @@ -186,8 +186,14 @@ START_TEST (mix_neon_test) { pa_mix_func_init_neon(flags); neon_func = pa_get_mix_func(PA_SAMPLE_S16NE); - pa_log_debug("Checking NEON mix"); + pa_log_debug("Checking NEON mix (s16, stereo)"); run_mix_test(neon_func, orig_func, 7, 2, true, true); + + pa_log_debug("Checking NEON mix (s16, 4-channel)"); + run_mix_test(neon_func, orig_func, 7, 4, true, true); + + pa_log_debug("Checking NEON mix (s16, mono)"); + run_mix_test(neon_func, orig_func, 7, 1, true, true); } END_TEST #endif /* defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) */ commit d58446963fd71a73c9b5b9f62843bc16deaba6ea Author: Peter Meerwald Date: Wed Apr 23 22:48:53 2014 +0200 tests: Add tests for mix special-case code Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-mix-test.c b/src/tests/cpu-mix-test.c index 2facaae..ab53c6c 100644 --- a/src/tests/cpu-mix-test.c +++ b/src/tests/cpu-mix-test.c @@ -23,6 +23,7 @@ #include +#include #include #include #include @@ -30,10 +31,6 @@ #include "runtime-test-util.h" -/* Only ARM NEON has mix tests, so disable the related functions for other - * architectures for now to avoid compiler warnings about unused functions. */ -#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) - #define SAMPLES 1028 #define TIMES 1000 #define TIMES2 100 @@ -149,7 +146,29 @@ static void run_mix_test( pa_mempool_free(pool); } -#endif /* defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) */ + +START_TEST (mix_special_test) { + pa_cpu_info cpu_info = { PA_CPU_UNDEFINED, {}, false }; + pa_do_mix_func_t orig_func, special_func; + + cpu_info.force_generic_code = true; + pa_mix_func_init(&cpu_info); + orig_func = pa_get_mix_func(PA_SAMPLE_S16NE); + + cpu_info.force_generic_code = false; + pa_mix_func_init(&cpu_info); + special_func = pa_get_mix_func(PA_SAMPLE_S16NE); + + pa_log_debug("Checking special mix (s16, stereo)"); + run_mix_test(special_func, orig_func, 7, 2, true, true); + + pa_log_debug("Checking special mix (s16, 4-channel)"); + run_mix_test(special_func, orig_func, 7, 4, true, true); + + pa_log_debug("Checking special mix (s16, mono)"); + run_mix_test(special_func, orig_func, 7, 1, true, true); +} +END_TEST #if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) START_TEST (mix_neon_test) { @@ -185,6 +204,7 @@ int main(int argc, char *argv[]) { s = suite_create("CPU"); tc = tcase_create("mix"); + tcase_add_test(tc, mix_special_test); #if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) tcase_add_test(tc, mix_neon_test); #endif commit 9576ba2d9e62625f1dad0151330ad14ccf429dc3 Author: Peter Meerwald Date: Tue Apr 22 18:25:48 2014 +0200 tests: Use single-line #ifdef for ARM NEON code Signed-off-by: Peter Meerwald diff --git a/src/tests/cpu-mix-test.c b/src/tests/cpu-mix-test.c index 934c33f..2facaae 100644 --- a/src/tests/cpu-mix-test.c +++ b/src/tests/cpu-mix-test.c @@ -32,8 +32,7 @@ /* Only ARM NEON has mix tests, so disable the related functions for other * architectures for now to avoid compiler warnings about unused functions. */ -#if defined (__arm__) && defined (__linux__) -#ifdef HAVE_NEON +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) #define SAMPLES 1028 #define TIMES 1000 @@ -150,11 +149,9 @@ static void run_mix_test( pa_mempool_free(pool); } -#endif /* HAVE_NEON */ -#endif /* defined (__arm__) && defined (__linux__) */ +#endif /* defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) */ -#if defined (__arm__) && defined (__linux__) -#ifdef HAVE_NEON +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) START_TEST (mix_neon_test) { pa_do_mix_func_t orig_func, neon_func; pa_cpu_arm_flag_t flags = 0; @@ -174,8 +171,7 @@ START_TEST (mix_neon_test) { run_mix_test(neon_func, orig_func, 7, 2, true, true); } END_TEST -#endif /* HAVE_NEON */ -#endif /* defined (__arm__) && defined (__linux__) */ +#endif /* defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) */ int main(int argc, char *argv[]) { int failed = 0; @@ -189,11 +185,9 @@ int main(int argc, char *argv[]) { s = suite_create("CPU"); tc = tcase_create("mix"); -#if defined (__arm__) && defined (__linux__) -#if HAVE_NEON +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) tcase_add_test(tc, mix_neon_test); #endif -#endif tcase_set_timeout(tc, 120); suite_add_tcase(s, tc); diff --git a/src/tests/cpu-sconv-test.c b/src/tests/cpu-sconv-test.c index f89f593..4e7848d 100644 --- a/src/tests/cpu-sconv-test.c +++ b/src/tests/cpu-sconv-test.c @@ -86,8 +86,7 @@ static void run_conv_test_float_to_s16( } /* This test is currently only run under NEON */ -#if defined (__arm__) && defined (__linux__) -#ifdef HAVE_NEON +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) static void run_conv_test_s16_to_float( pa_convert_func_t func, pa_convert_func_t orig_func, @@ -135,8 +134,7 @@ static void run_conv_test_s16_to_float( } PA_RUNTIME_TEST_RUN_STOP } } -#endif /* HAVE_NEON */ -#endif /* defined (__arm__) && defined (__linux__) */ +#endif /* defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) */ #if defined (__i386__) || defined (__amd64__) START_TEST (sconv_sse2_test) { @@ -194,8 +192,7 @@ START_TEST (sconv_sse_test) { END_TEST #endif /* defined (__i386__) || defined (__amd64__) */ -#if defined (__arm__) && defined (__linux__) -#ifdef HAVE_NEON +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) START_TEST (sconv_neon_test) { pa_cpu_arm_flag_t flags = 0; pa_convert_func_t orig_from_func, neon_from_func; @@ -235,8 +232,7 @@ START_TEST (sconv_neon_test) { run_conv_test_s16_to_float(neon_to_func, orig_to_func, 7, true, true); } END_TEST -#endif /* HAVE_NEON */ -#endif /* defined (__arm__) && defined (__linux__) */ +#endif /* defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) */ int main(int argc, char *argv[]) { int failed = 0; @@ -254,11 +250,9 @@ int main(int argc, char *argv[]) { tcase_add_test(tc, sconv_sse2_test); tcase_add_test(tc, sconv_sse_test); #endif -#if defined (__arm__) && defined (__linux__) -#if HAVE_NEON +#if defined (__arm__) && defined (__linux__) && defined (HAVE_NEON) tcase_add_test(tc, sconv_neon_test); #endif -#endif tcase_set_timeout(tc, 120); suite_add_tcase(s, tc); commit 4ca3216ee30794ac186f70843a13553407fa5d52 Author: Peter Meerwald Date: Tue Apr 22 18:19:05 2014 +0200 tests: Split cpu tests in separate files Signed-off-by: Peter Meerwald diff --git a/src/.gitignore b/src/.gitignore index 1490262..a90c7dc 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -36,7 +36,10 @@ close-test connect-stress cpulimit-test cpulimit-test2 -cpu-test +cpu-sconv-test +cpu-remap-test +cpu-mix-test +cpu-volume-test extended-test flist-test format-test diff --git a/src/Makefile.am b/src/Makefile.am index 40d8c04..2ff4967 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -244,7 +244,10 @@ TESTS_default = \ volume-test \ mix-test \ proplist-test \ - cpu-test \ + cpu-mix-test \ + cpu-remap-test \ + cpu-sconv-test \ + cpu-volume-test \ lock-autospawn-test \ mult-s16-test \ mix-special-test @@ -510,10 +513,25 @@ proplist_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la li proplist_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) proplist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) -cpu_test_SOURCES = tests/cpu-test.c tests/runtime-test-util.h -cpu_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la libpulsecommon- at PA_MAJORMINOR@.la -cpu_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) -cpu_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) +cpu_mix_test_SOURCES = tests/cpu-mix-test.c tests/runtime-test-util.h +cpu_mix_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la libpulsecommon- at PA_MAJORMINOR@.la +cpu_mix_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) +cpu_mix_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) + +cpu_remap_test_SOURCES = tests/cpu-remap-test.c tests/runtime-test-util.h +cpu_remap_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la libpulsecommon- at PA_MAJORMINOR@.la +cpu_remap_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) +cpu_remap_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) + +cpu_sconv_test_SOURCES = tests/cpu-sconv-test.c tests/runtime-test-util.h +cpu_sconv_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la libpulsecommon- at PA_MAJORMINOR@.la +cpu_sconv_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) +cpu_sconv_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) + +cpu_volume_test_SOURCES = tests/cpu-volume-test.c tests/runtime-test-util.h +cpu_volume_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la libpulsecommon- at PA_MAJORMINOR@.la +cpu_volume_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS) +cpu_volume_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS) mult_s16_test_SOURCES = tests/mult-s16-test.c tests/runtime-test-util.h mult_s16_test_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulse.la libpulsecommon- at PA_MAJORMINOR@.la diff --git a/src/tests/cpu-mix-test.c b/src/tests/cpu-mix-test.c new file mode 100644 index 0000000..934c33f --- /dev/null +++ b/src/tests/cpu-mix-test.c @@ -0,0 +1,206 @@ +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include +#include + +#include "runtime-test-util.h" + +/* Only ARM NEON has mix tests, so disable the related functions for other + * architectures for now to avoid compiler warnings about unused functions. */ +#if defined (__arm__) && defined (__linux__) +#ifdef HAVE_NEON + +#define SAMPLES 1028 +#define TIMES 1000 +#define TIMES2 100 + +static void acquire_mix_streams(pa_mix_info streams[], unsigned nstreams) { + unsigned i; + + for (i = 0; i < nstreams; i++) + streams[i].ptr = pa_memblock_acquire_chunk(&streams[i].chunk); +} + +static void release_mix_streams(pa_mix_info streams[], unsigned nstreams) { + unsigned i; + + for (i = 0; i < nstreams; i++) + pa_memblock_release(streams[i].chunk.memblock); +} + +static void run_mix_test( + pa_do_mix_func_t func, + pa_do_mix_func_t orig_func, + int align, + int channels, + bool correct, + bool perf) { + + PA_DECLARE_ALIGNED(8, int16_t, in0[SAMPLES * 4]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, in1[SAMPLES * 4]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, out[SAMPLES * 4]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, out_ref[SAMPLES * 4]) = { 0 }; + int16_t *samples0, *samples1; + int16_t *samples, *samples_ref; + int nsamples; + pa_mempool *pool; + pa_memchunk c0, c1; + pa_mix_info m[2]; + int i; + + pa_assert(channels == 1 || channels == 2 || channels == 4); + + /* Force sample alignment as requested */ + samples0 = in0 + (8 - align); + samples1 = in1 + (8 - align); + samples = out + (8 - align); + samples_ref = out_ref + (8 - align); + nsamples = channels * (SAMPLES - (8 - align)); + + fail_unless((pool = pa_mempool_new(false, 0)) != NULL, NULL); + + pa_random(samples0, nsamples * sizeof(int16_t)); + c0.memblock = pa_memblock_new_fixed(pool, samples0, nsamples * sizeof(int16_t), false); + c0.length = pa_memblock_get_length(c0.memblock); + c0.index = 0; + + pa_random(samples1, nsamples * sizeof(int16_t)); + c1.memblock = pa_memblock_new_fixed(pool, samples1, nsamples * sizeof(int16_t), false); + c1.length = pa_memblock_get_length(c1.memblock); + c1.index = 0; + + m[0].chunk = c0; + m[0].volume.channels = channels; + for (i = 0; i < channels; i++) { + m[0].volume.values[i] = PA_VOLUME_NORM; + m[0].linear[i].i = 0x5555; + } + + m[1].chunk = c1; + m[1].volume.channels = channels; + for (i = 0; i < channels; i++) { + m[1].volume.values[i] = PA_VOLUME_NORM; + m[1].linear[i].i = 0x6789; + } + + if (correct) { + acquire_mix_streams(m, 2); + orig_func(m, 2, channels, samples_ref, nsamples * sizeof(int16_t)); + release_mix_streams(m, 2); + + acquire_mix_streams(m, 2); + func(m, 2, channels, samples, nsamples * sizeof(int16_t)); + release_mix_streams(m, 2); + + for (i = 0; i < nsamples; i++) { + if (samples[i] != samples_ref[i]) { + pa_log_debug("Correctness test failed: align=%d, channels=%d", align, channels); + pa_log_debug("%d: %hd != %04hd (%hd + %hd)\n", + i, + samples[i], samples_ref[i], + samples0[i], samples1[i]); + fail(); + } + } + } + + if (perf) { + pa_log_debug("Testing %d-channel mixing performance with %d sample alignment", channels, align); + + PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { + acquire_mix_streams(m, 2); + func(m, 2, channels, samples, nsamples * sizeof(int16_t)); + release_mix_streams(m, 2); + } PA_RUNTIME_TEST_RUN_STOP + + PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { + acquire_mix_streams(m, 2); + orig_func(m, 2, channels, samples_ref, nsamples * sizeof(int16_t)); + release_mix_streams(m, 2); + } PA_RUNTIME_TEST_RUN_STOP + } + + pa_memblock_unref(c0.memblock); + pa_memblock_unref(c1.memblock); + + pa_mempool_free(pool); +} +#endif /* HAVE_NEON */ +#endif /* defined (__arm__) && defined (__linux__) */ + +#if defined (__arm__) && defined (__linux__) +#ifdef HAVE_NEON +START_TEST (mix_neon_test) { + pa_do_mix_func_t orig_func, neon_func; + pa_cpu_arm_flag_t flags = 0; + + pa_cpu_get_arm_flags(&flags); + + if (!(flags & PA_CPU_ARM_NEON)) { + pa_log_info("NEON not supported. Skipping"); + return; + } + + orig_func = pa_get_mix_func(PA_SAMPLE_S16NE); + pa_mix_func_init_neon(flags); + neon_func = pa_get_mix_func(PA_SAMPLE_S16NE); + + pa_log_debug("Checking NEON mix"); + run_mix_test(neon_func, orig_func, 7, 2, true, true); +} +END_TEST +#endif /* HAVE_NEON */ +#endif /* defined (__arm__) && defined (__linux__) */ + +int main(int argc, char *argv[]) { + int failed = 0; + Suite *s; + TCase *tc; + SRunner *sr; + + if (!getenv("MAKE_CHECK")) + pa_log_set_level(PA_LOG_DEBUG); + + s = suite_create("CPU"); + + tc = tcase_create("mix"); +#if defined (__arm__) && defined (__linux__) +#if HAVE_NEON + tcase_add_test(tc, mix_neon_test); +#endif +#endif + tcase_set_timeout(tc, 120); + suite_add_tcase(s, tc); + + sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/tests/cpu-remap-test.c b/src/tests/cpu-remap-test.c new file mode 100644 index 0000000..4b8ddd7 --- /dev/null +++ b/src/tests/cpu-remap-test.c @@ -0,0 +1,273 @@ +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include +#include + +#include "runtime-test-util.h" + +#define SAMPLES 1028 +#define TIMES 1000 +#define TIMES2 100 + +static void run_remap_test_mono_stereo_float( + pa_remap_t *remap, + pa_do_remap_func_t func, + pa_do_remap_func_t orig_func, + int align, + bool correct, + bool perf) { + + PA_DECLARE_ALIGNED(8, float, s_ref[SAMPLES*2]) = { 0 }; + PA_DECLARE_ALIGNED(8, float, s[SAMPLES*2]) = { 0 }; + PA_DECLARE_ALIGNED(8, float, m[SAMPLES]); + float *stereo, *stereo_ref; + float *mono; + int i, nsamples; + + /* Force sample alignment as requested */ + stereo = s + (8 - align); + stereo_ref = s_ref + (8 - align); + mono = m + (8 - align); + nsamples = SAMPLES - (8 - align); + + for (i = 0; i < nsamples; i++) + mono[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f); + + if (correct) { + orig_func(remap, stereo_ref, mono, nsamples); + func(remap, stereo, mono, nsamples); + + for (i = 0; i < nsamples * 2; i++) { + if (fabsf(stereo[i] - stereo_ref[i]) > 0.0001) { + pa_log_debug("Correctness test failed: align=%d", align); + pa_log_debug("%d: %.24f != %.24f (%.24f)\n", i, stereo[i], stereo_ref[i], mono[i]); + fail(); + } + } + } + + if (perf) { + pa_log_debug("Testing remap performance with %d sample alignment", align); + + PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { + func(remap, stereo, mono, nsamples); + } PA_RUNTIME_TEST_RUN_STOP + + PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { + orig_func(remap, stereo_ref, mono, nsamples); + } PA_RUNTIME_TEST_RUN_STOP + } +} + +static void run_remap_test_mono_stereo_s16( + pa_remap_t *remap, + pa_do_remap_func_t func, + pa_do_remap_func_t orig_func, + int align, + bool correct, + bool perf) { + + PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES*2]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES*2]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, m[SAMPLES]); + int16_t *stereo, *stereo_ref; + int16_t *mono; + int i, nsamples; + + /* Force sample alignment as requested */ + stereo = s + (8 - align); + stereo_ref = s_ref + (8 - align); + mono = m + (8 - align); + nsamples = SAMPLES - (8 - align); + + pa_random(mono, nsamples * sizeof(int16_t)); + + if (correct) { + orig_func(remap, stereo_ref, mono, nsamples); + func(remap, stereo, mono, nsamples); + + for (i = 0; i < nsamples * 2; i++) { + if (abs(stereo[i] - stereo_ref[i]) > 1) { + pa_log_debug("Correctness test failed: align=%d", align); + pa_log_debug("%d: %d != %d (%d)\n", i, stereo[i], stereo_ref[i], mono[i]); + fail(); + } + } + } + + if (perf) { + pa_log_debug("Testing remap performance with %d sample alignment", align); + + PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { + func(remap, stereo, mono, nsamples); + } PA_RUNTIME_TEST_RUN_STOP + + PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { + orig_func(remap, stereo_ref, mono, nsamples); + } PA_RUNTIME_TEST_RUN_STOP + } +} + +static void remap_test_mono_stereo_float( + pa_init_remap_func_t init_func, + pa_init_remap_func_t orig_init_func) { + + pa_remap_t remap; + pa_do_remap_func_t orig_func, func; + + remap.format = PA_SAMPLE_FLOAT32NE; + remap.i_ss.channels = 1; + remap.o_ss.channels = 2; + remap.map_table_f[0][0] = 1.0; + remap.map_table_f[1][0] = 1.0; + remap.map_table_i[0][0] = 0x10000; + remap.map_table_i[1][0] = 0x10000; + orig_init_func(&remap); + orig_func = remap.do_remap; + if (!orig_func) { + pa_log_warn("No reference remapping function, abort test"); + return; + } + + init_func(&remap); + func = remap.do_remap; + if (!func || func == orig_func) { + pa_log_warn("No remapping function, abort test"); + return; + } + + run_remap_test_mono_stereo_float(&remap, func, orig_func, 0, true, false); + run_remap_test_mono_stereo_float(&remap, func, orig_func, 1, true, false); + run_remap_test_mono_stereo_float(&remap, func, orig_func, 2, true, false); + run_remap_test_mono_stereo_float(&remap, func, orig_func, 3, true, true); +} + +static void remap_test_mono_stereo_s16( + pa_init_remap_func_t init_func, + pa_init_remap_func_t orig_init_func) { + + pa_remap_t remap; + pa_do_remap_func_t orig_func, func; + + remap.format = PA_SAMPLE_S16NE; + remap.i_ss.channels = 1; + remap.o_ss.channels = 2; + remap.map_table_f[0][0] = 1.0; + remap.map_table_f[1][0] = 1.0; + remap.map_table_i[0][0] = 0x10000; + remap.map_table_i[1][0] = 0x10000; + orig_init_func(&remap); + orig_func = remap.do_remap; + if (!orig_func) { + pa_log_warn("No reference remapping function, abort test"); + return; + } + + init_func(&remap); + func = remap.do_remap; + if (!func || func == orig_func) { + pa_log_warn("No remapping function, abort test"); + return; + } + + run_remap_test_mono_stereo_s16(&remap, func, orig_func, 0, true, false); + run_remap_test_mono_stereo_s16(&remap, func, orig_func, 1, true, false); + run_remap_test_mono_stereo_s16(&remap, func, orig_func, 2, true, false); + run_remap_test_mono_stereo_s16(&remap, func, orig_func, 3, true, true); +} + +#if defined (__i386__) || defined (__amd64__) +START_TEST (remap_mmx_test) { + pa_cpu_x86_flag_t flags = 0; + pa_init_remap_func_t init_func, orig_init_func; + + pa_cpu_get_x86_flags(&flags); + if (!(flags & PA_CPU_X86_MMX)) { + pa_log_info("MMX not supported. Skipping"); + return; + } + + pa_log_debug("Checking MMX remap (float, mono->stereo)"); + orig_init_func = pa_get_init_remap_func(); + pa_remap_func_init_mmx(flags); + init_func = pa_get_init_remap_func(); + remap_test_mono_stereo_float(init_func, orig_init_func); + + pa_log_debug("Checking MMX remap (s16, mono->stereo)"); + remap_test_mono_stereo_s16(init_func, orig_init_func); +} +END_TEST + +START_TEST (remap_sse2_test) { + pa_cpu_x86_flag_t flags = 0; + pa_init_remap_func_t init_func, orig_init_func; + + pa_cpu_get_x86_flags(&flags); + if (!(flags & PA_CPU_X86_SSE2)) { + pa_log_info("SSE2 not supported. Skipping"); + return; + } + + pa_log_debug("Checking SSE2 remap (float, mono->stereo)"); + orig_init_func = pa_get_init_remap_func(); + pa_remap_func_init_sse(flags); + init_func = pa_get_init_remap_func(); + remap_test_mono_stereo_float(init_func, orig_init_func); + + pa_log_debug("Checking SSE2 remap (s16, mono->stereo)"); + remap_test_mono_stereo_s16(init_func, orig_init_func); +} +END_TEST +#endif /* defined (__i386__) || defined (__amd64__) */ + +int main(int argc, char *argv[]) { + int failed = 0; + Suite *s; + TCase *tc; + SRunner *sr; + + if (!getenv("MAKE_CHECK")) + pa_log_set_level(PA_LOG_DEBUG); + + s = suite_create("CPU"); + + tc = tcase_create("remap"); +#if defined (__i386__) || defined (__amd64__) + tcase_add_test(tc, remap_mmx_test); + tcase_add_test(tc, remap_sse2_test); +#endif + tcase_set_timeout(tc, 120); + suite_add_tcase(s, tc); + + sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/tests/cpu-sconv-test.c b/src/tests/cpu-sconv-test.c new file mode 100644 index 0000000..f89f593 --- /dev/null +++ b/src/tests/cpu-sconv-test.c @@ -0,0 +1,271 @@ +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include +#include +#include + +#include "runtime-test-util.h" + +#define SAMPLES 1028 +#define TIMES 1000 +#define TIMES2 100 + +static void run_conv_test_float_to_s16( + pa_convert_func_t func, + pa_convert_func_t orig_func, + int align, + bool correct, + bool perf) { + + PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES]) = { 0 }; + PA_DECLARE_ALIGNED(8, float, f[SAMPLES]); + int16_t *samples, *samples_ref; + float *floats; + int i, nsamples; + + /* Force sample alignment as requested */ + samples = s + (8 - align); + samples_ref = s_ref + (8 - align); + floats = f + (8 - align); + nsamples = SAMPLES - (8 - align); + + for (i = 0; i < nsamples; i++) { + floats[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f); + } + + if (correct) { + orig_func(nsamples, floats, samples_ref); + func(nsamples, floats, samples); + + for (i = 0; i < nsamples; i++) { + if (abs(samples[i] - samples_ref[i]) > 1) { + pa_log_debug("Correctness test failed: align=%d", align); + pa_log_debug("%d: %04hx != %04hx (%.24f)\n", i, samples[i], samples_ref[i], floats[i]); + fail(); + } + } + } + + if (perf) { + pa_log_debug("Testing sconv performance with %d sample alignment", align); + + PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { + func(nsamples, floats, samples); + } PA_RUNTIME_TEST_RUN_STOP + + PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { + orig_func(nsamples, floats, samples_ref); + } PA_RUNTIME_TEST_RUN_STOP + } +} + +/* This test is currently only run under NEON */ +#if defined (__arm__) && defined (__linux__) +#ifdef HAVE_NEON +static void run_conv_test_s16_to_float( + pa_convert_func_t func, + pa_convert_func_t orig_func, + int align, + bool correct, + bool perf) { + + PA_DECLARE_ALIGNED(8, float, f[SAMPLES]) = { 0 }; + PA_DECLARE_ALIGNED(8, float, f_ref[SAMPLES]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]); + float *floats, *floats_ref; + int16_t *samples; + int i, nsamples; + + /* Force sample alignment as requested */ + floats = f + (8 - align); + floats_ref = f_ref + (8 - align); + samples = s + (8 - align); + nsamples = SAMPLES - (8 - align); + + pa_random(samples, nsamples * sizeof(int16_t)); + + if (correct) { + orig_func(nsamples, samples, floats_ref); + func(nsamples, samples, floats); + + for (i = 0; i < nsamples; i++) { + if (fabsf(floats[i] - floats_ref[i]) > 0.0001) { + pa_log_debug("Correctness test failed: align=%d", align); + pa_log_debug("%d: %.24f != %.24f (%d)\n", i, floats[i], floats_ref[i], samples[i]); + fail(); + } + } + } + + if (perf) { + pa_log_debug("Testing sconv performance with %d sample alignment", align); + + PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { + func(nsamples, samples, floats); + } PA_RUNTIME_TEST_RUN_STOP + + PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { + orig_func(nsamples, samples, floats_ref); + } PA_RUNTIME_TEST_RUN_STOP + } +} +#endif /* HAVE_NEON */ +#endif /* defined (__arm__) && defined (__linux__) */ + +#if defined (__i386__) || defined (__amd64__) +START_TEST (sconv_sse2_test) { + pa_cpu_x86_flag_t flags = 0; + pa_convert_func_t orig_func, sse2_func; + + pa_cpu_get_x86_flags(&flags); + + if (!(flags & PA_CPU_X86_SSE2)) { + pa_log_info("SSE2 not supported. Skipping"); + return; + } + + orig_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); + pa_convert_func_init_sse(PA_CPU_X86_SSE2); + sse2_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); + + pa_log_debug("Checking SSE2 sconv (float -> s16)"); + run_conv_test_float_to_s16(sse2_func, orig_func, 0, true, false); + run_conv_test_float_to_s16(sse2_func, orig_func, 1, true, false); + run_conv_test_float_to_s16(sse2_func, orig_func, 2, true, false); + run_conv_test_float_to_s16(sse2_func, orig_func, 3, true, false); + run_conv_test_float_to_s16(sse2_func, orig_func, 4, true, false); + run_conv_test_float_to_s16(sse2_func, orig_func, 5, true, false); + run_conv_test_float_to_s16(sse2_func, orig_func, 6, true, false); + run_conv_test_float_to_s16(sse2_func, orig_func, 7, true, true); +} +END_TEST + +START_TEST (sconv_sse_test) { + pa_cpu_x86_flag_t flags = 0; + pa_convert_func_t orig_func, sse_func; + + pa_cpu_get_x86_flags(&flags); + + if (!(flags & PA_CPU_X86_SSE)) { + pa_log_info("SSE not supported. Skipping"); + return; + } + + orig_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); + pa_convert_func_init_sse(PA_CPU_X86_SSE); + sse_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); + + pa_log_debug("Checking SSE sconv (float -> s16)"); + run_conv_test_float_to_s16(sse_func, orig_func, 0, true, false); + run_conv_test_float_to_s16(sse_func, orig_func, 1, true, false); + run_conv_test_float_to_s16(sse_func, orig_func, 2, true, false); + run_conv_test_float_to_s16(sse_func, orig_func, 3, true, false); + run_conv_test_float_to_s16(sse_func, orig_func, 4, true, false); + run_conv_test_float_to_s16(sse_func, orig_func, 5, true, false); + run_conv_test_float_to_s16(sse_func, orig_func, 6, true, false); + run_conv_test_float_to_s16(sse_func, orig_func, 7, true, true); +} +END_TEST +#endif /* defined (__i386__) || defined (__amd64__) */ + +#if defined (__arm__) && defined (__linux__) +#ifdef HAVE_NEON +START_TEST (sconv_neon_test) { + pa_cpu_arm_flag_t flags = 0; + pa_convert_func_t orig_from_func, neon_from_func; + pa_convert_func_t orig_to_func, neon_to_func; + + pa_cpu_get_arm_flags(&flags); + + if (!(flags & PA_CPU_ARM_NEON)) { + pa_log_info("NEON not supported. Skipping"); + return; + } + + orig_from_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); + orig_to_func = pa_get_convert_to_float32ne_function(PA_SAMPLE_S16LE); + pa_convert_func_init_neon(flags); + neon_from_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); + neon_to_func = pa_get_convert_to_float32ne_function(PA_SAMPLE_S16LE); + + pa_log_debug("Checking NEON sconv (float -> s16)"); + run_conv_test_float_to_s16(neon_from_func, orig_from_func, 0, true, false); + run_conv_test_float_to_s16(neon_from_func, orig_from_func, 1, true, false); + run_conv_test_float_to_s16(neon_from_func, orig_from_func, 2, true, false); + run_conv_test_float_to_s16(neon_from_func, orig_from_func, 3, true, false); + run_conv_test_float_to_s16(neon_from_func, orig_from_func, 4, true, false); + run_conv_test_float_to_s16(neon_from_func, orig_from_func, 5, true, false); + run_conv_test_float_to_s16(neon_from_func, orig_from_func, 6, true, false); + run_conv_test_float_to_s16(neon_from_func, orig_from_func, 7, true, true); + + pa_log_debug("Checking NEON sconv (s16 -> float)"); + run_conv_test_s16_to_float(neon_to_func, orig_to_func, 0, true, false); + run_conv_test_s16_to_float(neon_to_func, orig_to_func, 1, true, false); + run_conv_test_s16_to_float(neon_to_func, orig_to_func, 2, true, false); + run_conv_test_s16_to_float(neon_to_func, orig_to_func, 3, true, false); + run_conv_test_s16_to_float(neon_to_func, orig_to_func, 4, true, false); + run_conv_test_s16_to_float(neon_to_func, orig_to_func, 5, true, false); + run_conv_test_s16_to_float(neon_to_func, orig_to_func, 6, true, false); + run_conv_test_s16_to_float(neon_to_func, orig_to_func, 7, true, true); +} +END_TEST +#endif /* HAVE_NEON */ +#endif /* defined (__arm__) && defined (__linux__) */ + +int main(int argc, char *argv[]) { + int failed = 0; + Suite *s; + TCase *tc; + SRunner *sr; + + if (!getenv("MAKE_CHECK")) + pa_log_set_level(PA_LOG_DEBUG); + + s = suite_create("CPU"); + + tc = tcase_create("sconv"); +#if defined (__i386__) || defined (__amd64__) + tcase_add_test(tc, sconv_sse2_test); + tcase_add_test(tc, sconv_sse_test); +#endif +#if defined (__arm__) && defined (__linux__) +#if HAVE_NEON + tcase_add_test(tc, sconv_neon_test); +#endif +#endif + tcase_set_timeout(tc, 120); + suite_add_tcase(s, tc); + + sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/tests/cpu-test.c b/src/tests/cpu-test.c deleted file mode 100644 index 96137c7..0000000 --- a/src/tests/cpu-test.c +++ /dev/null @@ -1,877 +0,0 @@ -/*** - This file is part of PulseAudio. - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "runtime-test-util.h" - -/* Common defines for svolume tests */ -#define SAMPLES 1028 -#define TIMES 1000 -#define TIMES2 100 -#define PADDING 16 - -static void run_volume_test( - pa_do_volume_func_t func, - pa_do_volume_func_t orig_func, - int align, - int channels, - bool correct, - bool perf) { - - PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, s_orig[SAMPLES]) = { 0 }; - int32_t volumes[channels + PADDING]; - int16_t *samples, *samples_ref, *samples_orig; - int i, padding, nsamples, size; - - /* Force sample alignment as requested */ - samples = s + (8 - align); - samples_ref = s_ref + (8 - align); - samples_orig = s_orig + (8 - align); - nsamples = SAMPLES - (8 - align); - if (nsamples % channels) - nsamples -= nsamples % channels; - size = nsamples * sizeof(int16_t); - - pa_random(samples, size); - memcpy(samples_ref, samples, size); - memcpy(samples_orig, samples, size); - - for (i = 0; i < channels; i++) - volumes[i] = PA_CLAMP_VOLUME((pa_volume_t)(rand() >> 15)); - for (padding = 0; padding < PADDING; padding++, i++) - volumes[i] = volumes[padding]; - - if (correct) { - orig_func(samples_ref, volumes, channels, size); - func(samples, volumes, channels, size); - - for (i = 0; i < nsamples; i++) { - if (samples[i] != samples_ref[i]) { - pa_log_debug("Correctness test failed: align=%d, channels=%d", align, channels); - pa_log_debug("%d: %04hx != %04hx (%04hx * %08x)\n", i, samples[i], samples_ref[i], - samples_orig[i], volumes[i % channels]); - fail(); - } - } - } - - if (perf) { - pa_log_debug("Testing svolume %dch performance with %d sample alignment", channels, align); - - PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - memcpy(samples, samples_orig, size); - func(samples, volumes, channels, size); - } PA_RUNTIME_TEST_RUN_STOP - - PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - memcpy(samples_ref, samples_orig, size); - orig_func(samples_ref, volumes, channels, size); - } PA_RUNTIME_TEST_RUN_STOP - - fail_unless(memcmp(samples_ref, samples, size) == 0); - } -} - -#if defined (__i386__) || defined (__amd64__) -START_TEST (svolume_mmx_test) { - pa_do_volume_func_t orig_func, mmx_func; - pa_cpu_x86_flag_t flags = 0; - int i, j; - - pa_cpu_get_x86_flags(&flags); - - if (!((flags & PA_CPU_X86_MMX) && (flags & PA_CPU_X86_CMOV))) { - pa_log_info("MMX/CMOV not supported. Skipping"); - return; - } - - orig_func = pa_get_volume_func(PA_SAMPLE_S16NE); - pa_volume_func_init_mmx(flags); - mmx_func = pa_get_volume_func(PA_SAMPLE_S16NE); - - pa_log_debug("Checking MMX svolume"); - for (i = 1; i <= 3; i++) { - for (j = 0; j < 7; j++) - run_volume_test(mmx_func, orig_func, j, i, true, false); - } - run_volume_test(mmx_func, orig_func, 7, 1, true, true); - run_volume_test(mmx_func, orig_func, 7, 2, true, true); - run_volume_test(mmx_func, orig_func, 7, 3, true, true); -} -END_TEST - -START_TEST (svolume_sse_test) { - pa_do_volume_func_t orig_func, sse_func; - pa_cpu_x86_flag_t flags = 0; - int i, j; - - pa_cpu_get_x86_flags(&flags); - - if (!(flags & PA_CPU_X86_SSE2)) { - pa_log_info("SSE2 not supported. Skipping"); - return; - } - - orig_func = pa_get_volume_func(PA_SAMPLE_S16NE); - pa_volume_func_init_sse(flags); - sse_func = pa_get_volume_func(PA_SAMPLE_S16NE); - - pa_log_debug("Checking SSE2 svolume"); - for (i = 1; i <= 3; i++) { - for (j = 0; j < 7; j++) - run_volume_test(sse_func, orig_func, j, i, true, false); - } - run_volume_test(sse_func, orig_func, 7, 1, true, true); - run_volume_test(sse_func, orig_func, 7, 2, true, true); - run_volume_test(sse_func, orig_func, 7, 3, true, true); -} -END_TEST -#endif /* defined (__i386__) || defined (__amd64__) */ - -#if defined (__arm__) && defined (__linux__) -START_TEST (svolume_arm_test) { - pa_do_volume_func_t orig_func, arm_func; - pa_cpu_arm_flag_t flags = 0; - int i, j; - - pa_cpu_get_arm_flags(&flags); - - if (!(flags & PA_CPU_ARM_V6)) { - pa_log_info("ARMv6 instructions not supported. Skipping"); - return; - } - - orig_func = pa_get_volume_func(PA_SAMPLE_S16NE); - pa_volume_func_init_arm(flags); - arm_func = pa_get_volume_func(PA_SAMPLE_S16NE); - - pa_log_debug("Checking ARM svolume"); - for (i = 1; i <= 3; i++) { - for (j = 0; j < 7; j++) - run_volume_test(arm_func, orig_func, j, i, true, false); - } - run_volume_test(arm_func, orig_func, 7, 1, true, true); - run_volume_test(arm_func, orig_func, 7, 2, true, true); - run_volume_test(arm_func, orig_func, 7, 3, true, true); -} -END_TEST -#endif /* defined (__arm__) && defined (__linux__) */ - -START_TEST (svolume_orc_test) { - pa_do_volume_func_t orig_func, orc_func; - pa_cpu_info cpu_info; - int i, j; - -#if defined (__i386__) || defined (__amd64__) - pa_zero(cpu_info); - cpu_info.cpu_type = PA_CPU_X86; - pa_cpu_get_x86_flags(&cpu_info.flags.x86); -#endif - - orig_func = pa_get_volume_func(PA_SAMPLE_S16NE); - - if (!pa_cpu_init_orc(cpu_info)) { - pa_log_info("Orc not supported. Skipping"); - return; - } - - orc_func = pa_get_volume_func(PA_SAMPLE_S16NE); - - pa_log_debug("Checking Orc svolume"); - for (i = 1; i <= 2; i++) { - for (j = 0; j < 7; j++) - run_volume_test(orc_func, orig_func, j, i, true, false); - } - run_volume_test(orc_func, orig_func, 7, 1, true, true); - run_volume_test(orc_func, orig_func, 7, 2, true, true); -} -END_TEST - -#undef SAMPLES -#undef TIMES -#undef TIMES2 -#undef PADDING -/* End svolume tests */ - -/* Start conversion tests */ -#define SAMPLES 1028 -#define TIMES 1000 -#define TIMES2 100 - -static void run_conv_test_float_to_s16( - pa_convert_func_t func, - pa_convert_func_t orig_func, - int align, - bool correct, - bool perf) { - - PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES]) = { 0 }; - PA_DECLARE_ALIGNED(8, float, f[SAMPLES]); - int16_t *samples, *samples_ref; - float *floats; - int i, nsamples; - - /* Force sample alignment as requested */ - samples = s + (8 - align); - samples_ref = s_ref + (8 - align); - floats = f + (8 - align); - nsamples = SAMPLES - (8 - align); - - for (i = 0; i < nsamples; i++) { - floats[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f); - } - - if (correct) { - orig_func(nsamples, floats, samples_ref); - func(nsamples, floats, samples); - - for (i = 0; i < nsamples; i++) { - if (abs(samples[i] - samples_ref[i]) > 1) { - pa_log_debug("Correctness test failed: align=%d", align); - pa_log_debug("%d: %04hx != %04hx (%.24f)\n", i, samples[i], samples_ref[i], floats[i]); - fail(); - } - } - } - - if (perf) { - pa_log_debug("Testing sconv performance with %d sample alignment", align); - - PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - func(nsamples, floats, samples); - } PA_RUNTIME_TEST_RUN_STOP - - PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - orig_func(nsamples, floats, samples_ref); - } PA_RUNTIME_TEST_RUN_STOP - } -} - -/* This test is currently only run under NEON */ -#if defined (__arm__) && defined (__linux__) -#ifdef HAVE_NEON -static void run_conv_test_s16_to_float( - pa_convert_func_t func, - pa_convert_func_t orig_func, - int align, - bool correct, - bool perf) { - - PA_DECLARE_ALIGNED(8, float, f[SAMPLES]) = { 0 }; - PA_DECLARE_ALIGNED(8, float, f_ref[SAMPLES]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]); - float *floats, *floats_ref; - int16_t *samples; - int i, nsamples; - - /* Force sample alignment as requested */ - floats = f + (8 - align); - floats_ref = f_ref + (8 - align); - samples = s + (8 - align); - nsamples = SAMPLES - (8 - align); - - pa_random(samples, nsamples * sizeof(int16_t)); - - if (correct) { - orig_func(nsamples, samples, floats_ref); - func(nsamples, samples, floats); - - for (i = 0; i < nsamples; i++) { - if (fabsf(floats[i] - floats_ref[i]) > 0.0001) { - pa_log_debug("Correctness test failed: align=%d", align); - pa_log_debug("%d: %.24f != %.24f (%d)\n", i, floats[i], floats_ref[i], samples[i]); - fail(); - } - } - } - - if (perf) { - pa_log_debug("Testing sconv performance with %d sample alignment", align); - - PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - func(nsamples, samples, floats); - } PA_RUNTIME_TEST_RUN_STOP - - PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - orig_func(nsamples, samples, floats_ref); - } PA_RUNTIME_TEST_RUN_STOP - } -} -#endif /* HAVE_NEON */ -#endif /* defined (__arm__) && defined (__linux__) */ - -#if defined (__i386__) || defined (__amd64__) -START_TEST (sconv_sse2_test) { - pa_cpu_x86_flag_t flags = 0; - pa_convert_func_t orig_func, sse2_func; - - pa_cpu_get_x86_flags(&flags); - - if (!(flags & PA_CPU_X86_SSE2)) { - pa_log_info("SSE2 not supported. Skipping"); - return; - } - - orig_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); - pa_convert_func_init_sse(PA_CPU_X86_SSE2); - sse2_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); - - pa_log_debug("Checking SSE2 sconv (float -> s16)"); - run_conv_test_float_to_s16(sse2_func, orig_func, 0, true, false); - run_conv_test_float_to_s16(sse2_func, orig_func, 1, true, false); - run_conv_test_float_to_s16(sse2_func, orig_func, 2, true, false); - run_conv_test_float_to_s16(sse2_func, orig_func, 3, true, false); - run_conv_test_float_to_s16(sse2_func, orig_func, 4, true, false); - run_conv_test_float_to_s16(sse2_func, orig_func, 5, true, false); - run_conv_test_float_to_s16(sse2_func, orig_func, 6, true, false); - run_conv_test_float_to_s16(sse2_func, orig_func, 7, true, true); -} -END_TEST - -START_TEST (sconv_sse_test) { - pa_cpu_x86_flag_t flags = 0; - pa_convert_func_t orig_func, sse_func; - - pa_cpu_get_x86_flags(&flags); - - if (!(flags & PA_CPU_X86_SSE)) { - pa_log_info("SSE not supported. Skipping"); - return; - } - - orig_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); - pa_convert_func_init_sse(PA_CPU_X86_SSE); - sse_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); - - pa_log_debug("Checking SSE sconv (float -> s16)"); - run_conv_test_float_to_s16(sse_func, orig_func, 0, true, false); - run_conv_test_float_to_s16(sse_func, orig_func, 1, true, false); - run_conv_test_float_to_s16(sse_func, orig_func, 2, true, false); - run_conv_test_float_to_s16(sse_func, orig_func, 3, true, false); - run_conv_test_float_to_s16(sse_func, orig_func, 4, true, false); - run_conv_test_float_to_s16(sse_func, orig_func, 5, true, false); - run_conv_test_float_to_s16(sse_func, orig_func, 6, true, false); - run_conv_test_float_to_s16(sse_func, orig_func, 7, true, true); -} -END_TEST -#endif /* defined (__i386__) || defined (__amd64__) */ - -#if defined (__arm__) && defined (__linux__) -#ifdef HAVE_NEON -START_TEST (sconv_neon_test) { - pa_cpu_arm_flag_t flags = 0; - pa_convert_func_t orig_from_func, neon_from_func; - pa_convert_func_t orig_to_func, neon_to_func; - - pa_cpu_get_arm_flags(&flags); - - if (!(flags & PA_CPU_ARM_NEON)) { - pa_log_info("NEON not supported. Skipping"); - return; - } - - orig_from_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); - orig_to_func = pa_get_convert_to_float32ne_function(PA_SAMPLE_S16LE); - pa_convert_func_init_neon(flags); - neon_from_func = pa_get_convert_from_float32ne_function(PA_SAMPLE_S16LE); - neon_to_func = pa_get_convert_to_float32ne_function(PA_SAMPLE_S16LE); - - pa_log_debug("Checking NEON sconv (float -> s16)"); - run_conv_test_float_to_s16(neon_from_func, orig_from_func, 0, true, false); - run_conv_test_float_to_s16(neon_from_func, orig_from_func, 1, true, false); - run_conv_test_float_to_s16(neon_from_func, orig_from_func, 2, true, false); - run_conv_test_float_to_s16(neon_from_func, orig_from_func, 3, true, false); - run_conv_test_float_to_s16(neon_from_func, orig_from_func, 4, true, false); - run_conv_test_float_to_s16(neon_from_func, orig_from_func, 5, true, false); - run_conv_test_float_to_s16(neon_from_func, orig_from_func, 6, true, false); - run_conv_test_float_to_s16(neon_from_func, orig_from_func, 7, true, true); - - pa_log_debug("Checking NEON sconv (s16 -> float)"); - run_conv_test_s16_to_float(neon_to_func, orig_to_func, 0, true, false); - run_conv_test_s16_to_float(neon_to_func, orig_to_func, 1, true, false); - run_conv_test_s16_to_float(neon_to_func, orig_to_func, 2, true, false); - run_conv_test_s16_to_float(neon_to_func, orig_to_func, 3, true, false); - run_conv_test_s16_to_float(neon_to_func, orig_to_func, 4, true, false); - run_conv_test_s16_to_float(neon_to_func, orig_to_func, 5, true, false); - run_conv_test_s16_to_float(neon_to_func, orig_to_func, 6, true, false); - run_conv_test_s16_to_float(neon_to_func, orig_to_func, 7, true, true); -} -END_TEST -#endif /* HAVE_NEON */ -#endif /* defined (__arm__) && defined (__linux__) */ - -#undef SAMPLES -#undef TIMES -/* End conversion tests */ - -/* Start remap tests */ -#define SAMPLES 1028 -#define TIMES 1000 -#define TIMES2 100 - -static void run_remap_test_mono_stereo_float( - pa_remap_t *remap, - pa_do_remap_func_t func, - pa_do_remap_func_t orig_func, - int align, - bool correct, - bool perf) { - - PA_DECLARE_ALIGNED(8, float, s_ref[SAMPLES*2]) = { 0 }; - PA_DECLARE_ALIGNED(8, float, s[SAMPLES*2]) = { 0 }; - PA_DECLARE_ALIGNED(8, float, m[SAMPLES]); - float *stereo, *stereo_ref; - float *mono; - int i, nsamples; - - /* Force sample alignment as requested */ - stereo = s + (8 - align); - stereo_ref = s_ref + (8 - align); - mono = m + (8 - align); - nsamples = SAMPLES - (8 - align); - - for (i = 0; i < nsamples; i++) - mono[i] = 2.1f * (rand()/(float) RAND_MAX - 0.5f); - - if (correct) { - orig_func(remap, stereo_ref, mono, nsamples); - func(remap, stereo, mono, nsamples); - - for (i = 0; i < nsamples * 2; i++) { - if (fabsf(stereo[i] - stereo_ref[i]) > 0.0001) { - pa_log_debug("Correctness test failed: align=%d", align); - pa_log_debug("%d: %.24f != %.24f (%.24f)\n", i, stereo[i], stereo_ref[i], mono[i]); - fail(); - } - } - } - - if (perf) { - pa_log_debug("Testing remap performance with %d sample alignment", align); - - PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - func(remap, stereo, mono, nsamples); - } PA_RUNTIME_TEST_RUN_STOP - - PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - orig_func(remap, stereo_ref, mono, nsamples); - } PA_RUNTIME_TEST_RUN_STOP - } -} - -static void run_remap_test_mono_stereo_s16( - pa_remap_t *remap, - pa_do_remap_func_t func, - pa_do_remap_func_t orig_func, - int align, - bool correct, - bool perf) { - - PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES*2]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES*2]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, m[SAMPLES]); - int16_t *stereo, *stereo_ref; - int16_t *mono; - int i, nsamples; - - /* Force sample alignment as requested */ - stereo = s + (8 - align); - stereo_ref = s_ref + (8 - align); - mono = m + (8 - align); - nsamples = SAMPLES - (8 - align); - - pa_random(mono, nsamples * sizeof(int16_t)); - - if (correct) { - orig_func(remap, stereo_ref, mono, nsamples); - func(remap, stereo, mono, nsamples); - - for (i = 0; i < nsamples * 2; i++) { - if (abs(stereo[i] - stereo_ref[i]) > 1) { - pa_log_debug("Correctness test failed: align=%d", align); - pa_log_debug("%d: %d != %d (%d)\n", i, stereo[i], stereo_ref[i], mono[i]); - fail(); - } - } - } - - if (perf) { - pa_log_debug("Testing remap performance with %d sample alignment", align); - - PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - func(remap, stereo, mono, nsamples); - } PA_RUNTIME_TEST_RUN_STOP - - PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - orig_func(remap, stereo_ref, mono, nsamples); - } PA_RUNTIME_TEST_RUN_STOP - } -} - -static void remap_test_mono_stereo_float( - pa_init_remap_func_t init_func, - pa_init_remap_func_t orig_init_func) { - - pa_remap_t remap; - pa_do_remap_func_t orig_func, func; - - remap.format = PA_SAMPLE_FLOAT32NE; - remap.i_ss.channels = 1; - remap.o_ss.channels = 2; - remap.map_table_f[0][0] = 1.0; - remap.map_table_f[1][0] = 1.0; - remap.map_table_i[0][0] = 0x10000; - remap.map_table_i[1][0] = 0x10000; - orig_init_func(&remap); - orig_func = remap.do_remap; - if (!orig_func) { - pa_log_warn("No reference remapping function, abort test"); - return; - } - - init_func(&remap); - func = remap.do_remap; - if (!func || func == orig_func) { - pa_log_warn("No remapping function, abort test"); - return; - } - - run_remap_test_mono_stereo_float(&remap, func, orig_func, 0, true, false); - run_remap_test_mono_stereo_float(&remap, func, orig_func, 1, true, false); - run_remap_test_mono_stereo_float(&remap, func, orig_func, 2, true, false); - run_remap_test_mono_stereo_float(&remap, func, orig_func, 3, true, true); -} - -static void remap_test_mono_stereo_s16( - pa_init_remap_func_t init_func, - pa_init_remap_func_t orig_init_func) { - - pa_remap_t remap; - pa_do_remap_func_t orig_func, func; - - remap.format = PA_SAMPLE_S16NE; - remap.i_ss.channels = 1; - remap.o_ss.channels = 2; - remap.map_table_f[0][0] = 1.0; - remap.map_table_f[1][0] = 1.0; - remap.map_table_i[0][0] = 0x10000; - remap.map_table_i[1][0] = 0x10000; - orig_init_func(&remap); - orig_func = remap.do_remap; - if (!orig_func) { - pa_log_warn("No reference remapping function, abort test"); - return; - } - - init_func(&remap); - func = remap.do_remap; - if (!func || func == orig_func) { - pa_log_warn("No remapping function, abort test"); - return; - } - - run_remap_test_mono_stereo_s16(&remap, func, orig_func, 0, true, false); - run_remap_test_mono_stereo_s16(&remap, func, orig_func, 1, true, false); - run_remap_test_mono_stereo_s16(&remap, func, orig_func, 2, true, false); - run_remap_test_mono_stereo_s16(&remap, func, orig_func, 3, true, true); -} - -#if defined (__i386__) || defined (__amd64__) -START_TEST (remap_mmx_test) { - pa_cpu_x86_flag_t flags = 0; - pa_init_remap_func_t init_func, orig_init_func; - - pa_cpu_get_x86_flags(&flags); - if (!(flags & PA_CPU_X86_MMX)) { - pa_log_info("MMX not supported. Skipping"); - return; - } - - pa_log_debug("Checking MMX remap (float, mono->stereo)"); - orig_init_func = pa_get_init_remap_func(); - pa_remap_func_init_mmx(flags); - init_func = pa_get_init_remap_func(); - remap_test_mono_stereo_float(init_func, orig_init_func); - - pa_log_debug("Checking MMX remap (s16, mono->stereo)"); - remap_test_mono_stereo_s16(init_func, orig_init_func); -} -END_TEST - -START_TEST (remap_sse2_test) { - pa_cpu_x86_flag_t flags = 0; - pa_init_remap_func_t init_func, orig_init_func; - - pa_cpu_get_x86_flags(&flags); - if (!(flags & PA_CPU_X86_SSE2)) { - pa_log_info("SSE2 not supported. Skipping"); - return; - } - - pa_log_debug("Checking SSE2 remap (float, mono->stereo)"); - orig_init_func = pa_get_init_remap_func(); - pa_remap_func_init_sse(flags); - init_func = pa_get_init_remap_func(); - remap_test_mono_stereo_float(init_func, orig_init_func); - - pa_log_debug("Checking SSE2 remap (s16, mono->stereo)"); - remap_test_mono_stereo_s16(init_func, orig_init_func); -} -END_TEST -#endif /* defined (__i386__) || defined (__amd64__) */ - -#undef SAMPLES -#undef TIMES -#undef TIMES2 -/* End remap tests */ - -/* Start mix tests */ - -/* Only ARM NEON has mix tests, so disable the related functions for other - * architectures for now to avoid compiler warnings about unused functions. */ -#if defined (__arm__) && defined (__linux__) -#ifdef HAVE_NEON - -#define SAMPLES 1028 -#define TIMES 1000 -#define TIMES2 100 - -static void acquire_mix_streams(pa_mix_info streams[], unsigned nstreams) { - unsigned i; - - for (i = 0; i < nstreams; i++) - streams[i].ptr = pa_memblock_acquire_chunk(&streams[i].chunk); -} - -static void release_mix_streams(pa_mix_info streams[], unsigned nstreams) { - unsigned i; - - for (i = 0; i < nstreams; i++) - pa_memblock_release(streams[i].chunk.memblock); -} - -static void run_mix_test( - pa_do_mix_func_t func, - pa_do_mix_func_t orig_func, - int align, - int channels, - bool correct, - bool perf) { - - PA_DECLARE_ALIGNED(8, int16_t, in0[SAMPLES * 4]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, in1[SAMPLES * 4]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, out[SAMPLES * 4]) = { 0 }; - PA_DECLARE_ALIGNED(8, int16_t, out_ref[SAMPLES * 4]) = { 0 }; - int16_t *samples0, *samples1; - int16_t *samples, *samples_ref; - int nsamples; - pa_mempool *pool; - pa_memchunk c0, c1; - pa_mix_info m[2]; - int i; - - pa_assert(channels == 1 || channels == 2 || channels == 4); - - /* Force sample alignment as requested */ - samples0 = in0 + (8 - align); - samples1 = in1 + (8 - align); - samples = out + (8 - align); - samples_ref = out_ref + (8 - align); - nsamples = channels * (SAMPLES - (8 - align)); - - fail_unless((pool = pa_mempool_new(false, 0)) != NULL, NULL); - - pa_random(samples0, nsamples * sizeof(int16_t)); - c0.memblock = pa_memblock_new_fixed(pool, samples0, nsamples * sizeof(int16_t), false); - c0.length = pa_memblock_get_length(c0.memblock); - c0.index = 0; - - pa_random(samples1, nsamples * sizeof(int16_t)); - c1.memblock = pa_memblock_new_fixed(pool, samples1, nsamples * sizeof(int16_t), false); - c1.length = pa_memblock_get_length(c1.memblock); - c1.index = 0; - - m[0].chunk = c0; - m[0].volume.channels = channels; - for (i = 0; i < channels; i++) { - m[0].volume.values[i] = PA_VOLUME_NORM; - m[0].linear[i].i = 0x5555; - } - - m[1].chunk = c1; - m[1].volume.channels = channels; - for (i = 0; i < channels; i++) { - m[1].volume.values[i] = PA_VOLUME_NORM; - m[1].linear[i].i = 0x6789; - } - - if (correct) { - acquire_mix_streams(m, 2); - orig_func(m, 2, channels, samples_ref, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - - acquire_mix_streams(m, 2); - func(m, 2, channels, samples, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - - for (i = 0; i < nsamples; i++) { - if (samples[i] != samples_ref[i]) { - pa_log_debug("Correctness test failed: align=%d, channels=%d", align, channels); - pa_log_debug("%d: %hd != %04hd (%hd + %hd)\n", - i, - samples[i], samples_ref[i], - samples0[i], samples1[i]); - fail(); - } - } - } - - if (perf) { - pa_log_debug("Testing %d-channel mixing performance with %d sample alignment", channels, align); - - PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { - acquire_mix_streams(m, 2); - func(m, 2, channels, samples, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - } PA_RUNTIME_TEST_RUN_STOP - - PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { - acquire_mix_streams(m, 2); - orig_func(m, 2, channels, samples_ref, nsamples * sizeof(int16_t)); - release_mix_streams(m, 2); - } PA_RUNTIME_TEST_RUN_STOP - } - - pa_memblock_unref(c0.memblock); - pa_memblock_unref(c1.memblock); - - pa_mempool_free(pool); -} -#endif /* HAVE_NEON */ -#endif /* defined (__arm__) && defined (__linux__) */ - -#if defined (__arm__) && defined (__linux__) -#ifdef HAVE_NEON -START_TEST (mix_neon_test) { - pa_do_mix_func_t orig_func, neon_func; - pa_cpu_arm_flag_t flags = 0; - - pa_cpu_get_arm_flags(&flags); - - if (!(flags & PA_CPU_ARM_NEON)) { - pa_log_info("NEON not supported. Skipping"); - return; - } - - orig_func = pa_get_mix_func(PA_SAMPLE_S16NE); - pa_mix_func_init_neon(flags); - neon_func = pa_get_mix_func(PA_SAMPLE_S16NE); - - pa_log_debug("Checking NEON mix"); - run_mix_test(neon_func, orig_func, 7, 2, true, true); -} -END_TEST -#endif /* HAVE_NEON */ -#endif /* defined (__arm__) && defined (__linux__) */ -/* End mix tests */ - -int main(int argc, char *argv[]) { - int failed = 0; - Suite *s; - TCase *tc; - SRunner *sr; - - if (!getenv("MAKE_CHECK")) - pa_log_set_level(PA_LOG_DEBUG); - - s = suite_create("CPU"); - - /* Volume tests */ - tc = tcase_create("svolume"); -#if defined (__i386__) || defined (__amd64__) - tcase_add_test(tc, svolume_mmx_test); - tcase_add_test(tc, svolume_sse_test); -#endif -#if defined (__arm__) && defined (__linux__) - tcase_add_test(tc, svolume_arm_test); -#endif - tcase_add_test(tc, svolume_orc_test); - tcase_set_timeout(tc, 120); - suite_add_tcase(s, tc); - - /* Conversion tests */ - tc = tcase_create("sconv"); -#if defined (__i386__) || defined (__amd64__) - tcase_add_test(tc, sconv_sse2_test); - tcase_add_test(tc, sconv_sse_test); -#endif -#if defined (__arm__) && defined (__linux__) -#if HAVE_NEON - tcase_add_test(tc, sconv_neon_test); -#endif -#endif - tcase_set_timeout(tc, 120); - suite_add_tcase(s, tc); - - /* Remap tests */ - tc = tcase_create("remap"); -#if defined (__i386__) || defined (__amd64__) - tcase_add_test(tc, remap_mmx_test); - tcase_add_test(tc, remap_sse2_test); -#endif - tcase_set_timeout(tc, 120); - suite_add_tcase(s, tc); - /* Mix tests */ - tc = tcase_create("mix"); -#if defined (__arm__) && defined (__linux__) -#if HAVE_NEON - tcase_add_test(tc, mix_neon_test); -#endif -#endif - tcase_set_timeout(tc, 120); - suite_add_tcase(s, tc); - - sr = srunner_create(s); - srunner_run_all(sr, CK_NORMAL); - failed = srunner_ntests_failed(sr); - srunner_free(sr); - - return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/src/tests/cpu-volume-test.c b/src/tests/cpu-volume-test.c new file mode 100644 index 0000000..659136e --- /dev/null +++ b/src/tests/cpu-volume-test.c @@ -0,0 +1,249 @@ +/*** + This file is part of PulseAudio. + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include "runtime-test-util.h" + +/* Common defines for svolume tests */ +#define SAMPLES 1028 +#define TIMES 1000 +#define TIMES2 100 +#define PADDING 16 + +static void run_volume_test( + pa_do_volume_func_t func, + pa_do_volume_func_t orig_func, + int align, + int channels, + bool correct, + bool perf) { + + PA_DECLARE_ALIGNED(8, int16_t, s[SAMPLES]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, s_ref[SAMPLES]) = { 0 }; + PA_DECLARE_ALIGNED(8, int16_t, s_orig[SAMPLES]) = { 0 }; + int32_t volumes[channels + PADDING]; + int16_t *samples, *samples_ref, *samples_orig; + int i, padding, nsamples, size; + + /* Force sample alignment as requested */ + samples = s + (8 - align); + samples_ref = s_ref + (8 - align); + samples_orig = s_orig + (8 - align); + nsamples = SAMPLES - (8 - align); + if (nsamples % channels) + nsamples -= nsamples % channels; + size = nsamples * sizeof(int16_t); + + pa_random(samples, size); + memcpy(samples_ref, samples, size); + memcpy(samples_orig, samples, size); + + for (i = 0; i < channels; i++) + volumes[i] = PA_CLAMP_VOLUME((pa_volume_t)(rand() >> 15)); + for (padding = 0; padding < PADDING; padding++, i++) + volumes[i] = volumes[padding]; + + if (correct) { + orig_func(samples_ref, volumes, channels, size); + func(samples, volumes, channels, size); + + for (i = 0; i < nsamples; i++) { + if (samples[i] != samples_ref[i]) { + pa_log_debug("Correctness test failed: align=%d, channels=%d", align, channels); + pa_log_debug("%d: %04hx != %04hx (%04hx * %08x)\n", i, samples[i], samples_ref[i], + samples_orig[i], volumes[i % channels]); + fail(); + } + } + } + + if (perf) { + pa_log_debug("Testing svolume %dch performance with %d sample alignment", channels, align); + + PA_RUNTIME_TEST_RUN_START("func", TIMES, TIMES2) { + memcpy(samples, samples_orig, size); + func(samples, volumes, channels, size); + } PA_RUNTIME_TEST_RUN_STOP + + PA_RUNTIME_TEST_RUN_START("orig", TIMES, TIMES2) { + memcpy(samples_ref, samples_orig, size); + orig_func(samples_ref, volumes, channels, size); + } PA_RUNTIME_TEST_RUN_STOP + + fail_unless(memcmp(samples_ref, samples, size) == 0); + } +} + +#if defined (__i386__) || defined (__amd64__) +START_TEST (svolume_mmx_test) { + pa_do_volume_func_t orig_func, mmx_func; + pa_cpu_x86_flag_t flags = 0; + int i, j; + + pa_cpu_get_x86_flags(&flags); + + if (!((flags & PA_CPU_X86_MMX) && (flags & PA_CPU_X86_CMOV))) { + pa_log_info("MMX/CMOV not supported. Skipping"); + return; + } + + orig_func = pa_get_volume_func(PA_SAMPLE_S16NE); + pa_volume_func_init_mmx(flags); + mmx_func = pa_get_volume_func(PA_SAMPLE_S16NE); + + pa_log_debug("Checking MMX svolume"); + for (i = 1; i <= 3; i++) { + for (j = 0; j < 7; j++) + run_volume_test(mmx_func, orig_func, j, i, true, false); + } + run_volume_test(mmx_func, orig_func, 7, 1, true, true); + run_volume_test(mmx_func, orig_func, 7, 2, true, true); + run_volume_test(mmx_func, orig_func, 7, 3, true, true); +} +END_TEST + +START_TEST (svolume_sse_test) { + pa_do_volume_func_t orig_func, sse_func; + pa_cpu_x86_flag_t flags = 0; + int i, j; + + pa_cpu_get_x86_flags(&flags); + + if (!(flags & PA_CPU_X86_SSE2)) { + pa_log_info("SSE2 not supported. Skipping"); + return; + } + + orig_func = pa_get_volume_func(PA_SAMPLE_S16NE); + pa_volume_func_init_sse(flags); + sse_func = pa_get_volume_func(PA_SAMPLE_S16NE); + + pa_log_debug("Checking SSE2 svolume"); + for (i = 1; i <= 3; i++) { + for (j = 0; j < 7; j++) + run_volume_test(sse_func, orig_func, j, i, true, false); + } + run_volume_test(sse_func, orig_func, 7, 1, true, true); + run_volume_test(sse_func, orig_func, 7, 2, true, true); + run_volume_test(sse_func, orig_func, 7, 3, true, true); +} +END_TEST +#endif /* defined (__i386__) || defined (__amd64__) */ + +#if defined (__arm__) && defined (__linux__) +START_TEST (svolume_arm_test) { + pa_do_volume_func_t orig_func, arm_func; + pa_cpu_arm_flag_t flags = 0; + int i, j; + + pa_cpu_get_arm_flags(&flags); + + if (!(flags & PA_CPU_ARM_V6)) { + pa_log_info("ARMv6 instructions not supported. Skipping"); + return; + } + + orig_func = pa_get_volume_func(PA_SAMPLE_S16NE); + pa_volume_func_init_arm(flags); + arm_func = pa_get_volume_func(PA_SAMPLE_S16NE); + + pa_log_debug("Checking ARM svolume"); + for (i = 1; i <= 3; i++) { + for (j = 0; j < 7; j++) + run_volume_test(arm_func, orig_func, j, i, true, false); + } + run_volume_test(arm_func, orig_func, 7, 1, true, true); + run_volume_test(arm_func, orig_func, 7, 2, true, true); + run_volume_test(arm_func, orig_func, 7, 3, true, true); +} +END_TEST +#endif /* defined (__arm__) && defined (__linux__) */ + +START_TEST (svolume_orc_test) { + pa_do_volume_func_t orig_func, orc_func; + pa_cpu_info cpu_info; + int i, j; + +#if defined (__i386__) || defined (__amd64__) + pa_zero(cpu_info); + cpu_info.cpu_type = PA_CPU_X86; + pa_cpu_get_x86_flags(&cpu_info.flags.x86); +#endif + + orig_func = pa_get_volume_func(PA_SAMPLE_S16NE); + + if (!pa_cpu_init_orc(cpu_info)) { + pa_log_info("Orc not supported. Skipping"); + return; + } + + orc_func = pa_get_volume_func(PA_SAMPLE_S16NE); + + pa_log_debug("Checking Orc svolume"); + for (i = 1; i <= 2; i++) { + for (j = 0; j < 7; j++) + run_volume_test(orc_func, orig_func, j, i, true, false); + } + run_volume_test(orc_func, orig_func, 7, 1, true, true); + run_volume_test(orc_func, orig_func, 7, 2, true, true); +} +END_TEST + +int main(int argc, char *argv[]) { + int failed = 0; + Suite *s; + TCase *tc; + SRunner *sr; + + if (!getenv("MAKE_CHECK")) + pa_log_set_level(PA_LOG_DEBUG); + + s = suite_create("CPU"); + + tc = tcase_create("svolume"); +#if defined (__i386__) || defined (__amd64__) + tcase_add_test(tc, svolume_mmx_test); + tcase_add_test(tc, svolume_sse_test); +#endif +#if defined (__arm__) && defined (__linux__) + tcase_add_test(tc, svolume_arm_test); +#endif + tcase_add_test(tc, svolume_orc_test); + tcase_set_timeout(tc, 120); + suite_add_tcase(s, tc); + + sr = srunner_create(s); + srunner_run_all(sr, CK_NORMAL); + failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} commit f4ab8bd8353073dcebb1e4e9fd340b9999cc7e9a Author: Peter Meerwald Date: Fri Apr 18 09:59:32 2014 +0200 cpu: Add force_generic_code flag to cpu_info struct The remapper and channel mixing code have (faster) specialized and (slower) generic code certain code path. The flag force_generic_code can be set to force the generic code path which is useful for testing. Code duplication (such as in mix-special-test) can be avoided, cleanup patches follow. Signed-off-by: Peter Meerwald diff --git a/src/pulsecore/cpu.c b/src/pulsecore/cpu.c index 814abf6..e0c110e 100644 --- a/src/pulsecore/cpu.c +++ b/src/pulsecore/cpu.c @@ -23,6 +23,8 @@ void pa_cpu_init(pa_cpu_info *cpu_info) { cpu_info->cpu_type = PA_CPU_UNDEFINED; + /* don't force generic code, used for testing only */ + cpu_info->force_generic_code = false; if (!getenv("PULSE_NO_SIMD")) { if (pa_cpu_init_x86(&cpu_info->flags.x86)) cpu_info->cpu_type = PA_CPU_X86; @@ -30,4 +32,7 @@ void pa_cpu_init(pa_cpu_info *cpu_info) { cpu_info->cpu_type = PA_CPU_ARM; pa_cpu_init_orc(*cpu_info); } + + pa_remap_func_init(cpu_info); + pa_mix_func_init(cpu_info); } diff --git a/src/pulsecore/cpu.h b/src/pulsecore/cpu.h index 23262b5..03507de 100644 --- a/src/pulsecore/cpu.h +++ b/src/pulsecore/cpu.h @@ -40,8 +40,12 @@ struct pa_cpu_info { pa_cpu_x86_flag_t x86; pa_cpu_arm_flag_t arm; } flags; + bool force_generic_code; }; void pa_cpu_init(pa_cpu_info *cpu_info); +void pa_remap_func_init(const pa_cpu_info *cpu_info); +void pa_mix_func_init(const pa_cpu_info *cpu_info); + #endif /* foocpuhfoo */ diff --git a/src/pulsecore/mix.c b/src/pulsecore/mix.c index 03c71f0..06b22bd 100644 --- a/src/pulsecore/mix.c +++ b/src/pulsecore/mix.c @@ -32,6 +32,7 @@ #include #include +#include "cpu.h" #include "mix.h" #define VOLUME_PADDING 32 @@ -606,6 +607,13 @@ static pa_do_mix_func_t do_mix_table[] = { [PA_SAMPLE_S24_32RE] = (pa_do_mix_func_t) pa_mix_s24_32re_c }; +void pa_mix_func_init(const pa_cpu_info *cpu_info) { + if (cpu_info->force_generic_code) + do_mix_table[PA_SAMPLE_S16NE] = (pa_do_mix_func_t) pa_mix_generic_s16ne; + else + do_mix_table[PA_SAMPLE_S16NE] = (pa_do_mix_func_t) pa_mix_s16ne_c; +} + size_t pa_mix( pa_mix_info streams[], unsigned nstreams, diff --git a/src/pulsecore/remap.c b/src/pulsecore/remap.c index 09d4837..d9b121e 100644 --- a/src/pulsecore/remap.c +++ b/src/pulsecore/remap.c @@ -32,6 +32,7 @@ #include #include +#include "cpu.h" #include "remap.h" static void remap_mono_to_stereo_s16ne_c(pa_remap_t *m, int16_t *dst, const int16_t *src, unsigned n) { @@ -361,6 +362,8 @@ void pa_set_remap_func(pa_remap_t *m, pa_do_remap_func_t func_s16, pa_assert_not_reached(); } +static bool force_generic_code = false; + /* set the function that will execute the remapping based on the matrices */ static void init_remap_c(pa_remap_t *m) { unsigned n_oc, n_ic; @@ -370,6 +373,13 @@ static void init_remap_c(pa_remap_t *m) { n_ic = m->i_ss.channels; /* find some common channel remappings, fall back to full matrix operation. */ + if (force_generic_code) { + pa_log_info("Forced to use generic matrix remapping"); + pa_set_remap_func(m, (pa_do_remap_func_t) remap_channels_matrix_s16ne_c, + (pa_do_remap_func_t) remap_channels_matrix_float32ne_c); + return; + } + if (n_ic == 1 && n_oc == 2 && m->map_table_i[0][0] == 0x10000 && m->map_table_i[1][0] == 0x10000) { @@ -452,3 +462,7 @@ pa_init_remap_func_t pa_get_init_remap_func(void) { void pa_set_init_remap_func(pa_init_remap_func_t func) { init_remap_func = func; } + +void pa_remap_func_init(const pa_cpu_info *cpu_info) { + force_generic_code = cpu_info->force_generic_code; +} commit 61c888dc936ade04b8c57442cc1ed716b4f535bf Author: Peter Meerwald Date: Wed Sep 10 15:53:37 2014 +0200 cpu: Don't check for both x86 and ARM code Signed-off-by: Peter Meerwald diff --git a/src/pulsecore/cpu.c b/src/pulsecore/cpu.c index 542e86f..814abf6 100644 --- a/src/pulsecore/cpu.c +++ b/src/pulsecore/cpu.c @@ -26,7 +26,7 @@ void pa_cpu_init(pa_cpu_info *cpu_info) { if (!getenv("PULSE_NO_SIMD")) { if (pa_cpu_init_x86(&cpu_info->flags.x86)) cpu_info->cpu_type = PA_CPU_X86; - if (pa_cpu_init_arm(&cpu_info->flags.arm)) + else if (pa_cpu_init_arm(&cpu_info->flags.arm)) cpu_info->cpu_type = PA_CPU_ARM; pa_cpu_init_orc(*cpu_info); } commit 380591eb18daaddccc054073438a011df0e8bf20 Author: Peter Meerwald Date: Wed Sep 10 15:23:11 2014 +0200 core: Add pa_cpu_init() / cpu.c move code dealing with CPU specific code path initialization from daemon/main.c to pulsecore/cpu.c Signed-off-by: Peter Meerwald diff --git a/src/Makefile.am b/src/Makefile.am index 3ceaddc..40d8c04 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -906,7 +906,7 @@ libpulsecore_ at PA_MAJORMINOR@_la_SOURCES = \ pulsecore/rtpoll.c pulsecore/rtpoll.h \ pulsecore/stream-util.c pulsecore/stream-util.h \ pulsecore/mix.c pulsecore/mix.h \ - pulsecore/cpu.h \ + pulsecore/cpu.c pulsecore/cpu.h \ pulsecore/cpu-arm.c pulsecore/cpu-arm.h \ pulsecore/cpu-x86.c pulsecore/cpu-x86.h \ pulsecore/cpu-orc.c pulsecore/cpu-orc.h \ diff --git a/src/daemon/main.c b/src/daemon/main.c index 23fb660..4fd245a 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -86,9 +86,7 @@ #ifdef HAVE_DBUS #include #endif -#include -#include -#include +#include #include "cmdline.h" #include "cpulimit.h" @@ -1022,14 +1020,7 @@ int main(int argc, char *argv[]) { c->server_type = conf->local_server_type; #endif - c->cpu_info.cpu_type = PA_CPU_UNDEFINED; - if (!getenv("PULSE_NO_SIMD")) { - if (pa_cpu_init_x86(&(c->cpu_info.flags.x86))) - c->cpu_info.cpu_type = PA_CPU_X86; - if (pa_cpu_init_arm(&(c->cpu_info.flags.arm))) - c->cpu_info.cpu_type = PA_CPU_ARM; - pa_cpu_init_orc(c->cpu_info); - } + pa_cpu_init(&c->cpu_info); pa_assert_se(pa_signal_init(pa_mainloop_get_api(mainloop)) == 0); pa_signal_new(SIGINT, signal_callback, c); diff --git a/src/pulsecore/cpu.c b/src/pulsecore/cpu.c new file mode 100644 index 0000000..542e86f --- /dev/null +++ b/src/pulsecore/cpu.c @@ -0,0 +1,33 @@ +/*** + This file is part of PulseAudio. + + Copyright 2014 Peter Meerwald + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "cpu.h" +#include "cpu-orc.h" + +void pa_cpu_init(pa_cpu_info *cpu_info) { + cpu_info->cpu_type = PA_CPU_UNDEFINED; + if (!getenv("PULSE_NO_SIMD")) { + if (pa_cpu_init_x86(&cpu_info->flags.x86)) + cpu_info->cpu_type = PA_CPU_X86; + if (pa_cpu_init_arm(&cpu_info->flags.arm)) + cpu_info->cpu_type = PA_CPU_ARM; + pa_cpu_init_orc(*cpu_info); + } +} diff --git a/src/pulsecore/cpu.h b/src/pulsecore/cpu.h index 7fe6f0b..23262b5 100644 --- a/src/pulsecore/cpu.h +++ b/src/pulsecore/cpu.h @@ -42,4 +42,6 @@ struct pa_cpu_info { } flags; }; +void pa_cpu_init(pa_cpu_info *cpu_info); + #endif /* foocpuhfoo */ From tanuk at kemper.freedesktop.org Thu Sep 11 04:02:05 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Thu, 11 Sep 2014 04:02:05 -0700 (PDT) Subject: [pulseaudio-commits] 11 commits - src/modules Message-ID: <20140911110205.6D5897618C@kemper.freedesktop.org> src/modules/bluetooth/backend-ofono.c | 503 +++++++++++++++++++++++++++++++++- 1 file changed, 497 insertions(+), 6 deletions(-) New commits: commit f7c7cd1825a0bf0ad643d4dfd4a38f589930e886 Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:34 2014 +0200 bluetooth: Implement org.ofono.HandsfreeAudioAgent.Release() diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index 3f40941..cab5319 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -491,7 +491,15 @@ static DBusMessage *hf_audio_agent_release(DBusConnection *c, DBusMessage *m, vo return r; } - r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); + pa_log_debug("HF audio agent has been unregistered by oFono (%s)", backend->ofono_bus_id); + + pa_hashmap_remove_all(backend->cards); + + pa_xfree(backend->ofono_bus_id); + backend->ofono_bus_id = NULL; + + pa_assert_se(r = dbus_message_new_method_return(m)); + return r; } commit b1a09ebf7ea3ba9471d2376b2b42fc252897278d Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:33 2014 +0200 bluetooth: Handle CardRemoved signal diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index fe4e2ca..3f40941 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -269,6 +269,24 @@ fail: hf_audio_card_free(card); } +static void hf_audio_agent_card_removed(pa_bluetooth_backend *backend, const char *path) { + struct hf_audio_card *card; + + pa_assert(backend); + pa_assert(path); + + pa_log_debug("HF card removed: %s", path); + + card = pa_hashmap_remove(backend->cards, path); + if (!card) + return; + + if (card->transport) + pa_bluetooth_transport_unlink(card->transport); + + hf_audio_card_free(card); +} + static void hf_audio_agent_get_cards_reply(DBusPendingCall *pending, void *userdata) { DBusMessage *r; pa_dbus_pending *p; @@ -444,6 +462,15 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *da dbus_message_iter_recurse(&arg_i, &props_i); hf_audio_agent_card_found(backend, p, &props_i); + } else if (dbus_message_is_signal(m, "org.ofono.HandsfreeAudioManager", "CardRemoved")) { + const char *p; + + if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &p, DBUS_TYPE_INVALID)) { + pa_log_error("Failed to parse org.ofono.HandsfreeAudioManager.CardRemoved: %s", err.message); + goto fail; + } + + hf_audio_agent_card_removed(backend, p); } fail: commit 8f838b1f31b45db68303d45918e6fd4fc7018dcb Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:32 2014 +0200 bluetooth: Handle CardAdded signal diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index ef8b2ce..fe4e2ca 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -249,18 +249,19 @@ static void hf_audio_agent_card_found(pa_bluetooth_backend *backend, const char dbus_message_iter_next(props_i); } - pa_hashmap_put(backend->cards, card->path, card); - d = pa_bluetooth_discovery_get_device_by_address(backend->discovery, card->remote_address, card->local_address); - if (d) { - card->transport = pa_bluetooth_transport_new(d, backend->ofono_bus_id, path, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY, NULL, 0); - card->transport->acquire = hf_audio_agent_transport_acquire; - card->transport->release = hf_audio_agent_transport_release; - card->transport->userdata = card; - - pa_bluetooth_transport_put(card->transport); - } else + if (!d) { pa_log_error("Device doesnt exist for %s", path); + goto fail; + } + + card->transport = pa_bluetooth_transport_new(d, backend->ofono_bus_id, path, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY, NULL, 0); + card->transport->acquire = hf_audio_agent_transport_acquire; + card->transport->release = hf_audio_agent_transport_release; + card->transport->userdata = card; + + pa_bluetooth_transport_put(card->transport); + pa_hashmap_put(backend->cards, card->path, card); return; @@ -426,6 +427,23 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *da } } + } else if (dbus_message_is_signal(m, "org.ofono.HandsfreeAudioManager", "CardAdded")) { + const char *p; + DBusMessageIter arg_i, props_i; + + if (!dbus_message_iter_init(m, &arg_i) || !pa_streq(dbus_message_get_signature(m), "oa{sv}")) { + pa_log_error("Failed to parse org.ofono.HandsfreeAudioManager.CardAdded"); + goto fail; + } + + dbus_message_iter_get_basic(&arg_i, &p); + + pa_assert_se(dbus_message_iter_next(&arg_i)); + pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_ARRAY); + + dbus_message_iter_recurse(&arg_i, &props_i); + + hf_audio_agent_card_found(backend, p, &props_i); } fail: commit 0e7f303256ff9c156a00b0530c3a90d9a26c07ca Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:31 2014 +0200 bluetooth: Track oFono service diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index bc92f4a..ef8b2ce 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -384,6 +384,7 @@ static void hf_audio_agent_unregister(pa_bluetooth_backend *backend) { static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *data) { const char *sender; + DBusError err; pa_bluetooth_backend *backend = data; pa_assert(bus); @@ -394,6 +395,41 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *da if (!pa_safe_streq(backend->ofono_bus_id, sender) && !pa_streq("org.freedesktop.DBus", sender)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + dbus_error_init(&err); + + if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) { + const char *name, *old_owner, *new_owner; + + if (!dbus_message_get_args(m, &err, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old_owner, + DBUS_TYPE_STRING, &new_owner, + DBUS_TYPE_INVALID)) { + pa_log_error("Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message); + goto fail; + } + + if (pa_streq(name, OFONO_SERVICE)) { + + if (old_owner && *old_owner) { + pa_log_debug("oFono disappeared"); + + pa_hashmap_remove_all(backend->cards); + + pa_xfree(backend->ofono_bus_id); + backend->ofono_bus_id = NULL; + } + + if (new_owner && *new_owner) { + pa_log_debug("oFono appeared"); + hf_audio_agent_register(backend); + } + } + + } + +fail: + dbus_error_free(&err); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } commit c4c4de532d3837fcc42a50536130a14ed48f5153 Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:30 2014 +0200 bluetooth: Implement transport release for hf_audio_agent transports diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index 518e775..bc92f4a 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -188,6 +188,22 @@ static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool opti } static void hf_audio_agent_transport_release(pa_bluetooth_transport *t) { + struct hf_audio_card *card = t->userdata; + + pa_assert(card); + + if (t->state <= PA_BLUETOOTH_TRANSPORT_STATE_IDLE) { + pa_log_info("Transport %s already released", t->path); + return; + } + + if (card->fd < 0) + return; + + /* shutdown to make sure connection is dropped immediately */ + shutdown(card->fd, SHUT_RDWR); + close(card->fd); + card->fd = -1; } static void hf_audio_agent_card_found(pa_bluetooth_backend *backend, const char *path, DBusMessageIter *props_i) { commit 8dd4aa1f006b31ccee0bf17081e961ae86bb48c6 Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:29 2014 +0200 bluetooth: Implement transport acquire for hf_audio_agent transports diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index 02c2b65..518e775 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -23,9 +23,13 @@ #include #endif +#include +#include + #include #include #include +#include #include "bluez5-util.h" @@ -118,8 +122,69 @@ static void hf_audio_card_free(struct hf_audio_card *card) { pa_xfree(card); } +static int socket_accept(int sock) +{ + char c; + struct pollfd pfd; + + if (sock < 0) + return -ENOTCONN; + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sock; + pfd.events = POLLOUT; + + if (poll(&pfd, 1, 0) < 0) + return -errno; + + /* + * If socket already writable then it is not in defer setup state, + * otherwise it needs to be read to authorize the connection. + */ + if ((pfd.revents & POLLOUT)) + return 0; + + /* Enable socket by reading 1 byte */ + if (read(sock, &c, 1) < 0) + return -errno; + + return 0; +} + static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { - return -1; + struct hf_audio_card *card = t->userdata; + int err; + + pa_assert(card); + + if (!optional) { + DBusMessage *m; + + pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, "org.ofono.HandsfreeAudioCard", "Connect")); + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(card->backend->connection), m, NULL)); + + return -1; + } + + /* The correct block size should take into account the SCO MTU from + * the Bluetooth adapter and (for adapters in the USB bus) the MxPS + * value from the Isoc USB endpoint in use by btusb and should be + * made available to userspace by the Bluetooth kernel subsystem. + * Meanwhile the empiric value 48 will be used. */ + if (imtu) + *imtu = 48; + if (omtu) + *omtu = 48; + + t->codec = card->codec; + + err = socket_accept(card->fd); + if (err < 0) { + pa_log_error("Deferred setup failed on fd %d: %s", card->fd, pa_cstrerror(-err)); + return -1; + } + + return card->fd; } static void hf_audio_agent_transport_release(pa_bluetooth_transport *t) { commit c09866582063ff06f60b4c88e0de71fae989981f Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:28 2014 +0200 bluetooth: Parse HandsfreeAudioCard properties diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index 0da7c18..02c2b65 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -25,6 +25,7 @@ #include #include +#include #include "bluez5-util.h" @@ -56,6 +57,18 @@ " " \ "" +struct hf_audio_card { + pa_bluetooth_backend *backend; + char *path; + char *remote_address; + char *local_address; + + int fd; + uint8_t codec; + + pa_bluetooth_transport *transport; +}; + struct pa_bluetooth_backend { pa_core *core; pa_bluetooth_discovery *discovery; @@ -83,6 +96,97 @@ static pa_dbus_pending* hf_dbus_send_and_add_to_pending(pa_bluetooth_backend *ba return p; } +static struct hf_audio_card *hf_audio_card_new(pa_bluetooth_backend *backend, const char *path) { + struct hf_audio_card *card = pa_xnew0(struct hf_audio_card, 1); + + card->path = pa_xstrdup(path); + card->backend = backend; + card->fd = -1; + + return card; +} + +static void hf_audio_card_free(struct hf_audio_card *card) { + pa_assert(card); + + if (card->transport) + pa_bluetooth_transport_free(card->transport); + + pa_xfree(card->path); + pa_xfree(card->remote_address); + pa_xfree(card->local_address); + pa_xfree(card); +} + +static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { + return -1; +} + +static void hf_audio_agent_transport_release(pa_bluetooth_transport *t) { +} + +static void hf_audio_agent_card_found(pa_bluetooth_backend *backend, const char *path, DBusMessageIter *props_i) { + DBusMessageIter i, value_i; + const char *key, *value; + struct hf_audio_card *card; + pa_bluetooth_device *d; + + pa_assert(backend); + pa_assert(path); + pa_assert(props_i); + + pa_log_debug("New HF card found: %s", path); + + card = hf_audio_card_new(backend, path); + + while (dbus_message_iter_get_arg_type(props_i) != DBUS_TYPE_INVALID) { + char c; + + dbus_message_iter_recurse(props_i, &i); + + dbus_message_iter_get_basic(&i, &key); + dbus_message_iter_next(&i); + dbus_message_iter_recurse(&i, &value_i); + + if ((c = dbus_message_iter_get_arg_type(&value_i)) != DBUS_TYPE_STRING) { + pa_log_error("Invalid properties for %s: expected 's', received '%c'", path, c); + goto fail; + } + + dbus_message_iter_get_basic(&value_i, &value); + + if (pa_streq(key, "RemoteAddress")) { + pa_xfree(card->remote_address); + card->remote_address = pa_xstrdup(value); + } else if (pa_streq(key, "LocalAddress")) { + pa_xfree(card->local_address); + card->local_address = pa_xstrdup(value); + } + + pa_log_debug("%s: %s", key, value); + + dbus_message_iter_next(props_i); + } + + pa_hashmap_put(backend->cards, card->path, card); + + d = pa_bluetooth_discovery_get_device_by_address(backend->discovery, card->remote_address, card->local_address); + if (d) { + card->transport = pa_bluetooth_transport_new(d, backend->ofono_bus_id, path, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY, NULL, 0); + card->transport->acquire = hf_audio_agent_transport_acquire; + card->transport->release = hf_audio_agent_transport_release; + card->transport->userdata = card; + + pa_bluetooth_transport_put(card->transport); + } else + pa_log_error("Device doesnt exist for %s", path); + + return; + +fail: + hf_audio_card_free(card); +} + static void hf_audio_agent_get_cards_reply(DBusPendingCall *pending, void *userdata) { DBusMessage *r; pa_dbus_pending *p; @@ -114,7 +218,7 @@ static void hf_audio_agent_get_cards_reply(DBusPendingCall *pending, void *userd dbus_message_iter_recurse(&struct_i, &props_i); - /* TODO: Parse HandsfreeAudioCard properties */ + hf_audio_agent_card_found(backend, path, &props_i); dbus_message_iter_next(&array_i); } @@ -295,7 +399,8 @@ pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discover backend = pa_xnew0(pa_bluetooth_backend, 1); backend->core = c; backend->discovery = y; - backend->cards = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + backend->cards = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, + (pa_free_cb_t) hf_audio_card_free); dbus_error_init(&err); commit a5a0506c4e51a3254b4ac3267bd275c65a01ec34 Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:27 2014 +0200 bluetooth: List HandsfreeAudioCard objects from oFono diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index fb66fc7..0da7c18 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -83,6 +83,58 @@ static pa_dbus_pending* hf_dbus_send_and_add_to_pending(pa_bluetooth_backend *ba return p; } +static void hf_audio_agent_get_cards_reply(DBusPendingCall *pending, void *userdata) { + DBusMessage *r; + pa_dbus_pending *p; + pa_bluetooth_backend *backend; + DBusMessageIter i, array_i, struct_i, props_i; + + pa_assert_se(p = userdata); + pa_assert_se(backend = p->context_data); + pa_assert_se(r = dbus_pending_call_steal_reply(pending)); + + if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { + pa_log_error("Failed to get a list of handsfree audio cards from ofono: %s: %s", + dbus_message_get_error_name(r), pa_dbus_get_error_message(r)); + goto finish; + } + + if (!dbus_message_iter_init(r, &i) || !pa_streq(dbus_message_get_signature(r), "a(oa{sv})")) { + pa_log_error("Invalid arguments in GetCards() reply"); + goto finish; + } + + dbus_message_iter_recurse(&i, &array_i); + while (dbus_message_iter_get_arg_type(&array_i) != DBUS_TYPE_INVALID) { + const char *path; + + dbus_message_iter_recurse(&array_i, &struct_i); + dbus_message_iter_get_basic(&struct_i, &path); + dbus_message_iter_next(&struct_i); + + dbus_message_iter_recurse(&struct_i, &props_i); + + /* TODO: Parse HandsfreeAudioCard properties */ + + dbus_message_iter_next(&array_i); + } + +finish: + dbus_message_unref(r); + + PA_LLIST_REMOVE(pa_dbus_pending, backend->pending, p); + pa_dbus_pending_free(p); +} + +static void hf_audio_agent_get_cards(pa_bluetooth_backend *hf) { + DBusMessage *m; + + pa_assert(hf); + + pa_assert_se(m = dbus_message_new_method_call(OFONO_SERVICE, "/", HF_AUDIO_MANAGER_INTERFACE, "GetCards")); + hf_dbus_send_and_add_to_pending(hf, m, hf_audio_agent_get_cards_reply, NULL); +} + static void hf_audio_agent_register_reply(DBusPendingCall *pending, void *userdata) { DBusMessage *r; pa_dbus_pending *p; @@ -100,7 +152,7 @@ static void hf_audio_agent_register_reply(DBusPendingCall *pending, void *userda backend->ofono_bus_id = pa_xstrdup(dbus_message_get_sender(r)); - /* TODO: List all HandsfreeAudioCard objects */ + hf_audio_agent_get_cards(backend); finish: dbus_message_unref(r); commit 374c28a40eea2a608d7bc066803588b5d843df08 Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:26 2014 +0200 bluetooth: Register/Unregister Handsfree Audio Agent with oFono Register as a HandsfreeAudioAgent with oFono during backend initialization and unregiter during backend finalization. This commit also adds a check when receiving method calls or signals to make sure the sender matches with the D-Bus service we're registered with. diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index 1a4416e..fb66fc7 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -28,6 +28,9 @@ #include "bluez5-util.h" +#define HFP_AUDIO_CODEC_CVSD 0x01 +#define HFP_AUDIO_CODEC_MSBC 0x02 + #define OFONO_SERVICE "org.ofono" #define HF_AUDIO_AGENT_INTERFACE OFONO_SERVICE ".HandsfreeAudioAgent" #define HF_AUDIO_MANAGER_INTERFACE OFONO_SERVICE ".HandsfreeAudioManager" @@ -58,6 +61,7 @@ struct pa_bluetooth_backend { pa_bluetooth_discovery *discovery; pa_dbus_connection *connection; pa_hashmap *cards; + char *ofono_bus_id; PA_LLIST_HEAD(pa_dbus_pending, pending); }; @@ -79,20 +83,114 @@ static pa_dbus_pending* hf_dbus_send_and_add_to_pending(pa_bluetooth_backend *ba return p; } +static void hf_audio_agent_register_reply(DBusPendingCall *pending, void *userdata) { + DBusMessage *r; + pa_dbus_pending *p; + pa_bluetooth_backend *backend; + + pa_assert_se(p = userdata); + pa_assert_se(backend = p->context_data); + pa_assert_se(r = dbus_pending_call_steal_reply(pending)); + + if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) { + pa_log_error("Failed to register as a handsfree audio agent with ofono: %s: %s", + dbus_message_get_error_name(r), pa_dbus_get_error_message(r)); + goto finish; + } + + backend->ofono_bus_id = pa_xstrdup(dbus_message_get_sender(r)); + + /* TODO: List all HandsfreeAudioCard objects */ + +finish: + dbus_message_unref(r); + + PA_LLIST_REMOVE(pa_dbus_pending, backend->pending, p); + pa_dbus_pending_free(p); +} + +static void hf_audio_agent_register(pa_bluetooth_backend *hf) { + DBusMessage *m; + uint8_t codecs[2]; + const uint8_t *pcodecs = codecs; + int ncodecs = 0; + const char *path = HF_AUDIO_AGENT_PATH; + + pa_assert(hf); + + pa_assert_se(m = dbus_message_new_method_call(OFONO_SERVICE, "/", HF_AUDIO_MANAGER_INTERFACE, "Register")); + + codecs[ncodecs++] = HFP_AUDIO_CODEC_CVSD; + + pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pcodecs, ncodecs, + DBUS_TYPE_INVALID)); + + hf_dbus_send_and_add_to_pending(hf, m, hf_audio_agent_register_reply, NULL); +} + +static void hf_audio_agent_unregister(pa_bluetooth_backend *backend) { + DBusMessage *m; + const char *path = HF_AUDIO_AGENT_PATH; + + pa_assert(backend); + pa_assert(backend->connection); + + if (backend->ofono_bus_id) { + pa_assert_se(m = dbus_message_new_method_call(backend->ofono_bus_id, "/", HF_AUDIO_MANAGER_INTERFACE, "Unregister")); + pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)); + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(backend->connection), m, NULL)); + + pa_xfree(backend->ofono_bus_id); + backend->ofono_bus_id = NULL; + } +} + static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *data) { + const char *sender; + pa_bluetooth_backend *backend = data; + pa_assert(bus); pa_assert(m); + pa_assert(backend); + + sender = dbus_message_get_sender(m); + if (!pa_safe_streq(backend->ofono_bus_id, sender) && !pa_streq("org.freedesktop.DBus", sender)) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static DBusMessage *hf_audio_agent_release(DBusConnection *c, DBusMessage *m, void *data) { - DBusMessage *r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); + DBusMessage *r; + const char *sender; + pa_bluetooth_backend *backend = data; + + pa_assert(backend); + + sender = dbus_message_get_sender(m); + if (!pa_safe_streq(backend->ofono_bus_id, sender)) { + pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.NotAllowed", "Operation is not allowed by this sender")); + return r; + } + + r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); return r; } static DBusMessage *hf_audio_agent_new_connection(DBusConnection *c, DBusMessage *m, void *data) { - DBusMessage *r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); + DBusMessage *r; + const char *sender; + pa_bluetooth_backend *backend = data; + + pa_assert(backend); + + sender = dbus_message_get_sender(m); + if (!pa_safe_streq(backend->ofono_bus_id, sender)) { + pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.NotAllowed", "Operation is not allowed by this sender")); + return r; + } + + r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); return r; } @@ -180,6 +278,8 @@ pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discover pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(backend->connection), HF_AUDIO_AGENT_PATH, &vtable_hf_audio_agent, backend)); + hf_audio_agent_register(backend); + return backend; } @@ -188,6 +288,8 @@ void pa_bluetooth_backend_free(pa_bluetooth_backend *backend) { pa_dbus_free_pending_list(&backend->pending); + hf_audio_agent_unregister(backend); + dbus_connection_unregister_object_path(pa_dbus_connection_get(backend->connection), HF_AUDIO_AGENT_PATH); pa_dbus_remove_matches(pa_dbus_connection_get(backend->connection), commit d7a8ccce891454250a45e8ac7094cd4382aac3fa Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:25 2014 +0200 bluetooth: Create hf_dbus_send_and_add_to_pending() for oFono backend diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index 99da783..1a4416e 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -58,8 +58,27 @@ struct pa_bluetooth_backend { pa_bluetooth_discovery *discovery; pa_dbus_connection *connection; pa_hashmap *cards; + + PA_LLIST_HEAD(pa_dbus_pending, pending); }; +static pa_dbus_pending* hf_dbus_send_and_add_to_pending(pa_bluetooth_backend *backend, DBusMessage *m, + DBusPendingCallNotifyFunction func, void *call_data) { + pa_dbus_pending *p; + DBusPendingCall *call; + + pa_assert(backend); + pa_assert(m); + + pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(backend->connection), m, &call, -1)); + + p = pa_dbus_pending_new(pa_dbus_connection_get(backend->connection), m, call, backend, call_data); + PA_LLIST_PREPEND(pa_dbus_pending, backend->pending, p); + dbus_pending_call_set_notify(call, func, p, NULL); + + return p; +} + static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *data) { pa_assert(bus); pa_assert(m); @@ -167,6 +186,8 @@ pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discover void pa_bluetooth_backend_free(pa_bluetooth_backend *backend) { pa_assert(backend); + pa_dbus_free_pending_list(&backend->pending); + dbus_connection_unregister_object_path(pa_dbus_connection_get(backend->connection), HF_AUDIO_AGENT_PATH); pa_dbus_remove_matches(pa_dbus_connection_get(backend->connection), commit 98d3d857058d08bd23f7f344312fcae7751f1b60 Author: Jo??o Paulo Rechi Vita Date: Wed Sep 10 11:48:24 2014 +0200 bluetooth: Monitor D-Bus signals diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index 99ff09d..99da783 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -30,6 +30,7 @@ #define OFONO_SERVICE "org.ofono" #define HF_AUDIO_AGENT_INTERFACE OFONO_SERVICE ".HandsfreeAudioAgent" +#define HF_AUDIO_MANAGER_INTERFACE OFONO_SERVICE ".HandsfreeAudioManager" #define HF_AUDIO_AGENT_PATH "/HandsfreeAudioAgent" @@ -56,8 +57,16 @@ struct pa_bluetooth_backend { pa_core *core; pa_bluetooth_discovery *discovery; pa_dbus_connection *connection; + pa_hashmap *cards; }; +static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *data) { + pa_assert(bus); + pa_assert(m); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + static DBusMessage *hf_audio_agent_release(DBusConnection *c, DBusMessage *m, void *data) { DBusMessage *r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); return r; @@ -117,12 +126,35 @@ pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discover backend = pa_xnew0(pa_bluetooth_backend, 1); backend->core = c; backend->discovery = y; + backend->cards = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); dbus_error_init(&err); if (!(backend->connection = pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &err))) { pa_log("Failed to get D-Bus connection: %s", err.message); dbus_error_free(&err); + pa_xfree(backend); + return NULL; + } + + /* dynamic detection of handsfree audio cards */ + if (!dbus_connection_add_filter(pa_dbus_connection_get(backend->connection), filter_cb, backend, NULL)) { + pa_log_error("Failed to add filter function"); + pa_dbus_connection_unref(backend->connection); + pa_xfree(backend); + return NULL; + } + + if (pa_dbus_add_matches(pa_dbus_connection_get(backend->connection), &err, + "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'," + "arg0='" OFONO_SERVICE "'", + "type='signal',sender='" OFONO_SERVICE "',interface='" HF_AUDIO_MANAGER_INTERFACE "',member='CardAdded'", + "type='signal',sender='" OFONO_SERVICE "',interface='" HF_AUDIO_MANAGER_INTERFACE "',member='CardRemoved'", + NULL) < 0) { + pa_log("Failed to add oFono D-Bus matches: %s", err.message); + dbus_connection_remove_filter(pa_dbus_connection_get(backend->connection), filter_cb, backend); + pa_dbus_connection_unref(backend->connection); + pa_xfree(backend); return NULL; } @@ -135,11 +167,20 @@ pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discover void pa_bluetooth_backend_free(pa_bluetooth_backend *backend) { pa_assert(backend); - if (backend->connection) { - dbus_connection_unregister_object_path(pa_dbus_connection_get(backend->connection), HF_AUDIO_AGENT_PATH); + dbus_connection_unregister_object_path(pa_dbus_connection_get(backend->connection), HF_AUDIO_AGENT_PATH); - pa_dbus_connection_unref(backend->connection); - } + pa_dbus_remove_matches(pa_dbus_connection_get(backend->connection), + "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged'," + "arg0='" OFONO_SERVICE "'", + "type='signal',sender='" OFONO_SERVICE "',interface='" HF_AUDIO_MANAGER_INTERFACE "',member='CardAdded'", + "type='signal',sender='" OFONO_SERVICE "',interface='" HF_AUDIO_MANAGER_INTERFACE "',member='CardRemoved'", + NULL); + + dbus_connection_remove_filter(pa_dbus_connection_get(backend->connection), filter_cb, backend); + + pa_dbus_connection_unref(backend->connection); + + pa_hashmap_free(backend->cards); pa_xfree(backend); } From diwic at kemper.freedesktop.org Tue Sep 16 00:34:45 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Tue, 16 Sep 2014 00:34:45 -0700 (PDT) Subject: [pulseaudio-commits] 3 commits - src/modules Message-ID: <20140916073445.E2DEB7617E@kemper.freedesktop.org> src/modules/alsa/alsa-mixer.c | 14 +--- src/modules/alsa/alsa-mixer.h | 6 - src/modules/alsa/alsa-sink.c | 6 - src/modules/alsa/alsa-source.c | 6 - src/modules/alsa/alsa-ucm.c | 7 -- src/modules/alsa/alsa-util.c | 111 ++++++++++++++++++++++++------------ src/modules/alsa/alsa-util.h | 7 -- src/modules/alsa/module-alsa-card.c | 50 ++++++++-------- 8 files changed, 120 insertions(+), 87 deletions(-) New commits: commit 300a5e3ed70064c296e09bc4e40531f3257154c5 Author: David Henningsson Date: Mon Sep 1 15:58:22 2014 +0200 alsa: Remove unnecessary hctl handles being passed around Now that we have switched to using the mixer handle only, there is no use for sending hctl handles around. Signed-off-by: David Henningsson diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 6be56fe..8b23d90 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -2657,7 +2657,7 @@ static void path_create_settings(pa_alsa_path *p) { element_create_settings(p->elements, NULL); } -int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, snd_hctl_t *hctl, bool ignore_dB) { +int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB) { pa_alsa_element *e; pa_alsa_jack *j; double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX]; @@ -3851,7 +3851,6 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, snd_pcm_t *pcm_handle; pa_alsa_path_set *ps; snd_mixer_t *mixer_handle; - snd_hctl_t *hctl_handle; if (direction == PA_ALSA_DIRECTION_OUTPUT) { if (m->output_path_set) @@ -3870,7 +3869,7 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, pa_assert(pcm_handle); - mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL, &hctl_handle); + mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL); if (!mixer_handle) { /* Cannot open mixer, remove all entries */ pa_hashmap_remove_all(ps->paths); @@ -3878,7 +3877,7 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile, } PA_HASHMAP_FOREACH(p, ps->paths, state) { - if (pa_alsa_path_probe(p, mixer_handle, hctl_handle, m->profile_set->ignore_dB) < 0) { + if (pa_alsa_path_probe(p, mixer_handle, m->profile_set->ignore_dB) < 0) { pa_hashmap_remove(ps->paths, p); } } diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h index ff3cb2d..7e6300e 100644 --- a/src/modules/alsa/alsa-mixer.h +++ b/src/modules/alsa/alsa-mixer.h @@ -226,7 +226,7 @@ void pa_alsa_element_dump(pa_alsa_element *e); pa_alsa_path *pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction); pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction); -int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, snd_hctl_t *hctl, bool ignore_dB); +int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB); void pa_alsa_path_dump(pa_alsa_path *p); int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v); int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, bool *muted); @@ -335,7 +335,7 @@ void pa_alsa_profile_set_free(pa_alsa_profile_set *s); void pa_alsa_profile_set_dump(pa_alsa_profile_set *s); void pa_alsa_profile_set_drop_unsupported(pa_alsa_profile_set *s); -snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device, snd_hctl_t **hctl); +snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device); pa_alsa_fdlist *pa_alsa_fdlist_new(void); void pa_alsa_fdlist_free(pa_alsa_fdlist *fdl); diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index daa9061..9e9b863 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1886,12 +1886,10 @@ static void set_sink_name(pa_sink_new_data *data, pa_modargs *ma, const char *de } static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, bool ignore_dB) { - snd_hctl_t *hctl; - if (!mapping && !element) return; - if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device, &hctl))) { + if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) { pa_log_info("Failed to find a working mixer device."); return; } @@ -1901,7 +1899,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT))) goto fail; - if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, hctl, ignore_dB) < 0) + if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0) goto fail; pa_log_debug("Probed mixer path %s:", u->mixer_path->name); diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index c0759c6..2da0513 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1604,12 +1604,10 @@ static void set_source_name(pa_source_new_data *data, pa_modargs *ma, const char } static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, bool ignore_dB) { - snd_hctl_t *hctl; - if (!mapping && !element) return; - if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device, &hctl))) { + if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) { pa_log_info("Failed to find a working mixer device."); return; } @@ -1619,7 +1617,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT))) goto fail; - if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, hctl, ignore_dB) < 0) + if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0) goto fail; pa_log_debug("Probed mixer path %s:", u->mixer_path->name); diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c index 23522c7..6c848a9 100644 --- a/src/modules/alsa/alsa-ucm.c +++ b/src/modules/alsa/alsa-ucm.c @@ -1426,21 +1426,20 @@ static void profile_finalize_probing(pa_alsa_profile *p) { static void ucm_mapping_jack_probe(pa_alsa_mapping *m) { snd_pcm_t *pcm_handle; snd_mixer_t *mixer_handle; - snd_hctl_t *hctl_handle; pa_alsa_ucm_mapping_context *context = &m->ucm_context; pa_alsa_ucm_device *dev; uint32_t idx; pcm_handle = m->direction == PA_ALSA_DIRECTION_OUTPUT ? m->output_pcm : m->input_pcm; - mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL, &hctl_handle); - if (!mixer_handle || !hctl_handle) + mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL); + if (!mixer_handle) return; PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) { pa_alsa_jack *jack; jack = m->direction == PA_ALSA_DIRECTION_OUTPUT ? dev->output_jack : dev->input_jack; pa_assert (jack); - jack->has_control = pa_alsa_find_jack(hctl_handle, jack->alsa_name) != NULL; + jack->has_control = pa_alsa_mixer_find(mixer_handle, jack->alsa_name, 0) != NULL; pa_log_info("UCM jack %s has_control=%d", jack->name, jack->has_control); } diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 97edb67..0563c00 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -1476,30 +1476,6 @@ snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsig return NULL; } -snd_hctl_elem_t* pa_alsa_find_jack(snd_hctl_t *hctl, const char* jack_name) { - snd_ctl_elem_id_t *id; - - snd_ctl_elem_id_alloca(&id); - snd_ctl_elem_id_clear(id); - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_CARD); - snd_ctl_elem_id_set_name(id, jack_name); - - return snd_hctl_find_elem(hctl, id); -} - -snd_hctl_elem_t* pa_alsa_find_eld_ctl(snd_hctl_t *hctl, int device) { - snd_ctl_elem_id_t *id; - - /* See if we can find the ELD control */ - snd_ctl_elem_id_alloca(&id); - snd_ctl_elem_id_clear(id); - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_PCM); - snd_ctl_elem_id_set_name(id, "ELD"); - snd_ctl_elem_id_set_device(id, device); - - return snd_hctl_find_elem(hctl, id); -} - static int mixer_class_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2) { /* Dummy compare function */ @@ -1544,7 +1520,7 @@ static int mixer_class_event(snd_mixer_class_t *class, unsigned int mask, return 0; } -static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t **hctl) { +static int prepare_mixer(snd_mixer_t *mixer, const char *dev) { int err; snd_mixer_class_t *class; @@ -1556,13 +1532,6 @@ static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t **hctl) return -1; } - /* Note: The hctl handle returned should not be freed. - It is closed/freed by alsa-lib on snd_mixer_close/free */ - if (hctl && (err = snd_mixer_get_hctl(mixer, dev, hctl)) < 0) { - pa_log_info("Unable to get hctl of mixer %s: %s", dev, pa_alsa_strerror(err)); - return -1; - } - if (snd_mixer_class_malloc(&class)) { pa_log_info("Failed to allocate mixer class for %s", dev); return -1; @@ -1590,7 +1559,7 @@ static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t **hctl) return 0; } -snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device, snd_hctl_t **hctl) { +snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device) { int err; snd_mixer_t *m; char *md; @@ -1604,7 +1573,7 @@ snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device, snd_hctl /* Then, try by card index */ md = pa_sprintf_malloc("hw:%i", alsa_card_index); - if (prepare_mixer(m, md, hctl) >= 0) { + if (prepare_mixer(m, md) >= 0) { if (ctl_device) *ctl_device = md; @@ -1620,7 +1589,7 @@ snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device, snd_hctl return NULL; } -snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device, snd_hctl_t **hctl) { +snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) { int err; snd_mixer_t *m; const char *dev; @@ -1636,7 +1605,7 @@ snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device, snd_h /* First, try by name */ if ((dev = snd_pcm_name(pcm))) - if (prepare_mixer(m, dev, hctl) >= 0) { + if (prepare_mixer(m, dev) >= 0) { if (ctl_device) *ctl_device = pa_xstrdup(dev); @@ -1653,7 +1622,7 @@ snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device, snd_h md = pa_sprintf_malloc("hw:%i", card_idx); if (!dev || !pa_streq(dev, md)) - if (prepare_mixer(m, md, hctl) >= 0) { + if (prepare_mixer(m, md) >= 0) { if (ctl_device) *ctl_device = md; @@ -1671,25 +1640,19 @@ snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device, snd_h return NULL; } -int pa_alsa_get_hdmi_eld(snd_hctl_t *hctl, int device, pa_hdmi_eld *eld) { +int pa_alsa_get_hdmi_eld(snd_hctl_elem_t *elem, pa_hdmi_eld *eld) { /* The ELD format is specific to HDA Intel sound cards and defined in the HDA specification: http://www.intel.com/content/www/us/en/standards/high-definition-audio-specification.html */ int err; - snd_hctl_elem_t *elem; snd_ctl_elem_info_t *info; snd_ctl_elem_value_t *value; uint8_t *elddata; unsigned int eldsize, mnl; + unsigned int device; pa_assert(eld != NULL); - - /* See if we can find the ELD control */ - elem = pa_alsa_find_eld_ctl(hctl, device); - if (elem == NULL) { - pa_log_debug("No ELD info control found (for device=%d)", device); - return -1; - } + pa_assert(elem != NULL); /* Does it have any contents? */ snd_ctl_elem_info_alloca(&info); @@ -1700,6 +1663,7 @@ int pa_alsa_get_hdmi_eld(snd_hctl_t *hctl, int device, pa_hdmi_eld *eld) { return -1; } + device = snd_hctl_elem_get_device(elem); eldsize = snd_ctl_elem_info_get_count(info); elddata = (unsigned char *) snd_ctl_elem_value_get_bytes(value); if (elddata == NULL || eldsize == 0) { diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index 50b0aaf..fb47940 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -142,18 +142,15 @@ const char* pa_alsa_strerror(int errnum); bool pa_alsa_may_tsched(bool want); -snd_hctl_elem_t* pa_alsa_find_jack(snd_hctl_t *hctl, const char* jack_name); -snd_hctl_elem_t* pa_alsa_find_eld_ctl(snd_hctl_t *hctl, int device); - snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsigned int device); -snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device, snd_hctl_t **hctl); +snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device); typedef struct pa_hdmi_eld pa_hdmi_eld; struct pa_hdmi_eld { char monitor_name[17]; }; -int pa_alsa_get_hdmi_eld(snd_hctl_t *hctl, int device, pa_hdmi_eld *eld); +int pa_alsa_get_hdmi_eld(snd_hctl_elem_t *elem, pa_hdmi_eld *eld); #endif diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index d39d13e..ed332e0 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -111,7 +111,6 @@ struct userdata { int alsa_card_index; snd_mixer_t *mixer_handle; - snd_hctl_t *hctl_handle; pa_hashmap *jacks; pa_alsa_fdlist *mixer_fdl; @@ -422,7 +421,7 @@ static int hdmi_eld_changed(snd_mixer_elem_t *melem, unsigned int mask) { return 0; } - if (pa_alsa_get_hdmi_eld(u->hctl_handle, device, &eld) < 0) + if (pa_alsa_get_hdmi_eld(elem, &eld) < 0) memset(&eld, 0, sizeof(eld)); old_monitor_name = pa_proplist_gets(p->proplist, PA_PROP_DEVICE_PRODUCT_NAME); @@ -444,7 +443,7 @@ static void init_eld_ctls(struct userdata *u) { void *state; pa_device_port *port; - if (!u->hctl_handle) + if (!u->mixer_handle) return; PA_HASHMAP_FOREACH(port, u->card->ports, state) { @@ -501,7 +500,7 @@ static void init_jacks(struct userdata *u) { u->mixer_fdl = pa_alsa_fdlist_new(); - u->mixer_handle = pa_alsa_open_mixer(u->alsa_card_index, NULL, &u->hctl_handle); + u->mixer_handle = pa_alsa_open_mixer(u->alsa_card_index, NULL); if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) >= 0) { PA_HASHMAP_FOREACH(jack, u->jacks, state) { jack->melem = pa_alsa_mixer_find(u->mixer_handle, jack->alsa_name, 0); @@ -516,7 +515,7 @@ static void init_jacks(struct userdata *u) { } } else - pa_log("Failed to open hctl/mixer for jack detection"); + pa_log("Failed to open mixer for jack detection"); } commit f2120fc2b69579d51a2e1874649739a799815be9 Author: David Henningsson Date: Mon Sep 1 15:41:39 2014 +0200 alsa-mixer/card: Move to use the new mixer interface Use the new mixer API to get callbacks, instead of using the hctl API. Using the hctl API caused a memory leak, because alsa-lib itself used the hctl callbacks, which we were previously overriding. Signed-off-by: David Henningsson diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 201f835..6be56fe 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -1725,12 +1725,11 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) { return 0; } -static int jack_probe(pa_alsa_jack *j, snd_hctl_t *h) { - pa_assert(h); +static int jack_probe(pa_alsa_jack *j, snd_mixer_t *m) { pa_assert(j); pa_assert(j->path); - j->has_control = pa_alsa_find_jack(h, j->alsa_name) != NULL; + j->has_control = pa_alsa_mixer_find(m, j->alsa_name, 0) != NULL; if (j->has_control) { if (j->required_absent != PA_ALSA_REQUIRED_IGNORE) @@ -2678,7 +2677,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, snd_hctl_t *hctl, bool i pa_log_debug("Probing path '%s'", p->name); PA_LLIST_FOREACH(j, p->jacks) { - if (jack_probe(j, hctl) < 0) { + if (jack_probe(j, m) < 0) { p->supported = false; pa_log_debug("Probe of jack '%s' failed.", j->alsa_name); return -1; diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h index 4949560..ff3cb2d 100644 --- a/src/modules/alsa/alsa-mixer.h +++ b/src/modules/alsa/alsa-mixer.h @@ -164,7 +164,7 @@ struct pa_alsa_jack { char *alsa_name; /* E g "Headphone Jack" */ bool has_control; /* is the jack itself present? */ bool plugged_in; /* is this jack currently plugged in? */ - snd_hctl_elem_t *hctl_elem; /* Jack detection handle */ + snd_mixer_elem_t *melem; /* Jack detection handle */ pa_available_t state_unplugged, state_plugged; pa_alsa_required_t required; diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index 63ff6e6..d39d13e 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -350,8 +350,9 @@ static void report_port_state(pa_device_port *p, struct userdata *u) { pa_device_port_set_available(p, pa); } -static int report_jack_state(snd_hctl_elem_t *elem, unsigned int mask) { - struct userdata *u = snd_hctl_elem_get_callback_private(elem); +static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) { + struct userdata *u = snd_mixer_elem_get_callback_private(melem); + snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem); snd_ctl_elem_value_t *elem_value; bool plugged_in; void *state; @@ -374,7 +375,7 @@ static int report_jack_state(snd_hctl_elem_t *elem, unsigned int mask) { pa_log_debug("Jack '%s' is now %s", pa_strnull(snd_hctl_elem_get_name(elem)), plugged_in ? "plugged in" : "unplugged"); PA_HASHMAP_FOREACH(jack, u->jacks, state) - if (jack->hctl_elem == elem) { + if (jack->melem == melem) { jack->plugged_in = plugged_in; if (u->use_ucm) { pa_assert(u->card->ports); @@ -403,8 +404,9 @@ static pa_device_port* find_port_with_eld_device(pa_hashmap *ports, int device) return NULL; } -static int hdmi_eld_changed(snd_hctl_elem_t *elem, unsigned int mask) { - struct userdata *u = snd_hctl_elem_get_callback_private(elem); +static int hdmi_eld_changed(snd_mixer_elem_t *melem, unsigned int mask) { + struct userdata *u = snd_mixer_elem_get_callback_private(melem); + snd_hctl_elem_t *elem = snd_mixer_elem_get_private(melem); int device = snd_hctl_elem_get_device(elem); const char *old_monitor_name; pa_device_port *p; @@ -447,7 +449,7 @@ static void init_eld_ctls(struct userdata *u) { PA_HASHMAP_FOREACH(port, u->card->ports, state) { pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port); - snd_hctl_elem_t* hctl_elem; + snd_mixer_elem_t* melem; int device; pa_assert(data->path); @@ -455,15 +457,14 @@ static void init_eld_ctls(struct userdata *u) { if (device < 0) continue; - hctl_elem = pa_alsa_find_eld_ctl(u->hctl_handle, device); - if (!hctl_elem) { - pa_log_debug("No ELD device found for port %s.", port->name); - continue; + melem = pa_alsa_mixer_find(u->mixer_handle, "ELD", device); + if (melem) { + snd_mixer_elem_set_callback(melem, hdmi_eld_changed); + snd_mixer_elem_set_callback_private(melem, u); + hdmi_eld_changed(melem, 0); } - - snd_hctl_elem_set_callback_private(hctl_elem, u); - snd_hctl_elem_set_callback(hctl_elem, hdmi_eld_changed); - hdmi_eld_changed(hctl_elem, 0); + else + pa_log_debug("No ELD device found for port %s.", port->name); } } @@ -501,17 +502,17 @@ static void init_jacks(struct userdata *u) { u->mixer_fdl = pa_alsa_fdlist_new(); u->mixer_handle = pa_alsa_open_mixer(u->alsa_card_index, NULL, &u->hctl_handle); - if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, NULL, u->hctl_handle, u->core->mainloop) >= 0) { + if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) >= 0) { PA_HASHMAP_FOREACH(jack, u->jacks, state) { - jack->hctl_elem = pa_alsa_find_jack(u->hctl_handle, jack->alsa_name); - if (!jack->hctl_elem) { + jack->melem = pa_alsa_mixer_find(u->mixer_handle, jack->alsa_name, 0); + if (!jack->melem) { pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name); jack->has_control = false; continue; } - snd_hctl_elem_set_callback_private(jack->hctl_elem, u); - snd_hctl_elem_set_callback(jack->hctl_elem, report_jack_state); - report_jack_state(jack->hctl_elem, 0); + snd_mixer_elem_set_callback(jack->melem, report_jack_state); + snd_mixer_elem_set_callback_private(jack->melem, u); + report_jack_state(jack->melem, 0); } } else commit 1fd8848e64cfb352d0ab12ee27c8c667d81a8f6d Author: David Henningsson Date: Mon Sep 1 15:38:25 2014 +0200 alsa-util: Add functions for accessing mixer elements through mixer class Instead of using the hctl interface, we can find controls belonging to other iface types than "mixer". We do this by introducing a new mixer class "SND_MIXER_ELEM_PULSEAUDIO" and create snd_mixer_elem's for all PCM and CARD iface types (as Jacks are of the CARD type and ELD controls are of the PCM type). Signed-off-by: David Henningsson diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 1ce2e16..97edb67 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -1457,6 +1457,25 @@ bool pa_alsa_may_tsched(bool want) { return true; } +#define SND_MIXER_ELEM_PULSEAUDIO (SND_MIXER_ELEM_LAST + 10) + +snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsigned int device) { + snd_mixer_elem_t *elem; + + for (elem = snd_mixer_first_elem(mixer); elem; elem = snd_mixer_elem_next(elem)) { + snd_hctl_elem_t *helem; + if (snd_mixer_elem_get_type(elem) != SND_MIXER_ELEM_PULSEAUDIO) + continue; + helem = snd_mixer_elem_get_private(elem); + if (!pa_streq(snd_hctl_elem_get_name(helem), name)) + continue; + if (snd_hctl_elem_get_device(helem) != device) + continue; + return elem; + } + return NULL; +} + snd_hctl_elem_t* pa_alsa_find_jack(snd_hctl_t *hctl, const char* jack_name) { snd_ctl_elem_id_t *id; @@ -1481,8 +1500,53 @@ snd_hctl_elem_t* pa_alsa_find_eld_ctl(snd_hctl_t *hctl, int device) { return snd_hctl_find_elem(hctl, id); } +static int mixer_class_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2) +{ + /* Dummy compare function */ + return c1 == c2 ? 0 : (c1 > c2 ? 1 : -1); +} + +static int mixer_class_event(snd_mixer_class_t *class, unsigned int mask, + snd_hctl_elem_t *helem, snd_mixer_elem_t *melem) +{ + int err; + const char *name = snd_hctl_elem_get_name(helem); + if (mask & SND_CTL_EVENT_MASK_ADD) { + snd_ctl_elem_iface_t iface = snd_hctl_elem_get_interface(helem); + if (iface == SND_CTL_ELEM_IFACE_CARD || iface == SND_CTL_ELEM_IFACE_PCM) { + snd_mixer_elem_t *new_melem; + + /* Put the hctl pointer as our private data - it will be useful for callbacks */ + if ((err = snd_mixer_elem_new(&new_melem, SND_MIXER_ELEM_PULSEAUDIO, 0, helem, NULL)) < 0) { + pa_log_warn("snd_mixer_elem_new failed: %s", pa_alsa_strerror(err)); + return 0; + } + + if ((err = snd_mixer_elem_attach(new_melem, helem)) < 0) { + pa_log_warn("snd_mixer_elem_attach failed: %s", pa_alsa_strerror(err)); + snd_mixer_elem_free(melem); + return 0; + } + + if ((err = snd_mixer_elem_add(new_melem, class)) < 0) { + pa_log_warn("snd_mixer_elem_add failed: %s", pa_alsa_strerror(err)); + return 0; + } + } + } + else if (mask & SND_CTL_EVENT_MASK_VALUE) { + snd_mixer_elem_value(melem); /* Calls the element callback */ + return 0; + } + else + pa_log_info("Got an unknown mixer class event for %s: mask 0x%x\n", name, mask); + + return 0; +} + static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t **hctl) { int err; + snd_mixer_class_t *class; pa_assert(mixer); pa_assert(dev); @@ -1499,6 +1563,19 @@ static int prepare_mixer(snd_mixer_t *mixer, const char *dev, snd_hctl_t **hctl) return -1; } + if (snd_mixer_class_malloc(&class)) { + pa_log_info("Failed to allocate mixer class for %s", dev); + return -1; + } + snd_mixer_class_set_event(class, mixer_class_event); + snd_mixer_class_set_compare(class, mixer_class_compare); + if ((err = snd_mixer_class_register(class, mixer)) < 0) { + pa_log_info("Unable register mixer class for %s: %s", dev, pa_alsa_strerror(err)); + snd_mixer_class_free(class); + return -1; + } + /* From here on, the mixer class is deallocated by alsa on snd_mixer_close/free. */ + if ((err = snd_mixer_selem_register(mixer, NULL, NULL)) < 0) { pa_log_warn("Unable to register mixer: %s", pa_alsa_strerror(err)); return -1; diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index bb2ad4e..50b0aaf 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -145,6 +145,8 @@ bool pa_alsa_may_tsched(bool want); snd_hctl_elem_t* pa_alsa_find_jack(snd_hctl_t *hctl, const char* jack_name); snd_hctl_elem_t* pa_alsa_find_eld_ctl(snd_hctl_t *hctl, int device); +snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsigned int device); + snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device, snd_hctl_t **hctl); typedef struct pa_hdmi_eld pa_hdmi_eld; From tanuk at kemper.freedesktop.org Tue Sep 16 04:35:38 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Tue, 16 Sep 2014 04:35:38 -0700 (PDT) Subject: [pulseaudio-commits] po/LINGUAS po/sk.po Message-ID: <20140916113538.8397A7617E@kemper.freedesktop.org> po/LINGUAS | 1 po/sk.po | 2733 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2734 insertions(+) New commits: commit 7a44c9ee0f89d08082498d1c0e6f21983df0ca64 Author: Dusan Kazik Date: Tue Sep 16 14:30:31 2014 +0300 i18n: Add Slovak translation diff --git a/po/LINGUAS b/po/LINGUAS index 3e3d9de..addf24a 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -25,6 +25,7 @@ pl pt_BR pt ru +sk sr at latin sr sv diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 0000000..a6c69fd --- /dev/null +++ b/po/sk.po @@ -0,0 +1,2733 @@ +# Slovak translation for PulseAudio. +# Copyright (C) 2014 PulseAudio's COPYRIGHT HOLDER +# This file is distributed under the same license as the PulseAudio package. +# Du??an Kazik , 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: PulseAudio master\n" +"Report-Msgid-Bugs-To: https://bugs.freedesktop.org/enter_bug.cgi?" +"product=PulseAudio&keywords=I18N+L10N&component=misc\n" +"POT-Creation-Date: 2014-09-14 10:24+0000\n" +"PO-Revision-Date: 2014-09-14 20:39+0100\n" +"Last-Translator: Du??an Kazik \n" +"Language-Team: Slovak \n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../src/daemon/cmdline.c:113 +#, c-format +msgid "" +"%s [options]\n" +"\n" +"COMMANDS:\n" +" -h, --help Show this help\n" +" --version Show version\n" +" --dump-conf Dump default configuration\n" +" --dump-modules Dump list of available modules\n" +" --dump-resample-methods Dump available resample methods\n" +" --cleanup-shm Cleanup stale shared memory " +"segments\n" +" --start Start the daemon if it is not " +"running\n" +" -k --kill Kill a running daemon\n" +" --check Check for a running daemon (only " +"returns exit code)\n" +"\n" +"OPTIONS:\n" +" --system[=BOOL] Run as system-wide instance\n" +" -D, --daemonize[=BOOL] Daemonize after startup\n" +" --fail[=BOOL] Quit when startup fails\n" +" --high-priority[=BOOL] Try to set high nice level\n" +" (only available as root, when SUID " +"or\n" +" with elevated RLIMIT_NICE)\n" +" --realtime[=BOOL] Try to enable realtime scheduling\n" +" (only available as root, when SUID " +"or\n" +" with elevated RLIMIT_RTPRIO)\n" +" --disallow-module-loading[=BOOL] Disallow module user requested " +"module\n" +" loading/unloading after startup\n" +" --disallow-exit[=BOOL] Disallow user requested exit\n" +" --exit-idle-time=SECS Terminate the daemon when idle and " +"this\n" +" time passed\n" +" --scache-idle-time=SECS Unload autoloaded samples when idle " +"and\n" +" this time passed\n" +" --log-level[=LEVEL] Increase or set verbosity level\n" +" -v --verbose Increase the verbosity level\n" +" --log-target={auto,syslog,stderr,file:PATH,newfile:PATH}\n" +" Specify the log target\n" +" --log-meta[=BOOL] Include code location in log " +"messages\n" +" --log-time[=BOOL] Include timestamps in log messages\n" +" --log-backtrace=FRAMES Include a backtrace in log messages\n" +" -p, --dl-search-path=PATH Set the search path for dynamic " +"shared\n" +" objects (plugins)\n" +" --resample-method=METHOD Use the specified resampling method\n" +" (See --dump-resample-methods for\n" +" possible values)\n" +" --use-pid-file[=BOOL] Create a PID file\n" +" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n" +" platforms that support it.\n" +" --disable-shm[=BOOL] Disable shared memory support.\n" +"\n" +"STARTUP SCRIPT:\n" +" -L, --load=\"MODULE ARGUMENTS\" Load the specified plugin module " +"with\n" +" the specified argument\n" +" -F, --file=FILENAME Run the specified script\n" +" -C Open a command line on the running " +"TTY\n" +" after startup\n" +"\n" +" -n Don't load default script file\n" +msgstr "" + +#: ../src/daemon/cmdline.c:245 +msgid "--daemonize expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:253 +msgid "--fail expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:264 +msgid "" +"--log-level expects log level argument (either numeric in range 0..4 or one " +"of debug, info, notice, warn, error)." +msgstr "" + +#: ../src/daemon/cmdline.c:276 +msgid "--high-priority expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:284 +msgid "--realtime expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:292 +msgid "--disallow-module-loading expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:300 +msgid "--disallow-exit expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:308 +msgid "--use-pid-file expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:327 +msgid "" +"Invalid log target: use either 'syslog', 'journal','stderr' or 'auto' or a " +"valid file name 'file:', 'newfile:'." +msgstr "" + +#: ../src/daemon/cmdline.c:329 +msgid "" +"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file " +"name 'file:', 'newfile:'." +msgstr "" + +#: ../src/daemon/cmdline.c:337 +msgid "--log-time expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:345 +msgid "--log-meta expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:365 +#, c-format +msgid "Invalid resample method '%s'." +msgstr "Neplatn?? met??da prevzorkovania ???%s???." + +#: ../src/daemon/cmdline.c:372 +msgid "--system expects boolean argument" +msgstr "Vo??ba --system o??ak??va booleovsk?? parameter" + +#: ../src/daemon/cmdline.c:380 +msgid "--no-cpu-limit expects boolean argument" +msgstr "" + +#: ../src/daemon/cmdline.c:388 +msgid "--disable-shm expects boolean argument" +msgstr "" + +#: ../src/daemon/daemon-conf.c:260 +#, c-format +msgid "[%s:%u] Invalid log target '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:275 +#, c-format +msgid "[%s:%u] Invalid log level '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:290 +#, c-format +msgid "[%s:%u] Invalid resample method '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:312 +#, c-format +msgid "[%s:%u] Invalid rlimit '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:332 +#, c-format +msgid "[%s:%u] Invalid sample format '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:349 ../src/daemon/daemon-conf.c:366 +#, c-format +msgid "[%s:%u] Invalid sample rate '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:389 +#, c-format +msgid "[%s:%u] Invalid sample channels '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:406 +#, c-format +msgid "[%s:%u] Invalid channel map '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:423 +#, c-format +msgid "[%s:%u] Invalid number of fragments '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:440 +#, c-format +msgid "[%s:%u] Invalid fragment size '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:457 +#, c-format +msgid "[%s:%u] Invalid nice level '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:500 +#, c-format +msgid "[%s:%u] Invalid server type '%s'." +msgstr "" + +#: ../src/daemon/daemon-conf.c:613 +#, c-format +msgid "Failed to open configuration file: %s" +msgstr "Zlyhalo otvorenie konfigura??n??ho s??boru: %s" + +#: ../src/daemon/daemon-conf.c:629 +msgid "" +"The specified default channel map has a different number of channels than " +"the specified default number of channels." +msgstr "" +"Ur??en?? predvolen?? mapa kan??lov obsahuje odli??n?? po??et kan??lov ako je ur??en?? " +"predvolen?? po??et kan??lov." + +#: ../src/daemon/daemon-conf.c:716 +#, c-format +msgid "### Read from configuration file: %s ###\n" +msgstr "### ????ta?? z konfigura??n??ho s??boru: %s ###\n" + +#: ../src/daemon/dumpmodules.c:59 +#, c-format +msgid "Name: %s\n" +msgstr "N??zov: %s\n" + +#: ../src/daemon/dumpmodules.c:62 +#, c-format +msgid "No module information available\n" +msgstr "Nie s?? dostupn?? ??iadne inform??cie o module\n" + +#: ../src/daemon/dumpmodules.c:65 +#, c-format +msgid "Version: %s\n" +msgstr "Verzia: %s\n" + +#: ../src/daemon/dumpmodules.c:67 +#, c-format +msgid "Description: %s\n" +msgstr "Popis: %s\n" + +#: ../src/daemon/dumpmodules.c:69 +#, c-format +msgid "Author: %s\n" +msgstr "Autor: %s\n" + +#: ../src/daemon/dumpmodules.c:71 +#, c-format +msgid "Usage: %s\n" +msgstr "Vyu??itie: %s\n" + +#: ../src/daemon/dumpmodules.c:72 +#, c-format +msgid "Load Once: %s\n" +msgstr "Na????tan?? raz: %s\n" + +#: ../src/daemon/dumpmodules.c:74 +#, c-format +msgid "DEPRECATION WARNING: %s\n" +msgstr "" + +#: ../src/daemon/dumpmodules.c:78 +#, c-format +msgid "Path: %s\n" +msgstr "Cesta: %s\n" + +#: ../src/daemon/ltdl-bind-now.c:77 +#, c-format +msgid "Failed to open module %s: %s" +msgstr "Zlyhalo otvorenie modulu %s: %s" + +#: ../src/daemon/ltdl-bind-now.c:128 +msgid "Failed to find original lt_dlopen loader." +msgstr "" + +#: ../src/daemon/ltdl-bind-now.c:133 +msgid "Failed to allocate new dl loader." +msgstr "" + +#: ../src/daemon/ltdl-bind-now.c:146 +msgid "Failed to add bind-now-loader." +msgstr "" + +#: ../src/daemon/main.c:158 +#, c-format +msgid "Failed to find user '%s'." +msgstr "Zlyhalo n??jdenie pou????vate??a ???%s???." + +#: ../src/daemon/main.c:163 +#, c-format +msgid "Failed to find group '%s'." +msgstr "Zlyhalo n??jdenie skupiny ???%s???." + +#: ../src/daemon/main.c:172 +#, c-format +msgid "GID of user '%s' and of group '%s' don't match." +msgstr "" + +#: ../src/daemon/main.c:177 +#, c-format +msgid "Home directory of user '%s' is not '%s', ignoring." +msgstr "" + +#: ../src/daemon/main.c:180 ../src/daemon/main.c:185 +#, c-format +msgid "Failed to create '%s': %s" +msgstr "Zlyhalo vytvorenie ???%s???: %s" + +#: ../src/daemon/main.c:192 +#, c-format +msgid "Failed to change group list: %s" +msgstr "Zlyhala zmena zoznamu skup??n: %s" + +#: ../src/daemon/main.c:208 +#, c-format +msgid "Failed to change GID: %s" +msgstr "" + +#: ../src/daemon/main.c:224 +#, c-format +msgid "Failed to change UID: %s" +msgstr "" + +#: ../src/daemon/main.c:253 +msgid "System wide mode unsupported on this platform." +msgstr "" + +#: ../src/daemon/main.c:464 +msgid "Failed to parse command line." +msgstr "Zlyhalo analyzovanie pr??kazov??ho riadku." + +#: ../src/daemon/main.c:503 +msgid "" +"System mode refused for non-root user. Only starting the D-Bus server lookup " +"service." +msgstr "" + +#: ../src/daemon/main.c:602 +#, c-format +msgid "Failed to kill daemon: %s" +msgstr "Zlyhalo zabitie slu??by: %s" + +#: ../src/daemon/main.c:631 +msgid "" +"This program is not intended to be run as root (unless --system is " +"specified)." +msgstr "" + +#: ../src/daemon/main.c:634 +msgid "Root privileges required." +msgstr "Vy??aduj?? sa privil??gi?? spr??vcu" + +#: ../src/daemon/main.c:641 +msgid "--start not supported for system instances." +msgstr "Vo??ba --start nie je podporovan?? pre syst??mov?? in??tancie." + +#: ../src/daemon/main.c:681 +#, c-format +msgid "User-configured server at %s, refusing to start/autospawn." +msgstr "" + +#: ../src/daemon/main.c:687 +#, c-format +msgid "" +"User-configured server at %s, which appears to be local. Probing deeper." +msgstr "" + +#: ../src/daemon/main.c:692 +msgid "Running in system mode, but --disallow-exit not set!" +msgstr "" + +#: ../src/daemon/main.c:695 +msgid "Running in system mode, but --disallow-module-loading not set!" +msgstr "" + +#: ../src/daemon/main.c:698 +msgid "Running in system mode, forcibly disabling SHM mode!" +msgstr "" + +#: ../src/daemon/main.c:703 +msgid "Running in system mode, forcibly disabling exit idle time!" +msgstr "" + +#: ../src/daemon/main.c:736 +msgid "Failed to acquire stdio." +msgstr "" + +#: ../src/daemon/main.c:742 ../src/daemon/main.c:813 +#, c-format +msgid "pipe() failed: %s" +msgstr "" + +#: ../src/daemon/main.c:747 ../src/daemon/main.c:818 +#, c-format +msgid "fork() failed: %s" +msgstr "" + +#: ../src/daemon/main.c:762 ../src/daemon/main.c:833 ../src/utils/pacat.c:569 +#, c-format +msgid "read() failed: %s" +msgstr "" + +#: ../src/daemon/main.c:768 +msgid "Daemon startup failed." +msgstr "Zlyhalo spustenie slu??by." + +#: ../src/daemon/main.c:801 +#, c-format +msgid "setsid() failed: %s" +msgstr "" + +#: ../src/daemon/main.c:924 +msgid "Failed to get machine ID" +msgstr "Zlyhalo z??skanie identifik??tora stroja" + +#: ../src/daemon/main.c:950 +msgid "" +"OK, so you are running PA in system mode. Please note that you most likely " +"shouldn't be doing that.\n" +"If you do it nonetheless then it's your own fault if things don't work as " +"expected.\n" +"Please read http://pulseaudio.org/wiki/WhatIsWrongWithSystemMode for an " +"explanation why system mode is usually a bad idea." +msgstr "" + +#: ../src/daemon/main.c:967 +msgid "pa_pid_file_create() failed." +msgstr "" + +#: ../src/daemon/main.c:997 +msgid "pa_core_new() failed." +msgstr "" + +#: ../src/daemon/main.c:1064 +msgid "Failed to initialize daemon." +msgstr "Zlyhala inicializ??cia slu??by." + +#: ../src/daemon/main.c:1069 +msgid "Daemon startup without any loaded modules, refusing to work." +msgstr "" + +#: ../src/daemon/pulseaudio.desktop.in.h:1 +msgid "PulseAudio Sound System" +msgstr "Zvukov?? syst??m PulseAudio" + +#: ../src/daemon/pulseaudio.desktop.in.h:2 +msgid "Start the PulseAudio Sound System" +msgstr "Spustenie zvukov??ho syst??mu PulseAudio" + +#: ../src/modules/alsa/alsa-mixer.c:2294 +msgid "Input" +msgstr "Vstup" + +#: ../src/modules/alsa/alsa-mixer.c:2295 +msgid "Docking Station Input" +msgstr "" + +#: ../src/modules/alsa/alsa-mixer.c:2296 +msgid "Docking Station Microphone" +msgstr "" + +#: ../src/modules/alsa/alsa-mixer.c:2297 +msgid "Docking Station Line In" +msgstr "" + +#: ../src/modules/alsa/alsa-mixer.c:2298 ../src/modules/alsa/alsa-mixer.c:2383 +msgid "Line In" +msgstr "Vstupn?? linka" + +#: ../src/modules/alsa/alsa-mixer.c:2299 ../src/modules/alsa/alsa-mixer.c:2377 +#: ../src/modules/bluetooth/module-bluez4-device.c:2101 +#: ../src/modules/bluetooth/module-bluez5-device.c:1635 +msgid "Microphone" +msgstr "Mikrof??n" + +#: ../src/modules/alsa/alsa-mixer.c:2300 ../src/modules/alsa/alsa-mixer.c:2378 +msgid "Front Microphone" +msgstr "Predn?? mikrof??n" + +#: ../src/modules/alsa/alsa-mixer.c:2301 ../src/modules/alsa/alsa-mixer.c:2379 +msgid "Rear Microphone" +msgstr "Zadn?? mikrof??n" + +#: ../src/modules/alsa/alsa-mixer.c:2302 +msgid "External Microphone" +msgstr "Extern?? mikrof??n" + +#: ../src/modules/alsa/alsa-mixer.c:2303 ../src/modules/alsa/alsa-mixer.c:2381 +msgid "Internal Microphone" +msgstr "Vstavan?? mikrof??n" + +#: ../src/modules/alsa/alsa-mixer.c:2304 ../src/modules/alsa/alsa-mixer.c:2384 +msgid "Radio" +msgstr "R??dio" + +#: ../src/modules/alsa/alsa-mixer.c:2305 ../src/modules/alsa/alsa-mixer.c:2385 +msgid "Video" +msgstr "Video" + +#: ../src/modules/alsa/alsa-mixer.c:2306 +msgid "Automatic Gain Control" +msgstr "Automatick?? ovl??danie zosilnenia" + +#: ../src/modules/alsa/alsa-mixer.c:2307 +msgid "No Automatic Gain Control" +msgstr "Bez automatick??ho ovl??dania zosilnenia" + +#: ../src/modules/alsa/alsa-mixer.c:2308 +msgid "Boost" +msgstr "Zosilnenie" + +#: ../src/modules/alsa/alsa-mixer.c:2309 +msgid "No Boost" +msgstr "Bez zosilnenia" + +#: ../src/modules/alsa/alsa-mixer.c:2310 +msgid "Amplifier" +msgstr "Zosil??ova??" + +#: ../src/modules/alsa/alsa-mixer.c:2311 +msgid "No Amplifier" +msgstr "Bez zosil??ova??a" + +#: ../src/modules/alsa/alsa-mixer.c:2312 +msgid "Bass Boost" +msgstr "Zosilnenie basov" + +#: ../src/modules/alsa/alsa-mixer.c:2313 +msgid "No Bass Boost" +msgstr "Bez zosilnenia basov" + +#: ../src/modules/alsa/alsa-mixer.c:2314 +#: ../src/modules/bluetooth/module-bluez4-device.c:2106 +#: ../src/modules/bluetooth/module-bluez5-device.c:1642 +msgid "Speaker" +msgstr "Reproduktor" + +#: ../src/modules/alsa/alsa-mixer.c:2315 ../src/modules/alsa/alsa-mixer.c:2387 +msgid "Headphones" +msgstr "Sl??chadl??" + +#: ../src/modules/alsa/alsa-mixer.c:2376 +msgid "Analog Input" +msgstr "Anal??gov?? vstup" + +#: ../src/modules/alsa/alsa-mixer.c:2380 +msgid "Dock Microphone" +msgstr "" + +#: ../src/modules/alsa/alsa-mixer.c:2382 +msgid "Headset Microphone" +msgstr "" + +#: ../src/modules/alsa/alsa-mixer.c:2386 +msgid "Analog Output" +msgstr "Anal??gov?? v??stup" + +#: ../src/modules/alsa/alsa-mixer.c:2388 +msgid "LFE on Separate Mono Output" +msgstr "" + +#: ../src/modules/alsa/alsa-mixer.c:2389 +msgid "Line Out" +msgstr "V??stupn?? linka" + +#: ../src/modules/alsa/alsa-mixer.c:2390 +msgid "Analog Mono Output" +msgstr "Anal??gov?? mono v??stup" + +#: ../src/modules/alsa/alsa-mixer.c:2391 +msgid "Speakers" +msgstr "Reproduktory" + +#: ../src/modules/alsa/alsa-mixer.c:2392 +msgid "HDMI / DisplayPort" +msgstr "HDMI / DisplayPort" + +#: ../src/modules/alsa/alsa-mixer.c:2393 +msgid "Digital Output (S/PDIF)" +msgstr "Digit??lny v??stup (S/PDIF)" + +#: ../src/modules/alsa/alsa-mixer.c:2394 +msgid "Digital Input (S/PDIF)" +msgstr "Digit??lny vstup (S/PDIF)" + +#: ../src/modules/alsa/alsa-mixer.c:2395 +msgid "Digital Passthrough (S/PDIF)" +msgstr "Digit??lny prechod (S/PDIF)" + +#: ../src/modules/alsa/alsa-mixer.c:3903 +msgid "Analog Mono" +msgstr "Anal??gov?? mono" + +#: ../src/modules/alsa/alsa-mixer.c:3904 +msgid "Analog Stereo" +msgstr "Anal??gov?? stereo" + +#: ../src/modules/alsa/alsa-mixer.c:3905 +msgid "Multichannel" +msgstr "Viackan??lov??" + +#: ../src/modules/alsa/alsa-mixer.c:3906 +msgid "Analog Surround 2.1" +msgstr "Anal??gov?? priestorov?? 2.1" + +#: ../src/modules/alsa/alsa-mixer.c:3907 +msgid "Analog Surround 3.0" +msgstr "Anal??gov?? priestorov?? 3.0" + +#: ../src/modules/alsa/alsa-mixer.c:3908 +msgid "Analog Surround 3.1" +msgstr "Anal??gov?? priestorov?? 3.1" + +#: ../src/modules/alsa/alsa-mixer.c:3909 +msgid "Analog Surround 4.0" +msgstr "Anal??gov?? priestorov?? 4.0" + +#: ../src/modules/alsa/alsa-mixer.c:3910 +msgid "Analog Surround 4.1" +msgstr "Anal??gov?? priestorov?? 4.1" + +#: ../src/modules/alsa/alsa-mixer.c:3911 +msgid "Analog Surround 5.0" +msgstr "Anal??gov?? priestorov?? 5.0" + +#: ../src/modules/alsa/alsa-mixer.c:3912 +msgid "Analog Surround 5.1" +msgstr "Anal??gov?? priestorov?? 5.1" + +#: ../src/modules/alsa/alsa-mixer.c:3913 +msgid "Analog Surround 6.0" +msgstr "Anal??gov?? priestorov?? 6.0" + +#: ../src/modules/alsa/alsa-mixer.c:3914 +msgid "Analog Surround 6.1" +msgstr "Anal??gov?? priestorov?? 6.1" + +#: ../src/modules/alsa/alsa-mixer.c:3915 +msgid "Analog Surround 7.0" +msgstr "Anal??gov?? priestorov?? 7.0" + +#: ../src/modules/alsa/alsa-mixer.c:3916 +msgid "Analog Surround 7.1" +msgstr "Anal??gov?? priestorov?? 7.1" + +#: ../src/modules/alsa/alsa-mixer.c:3917 +msgid "Digital Stereo (IEC958)" +msgstr "Digit??lne stereo (IEC958)" + +#: ../src/modules/alsa/alsa-mixer.c:3918 +msgid "Digital Passthrough (IEC958)" +msgstr "Digit??lny prechod (IEC958)" + +#: ../src/modules/alsa/alsa-mixer.c:3919 +msgid "Digital Surround 4.0 (IEC958/AC3)" +msgstr "Digit??lny priestorov?? 4.0 (IEC958/AC3)" + +#: ../src/modules/alsa/alsa-mixer.c:3920 +msgid "Digital Surround 5.1 (IEC958/AC3)" +msgstr "Digit??lny priestorov?? 5.1 (IEC958/AC3)" + +#: ../src/modules/alsa/alsa-mixer.c:3921 +msgid "Digital Surround 5.1 (IEC958/DTS)" +msgstr "Digit??lny priestorov?? 5.1 (IEC958/DTS)" + +#: ../src/modules/alsa/alsa-mixer.c:3922 +msgid "Digital Stereo (HDMI)" +msgstr "Digit??lny stereo (HDMI)" + +#: ../src/modules/alsa/alsa-mixer.c:3923 +msgid "Digital Surround 5.1 (HDMI)" +msgstr "Digit??lny priestorov?? 5.1 (HDMI)" + +#: ../src/modules/alsa/alsa-mixer.c:4054 +msgid "Analog Mono Duplex" +msgstr "Obojsmern?? anal??gov?? mono" + +#: ../src/modules/alsa/alsa-mixer.c:4055 +msgid "Analog Stereo Duplex" +msgstr "Obojsmern?? anal??gov?? stereo" + +#: ../src/modules/alsa/alsa-mixer.c:4056 +msgid "Digital Stereo Duplex (IEC958)" +msgstr "Obojsmern?? digit??lny stereo (IEC958)" + +#: ../src/modules/alsa/alsa-mixer.c:4057 +#: ../src/modules/alsa/module-alsa-card.c:193 +#: ../src/modules/bluetooth/module-bluez4-device.c:2297 +#: ../src/modules/bluetooth/module-bluez5-device.c:1866 +msgid "Off" +msgstr "Vypnut??" + +#: ../src/modules/alsa/alsa-mixer.c:4156 +#, c-format +msgid "%s Output" +msgstr "%s v??stup" + +#: ../src/modules/alsa/alsa-mixer.c:4164 +#, c-format +msgid "%s Input" +msgstr "%s vstup" + +#: ../src/modules/alsa/alsa-sink.c:570 ../src/modules/alsa/alsa-sink.c:748 +#, c-format +msgid "" +"ALSA woke us up to write new data to the device, but there was actually " +"nothing to write!\n" +"Most likely this is a bug in the ALSA driver '%s'. Please report this issue " +"to the ALSA developers.\n" +"We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() " +"returned 0 or another value < min_avail." +msgstr "" + +#: ../src/modules/alsa/alsa-source.c:529 ../src/modules/alsa/alsa-source.c:681 +#, c-format +msgid "" +"ALSA woke us up to read new data from the device, but there was actually " +"nothing to read!\n" +"Most likely this is a bug in the ALSA driver '%s'. Please report this issue " +"to the ALSA developers.\n" +"We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() " +"returned 0 or another value < min_avail." +msgstr "" + +#: ../src/modules/alsa/alsa-util.c:1135 ../src/modules/alsa/alsa-util.c:1210 +#, c-format +msgid "" +"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu " +"ms).\n" +"Most likely this is a bug in the ALSA driver '%s'. Please report this issue " +"to the ALSA developers." +msgstr "" + +#: ../src/modules/alsa/alsa-util.c:1185 +#, c-format +msgid "" +"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s" +"%lu ms).\n" +"Most likely this is a bug in the ALSA driver '%s'. Please report this issue " +"to the ALSA developers." +msgstr "" + +#: ../src/modules/alsa/alsa-util.c:1226 +#, c-format +msgid "" +"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail " +"%lu.\n" +"Most likely this is a bug in the ALSA driver '%s'. Please report this issue " +"to the ALSA developers." +msgstr "" + +#: ../src/modules/alsa/alsa-util.c:1269 +#, c-format +msgid "" +"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes " +"(%lu ms).\n" +"Most likely this is a bug in the ALSA driver '%s'. Please report this issue " +"to the ALSA developers." +msgstr "" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2091 +#: ../src/modules/bluetooth/module-bluez5-device.c:1625 +msgid "Headset" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2096 +#: ../src/modules/bluetooth/module-bluez5-device.c:1630 +msgid "Handsfree" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2111 +#: ../src/modules/bluetooth/module-bluez5-device.c:1648 +msgid "Headphone" +msgstr "Sl??chadlo" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2116 +#: ../src/modules/bluetooth/module-bluez5-device.c:1653 +msgid "Portable" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2121 +#: ../src/modules/bluetooth/module-bluez5-device.c:1658 +msgid "Car" +msgstr "Automobil" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2126 +#: ../src/modules/bluetooth/module-bluez5-device.c:1663 +msgid "HiFi" +msgstr "HiFi" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2131 +#: ../src/modules/bluetooth/module-bluez5-device.c:1668 +msgid "Phone" +msgstr "Telef??n" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2139 +#: ../src/modules/bluetooth/module-bluez5-device.c:1620 +#: ../src/modules/bluetooth/module-bluez5-device.c:1636 +#: ../src/modules/bluetooth/module-bluez5-device.c:1674 +msgid "Bluetooth Output" +msgstr "V??stup cez Bluetooth" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2142 +#: ../src/modules/bluetooth/module-bluez5-device.c:1619 +#: ../src/modules/bluetooth/module-bluez5-device.c:1641 +#: ../src/modules/bluetooth/module-bluez5-device.c:1647 +#: ../src/modules/bluetooth/module-bluez5-device.c:1673 +msgid "Bluetooth Input" +msgstr "Vstup cez Bluetooth" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2178 +msgid "High Fidelity Playback (A2DP)" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2189 +msgid "High Fidelity Capture (A2DP)" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2200 +msgid "Telephony Duplex (HSP/HFP)" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez4-device.c:2212 +msgid "Handsfree Gateway" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez5-device.c:1711 +msgid "High Fidelity Playback (A2DP Sink)" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez5-device.c:1722 +msgid "High Fidelity Capture (A2DP Source)" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez5-device.c:1733 +msgid "Headset Head Unit (HSP/HFP)" +msgstr "" + +#: ../src/modules/bluetooth/module-bluez5-device.c:1745 +msgid "Headset Audio Gateway (HSP/HFP)" +msgstr "" + +#: ../src/modules/echo-cancel/module-echo-cancel.c:63 +msgid "" +"source_name= source_properties= source_master= sink_name= sink_properties= sink_master= adjust_time= adjust_threshold= format= rate= channels= channel_map= " +"aec_method= aec_args= " +"save_aec= autoloaded= use_volume_sharing= " +msgstr "" + +#. add on profile +#: ../src/modules/macosx/module-coreaudio-device.c:756 +msgid "On" +msgstr "Zapnut??" + +#: ../src/modules/module-always-sink.c:38 +msgid "Always keeps at least one sink loaded even if it's a null one" +msgstr "" + +#: ../src/modules/module-always-sink.c:82 +msgid "Dummy Output" +msgstr "Fikt??vny v??stup" + +#: ../src/modules/module-equalizer-sink.c:72 +msgid "General Purpose Equalizer" +msgstr "" + +#: ../src/modules/module-equalizer-sink.c:76 +msgid "" +"sink_name= sink_properties= " +"sink_master= format= rate= " +"channels= channel_map= autoloaded= use_volume_sharing= " +msgstr "" + +#: ../src/modules/module-filter-apply.c:48 +msgid "autoclean=" +msgstr "" + +#: ../src/modules/module-ladspa-sink.c:53 +msgid "Virtual LADSPA sink" +msgstr "" + +#: ../src/modules/module-ladspa-sink.c:57 +msgid "" +"sink_name= sink_properties= " +"master= format= rate= " +"channels= channel_map= plugin= label= control= input_ladspaport_map= output_ladspaport_map= " +msgstr "" + +#: ../src/modules/module-null-sink.c:49 +msgid "Clocked NULL sink" +msgstr "" + +#: ../src/modules/module-null-sink.c:280 +msgid "Null Output" +msgstr "" + +#: ../src/modules/module-rygel-media-server.c:510 +#: ../src/modules/module-rygel-media-server.c:548 +#: ../src/modules/module-rygel-media-server.c:907 +msgid "Output Devices" +msgstr "V??stupn?? zariadenia" + +#: ../src/modules/module-rygel-media-server.c:511 +#: ../src/modules/module-rygel-media-server.c:549 +#: ../src/modules/module-rygel-media-server.c:908 +msgid "Input Devices" +msgstr "Vstupn?? zariadenia" + +#: ../src/modules/module-rygel-media-server.c:1065 +msgid "Audio on @HOSTNAME@" +msgstr "" + +#. TODO: old tunnel put here the remote sink_name into stream name e.g. 'Null Output for lynxis at lazus' +#. TODO: old tunnel put here the remote source_name into stream name e.g. 'Null Output for lynxis at lazus' +#: ../src/modules/module-tunnel-sink-new.c:299 +#: ../src/modules/module-tunnel-source-new.c:307 +#, c-format +msgid "Tunnel for %s@%s" +msgstr "" + +#: ../src/modules/module-tunnel-sink-new.c:509 +#: ../src/modules/module-tunnel-source-new.c:518 +#, c-format +msgid "Tunnel to %s/%s" +msgstr "" + +#: ../src/modules/module-virtual-surround-sink.c:49 +msgid "Virtual surround sink" +msgstr "" + +#: ../src/modules/module-virtual-surround-sink.c:53 +msgid "" +"sink_name= sink_properties= " +"master= format= rate= " +"channels= channel_map= " +"use_volume_sharing= force_flat_volume= hrir=/path/to/" +"left_hrir.wav " +msgstr "" + +#: ../src/modules/reserve-wrap.c:151 +msgid "PulseAudio Sound Server" +msgstr "Zvukov?? server PulseAudio" + +#: ../src/pulse/channelmap.c:105 ../src/pulse/channelmap.c:760 +msgid "Mono" +msgstr "Mono" + +#: ../src/pulse/channelmap.c:107 +msgid "Front Center" +msgstr "Predn?? stredov??" + +#: ../src/pulse/channelmap.c:108 +msgid "Front Left" +msgstr "Predn?? ??av??" + +#: ../src/pulse/channelmap.c:109 +msgid "Front Right" +msgstr "Predn?? prav??" + +#: ../src/pulse/channelmap.c:111 +msgid "Rear Center" +msgstr "Zadn?? stredov??" + +#: ../src/pulse/channelmap.c:112 +msgid "Rear Left" +msgstr "Zadn?? ??av??" + +#: ../src/pulse/channelmap.c:113 +msgid "Rear Right" +msgstr "Zadn?? prav??" + +#: ../src/pulse/channelmap.c:115 +msgid "Subwoofer" +msgstr "Subwoofer" + +#: ../src/pulse/channelmap.c:117 +msgid "Front Left-of-center" +msgstr "" + +#: ../src/pulse/channelmap.c:118 +msgid "Front Right-of-center" +msgstr "" + +#: ../src/pulse/channelmap.c:120 +msgid "Side Left" +msgstr "??av?? strana" + +#: ../src/pulse/channelmap.c:121 +msgid "Side Right" +msgstr "Prav?? strana" + +#: ../src/pulse/channelmap.c:123 +msgid "Auxiliary 0" +msgstr "" + +#: ../src/pulse/channelmap.c:124 +msgid "Auxiliary 1" +msgstr "" + +#: ../src/pulse/channelmap.c:125 +msgid "Auxiliary 2" +msgstr "" + +#: ../src/pulse/channelmap.c:126 +msgid "Auxiliary 3" +msgstr "" + +#: ../src/pulse/channelmap.c:127 +msgid "Auxiliary 4" +msgstr "" + +#: ../src/pulse/channelmap.c:128 +msgid "Auxiliary 5" +msgstr "" + +#: ../src/pulse/channelmap.c:129 +msgid "Auxiliary 6" +msgstr "" + +#: ../src/pulse/channelmap.c:130 +msgid "Auxiliary 7" +msgstr "" + +#: ../src/pulse/channelmap.c:131 +msgid "Auxiliary 8" +msgstr "" + +#: ../src/pulse/channelmap.c:132 +msgid "Auxiliary 9" +msgstr "" + +#: ../src/pulse/channelmap.c:133 +msgid "Auxiliary 10" +msgstr "" + +#: ../src/pulse/channelmap.c:134 +msgid "Auxiliary 11" +msgstr "" + +#: ../src/pulse/channelmap.c:135 +msgid "Auxiliary 12" +msgstr "" + +#: ../src/pulse/channelmap.c:136 +msgid "Auxiliary 13" +msgstr "" + +#: ../src/pulse/channelmap.c:137 +msgid "Auxiliary 14" +msgstr "" + +#: ../src/pulse/channelmap.c:138 +msgid "Auxiliary 15" +msgstr "" + +#: ../src/pulse/channelmap.c:139 +msgid "Auxiliary 16" +msgstr "" + +#: ../src/pulse/channelmap.c:140 +msgid "Auxiliary 17" +msgstr "" + +#: ../src/pulse/channelmap.c:141 +msgid "Auxiliary 18" +msgstr "" + +#: ../src/pulse/channelmap.c:142 +msgid "Auxiliary 19" +msgstr "" + +#: ../src/pulse/channelmap.c:143 +msgid "Auxiliary 20" +msgstr "" + +#: ../src/pulse/channelmap.c:144 +msgid "Auxiliary 21" +msgstr "" + +#: ../src/pulse/channelmap.c:145 +msgid "Auxiliary 22" +msgstr "" + +#: ../src/pulse/channelmap.c:146 +msgid "Auxiliary 23" +msgstr "" + +#: ../src/pulse/channelmap.c:147 +msgid "Auxiliary 24" +msgstr "" + +#: ../src/pulse/channelmap.c:148 +msgid "Auxiliary 25" +msgstr "" + +#: ../src/pulse/channelmap.c:149 +msgid "Auxiliary 26" +msgstr "" + +#: ../src/pulse/channelmap.c:150 +msgid "Auxiliary 27" +msgstr "" + +#: ../src/pulse/channelmap.c:151 +msgid "Auxiliary 28" +msgstr "" + +#: ../src/pulse/channelmap.c:152 +msgid "Auxiliary 29" +msgstr "" + +#: ../src/pulse/channelmap.c:153 +msgid "Auxiliary 30" +msgstr "" + +#: ../src/pulse/channelmap.c:154 +msgid "Auxiliary 31" +msgstr "" + +#: ../src/pulse/channelmap.c:156 +msgid "Top Center" +msgstr "Horn?? stredov??" + +#: ../src/pulse/channelmap.c:158 +msgid "Top Front Center" +msgstr "Horn?? predn?? stredov??" + +#: ../src/pulse/channelmap.c:159 +msgid "Top Front Left" +msgstr "Horn?? predn?? ??av??" + +#: ../src/pulse/channelmap.c:160 +msgid "Top Front Right" +msgstr "Horn?? predn?? prav??" + +#: ../src/pulse/channelmap.c:162 +msgid "Top Rear Center" +msgstr "Horn?? zadn?? stredov??" + +#: ../src/pulse/channelmap.c:163 +msgid "Top Rear Left" +msgstr "Horn?? zadn?? ??av??" + +#: ../src/pulse/channelmap.c:164 +msgid "Top Rear Right" +msgstr "Horn?? zadn?? prav??" + +#: ../src/pulse/channelmap.c:481 ../src/pulse/format.c:123 +#: ../src/pulse/sample.c:177 ../src/pulse/volume.c:296 +#: ../src/pulse/volume.c:322 ../src/pulse/volume.c:342 +#: ../src/pulse/volume.c:374 ../src/pulse/volume.c:414 +#: ../src/pulse/volume.c:433 +msgid "(invalid)" +msgstr "(neplatn??)" + +#: ../src/pulse/channelmap.c:764 +msgid "Stereo" +msgstr "Stereo" + +#: ../src/pulse/channelmap.c:769 +msgid "Surround 4.0" +msgstr "Priestorov?? 4.0" + +#: ../src/pulse/channelmap.c:775 +msgid "Surround 4.1" +msgstr "Priestorov?? 4.1" + +#: ../src/pulse/channelmap.c:781 +msgid "Surround 5.0" +msgstr "Priestorov?? 5.0" + +#: ../src/pulse/channelmap.c:787 +msgid "Surround 5.1" +msgstr "Priestorov?? 5.1" + +#: ../src/pulse/channelmap.c:794 +msgid "Surround 7.1" +msgstr "Priestorov?? 7.1" + +#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:99 +msgid "xcb_connect() failed" +msgstr "" + +#: ../src/pulse/client-conf-x11.c:60 ../src/utils/pax11publish.c:104 +msgid "xcb_connection_has_error() returned true" +msgstr "" + +#: ../src/pulse/client-conf-x11.c:96 +msgid "Failed to parse cookie data" +msgstr "" + +#: ../src/pulse/context.c:658 +#, c-format +msgid "fork(): %s" +msgstr "" + +#: ../src/pulse/context.c:713 +#, c-format +msgid "waitpid(): %s" +msgstr "" + +#: ../src/pulse/context.c:1414 +#, c-format +msgid "Received message for unknown extension '%s'" +msgstr "" + +#: ../src/pulse/direction.c:39 +msgid "input" +msgstr "" + +#: ../src/pulse/direction.c:41 +msgid "output" +msgstr "" + +#: ../src/pulse/direction.c:43 +msgid "bidirectional" +msgstr "" + +#: ../src/pulse/direction.c:45 +msgid "invalid" +msgstr "" + +#: ../src/pulsecore/core-util.c:1821 +#, c-format +msgid "" +"XDG_RUNTIME_DIR (%s) is not owned by us (uid %d), but by uid %d! (This could " +"e g happen if you try to connect to a non-root PulseAudio as a root user, " +"over the native protocol. Don't do that.)" +msgstr "" + +#: ../src/pulsecore/core-util.h:95 +msgid "yes" +msgstr "" + +#: ../src/pulsecore/core-util.h:95 +msgid "no" +msgstr "" + +#: ../src/pulsecore/lock-autospawn.c:143 ../src/pulsecore/lock-autospawn.c:229 +msgid "Cannot access autospawn lock." +msgstr "" + +#: ../src/pulsecore/log.c:155 +#, c-format +msgid "Failed to open target file '%s'." +msgstr "" + +#: ../src/pulsecore/log.c:178 +#, c-format +msgid "" +"Tried to open target file '%s', '%s.1', '%s.2' ... '%s.%d', but all failed." +msgstr "" + +#: ../src/pulsecore/log.c:633 +msgid "Invalid log target." +msgstr "" + +#: ../src/pulsecore/sink.c:3429 +msgid "Built-in Audio" +msgstr "Vstavan?? audio" + +#: ../src/pulsecore/sink.c:3434 +msgid "Modem" +msgstr "Modem" + +#: ../src/pulse/error.c:40 +msgid "OK" +msgstr "OK" + +#: ../src/pulse/error.c:41 +msgid "Access denied" +msgstr "Pr??stup zamietnut??" + +#: ../src/pulse/error.c:42 +msgid "Unknown command" +msgstr "Nezn??my pr??kaz" + +#: ../src/pulse/error.c:43 +msgid "Invalid argument" +msgstr "Neplatn?? parameter" + +#: ../src/pulse/error.c:44 +msgid "Entity exists" +msgstr "" + +#: ../src/pulse/error.c:45 +msgid "No such entity" +msgstr "" + +#: ../src/pulse/error.c:46 +msgid "Connection refused" +msgstr "" + +#: ../src/pulse/error.c:47 +msgid "Protocol error" +msgstr "" + +#: ../src/pulse/error.c:48 +msgid "Timeout" +msgstr "Vypr??anie ??asu" + +#: ../src/pulse/error.c:49 +msgid "No authentication key" +msgstr "" + +#: ../src/pulse/error.c:50 +msgid "Internal error" +msgstr "Intern?? chyba" + +#: ../src/pulse/error.c:51 +msgid "Connection terminated" +msgstr "" + +#: ../src/pulse/error.c:52 +msgid "Entity killed" +msgstr "" + +#: ../src/pulse/error.c:53 +msgid "Invalid server" +msgstr "Neplatn?? server" + +#: ../src/pulse/error.c:54 +msgid "Module initialization failed" +msgstr "" + +#: ../src/pulse/error.c:55 +msgid "Bad state" +msgstr "Zl?? stav" + +#: ../src/pulse/error.c:56 +msgid "No data" +msgstr "??iadne ??daje" + +#: ../src/pulse/error.c:57 +msgid "Incompatible protocol version" +msgstr "" + +#: ../src/pulse/error.c:58 +msgid "Too large" +msgstr "" + +#: ../src/pulse/error.c:59 +msgid "Not supported" +msgstr "" + +#: ../src/pulse/error.c:60 +msgid "Unknown error code" +msgstr "" + +#: ../src/pulse/error.c:61 +msgid "No such extension" +msgstr "" + +#: ../src/pulse/error.c:62 +msgid "Obsolete functionality" +msgstr "" + +#: ../src/pulse/error.c:63 +msgid "Missing implementation" +msgstr "" + +#: ../src/pulse/error.c:64 +msgid "Client forked" +msgstr "" + +#: ../src/pulse/error.c:65 +msgid "Input/Output error" +msgstr "Vstupno/v??stupn?? chyba" + +#: ../src/pulse/error.c:66 +msgid "Device or resource busy" +msgstr "Zariadenie alebo prostriedok je zanepr??zdnen??" + +#: ../src/pulse/sample.c:179 +#, c-format +msgid "%s %uch %uHz" +msgstr "" + +#: ../src/pulse/sample.c:191 +#, c-format +msgid "%0.1f GiB" +msgstr "" + +#: ../src/pulse/sample.c:193 +#, c-format +msgid "%0.1f MiB" +msgstr "" + +#: ../src/pulse/sample.c:195 +#, c-format +msgid "%0.1f KiB" +msgstr "" + +#: ../src/pulse/sample.c:197 +#, c-format +msgid "%u B" +msgstr "" + +#: ../src/tests/resampler-test.c:257 +#, c-format +msgid "" +"%s [options]\n" +"\n" +"-h, --help Show this help\n" +"-v, --verbose Print debug messages\n" +" --from-rate=SAMPLERATE From sample rate in Hz (defaults to " +"44100)\n" +" --from-format=SAMPLEFORMAT From sample type (defaults to s16le)\n" +" --from-channels=CHANNELS From number of channels (defaults to " +"1)\n" +" --to-rate=SAMPLERATE To sample rate in Hz (defaults to " +"44100)\n" +" --to-format=SAMPLEFORMAT To sample type (defaults to s16le)\n" +" --to-channels=CHANNELS To number of channels (defaults to 1)\n" +" --resample-method=METHOD Resample method (defaults to auto)\n" +" --seconds=SECONDS From stream duration (defaults to 60)\n" +"\n" +"If the formats are not specified, the test performs all formats " +"combinations,\n" +"back and forth.\n" +"\n" +"Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, " +"alaw,\n" +"s24le, s24be, s24-32le, s24-32be, s32le, s32be (defaults to s16ne)\n" +"\n" +"See --dump-resample-methods for possible values of resample methods.\n" +msgstr "" + +#: ../src/tests/resampler-test.c:356 +#, c-format +msgid "%s %s\n" +msgstr "" + +#: ../src/utils/pacat.c:118 +#, c-format +msgid "Failed to drain stream: %s" +msgstr "" + +#: ../src/utils/pacat.c:123 +msgid "Playback stream drained." +msgstr "" + +#: ../src/utils/pacat.c:134 +msgid "Draining connection to server." +msgstr "" + +#: ../src/utils/pacat.c:147 +#, c-format +msgid "pa_stream_drain(): %s" +msgstr "" + +#: ../src/utils/pacat.c:170 +#, c-format +msgid "pa_stream_write() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:211 +#, c-format +msgid "pa_stream_begin_write() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:261 ../src/utils/pacat.c:291 +#, c-format +msgid "pa_stream_peek() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:341 +msgid "Stream successfully created." +msgstr "" + +#: ../src/utils/pacat.c:344 +#, c-format +msgid "pa_stream_get_buffer_attr() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:348 +#, c-format +msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u" +msgstr "" + +#: ../src/utils/pacat.c:351 +#, c-format +msgid "Buffer metrics: maxlength=%u, fragsize=%u" +msgstr "" + +#: ../src/utils/pacat.c:355 +#, c-format +msgid "Using sample spec '%s', channel map '%s'." +msgstr "" + +#: ../src/utils/pacat.c:359 +#, c-format +msgid "Connected to device %s (index: %u, suspended: %s)." +msgstr "" + +#: ../src/utils/pacat.c:369 +#, c-format +msgid "Stream error: %s" +msgstr "" + +#: ../src/utils/pacat.c:379 +#, c-format +msgid "Stream device suspended.%s" +msgstr "" + +#: ../src/utils/pacat.c:381 +#, c-format +msgid "Stream device resumed.%s" +msgstr "" + +#: ../src/utils/pacat.c:389 +#, c-format +msgid "Stream underrun.%s" +msgstr "" + +#: ../src/utils/pacat.c:396 +#, c-format +msgid "Stream overrun.%s" +msgstr "" + +#: ../src/utils/pacat.c:403 +#, c-format +msgid "Stream started.%s" +msgstr "" + +#: ../src/utils/pacat.c:410 +#, c-format +msgid "Stream moved to device %s (%u, %ssuspended).%s" +msgstr "" + +#: ../src/utils/pacat.c:410 +msgid "not " +msgstr "" + +#: ../src/utils/pacat.c:417 +#, c-format +msgid "Stream buffer attributes changed.%s" +msgstr "" + +#: ../src/utils/pacat.c:432 +msgid "Cork request stack is empty: corking stream" +msgstr "" + +#: ../src/utils/pacat.c:438 +msgid "Cork request stack is empty: uncorking stream" +msgstr "" + +#: ../src/utils/pacat.c:442 +msgid "Warning: Received more uncork requests than cork requests!" +msgstr "" + +#: ../src/utils/pacat.c:467 +#, c-format +msgid "Connection established.%s" +msgstr "" + +#: ../src/utils/pacat.c:470 +#, c-format +msgid "pa_stream_new() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:508 +#, c-format +msgid "pa_stream_connect_playback() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:514 +#, c-format +msgid "Failed to set monitor stream: %s" +msgstr "" + +#: ../src/utils/pacat.c:518 +#, c-format +msgid "pa_stream_connect_record() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:531 ../src/utils/pactl.c:1455 +#, c-format +msgid "Connection failure: %s" +msgstr "" + +#: ../src/utils/pacat.c:564 +msgid "Got EOF." +msgstr "" + +#: ../src/utils/pacat.c:601 +#, c-format +msgid "write() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:622 +msgid "Got signal, exiting." +msgstr "" + +#: ../src/utils/pacat.c:636 +#, c-format +msgid "Failed to get latency: %s" +msgstr "" + +#: ../src/utils/pacat.c:641 +#, c-format +msgid "Time: %0.3f sec; Latency: %0.0f usec." +msgstr "" + +#: ../src/utils/pacat.c:662 +#, c-format +msgid "pa_stream_update_timing_info() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:672 +#, c-format +msgid "" +"%s [options]\n" +"\n" +" -h, --help Show this help\n" +" --version Show version\n" +"\n" +" -r, --record Create a connection for recording\n" +" -p, --playback Create a connection for playback\n" +"\n" +" -v, --verbose Enable verbose operations\n" +"\n" +" -s, --server=SERVER The name of the server to connect " +"to\n" +" -d, --device=DEVICE The name of the sink/source to " +"connect to\n" +" -n, --client-name=NAME How to call this client on the " +"server\n" +" --stream-name=NAME How to call this stream on the " +"server\n" +" --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, s32le, s32be, " +"s24le, s24be,\n" +" s24-32le, s24-32be (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" +" --fix-format Take the sample format from the sink/" +"source the stream is\n" +" being connected to.\n" +" --fix-rate Take the sampling rate from the sink/" +"source the stream is\n" +" being connected to.\n" +" --fix-channels Take the number of channels and the " +"channel map\n" +" from the sink/source the stream is " +"being connected to.\n" +" --no-remix Don't upmix or downmix channels.\n" +" --no-remap Map channels by index instead of " +"name.\n" +" --latency=BYTES Request the specified latency in " +"bytes.\n" +" --process-time=BYTES Request the specified process time " +"per request in bytes.\n" +" --latency-msec=MSEC Request the specified latency in " +"msec.\n" +" --process-time-msec=MSEC Request the specified process time " +"per request in msec.\n" +" --property=PROPERTY=VALUE Set the specified property to the " +"specified value.\n" +" --raw Record/play raw PCM data.\n" +" --passthrough Passthrough data.\n" +" --file-format[=FFORMAT] Record/play formatted PCM data.\n" +" --list-file-formats List available file formats.\n" +" --monitor-stream=INDEX Record from the sink input with " +"index INDEX.\n" +msgstr "" + +#: ../src/utils/pacat.c:810 +#, c-format +msgid "" +"pacat %s\n" +"Compiled with libpulse %s\n" +"Linked with libpulse %s\n" +msgstr "" + +#: ../src/utils/pacat.c:843 ../src/utils/pactl.c:1651 +#, c-format +msgid "Invalid client name '%s'" +msgstr "" + +#: ../src/utils/pacat.c:858 +#, c-format +msgid "Invalid stream name '%s'" +msgstr "" + +#: ../src/utils/pacat.c:895 +#, c-format +msgid "Invalid channel map '%s'" +msgstr "" + +#: ../src/utils/pacat.c:924 ../src/utils/pacat.c:938 +#, c-format +msgid "Invalid latency specification '%s'" +msgstr "" + +#: ../src/utils/pacat.c:931 ../src/utils/pacat.c:945 +#, c-format +msgid "Invalid process time specification '%s'" +msgstr "" + +#: ../src/utils/pacat.c:957 +#, c-format +msgid "Invalid property '%s'" +msgstr "" + +#: ../src/utils/pacat.c:976 +#, c-format +msgid "Unknown file format %s." +msgstr "" + +#: ../src/utils/pacat.c:991 +msgid "Failed to parse the argument for --monitor-stream" +msgstr "" + +#: ../src/utils/pacat.c:1002 +msgid "Invalid sample specification" +msgstr "" + +#: ../src/utils/pacat.c:1012 +#, c-format +msgid "open(): %s" +msgstr "" + +#: ../src/utils/pacat.c:1017 +#, c-format +msgid "dup2(): %s" +msgstr "" + +#: ../src/utils/pacat.c:1024 +msgid "Too many arguments." +msgstr "" + +#: ../src/utils/pacat.c:1035 +msgid "Failed to generate sample specification for file." +msgstr "" + +#: ../src/utils/pacat.c:1061 +msgid "Failed to open audio file." +msgstr "" + +#: ../src/utils/pacat.c:1067 +msgid "" +"Warning: specified sample specification will be overwritten with " +"specification from file." +msgstr "" + +#: ../src/utils/pacat.c:1070 ../src/utils/pactl.c:1718 +msgid "Failed to determine sample specification from file." +msgstr "" + +#: ../src/utils/pacat.c:1079 +msgid "Warning: Failed to determine channel map from file." +msgstr "" + +#: ../src/utils/pacat.c:1090 +msgid "Channel map doesn't match sample specification" +msgstr "" + +#: ../src/utils/pacat.c:1101 +msgid "Warning: failed to write channel map to file." +msgstr "" + +#: ../src/utils/pacat.c:1116 +#, c-format +msgid "" +"Opening a %s stream with sample specification '%s' and channel map '%s'." +msgstr "" + +#: ../src/utils/pacat.c:1117 +msgid "recording" +msgstr "" + +#: ../src/utils/pacat.c:1117 +msgid "playback" +msgstr "" + +#: ../src/utils/pacat.c:1141 +msgid "Failed to set media name." +msgstr "" + +#: ../src/utils/pacat.c:1148 ../src/utils/pactl.c:2068 +msgid "pa_mainloop_new() failed." +msgstr "" + +#: ../src/utils/pacat.c:1171 +msgid "io_new() failed." +msgstr "" + +#: ../src/utils/pacat.c:1178 ../src/utils/pactl.c:2080 +msgid "pa_context_new() failed." +msgstr "" + +#: ../src/utils/pacat.c:1186 ../src/utils/pactl.c:2086 +#, c-format +msgid "pa_context_connect() failed: %s" +msgstr "" + +#: ../src/utils/pacat.c:1192 +msgid "pa_context_rttime_new() failed." +msgstr "" + +#: ../src/utils/pacat.c:1199 ../src/utils/pactl.c:2091 +msgid "pa_mainloop_run() failed." +msgstr "" + +#: ../src/utils/pacmd.c:53 ../src/utils/pactl.c:1573 +msgid "NAME [ARGS ...]" +msgstr "" + +#: ../src/utils/pacmd.c:54 ../src/utils/pacmd.c:62 ../src/utils/pactl.c:1574 +msgid "NAME|#N" +msgstr "" + +#: ../src/utils/pacmd.c:55 ../src/utils/pacmd.c:65 ../src/utils/pactl.c:1572 +#: ../src/utils/pactl.c:1578 +msgid "NAME" +msgstr "" + +#: ../src/utils/pacmd.c:56 +msgid "NAME|#N VOLUME" +msgstr "" + +#: ../src/utils/pacmd.c:57 +msgid "#N VOLUME" +msgstr "" + +#: ../src/utils/pacmd.c:58 ../src/utils/pacmd.c:72 ../src/utils/pactl.c:1576 +msgid "NAME|#N 1|0" +msgstr "" + +#: ../src/utils/pacmd.c:59 +msgid "#N 1|0" +msgstr "" + +#: ../src/utils/pacmd.c:60 +msgid "NAME|#N KEY=VALUE" +msgstr "" + +#: ../src/utils/pacmd.c:61 +msgid "#N KEY=VALUE" +msgstr "" + +#: ../src/utils/pacmd.c:63 +msgid "#N" +msgstr "" + +#: ../src/utils/pacmd.c:64 +msgid "NAME SINK|#N" +msgstr "" + +#: ../src/utils/pacmd.c:66 ../src/utils/pacmd.c:67 +msgid "NAME FILENAME" +msgstr "" + +#: ../src/utils/pacmd.c:68 +msgid "PATHNAME" +msgstr "" + +#: ../src/utils/pacmd.c:69 +msgid "FILENAME SINK|#N" +msgstr "" + +#: ../src/utils/pacmd.c:71 ../src/utils/pactl.c:1575 +msgid "#N SINK|SOURCE" +msgstr "" + +#: ../src/utils/pacmd.c:73 ../src/utils/pacmd.c:79 ../src/utils/pacmd.c:80 +msgid "1|0" +msgstr "" + +#: ../src/utils/pacmd.c:74 ../src/utils/pactl.c:1577 +msgid "CARD PROFILE" +msgstr "" + +#: ../src/utils/pacmd.c:75 ../src/utils/pactl.c:1579 +msgid "NAME|#N PORT" +msgstr "" + +#: ../src/utils/pacmd.c:76 ../src/utils/pactl.c:1585 +msgid "CARD-NAME|CARD-#N PORT OFFSET" +msgstr "" + +#: ../src/utils/pacmd.c:77 +msgid "TARGET" +msgstr "" + +#: ../src/utils/pacmd.c:78 +msgid "NUMERIC LEVEL" +msgstr "" + +#: ../src/utils/pacmd.c:81 +msgid "FRAMES" +msgstr "" + +#: ../src/utils/pacmd.c:83 +#, c-format +msgid "" +"\n" +" -h, --help Show this help\n" +" --version Show version\n" +"When no command is given pacmd starts in the interactive mode.\n" +msgstr "" + +#: ../src/utils/pacmd.c:130 +#, c-format +msgid "" +"pacmd %s\n" +"Compiled with libpulse %s\n" +"Linked with libpulse %s\n" +msgstr "" + +#: ../src/utils/pacmd.c:144 +msgid "No PulseAudio daemon running, or not running as session daemon." +msgstr "" + +#: ../src/utils/pacmd.c:149 +#, c-format +msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s" +msgstr "" + +#: ../src/utils/pacmd.c:166 +#, c-format +msgid "connect(): %s" +msgstr "" + +#: ../src/utils/pacmd.c:174 +msgid "Failed to kill PulseAudio daemon." +msgstr "" + +#: ../src/utils/pacmd.c:182 +msgid "Daemon not responding." +msgstr "" + +#: ../src/utils/pacmd.c:214 ../src/utils/pacmd.c:323 ../src/utils/pacmd.c:341 +#, c-format +msgid "write(): %s" +msgstr "" + +#: ../src/utils/pacmd.c:270 +#, c-format +msgid "poll(): %s" +msgstr "" + +#: ../src/utils/pacmd.c:281 ../src/utils/pacmd.c:301 +#, c-format +msgid "read(): %s" +msgstr "" + +#: ../src/utils/pactl.c:166 +#, c-format +msgid "Failed to get statistics: %s" +msgstr "" + +#: ../src/utils/pactl.c:172 +#, c-format +msgid "Currently in use: %u blocks containing %s bytes total.\n" +msgstr "" + +#: ../src/utils/pactl.c:175 +#, c-format +msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n" +msgstr "" + +#: ../src/utils/pactl.c:178 +#, c-format +msgid "Sample cache size: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:187 +#, c-format +msgid "Failed to get server information: %s" +msgstr "" + +#: ../src/utils/pactl.c:192 +#, c-format +msgid "" +"Server String: %s\n" +"Library Protocol Version: %u\n" +"Server Protocol Version: %u\n" +"Is Local: %s\n" +"Client Index: %u\n" +"Tile Size: %zu\n" +msgstr "" + +#: ../src/utils/pactl.c:208 +#, c-format +msgid "" +"User Name: %s\n" +"Host Name: %s\n" +"Server Name: %s\n" +"Server Version: %s\n" +"Default Sample Specification: %s\n" +"Default Channel Map: %s\n" +"Default Sink: %s\n" +"Default Source: %s\n" +"Cookie: %04x:%04x\n" +msgstr "" + +#: ../src/utils/pactl.c:257 ../src/utils/pactl.c:902 ../src/utils/pactl.c:980 +#, c-format +msgid "Failed to get sink information: %s" +msgstr "" + +#: ../src/utils/pactl.c:283 +#, c-format +msgid "" +"Sink #%u\n" +"\tState: %s\n" +"\tName: %s\n" +"\tDescription: %s\n" +"\tDriver: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tOwner Module: %u\n" +"\tMute: %s\n" +"\tVolume: %s\n" +"\t balance %0.2f\n" +"\tBase Volume: %s\n" +"\tMonitor Source: %s\n" +"\tLatency: %0.0f usec, configured %0.0f usec\n" +"\tFlags: %s%s%s%s%s%s%s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:327 ../src/utils/pactl.c:433 ../src/utils/pactl.c:594 +#, c-format +msgid "\tPorts:\n" +msgstr "" + +#: ../src/utils/pactl.c:334 ../src/utils/pactl.c:440 +#, c-format +msgid "\tActive Port: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:340 ../src/utils/pactl.c:446 +#, c-format +msgid "\tFormats:\n" +msgstr "" + +#: ../src/utils/pactl.c:364 ../src/utils/pactl.c:922 ../src/utils/pactl.c:995 +#, c-format +msgid "Failed to get source information: %s" +msgstr "" + +#: ../src/utils/pactl.c:390 +#, c-format +msgid "" +"Source #%u\n" +"\tState: %s\n" +"\tName: %s\n" +"\tDescription: %s\n" +"\tDriver: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tOwner Module: %u\n" +"\tMute: %s\n" +"\tVolume: %s\n" +"\t balance %0.2f\n" +"\tBase Volume: %s\n" +"\tMonitor of Sink: %s\n" +"\tLatency: %0.0f usec, configured %0.0f usec\n" +"\tFlags: %s%s%s%s%s%s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:418 ../src/utils/pactl.c:488 ../src/utils/pactl.c:531 +#: ../src/utils/pactl.c:573 ../src/utils/pactl.c:671 ../src/utils/pactl.c:672 +#: ../src/utils/pactl.c:683 ../src/utils/pactl.c:741 ../src/utils/pactl.c:742 +#: ../src/utils/pactl.c:753 ../src/utils/pactl.c:804 ../src/utils/pactl.c:805 +#: ../src/utils/pactl.c:811 +msgid "n/a" +msgstr "" + +#: ../src/utils/pactl.c:457 ../src/utils/pactl.c:861 +#, c-format +msgid "Failed to get module information: %s" +msgstr "" + +#: ../src/utils/pactl.c:480 +#, c-format +msgid "" +"Module #%u\n" +"\tName: %s\n" +"\tArgument: %s\n" +"\tUsage counter: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:499 +#, c-format +msgid "Failed to get client information: %s" +msgstr "" + +#: ../src/utils/pactl.c:525 +#, c-format +msgid "" +"Client #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:542 +#, c-format +msgid "Failed to get card information: %s" +msgstr "" + +#: ../src/utils/pactl.c:565 +#, c-format +msgid "" +"Card #%u\n" +"\tName: %s\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:581 +#, c-format +msgid "\tProfiles:\n" +msgstr "" + +#: ../src/utils/pactl.c:588 +#, c-format +msgid "\tActive Profile: %s\n" +msgstr "" + +#: ../src/utils/pactl.c:602 +#, c-format +msgid "" +"\t\t\tProperties:\n" +"\t\t\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:607 +#, c-format +msgid "\t\t\tPart of profile(s): %s" +msgstr "" + +#: ../src/utils/pactl.c:624 ../src/utils/pactl.c:942 ../src/utils/pactl.c:1010 +#, c-format +msgid "Failed to get sink input information: %s" +msgstr "" + +#: ../src/utils/pactl.c:653 +#, c-format +msgid "" +"Sink Input #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tClient: %s\n" +"\tSink: %u\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tFormat: %s\n" +"\tCorked: %s\n" +"\tMute: %s\n" +"\tVolume: %s\n" +"\t balance %0.2f\n" +"\tBuffer Latency: %0.0f usec\n" +"\tSink Latency: %0.0f usec\n" +"\tResample method: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:694 ../src/utils/pactl.c:962 ../src/utils/pactl.c:1025 +#, c-format +msgid "Failed to get source output information: %s" +msgstr "" + +#: ../src/utils/pactl.c:723 +#, c-format +msgid "" +"Source Output #%u\n" +"\tDriver: %s\n" +"\tOwner Module: %s\n" +"\tClient: %s\n" +"\tSource: %u\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tFormat: %s\n" +"\tCorked: %s\n" +"\tMute: %s\n" +"\tVolume: %s\n" +"\t balance %0.2f\n" +"\tBuffer Latency: %0.0f usec\n" +"\tSource Latency: %0.0f usec\n" +"\tResample method: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:764 +#, c-format +msgid "Failed to get sample information: %s" +msgstr "" + +#: ../src/utils/pactl.c:791 +#, c-format +msgid "" +"Sample #%u\n" +"\tName: %s\n" +"\tSample Specification: %s\n" +"\tChannel Map: %s\n" +"\tVolume: %s\n" +"\t balance %0.2f\n" +"\tDuration: %0.1fs\n" +"\tSize: %s\n" +"\tLazy: %s\n" +"\tFilename: %s\n" +"\tProperties:\n" +"\t\t%s\n" +msgstr "" + +#: ../src/utils/pactl.c:819 ../src/utils/pactl.c:829 +#, c-format +msgid "Failure: %s" +msgstr "" + +#: ../src/utils/pactl.c:868 +#, c-format +msgid "Failed to unload module: Module %s not loaded" +msgstr "" + +#: ../src/utils/pactl.c:886 +#, c-format +msgid "" +"Failed to set volume: You tried to set volumes for %d channels, whereas " +"channel/s supported = %d\n" +msgstr "" + +#: ../src/utils/pactl.c:1052 +#, c-format +msgid "Failed to set format: invalid format string %s" +msgstr "" + +#: ../src/utils/pactl.c:1095 +#, c-format +msgid "Failed to upload sample: %s" +msgstr "" + +#: ../src/utils/pactl.c:1112 +msgid "Premature end of file" +msgstr "" + +#: ../src/utils/pactl.c:1132 +msgid "new" +msgstr "" + +#: ../src/utils/pactl.c:1135 +msgid "change" +msgstr "" + +#: ../src/utils/pactl.c:1138 +msgid "remove" +msgstr "" + +#: ../src/utils/pactl.c:1141 ../src/utils/pactl.c:1176 +msgid "unknown" +msgstr "" + +#: ../src/utils/pactl.c:1149 +msgid "sink" +msgstr "" + +#: ../src/utils/pactl.c:1152 +msgid "source" +msgstr "" + +#: ../src/utils/pactl.c:1155 +msgid "sink-input" +msgstr "" + +#: ../src/utils/pactl.c:1158 +msgid "source-output" +msgstr "" + +#: ../src/utils/pactl.c:1161 +msgid "module" +msgstr "" + +#: ../src/utils/pactl.c:1164 +msgid "client" +msgstr "" + +#: ../src/utils/pactl.c:1167 +msgid "sample-cache" +msgstr "" + +#: ../src/utils/pactl.c:1170 +msgid "server" +msgstr "" + +#: ../src/utils/pactl.c:1173 +msgid "card" +msgstr "" + +#: ../src/utils/pactl.c:1182 +#, c-format +msgid "Event '%s' on %s #%u\n" +msgstr "" + +#: ../src/utils/pactl.c:1461 +msgid "Got SIGINT, exiting." +msgstr "" + +#: ../src/utils/pactl.c:1488 +msgid "Invalid volume specification" +msgstr "" + +#: ../src/utils/pactl.c:1511 +msgid "Volume outside permissible range.\n" +msgstr "" + +#: ../src/utils/pactl.c:1524 +msgid "Invalid number of volume specifications.\n" +msgstr "" + +#: ../src/utils/pactl.c:1536 +msgid "Inconsistent volume specification.\n" +msgstr "" + +#: ../src/utils/pactl.c:1566 ../src/utils/pactl.c:1567 +#: ../src/utils/pactl.c:1568 ../src/utils/pactl.c:1569 +#: ../src/utils/pactl.c:1570 ../src/utils/pactl.c:1571 +#: ../src/utils/pactl.c:1572 ../src/utils/pactl.c:1573 +#: ../src/utils/pactl.c:1574 ../src/utils/pactl.c:1575 +#: ../src/utils/pactl.c:1576 ../src/utils/pactl.c:1577 +#: ../src/utils/pactl.c:1578 ../src/utils/pactl.c:1579 +#: ../src/utils/pactl.c:1580 ../src/utils/pactl.c:1581 +#: ../src/utils/pactl.c:1582 ../src/utils/pactl.c:1583 +#: ../src/utils/pactl.c:1584 ../src/utils/pactl.c:1585 +#: ../src/utils/pactl.c:1586 +msgid "[options]" +msgstr "" + +#: ../src/utils/pactl.c:1568 +msgid "[TYPE]" +msgstr "" + +#: ../src/utils/pactl.c:1570 +msgid "FILENAME [NAME]" +msgstr "" + +#: ../src/utils/pactl.c:1571 +msgid "NAME [SINK]" +msgstr "" + +#: ../src/utils/pactl.c:1580 +msgid "NAME|#N VOLUME [VOLUME ...]" +msgstr "" + +#: ../src/utils/pactl.c:1581 +msgid "#N VOLUME [VOLUME ...]" +msgstr "" + +#: ../src/utils/pactl.c:1582 +msgid "NAME|#N 1|0|toggle" +msgstr "" + +#: ../src/utils/pactl.c:1583 +msgid "#N 1|0|toggle" +msgstr "" + +#: ../src/utils/pactl.c:1584 +msgid "#N FORMATS" +msgstr "" + +#: ../src/utils/pactl.c:1587 +#, c-format +msgid "" +"\n" +"The special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@\n" +"can be used to specify the default sink, source and monitor.\n" +msgstr "" + +#: ../src/utils/pactl.c:1590 +#, c-format +msgid "" +"\n" +" -h, --help Show this help\n" +" --version Show version\n" +"\n" +" -s, --server=SERVER The name of the server to connect " +"to\n" +" -n, --client-name=NAME How to call this client on the " +"server\n" +msgstr "" + +#: ../src/utils/pactl.c:1631 +#, c-format +msgid "" +"pactl %s\n" +"Compiled with libpulse %s\n" +"Linked with libpulse %s\n" +msgstr "" + +#: ../src/utils/pactl.c:1690 +#, c-format +msgid "Specify nothing, or one of: %s" +msgstr "" + +#: ../src/utils/pactl.c:1700 +msgid "Please specify a sample file to load" +msgstr "" + +#: ../src/utils/pactl.c:1713 +msgid "Failed to open sound file." +msgstr "" + +#: ../src/utils/pactl.c:1725 +msgid "Warning: Failed to determine sample specification from file." +msgstr "" + +#: ../src/utils/pactl.c:1735 +msgid "You have to specify a sample name to play" +msgstr "" + +#: ../src/utils/pactl.c:1747 +msgid "You have to specify a sample name to remove" +msgstr "" + +#: ../src/utils/pactl.c:1756 +msgid "You have to specify a sink input index and a sink" +msgstr "" + +#: ../src/utils/pactl.c:1766 +msgid "You have to specify a source output index and a source" +msgstr "" + +#: ../src/utils/pactl.c:1781 +msgid "You have to specify a module name and arguments." +msgstr "" + +#: ../src/utils/pactl.c:1801 +msgid "You have to specify a module index or name" +msgstr "" + +#: ../src/utils/pactl.c:1814 +msgid "" +"You may not specify more than one sink. You have to specify a boolean value." +msgstr "" + +#: ../src/utils/pactl.c:1819 ../src/utils/pactl.c:1839 +msgid "Invalid suspend specification." +msgstr "" + +#: ../src/utils/pactl.c:1834 +msgid "" +"You may not specify more than one source. You have to specify a boolean " +"value." +msgstr "" + +#: ../src/utils/pactl.c:1851 +msgid "You have to specify a card name/index and a profile name" +msgstr "" + +#: ../src/utils/pactl.c:1862 +msgid "You have to specify a sink name/index and a port name" +msgstr "" + +#: ../src/utils/pactl.c:1873 +msgid "You have to specify a sink name" +msgstr "" + +#: ../src/utils/pactl.c:1883 +msgid "You have to specify a source name/index and a port name" +msgstr "" + +#: ../src/utils/pactl.c:1894 +msgid "You have to specify a source name" +msgstr "" + +#: ../src/utils/pactl.c:1904 +msgid "You have to specify a sink name/index and a volume" +msgstr "" + +#: ../src/utils/pactl.c:1917 +msgid "You have to specify a source name/index and a volume" +msgstr "" + +#: ../src/utils/pactl.c:1930 +msgid "You have to specify a sink input index and a volume" +msgstr "" + +#: ../src/utils/pactl.c:1935 +msgid "Invalid sink input index" +msgstr "" + +#: ../src/utils/pactl.c:1946 +msgid "You have to specify a source output index and a volume" +msgstr "" + +#: ../src/utils/pactl.c:1951 +msgid "Invalid source output index" +msgstr "" + +#: ../src/utils/pactl.c:1962 +msgid "You have to specify a sink name/index and a mute boolean" +msgstr "" + +#: ../src/utils/pactl.c:1967 ../src/utils/pactl.c:1982 +#: ../src/utils/pactl.c:2002 ../src/utils/pactl.c:2020 +msgid "Invalid mute specification" +msgstr "" + +#: ../src/utils/pactl.c:1977 +msgid "You have to specify a source name/index and a mute boolean" +msgstr "" + +#: ../src/utils/pactl.c:1992 +msgid "You have to specify a sink input index and a mute boolean" +msgstr "" + +#: ../src/utils/pactl.c:1997 +msgid "Invalid sink input index specification" +msgstr "" + +#: ../src/utils/pactl.c:2010 +msgid "You have to specify a source output index and a mute boolean" +msgstr "" + +#: ../src/utils/pactl.c:2015 +msgid "Invalid source output index specification" +msgstr "" + +#: ../src/utils/pactl.c:2032 +msgid "" +"You have to specify a sink index and a semicolon-separated list of supported " +"formats" +msgstr "" + +#: ../src/utils/pactl.c:2044 +msgid "You have to specify a card name/index, a port name and a latency offset" +msgstr "" + +#: ../src/utils/pactl.c:2051 +msgid "Could not parse latency offset" +msgstr "" + +#: ../src/utils/pactl.c:2063 +msgid "No valid command specified." +msgstr "Nebol u??en?? ??iadny platn?? pr??kaz." + +#: ../src/utils/pasuspender.c:81 +#, c-format +msgid "fork(): %s\n" +msgstr "" + +#: ../src/utils/pasuspender.c:94 +#, c-format +msgid "execvp(): %s\n" +msgstr "" + +#: ../src/utils/pasuspender.c:113 +#, c-format +msgid "Failure to resume: %s\n" +msgstr "Zlyhanie pri pokra??ovan??: %s\n" + +#: ../src/utils/pasuspender.c:147 +#, c-format +msgid "Failure to suspend: %s\n" +msgstr "Zlyhanie pri usp??van??: %s\n" + +#: ../src/utils/pasuspender.c:172 +#, c-format +msgid "WARNING: Sound server is not local, not suspending.\n" +msgstr "UPOZORNENIE: Zvukov?? server nie je miestny. Neusp??va sa.\n" + +#: ../src/utils/pasuspender.c:185 +#, c-format +msgid "Connection failure: %s\n" +msgstr "Zlyhanie pripojenia: %s\n" + +#: ../src/utils/pasuspender.c:203 +#, c-format +msgid "Got SIGINT, exiting.\n" +msgstr "" + +#: ../src/utils/pasuspender.c:221 +#, c-format +msgid "WARNING: Child process terminated by signal %u\n" +msgstr "" + +#: ../src/utils/pasuspender.c:230 +#, c-format +msgid "" +"%s [options] ... \n" +"\n" +" -h, --help Show this help\n" +" --version Show version\n" +" -s, --server=SERVER The name of the server to connect " +"to\n" +"\n" +msgstr "" +"%s [vo??by] ... \n" +"\n" +" -h, --help Zobraz?? tohto pomocn??ka\n" +" --version Zobraz?? verziu\n" +" -s, --server=SERVER N??zov servera, na ktor?? sa pripoji??\n" +"\n" + +#: ../src/utils/pasuspender.c:268 +#, c-format +msgid "" +"pasuspender %s\n" +"Compiled with libpulse %s\n" +"Linked with libpulse %s\n" +msgstr "" + +#: ../src/utils/pasuspender.c:297 +#, c-format +msgid "pa_mainloop_new() failed.\n" +msgstr "" + +#: ../src/utils/pasuspender.c:310 +#, c-format +msgid "pa_context_new() failed.\n" +msgstr "" + +#: ../src/utils/pasuspender.c:322 +#, c-format +msgid "pa_mainloop_run() failed.\n" +msgstr "" + +#: ../src/utils/pax11publish.c:60 +#, c-format +msgid "" +"%s [-D display] [-S server] [-O sink] [-I source] [-c file] [-d|-e|-i|-r]\n" +"\n" +" -d Show current PulseAudio data attached to X11 display (default)\n" +" -e Export local PulseAudio data to X11 display\n" +" -i Import PulseAudio data from X11 display to local environment " +"variables and cookie file.\n" +" -r Remove PulseAudio data from X11 display\n" +msgstr "" + +#: ../src/utils/pax11publish.c:93 +#, c-format +msgid "Failed to parse command line.\n" +msgstr "Zlyhalo analyzovanie pr??kazov??ho riadku.\n" + +#: ../src/utils/pax11publish.c:112 +#, c-format +msgid "Server: %s\n" +msgstr "Server: %s\n" + +#: ../src/utils/pax11publish.c:114 +#, c-format +msgid "Source: %s\n" +msgstr "Zdroj: %s\n" + +#: ../src/utils/pax11publish.c:116 +#, c-format +msgid "Sink: %s\n" +msgstr "" + +#: ../src/utils/pax11publish.c:118 +#, c-format +msgid "Cookie: %s\n" +msgstr "" + +#: ../src/utils/pax11publish.c:136 +#, c-format +msgid "Failed to parse cookie data\n" +msgstr "" + +#: ../src/utils/pax11publish.c:141 +#, c-format +msgid "Failed to save cookie data\n" +msgstr "" + +#: ../src/utils/pax11publish.c:170 +#, c-format +msgid "Failed to get FQDN.\n" +msgstr "" + +#: ../src/utils/pax11publish.c:190 +#, c-format +msgid "Failed to load cookie data\n" +msgstr "" + +#: ../src/utils/pax11publish.c:208 +#, c-format +msgid "Not yet implemented.\n" +msgstr "" From tanuk at kemper.freedesktop.org Tue Sep 16 05:17:33 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Tue, 16 Sep 2014 05:17:33 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140916121733.7DDFE7617E@kemper.freedesktop.org> src/modules/bluetooth/backend-ofono.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) New commits: commit 75bf00a5071f307304d58864f9b980e0a56f39f2 Author: Jo??o Paulo Rechi Vita Date: Mon Sep 15 13:02:02 2014 +0300 bluetooth: Implement org.ofono.HandsfreeAudioAgent.NewConnection() diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index cab5319..d1ee146 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -505,7 +505,10 @@ static DBusMessage *hf_audio_agent_release(DBusConnection *c, DBusMessage *m, vo static DBusMessage *hf_audio_agent_new_connection(DBusConnection *c, DBusMessage *m, void *data) { DBusMessage *r; - const char *sender; + const char *sender, *path; + int fd; + uint8_t codec; + struct hf_audio_card *card; pa_bluetooth_backend *backend = data; pa_assert(backend); @@ -516,7 +519,32 @@ static DBusMessage *hf_audio_agent_new_connection(DBusConnection *c, DBusMessage return r; } - r = dbus_message_new_error(m, "org.ofono.Error.NotImplemented", "Operation is not implemented"); + if (dbus_message_get_args(m, NULL, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_UNIX_FD, &fd, + DBUS_TYPE_BYTE, &codec, + DBUS_TYPE_INVALID) == FALSE) { + pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.InvalidArguments", "Invalid arguments in method call")); + return r; + } + + card = pa_hashmap_get(backend->cards, path); + + if (!card || codec != HFP_AUDIO_CODEC_CVSD || card->transport->state == PA_BLUETOOTH_TRANSPORT_STATE_PLAYING) { + pa_log_warn("New audio connection invalid arguments (path=%s fd=%d, codec=%d)", path, fd, codec); + pa_assert_se(r = dbus_message_new_error(m, "org.ofono.Error.InvalidArguments", "Invalid arguments in method call")); + return r; + } + + pa_log_debug("New audio connection on card %s (fd=%d, codec=%d)", path, fd, codec); + + card->fd = fd; + card->transport->codec = codec; + + pa_bluetooth_transport_set_state(card->transport, PA_BLUETOOTH_TRANSPORT_STATE_PLAYING); + + pa_assert_se(r = dbus_message_new_method_return(m)); + return r; } From tanuk at kemper.freedesktop.org Thu Sep 18 00:55:33 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Thu, 18 Sep 2014 00:55:33 -0700 (PDT) Subject: [pulseaudio-commits] 2 commits - src/modules Message-ID: <20140918075533.3B8AE76255@kemper.freedesktop.org> src/modules/bluetooth/module-bluetooth-policy.c | 7 ++----- src/modules/bluetooth/module-bluez5-device.c | 2 ++ 2 files changed, 4 insertions(+), 5 deletions(-) New commits: commit eb108b35398ab0c9502e57f541654f41ce24bb1f Author: Luiz Augusto von Dentz Date: Wed Sep 17 13:05:00 2014 +0300 bluetooth: Allow policy module to pick 'off' profile This allow 'off' profile to be choosen when no other profile is available which is considered better since it requires less resources than other profiles. diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c index 8bbda3d..860868f 100644 --- a/src/modules/bluetooth/module-bluetooth-policy.c +++ b/src/modules/bluetooth/module-bluetooth-policy.c @@ -143,12 +143,9 @@ static pa_card_profile *find_best_profile(pa_card *card) { void *state; pa_card_profile *profile; pa_card_profile *result = card->active_profile; - pa_card_profile *off; - - pa_assert_se(off = pa_hashmap_get(card->profiles, "off")); PA_HASHMAP_FOREACH(profile, card->profiles, state) { - if (profile->available == PA_AVAILABLE_NO || profile == off) + if (profile->available == PA_AVAILABLE_NO) continue; if (result == NULL || @@ -157,7 +154,7 @@ static pa_card_profile *find_best_profile(pa_card *card) { result = profile; } - return result ? result : off; + return result; } static pa_hook_result_t profile_available_hook_callback(pa_core *c, pa_card_profile *profile, void *userdata) { commit 7fac520d8960f2ba2bf1b79d675c03ac6584837f Author: Jo??o Paulo Rechi Vita Date: Wed Sep 17 13:04:59 2014 +0300 bluetooth: Switch transport state to idle in case of HUP In case the socket HUP the transport state should be set to idle which will indicate the profile is no longer available. diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c index fdf4078..48e498b 100644 --- a/src/modules/bluetooth/module-bluez5-device.c +++ b/src/modules/bluetooth/module-bluez5-device.c @@ -1980,6 +1980,7 @@ static pa_hook_result_t transport_state_changed_cb(pa_bluetooth_discovery *y, pa /* Run from main thread context */ static int device_process_msg(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct bluetooth_msg *m = BLUETOOTH_MSG(obj); + struct userdata *u = m->card->userdata; switch (code) { case BLUETOOTH_MESSAGE_IO_THREAD_FAILED: @@ -1990,6 +1991,7 @@ static int device_process_msg(pa_msgobject *obj, int code, void *data, int64_t o pa_assert_se(pa_card_set_profile(m->card, pa_hashmap_get(m->card->profiles, "off"), false) >= 0); break; case BLUETOOTH_MESSAGE_STREAM_FD_HUP: + pa_bluetooth_transport_set_state(u->transport, PA_BLUETOOTH_TRANSPORT_STATE_IDLE); break; } From diwic at kemper.freedesktop.org Thu Sep 18 02:52:21 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Thu, 18 Sep 2014 02:52:21 -0700 (PDT) Subject: [pulseaudio-commits] 3 commits - src/tests Message-ID: <20140918095221.CB30F76255@kemper.freedesktop.org> src/tests/alsa-time-test.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) New commits: commit f8aa823998f3b75691b67f032320cb4bf228f313 Author: David Henningsson Date: Wed Sep 10 14:52:01 2014 +0200 alsa-time-test: Make constants for channels and rate Hard-coding constants on several places is bad coding practice. Signed-off-by: David Henningsson diff --git a/src/tests/alsa-time-test.c b/src/tests/alsa-time-test.c index 20f16cc..b4eedab 100644 --- a/src/tests/alsa-time-test.c +++ b/src/tests/alsa-time-test.c @@ -10,6 +10,9 @@ #include +#define SAMPLE_RATE 44100 +#define CHANNELS 2 + static uint64_t timespec_us(const struct timespec *ts) { return ts->tv_sec * 1000000LLU + @@ -23,9 +26,9 @@ int main(int argc, char *argv[]) { snd_pcm_sw_params_t *swparams; snd_pcm_status_t *status; snd_pcm_t *pcm; - unsigned rate = 44100; + unsigned rate = SAMPLE_RATE; unsigned periods = 2; - snd_pcm_uframes_t boundary, buffer_size = 44100/10; /* 100s */ + snd_pcm_uframes_t boundary, buffer_size = SAMPLE_RATE/10; /* 100s */ int dir = 1; int fillrate; struct timespec start, last_timestamp = { 0, 0 }; @@ -58,7 +61,7 @@ int main(int argc, char *argv[]) { cap = argc > 2 ? atoi(argv[2]) : 0; fillrate = argc > 3 ? atoi(argv[3]) : 1; - samples = calloc(fillrate, 2*sizeof(uint16_t)); + samples = calloc(fillrate, CHANNELS*sizeof(uint16_t)); assert(samples); if (cap == 0) @@ -82,7 +85,7 @@ int main(int argc, char *argv[]) { r = snd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, NULL); assert(r == 0); - r = snd_pcm_hw_params_set_channels(pcm, hwparams, 2); + r = snd_pcm_hw_params_set_channels(pcm, hwparams, CHANNELS); assert(r == 0); r = snd_pcm_hw_params_set_periods_integer(pcm, hwparams); @@ -216,9 +219,9 @@ int main(int argc, char *argv[]) { timestamp_us = timespec_us(×tamp); if (cap == 0) - pos = (unsigned long long) ((sample_count - handled - delay) * 1000000LU / 44100); + pos = (unsigned long long) ((sample_count - handled - delay) * 1000000LU / SAMPLE_RATE); else - pos = (unsigned long long) ((sample_count - handled + delay) * 1000000LU / 44100); + pos = (unsigned long long) ((sample_count - handled + delay) * 1000000LU / SAMPLE_RATE); if (count++ % 50 == 0) printf("Elapsed\tCPU\tALSA\tPos\tSamples\tavail\tdelay\trevents\thandled\tstate\n"); commit c9e8c0703fd8900ac5513ddb66206cbcbaf1da5c Author: David Henningsson Date: Wed Sep 10 14:45:01 2014 +0200 alsa-time-test: Do not use Lennart's card by default Lennart probably had a card with a specific name. It is not a common name anymore. Signed-off-by: David Henningsson diff --git a/src/tests/alsa-time-test.c b/src/tests/alsa-time-test.c index 5d75756..20f16cc 100644 --- a/src/tests/alsa-time-test.c +++ b/src/tests/alsa-time-test.c @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) { start_us = timespec_us(&start); - dev = argc > 1 ? argv[1] : "front:AudioPCI"; + dev = argc > 1 ? argv[1] : "front:0"; cap = argc > 2 ? atoi(argv[2]) : 0; fillrate = argc > 3 ? atoi(argv[3]) : 1; commit d303489ef0b4908815bea1e0e7329b5f45e7340f Author: David Henningsson Date: Wed Sep 10 14:43:19 2014 +0200 alsa-time-test: Add fillrate parameter As a third parameter, add the number of samples to read/write in every iteration. This will help slow CPUs. Signed-off-by: David Henningsson diff --git a/src/tests/alsa-time-test.c b/src/tests/alsa-time-test.c index 3c82fdc..5d75756 100644 --- a/src/tests/alsa-time-test.c +++ b/src/tests/alsa-time-test.c @@ -27,12 +27,14 @@ int main(int argc, char *argv[]) { unsigned periods = 2; snd_pcm_uframes_t boundary, buffer_size = 44100/10; /* 100s */ int dir = 1; + int fillrate; struct timespec start, last_timestamp = { 0, 0 }; uint64_t start_us, last_us = 0; snd_pcm_sframes_t last_avail = 0, last_delay = 0; struct pollfd *pollfds; int n_pollfd; int64_t sample_count = 0; + uint16_t *samples; struct sched_param sp; r = -1; @@ -54,6 +56,10 @@ int main(int argc, char *argv[]) { dev = argc > 1 ? argv[1] : "front:AudioPCI"; cap = argc > 2 ? atoi(argv[2]) : 0; + fillrate = argc > 3 ? atoi(argv[3]) : 1; + + samples = calloc(fillrate, 2*sizeof(uint16_t)); + assert(samples); if (cap == 0) r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_PLAYBACK, 0); @@ -108,7 +114,7 @@ int main(int argc, char *argv[]) { r = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size); assert(r == 0); - r = snd_pcm_sw_params_set_start_threshold(pcm, swparams, buffer_size); + r = snd_pcm_sw_params_set_start_threshold(pcm, swparams, buffer_size - (buffer_size % fillrate)); assert(r == 0); r = snd_pcm_sw_params_get_boundary(swparams, &boundary); @@ -185,19 +191,17 @@ int main(int argc, char *argv[]) { assert(!revents || avail > 0); - if ((!cap && avail) || (cap && (unsigned)avail >= buffer_size)) { + if ((!cap && (avail >= fillrate)) || (cap && (unsigned)avail >= buffer_size)) { snd_pcm_sframes_t sframes; - static const uint16_t psamples[2] = { 0, 0 }; - uint16_t csamples[2]; if (cap == 0) - sframes = snd_pcm_writei(pcm, psamples, 1); + sframes = snd_pcm_writei(pcm, samples, fillrate); else - sframes = snd_pcm_readi(pcm, csamples, 1); - assert(sframes == 1); + sframes = snd_pcm_readi(pcm, samples, fillrate); + assert(sframes == fillrate); - handled = 1; - sample_count++; + handled = fillrate; + sample_count += fillrate; } if (!handled && From diwic at kemper.freedesktop.org Thu Sep 18 03:08:51 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Thu, 18 Sep 2014 03:08:51 -0700 (PDT) Subject: [pulseaudio-commits] src/pulsecore Message-ID: <20140918100851.53F9B76255@kemper.freedesktop.org> src/pulsecore/srbchannel.c | 24 +++++++++++++++++++++--- src/pulsecore/srbchannel.h | 3 --- 2 files changed, 21 insertions(+), 6 deletions(-) New commits: commit e521d38787ff99ed1a8427eb9b6c72e958406e58 Author: David Henningsson Date: Wed Sep 17 08:56:51 2014 +0200 srbchannel: Defer reading when setting up read callback Calling the callback while setting it up can make things complicated for clients, as the callback can do arbitrarily things. In this case, a protocol error caused the srbchannel to be owned by both the pstream and the native connection. Now the read callback is deferred, making sure the callback is called from a cleaner context where errors are handled appropriately. Reported-by: Tanu Kaskinen Signed-off-by: David Henningsson diff --git a/src/pulsecore/srbchannel.c b/src/pulsecore/srbchannel.c index 3f81e25..a0f916e 100644 --- a/src/pulsecore/srbchannel.c +++ b/src/pulsecore/srbchannel.c @@ -86,6 +86,7 @@ struct pa_srbchannel { pa_srbchannel_cb_t callback; pa_io_event *read_event; + pa_defer_event *defer_event; pa_mainloop_api *mainloop; }; @@ -211,6 +212,17 @@ static void semread_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_f srbchannel_rwloop(sr); } +static void defer_cb(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { + pa_srbchannel* sr = userdata; + +#ifdef DEBUG_SRBCHANNEL + pa_log("Calling rw loop from deferred event"); +#endif + + m->defer_enable(e, 0); + srbchannel_rwloop(sr); +} + pa_srbchannel* pa_srbchannel_new(pa_mainloop_api *m, pa_mempool *p) { int capacity; int readfd; @@ -331,9 +343,13 @@ void pa_srbchannel_set_callback(pa_srbchannel *sr, pa_srbchannel_cb_t callback, sr->callback = callback; sr->cb_userdata = userdata; - if (sr->callback) - /* Maybe deferred event? */ - srbchannel_rwloop(sr); + if (sr->callback) { + /* If there are events to be read already in the ringbuffer, we will not get any IO event for that, + because that's how pa_fdsem works. Therefore check the ringbuffer in a defer event instead. */ + if (!sr->defer_event) + sr->defer_event = sr->mainloop->defer_new(sr->mainloop, defer_cb, sr); + sr->mainloop->defer_enable(sr->defer_event, 1); + } } void pa_srbchannel_free(pa_srbchannel *sr) @@ -343,6 +359,8 @@ void pa_srbchannel_free(pa_srbchannel *sr) #endif pa_assert(sr); + if (sr->defer_event) + sr->mainloop->defer_free(sr->defer_event); if (sr->read_event) sr->mainloop->io_free(sr->read_event); diff --git a/src/pulsecore/srbchannel.h b/src/pulsecore/srbchannel.h index e41cc52..c96877e 100644 --- a/src/pulsecore/srbchannel.h +++ b/src/pulsecore/srbchannel.h @@ -52,9 +52,6 @@ size_t pa_srbchannel_read(pa_srbchannel *sr, void *data, size_t l); * * Return false to abort all processing (e g if the srbchannel has been freed during the callback). * Otherwise return true. - * - * Note that the callback will be called immediately, to be able to process stuff that - * might already be in the buffer. */ typedef bool (*pa_srbchannel_cb_t)(pa_srbchannel *sr, void *userdata); void pa_srbchannel_set_callback(pa_srbchannel *sr, pa_srbchannel_cb_t callback, void *userdata); From tanuk at kemper.freedesktop.org Sun Sep 21 03:04:41 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Sun, 21 Sep 2014 03:04:41 -0700 (PDT) Subject: [pulseaudio-commits] Makefile.am pulseaudio.supp Message-ID: <20140921100442.059977618E@kemper.freedesktop.org> Makefile.am | 1 + pulseaudio.supp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) New commits: commit 84ce398ea829e932269cf30af1aff5b1fe846316 Author: Tanu Kaskinen Date: Fri Sep 19 14:39:50 2014 +0300 Add a Valgrind suppression file diff --git a/Makefile.am b/Makefile.am index ddbf64a..07dc73f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,7 @@ EXTRA_DIST = \ bootstrap.sh \ git-version-gen \ LICENSE \ + pulseaudio.supp \ GPL \ LGPL \ doxygen/Makefile.am \ diff --git a/pulseaudio.supp b/pulseaudio.supp new file mode 100644 index 0000000..83f9ad1 --- /dev/null +++ b/pulseaudio.supp @@ -0,0 +1,50 @@ +# This file contains error suppression rules for Valgrind. These rules suppress +# errors in alsa-lib that are caused by Valgrind not handling the +# SNDRV_CTL_IOCTL_TLV_READ ioctl. More information about the Valgrind bug: +# http://thread.gmane.org/gmane.comp.debugging.valgrind/11888 +# +# To use this file, pass the command line option --suppressions= to +# Valgrind. +# +# If you find new false positives, and want to add new suppressions, the +# --gen-suppression=all option can be very useful. It prints automatically +# generated suppression rules that can be copy-pasted here. + +{ + alsa-lib/snd_tlv_get_dB_range + Memcheck:Cond + fun:snd_tlv_get_dB_range +} + +{ + alsa-lib/snd_tlv_convert_to_dB + Memcheck:Cond + fun:snd_tlv_convert_to_dB +} + +{ + alsa-lib/snd_tlv_convert_from_dB + Memcheck:Cond + fun:snd_tlv_convert_from_dB +} + +{ + alsa-lib/set_volume_ops + Memcheck:Cond + fun:set_volume_ops +} + +{ + alsa-lib/snd_ctl_hw_elem_write + Memcheck:Param + ioctl(generic) + fun:ioctl + fun:snd_ctl_hw_elem_write +} + +{ + alsa-lib/selem_read + Memcheck:Cond + fun:bcmp + fun:selem_read +} From diwic at kemper.freedesktop.org Mon Sep 22 04:29:49 2014 From: diwic at kemper.freedesktop.org (David Henningsson) Date: Mon, 22 Sep 2014 04:29:49 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140922112949.CA527761F1@kemper.freedesktop.org> src/modules/module-switch-on-connect.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) New commits: commit 1ff4f1b67a813d1772f04f4d394588a0a4483c28 Author: Hui Wang Date: Mon Sep 22 11:50:49 2014 +0800 module-switch-on-connect: add an argument for conditionally connecting On a machine without fixed connecting audio devices like internal microphone or internal speaker, and when there is no external audio devices plugging in, the default source/sink is alsa_input/alsa_output and there is no input devices/output devices listed in the gnome sound-setting. Under this situation, if we connect a bluetooth headset, the gnome sound-setting will list bluez input/output devices, but they are not active devices by default. This looks very weird that sound-setting lists only one input device and one output device, but they are not active. To change this situation, we add an argument, the policy is if a new source/sink is connected and current default source/sink's active_port is AVAILABLE_NO, we let the new added one switch to default one. BugLink: http://bugs.launchpad.net/bugs/1369476 Signed-off-by: Hui Wang diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c index d9275d3..90b86d1 100644 --- a/src/modules/module-switch-on-connect.c +++ b/src/modules/module-switch-on-connect.c @@ -38,11 +38,15 @@ #include "module-switch-on-connect-symdef.h" PA_MODULE_AUTHOR("Michael Terry"); -PA_MODULE_DESCRIPTION("When a sink/source is added, switch to it"); +PA_MODULE_DESCRIPTION("When a sink/source is added, switch to it or conditionally switch to it"); PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(true); +PA_MODULE_USAGE( + "only_from_unavailable= " +); static const char* const valid_modargs[] = { + "only_from_unavailable", NULL, }; @@ -50,6 +54,7 @@ struct userdata { pa_hook_slot *sink_put_slot, *source_put_slot; + bool only_from_unavailable; }; static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) { @@ -57,9 +62,11 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* uint32_t idx; pa_sink *def; const char *s; + struct userdata *u = userdata; pa_assert(c); pa_assert(sink); + pa_assert(userdata); /* Don't want to run during startup or shutdown */ if (c->state != PA_CORE_RUNNING) @@ -77,6 +84,10 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* if (def == sink) return PA_HOOK_OK; + if (u->only_from_unavailable) + if (!def->active_port || def->active_port->available != PA_AVAILABLE_NO) + return PA_HOOK_OK; + /* Actually do the switch to the new sink */ pa_namereg_set_default_sink(c, sink); @@ -106,9 +117,11 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, uint32_t idx; pa_source *def; const char *s; + struct userdata *u = userdata; pa_assert(c); pa_assert(source); + pa_assert(userdata); /* Don't want to run during startup or shutdown */ if (c->state != PA_CORE_RUNNING) @@ -130,6 +143,10 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, if (def == source) return PA_HOOK_OK; + if (u->only_from_unavailable) + if (!def->active_port || def->active_port->available != PA_AVAILABLE_NO) + return PA_HOOK_OK; + /* Actually do the switch to the new source */ pa_namereg_set_default_source(c, source); @@ -171,8 +188,21 @@ int pa__init(pa_module*m) { u->sink_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+30, (pa_hook_cb_t) sink_put_hook_callback, u); u->source_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE+20, (pa_hook_cb_t) source_put_hook_callback, u); + if (pa_modargs_get_value_boolean(ma, "only_from_unavailable", &u->only_from_unavailable) < 0) { + pa_log("Failed to get a boolean value for only_from_unavailable."); + goto fail; + } + pa_modargs_free(ma); return 0; + +fail: + if (ma) + pa_modargs_free(ma); + + pa__done(m); + + return -1; } void pa__done(pa_module*m) { From tanuk at kemper.freedesktop.org Sun Sep 28 03:37:02 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Sun, 28 Sep 2014 03:37:02 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140928103702.9161B7618D@kemper.freedesktop.org> src/modules/bluetooth/module-bluez4-device.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) New commits: commit 380a7fc2401ea26151e0383adff05314a263ac31 Author: Pali Roh??r Date: Thu Sep 25 15:27:58 2014 +0200 bluetooth: bluez4: Add profile name to sinks and sources Now a2dp and hsp sinks and sources will have different names which means that applications and other modules can use sink/source to distinguish selected profile. Module module-device-restore uses sink/source name and port name as identifier, so if different profiles have different names module-device-restore can store volume settings for each profile. So with this patch it is possible to configure different volume settings for a2dp and hsp profiles. This patch does not change port names so gnome applications will be happy. Note that similar patch is needed also for bluez5, but I'm not using bluez5 so I cannot write or test it. Signed-off-by: Pali Roh??r diff --git a/src/modules/bluetooth/module-bluez4-device.c b/src/modules/bluetooth/module-bluez4-device.c index c70e4a6..0be0c57 100644 --- a/src/modules/bluetooth/module-bluez4-device.c +++ b/src/modules/bluetooth/module-bluez4-device.c @@ -1371,7 +1371,7 @@ static void source_set_volume_cb(pa_source *s) { } /* Run from main thread */ -static char *get_name(const char *type, pa_modargs *ma, const char *device_id, bool *namereg_fail) { +static char *get_name(const char *type, pa_modargs *ma, const char *device_id, const char *profile, bool *namereg_fail) { char *t; const char *n; @@ -1396,7 +1396,10 @@ static char *get_name(const char *type, pa_modargs *ma, const char *device_id, b *namereg_fail = false; } - return pa_sprintf_malloc("bluez_%s.%s", type, n); + if (profile) + return pa_sprintf_malloc("bluez_%s.%s.%s", type, n, profile); + else + return pa_sprintf_malloc("bluez_%s.%s", type, n); } static int sco_over_pcm_state_update(struct userdata *u, bool changed) { @@ -1567,7 +1570,7 @@ static int add_sink(struct userdata *u) { if (u->profile == PA_BLUEZ4_PROFILE_HSP) pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone"); data.card = u->card; - data.name = get_name("sink", u->modargs, u->address, &b); + data.name = get_name("sink", u->modargs, u->address, pa_bluez4_profile_to_string(u->profile), &b); data.namereg_fail = b; if (pa_modargs_get_proplist(u->modargs, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) { @@ -1638,7 +1641,7 @@ static int add_source(struct userdata *u) { pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone"); data.card = u->card; - data.name = get_name("source", u->modargs, u->address, &b); + data.name = get_name("source", u->modargs, u->address, pa_bluez4_profile_to_string(u->profile), &b); data.namereg_fail = b; if (pa_modargs_get_proplist(u->modargs, "source_properties", data.proplist, PA_UPDATE_REPLACE) < 0) { @@ -2267,7 +2270,7 @@ static int add_card(struct userdata *u) { pa_proplist_sets(data.proplist, "bluez.path", device->path); pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", (unsigned) device->class); pa_proplist_sets(data.proplist, "bluez.alias", device->alias); - data.name = get_name("card", u->modargs, device->address, &b); + data.name = get_name("card", u->modargs, device->address, NULL, &b); data.namereg_fail = b; if (pa_modargs_get_proplist(u->modargs, "card_properties", data.proplist, PA_UPDATE_REPLACE) < 0) { From tanuk at kemper.freedesktop.org Sun Sep 28 03:56:29 2014 From: tanuk at kemper.freedesktop.org (Tanu Kaskinen) Date: Sun, 28 Sep 2014 03:56:29 -0700 (PDT) Subject: [pulseaudio-commits] src/modules Message-ID: <20140928105629.BD6B57618D@kemper.freedesktop.org> src/modules/module-switch-on-port-available.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) New commits: commit 0e44b127d0a1fb70803a9bd7b12f8dfcdb80cf58 Author: Hui Wang Date: Fri Sep 26 11:34:28 2014 +0800 module-switch-on-port-available: make the output more accurate It is possible that the chosen active_port doesn't equal new_data->active_port, using p->name is more accurate. Please refer to sink_new_hook_callback() Signed-off-by: Hui Wang diff --git a/src/modules/module-switch-on-port-available.c b/src/modules/module-switch-on-port-available.c index b0938d5..7397bcc 100644 --- a/src/modules/module-switch-on-port-available.c +++ b/src/modules/module-switch-on-port-available.c @@ -264,8 +264,7 @@ static pa_hook_result_t source_new_hook_callback(pa_core *c, pa_source_new_data pa_device_port *p = new_sink_source(new_data->ports, new_data->active_port); if (p) { - pa_log_debug("Switching initial port for source '%s' to '%s'", new_data->name, - new_data->active_port); + pa_log_debug("Switching initial port for source '%s' to '%s'", new_data->name, p->name); pa_source_new_data_set_port(new_data, p->name); } return PA_HOOK_OK;