summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/daemon/caps.c5
-rw-r--r--src/daemon/main.c2
-rw-r--r--src/map-file2
-rw-r--r--src/modules/alsa-util.c24
-rw-r--r--src/modules/alsa-util.h2
-rw-r--r--src/modules/module-alsa-sink.c8
-rw-r--r--src/modules/module-alsa-source.c9
-rw-r--r--src/modules/module-suspend-on-idle.c2
-rw-r--r--src/modules/module-tunnel.c9
-rw-r--r--src/pulse/introspect.c2
-rw-r--r--src/pulse/volume.c32
-rw-r--r--src/pulse/volume.h21
-rw-r--r--src/pulsecore/core-util.c15
-rw-r--r--src/pulsecore/core-util.h13
-rw-r--r--src/pulsecore/flist.h3
-rw-r--r--src/pulsecore/log.c3
-rw-r--r--src/pulsecore/memblock.c18
-rw-r--r--src/pulsecore/protocol-native.c4
-rw-r--r--src/pulsecore/sink-input.c3
-rw-r--r--src/pulsecore/thread.h3
-rw-r--r--src/tests/voltest.c4
21 files changed, 126 insertions, 58 deletions
diff --git a/src/daemon/caps.c b/src/daemon/caps.c
index f7b6658b..707b5323 100644
--- a/src/daemon/caps.c
+++ b/src/daemon/caps.c
@@ -34,6 +34,7 @@
#include <pulsecore/macro.h>
#include <pulsecore/core-error.h>
#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
@@ -112,9 +113,9 @@ void pa_drop_caps(void) {
#ifndef __OPTIMIZE__
/* Valgrind doesn't not know set_caps, so we bypass it here -- but
- * only in development builts.*/
+ * only in development builds.*/
- if (getenv("VALGRIND") && !pa_have_caps())
+ if (pa_in_valgrind() && !pa_have_caps())
return;
#endif
diff --git a/src/daemon/main.c b/src/daemon/main.c
index 53f5d193..fad635f0 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -793,6 +793,8 @@ int main(int argc, char *argv[]) {
pa_log_debug(_("Compiled with Valgrind support: no"));
#endif
+ pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
+
#ifdef __OPTIMIZE__
pa_log_debug(_("Optimized build: yes"));
#else
diff --git a/src/map-file b/src/map-file
index 50cb780a..7211914a 100644
--- a/src/map-file
+++ b/src/map-file
@@ -105,7 +105,7 @@ pa_cvolume_max;
pa_cvolume_remap;
pa_cvolume_set;
pa_cvolume_snprint;
-pa_cvolume_snprint_dB;
+pa_sw_cvolume_snprint_dB;
pa_cvolume_valid;
pa_ext_stream_restore_delete;
pa_ext_stream_restore_read;
diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c
index c3eb72f5..ffe7795e 100644
--- a/src/modules/alsa-util.c
+++ b/src/modules/alsa-util.c
@@ -1109,27 +1109,3 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
return item;
}
-
-pa_cvolume *pa_alsa_volume_divide(pa_cvolume *r, const pa_cvolume *t) {
- unsigned i;
-
- pa_assert(r);
- pa_assert(t);
- pa_assert(r->channels == t->channels);
-
- for (i = 0; i < r->channels; i++) {
- double a, b, c;
-
- a = pa_sw_volume_to_linear(r->values[i]); /* the hw volume */
- b = pa_sw_volume_to_linear(t->values[i]); /* the intended volume */
-
- if (a <= 0)
- c = 0;
- else
- c = b / a;
-
- r->values[i] = pa_sw_volume_from_linear(c);
- }
-
- return r;
-}
diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h
index 7991a107..b66adc13 100644
--- a/src/modules/alsa-util.h
+++ b/src/modules/alsa-util.h
@@ -92,6 +92,4 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents);
pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll);
-pa_cvolume *pa_alsa_volume_divide(pa_cvolume *r, const pa_cvolume *t);
-
#endif
diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c
index 8f907745..0e15da3c 100644
--- a/src/modules/module-alsa-sink.c
+++ b/src/modules/module-alsa-sink.c
@@ -539,8 +539,8 @@ static int suspend(struct userdata *u) {
pa_smoother_pause(u->smoother, pa_rtclock_usec());
- /* Let's suspend */
- snd_pcm_drain(u->pcm_handle);
+ /* Let's suspend -- we don't call snd_pcm_drain() here since that might
+ * take awfully long with our long buffer sizes today. */
snd_pcm_close(u->pcm_handle);
u->pcm_handle = NULL;
@@ -569,7 +569,7 @@ static int update_sw_params(struct userdata *u) {
if ((latency = pa_sink_get_requested_latency_within_thread(u->sink)) != (pa_usec_t) -1) {
size_t b;
- pa_log_debug("latency set to %0.2f", (double) latency / PA_USEC_PER_MSEC);
+ pa_log_debug("latency set to %0.2fms", (double) latency / PA_USEC_PER_MSEC);
b = pa_usec_to_bytes(latency, &u->sink->sample_spec);
@@ -936,7 +936,7 @@ static int sink_set_volume_cb(pa_sink *s) {
/* Match exactly what the user requested by software */
- pa_alsa_volume_divide(&r, &s->volume);
+ pa_sw_cvolume_divide(&r, &s->volume, &r);
pa_sink_set_soft_volume(s, &r);
pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume));
diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c
index d5e21704..2827ecfe 100644
--- a/src/modules/module-alsa-source.c
+++ b/src/modules/module-alsa-source.c
@@ -211,9 +211,10 @@ static int try_recover(struct userdata *u, const char *call, int err) {
static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) {
size_t left_to_record;
+ size_t rec_space = u->hwbuf_size - (size_t) u->hwbuf_unused_frames*u->frame_size;
- if ((size_t) n*u->frame_size < u->hwbuf_size)
- left_to_record = u->hwbuf_size - ((size_t) n*u->frame_size);
+ if ((size_t) n*u->frame_size < rec_space)
+ left_to_record = rec_space - ((size_t) n*u->frame_size);
else
left_to_record = 0;
@@ -514,7 +515,7 @@ static int update_sw_params(struct userdata *u) {
if ((latency = pa_source_get_requested_latency_within_thread(u->source)) != (pa_usec_t) -1) {
size_t b;
- pa_log_debug("latency set to %0.2f", (double) latency / PA_USEC_PER_MSEC);
+ pa_log_debug("latency set to %0.2fms", (double) latency / PA_USEC_PER_MSEC);
b = pa_usec_to_bytes(latency, &u->source->sample_spec);
@@ -881,7 +882,7 @@ static int source_set_volume_cb(pa_source *s) {
/* Match exactly what the user requested by software */
- pa_alsa_volume_divide(&r, &s->volume);
+ pa_sw_cvolume_divide(&r, &s->volume, &r);
pa_source_set_soft_volume(s, &r);
pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume));
diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c
index bc7c023c..6cc28ec5 100644
--- a/src/modules/module-suspend-on-idle.c
+++ b/src/modules/module-suspend-on-idle.c
@@ -337,7 +337,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
int pa__init(pa_module*m) {
pa_modargs *ma = NULL;
struct userdata *u;
- uint32_t timeout = 1;
+ uint32_t timeout = 5;
uint32_t idx;
pa_sink *sink;
pa_source *source;
diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index de3c7274..4bbb11a5 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -159,7 +159,7 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = command_suspended,
[PA_COMMAND_RECORD_STREAM_SUSPENDED] = command_suspended,
[PA_COMMAND_PLAYBACK_STREAM_MOVED] = command_moved,
- [PA_COMMAND_RECORD_STREAM_MOVED] = command_moved,
+ [PA_COMMAND_RECORD_STREAM_MOVED] = command_moved
};
struct userdata {
@@ -1494,6 +1494,13 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
#endif
}
+ if (u->version >= 14) {
+#ifdef TUNNEL_SINK
+ pa_tagstruct_put_boolean(reply, FALSE); /* volume_set */
+#endif
+ pa_tagstruct_put_boolean(reply, TRUE); /* early rquests */
+ }
+
pa_pstream_send_tagstruct(u->pstream, reply);
pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, create_stream_callback, u, NULL);
diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c
index 4e362fd8..38091581 100644
--- a/src/pulse/introspect.c
+++ b/src/pulse/introspect.c
@@ -24,6 +24,8 @@
#include <config.h>
#endif
+#include <string.h>
+
#include <pulse/context.h>
#include <pulse/gccmacro.h>
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 0ef02d98..99a85f44 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -104,6 +104,15 @@ pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a) * pa_sw_volume_to_linear(b));
}
+pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) {
+ double v = pa_sw_volume_to_linear(b);
+
+ if (v <= 0)
+ return 0;
+
+ return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a) / v);
+}
+
#define USER_DECIBEL_RANGE 60
pa_volume_t pa_sw_volume_from_dB(double dB) {
@@ -170,7 +179,7 @@ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c) {
return s;
}
-char *pa_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c) {
+char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c) {
unsigned channel;
pa_bool_t first = TRUE;
char *e;
@@ -220,12 +229,23 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const
pa_assert(a);
pa_assert(b);
- for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++) {
+ for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++)
+ dest->values[i] = pa_sw_volume_multiply(a->values[i], b->values[i]);
- dest->values[i] = pa_sw_volume_multiply(
- i < a->channels ? a->values[i] : PA_VOLUME_NORM,
- i < b->channels ? b->values[i] : PA_VOLUME_NORM);
- }
+ dest->channels = (uint8_t) i;
+
+ return dest;
+}
+
+pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b) {
+ unsigned i;
+
+ pa_assert(dest);
+ pa_assert(a);
+ pa_assert(b);
+
+ for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++)
+ dest->values[i] = pa_sw_volume_divide(a->values[i], b->values[i]);
dest->channels = (uint8_t) i;
diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index 9f6e5f05..75051af5 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -145,10 +145,10 @@ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c);
* any release without warning and without being considered API or ABI
* breakage. You should not use this definition anywhere where it
* might become part of an ABI. \since 0.9.13 */
-#define PA_CVOLUME_SNPRINT_DB_MAX 448
+#define PA_SW_CVOLUME_SNPRINT_DB_MAX 448
/** Pretty print a volume structure but show dB values. \since 0.9.13 */
-char *pa_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c);
+char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c);
/** Return the average volume of all channels */
pa_volume_t pa_cvolume_avg(const pa_cvolume *a) PA_GCC_PURE;
@@ -168,12 +168,25 @@ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) PA_GCC_PURE
/** Return 1 if the specified volume has all channels on normal level */
#define pa_cvolume_is_norm(a) pa_cvolume_channels_equal_to((a), PA_VOLUME_NORM)
-/** Multiply two volumes specifications, return the result. This uses PA_VOLUME_NORM as neutral element of multiplication. This is only valid for software volumes! */
+/** Multiply two volume specifications, return the result. This uses
+ * PA_VOLUME_NORM as neutral element of multiplication. This is only
+ * valid for software volumes! */
pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) PA_GCC_CONST;
-/** Multiply to per-channel volumes and return the result in *dest. This is only valid for software volumes! */
+/** Multiply two per-channel volumes and return the result in
+ * *dest. This is only valid for software volumes! */
pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
+/** Divide two volume specifications, return the result. This uses
+ * PA_VOLUME_NORM as neutral element of division. This is only valid
+ * for software volumes! If a division by zero is tried the result
+ * will be 0. \since 0.9.13 */
+pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) PA_GCC_CONST;
+
+/** Multiply to per-channel volumes and return the result in
+ * *dest. This is only valid for software volumes! \since 0.9.13 */
+pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
+
/** Convert a decibel value to a volume. This is only valid for software volumes! */
pa_volume_t pa_sw_volume_from_dB(double f) PA_GCC_CONST;
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 0bc5cb40..dde34d7b 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -2472,3 +2472,18 @@ char *pa_uname_string(void) {
return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
}
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+pa_bool_t pa_in_valgrind(void) {
+ static int b = 0;
+
+ /* To make heisenbugs a bit simpler to find we check for $VALGRIND
+ * here instead of really checking whether we run in valgrind or
+ * not. */
+
+ if (b < 1)
+ b = getenv("VALGRIND") ? 2 : 1;
+
+ return b > 1;
+}
+#endif
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index df8ce3f8..fd6ee896 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -35,6 +35,10 @@
#include <pulse/gccmacro.h>
#include <pulsecore/macro.h>
+#ifndef PACKAGE
+#error "Please include config.h before including this file!"
+#endif
+
struct timeval;
/* These resource limits are pretty new on Linux, let's define them
@@ -193,4 +197,13 @@ pa_bool_t pa_in_system_mode(void);
char *pa_machine_id(void);
char *pa_uname_string(void);
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+pa_bool_t pa_in_valgrind(void);
+#else
+static inline pa_bool_t pa_in_valgrind(void) {
+ return FALSE;
+}
+#endif
+
#endif
diff --git a/src/pulsecore/flist.h b/src/pulsecore/flist.h
index 2d8422f9..512dd357 100644
--- a/src/pulsecore/flist.h
+++ b/src/pulsecore/flist.h
@@ -26,6 +26,7 @@
#include <pulse/gccmacro.h>
#include <pulsecore/once.h>
+#include <pulsecore/core-util.h>
/* A multiple-reader multipler-write lock-free free list implementation */
@@ -56,6 +57,8 @@ void* pa_flist_pop(pa_flist*l);
} \
static void name##_flist_destructor(void) PA_GCC_DESTRUCTOR; \
static void name##_flist_destructor(void) { \
+ if (!pa_in_valgrind()) \
+ return; \
if (name##_flist.flist) \
pa_flist_free(name##_flist.flist, (free_cb)); \
} \
diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c
index d7318081..b1de6966 100644
--- a/src/pulsecore/log.c
+++ b/src/pulsecore/log.c
@@ -85,6 +85,9 @@ void pa_log_set_ident(const char *p) {
/* To make valgrind shut up. */
static void ident_destructor(void) PA_GCC_DESTRUCTOR;
static void ident_destructor(void) {
+ if (!pa_in_valgrind())
+ return;
+
pa_xfree(log_ident);
pa_xfree(log_ident_local);
}
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index 400a4e1e..d9e1bf1c 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -261,9 +261,11 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {
}
}
-#ifdef HAVE_VALGRIND_MEMCHECK_H
- VALGRIND_MALLOCLIKE_BLOCK(slot, p->block_size, 0, 0);
-#endif
+/* #ifdef HAVE_VALGRIND_MEMCHECK_H */
+/* if (PA_UNLIKELY(pa_in_valgrind())) { */
+/* VALGRIND_MALLOCLIKE_BLOCK(slot, p->block_size, 0, 0); */
+/* } */
+/* #endif */
return slot;
}
@@ -534,16 +536,18 @@ static void memblock_free(pa_memblock *b) {
call_free = b->type == PA_MEMBLOCK_POOL_EXTERNAL;
+/* #ifdef HAVE_VALGRIND_MEMCHECK_H */
+/* if (PA_UNLIKELY(pa_in_valgrind())) { */
+/* VALGRIND_FREELIKE_BLOCK(slot, b->pool->block_size); */
+/* } */
+/* #endif */
+
/* The free list dimensions should easily allow all slots
* to fit in, hence try harder if pushing this slot into
* the free list fails */
while (pa_flist_push(b->pool->free_slots, slot) < 0)
;
-#ifdef HAVE_VALGRIND_MEMCHECK_H
- VALGRIND_FREELIKE_BLOCK(slot, b->pool->block_size);
-#endif
-
if (call_free)
if (pa_flist_push(PA_STATIC_FLIST_GET(unused_memblocks), b) < 0)
pa_xfree(b);
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 5c6dbf44..778aab57 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -3168,6 +3168,10 @@ static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uin
CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY);
pa_sink_input_cork(s->sink_input, b);
+
+ if (b)
+ s->is_underrun = TRUE;
+
pa_pstream_send_simple_ack(c->pstream, tag);
}
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 326a7e2c..4f70347f 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -1030,6 +1030,9 @@ void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state
} else if (uncorking) {
+ i->thread_info.underrun_for = (uint64_t) -1;
+ i->thread_info.playing_for = 0;
+
pa_log_debug("Requesting rewind due to uncorking");
/* OK, we're being uncorked. Make sure we're not rewound when
diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h
index 87e850d6..eabe9ba4 100644
--- a/src/pulsecore/thread.h
+++ b/src/pulsecore/thread.h
@@ -25,6 +25,7 @@
#include <pulse/def.h>
#include <pulsecore/once.h>
+#include <pulsecore/core-util.h>
#ifndef PACKAGE
#error "Please include config.h before including this file!"
@@ -69,6 +70,8 @@ void *pa_tls_set(pa_tls *t, void *userdata);
static void name##_tls_destructor(void) PA_GCC_DESTRUCTOR; \
static void name##_tls_destructor(void) { \
static void (*_free_cb)(void*) = free_cb; \
+ if (!pa_in_valgrind()) \
+ return; \
if (!name##_tls.tls) \
return; \
if (_free_cb) { \
diff --git a/src/tests/voltest.c b/src/tests/voltest.c
index bbf3ea1c..5bfc97e0 100644
--- a/src/tests/voltest.c
+++ b/src/tests/voltest.c
@@ -17,14 +17,14 @@ int main(int argc, char *argv[]) {
}
for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) {
- char s[PA_CVOLUME_SNPRINT_MAX], t[PA_CVOLUME_SNPRINT_DB_MAX];
+ char s[PA_CVOLUME_SNPRINT_MAX], t[PA_SW_CVOLUME_SNPRINT_DB_MAX];
pa_cvolume_set(&cv, 2, v);
printf("Volume: %3i [%s] [%s]\n",
v,
pa_cvolume_snprint(s, sizeof(s), &cv),
- pa_cvolume_snprint_dB(t, sizeof(t), &cv));
+ pa_sw_cvolume_snprint_dB(t, sizeof(t), &cv));
}