mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
- Change meaning of special values of latency request: 0 -> "minimal latency, please"; (pa_usec_t)-1 -> "don't care"
- Remove "source" word from monitor source description - Increase default tsched watermark to 20ms again - For the first iteration after snd_pcm_start() halve the sleep time as workaround for USB devices with quick starts git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/glitch-free@2291 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
88227c41c1
commit
e16a1987a3
6 changed files with 33 additions and 26 deletions
|
|
@ -93,7 +93,7 @@ static const char* const valid_modargs[] = {
|
||||||
|
|
||||||
#define DEFAULT_DEVICE "default"
|
#define DEFAULT_DEVICE "default"
|
||||||
#define DEFAULT_TSCHED_BUFFER_USEC (10*PA_USEC_PER_SEC) /* 10s */
|
#define DEFAULT_TSCHED_BUFFER_USEC (10*PA_USEC_PER_SEC) /* 10s */
|
||||||
#define DEFAULT_TSCHED_WATERMARK_USEC (10*PA_USEC_PER_MSEC) /* 20ms */
|
#define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC) /* 20ms */
|
||||||
|
|
||||||
struct userdata {
|
struct userdata {
|
||||||
pa_core *core;
|
pa_core *core;
|
||||||
|
|
@ -476,7 +476,7 @@ static pa_usec_t hw_sleep_time(struct userdata *u) {
|
||||||
|
|
||||||
usec = pa_sink_get_requested_latency_within_thread(u->sink);
|
usec = pa_sink_get_requested_latency_within_thread(u->sink);
|
||||||
|
|
||||||
if (usec <= 0)
|
if (usec == (pa_usec_t) -1)
|
||||||
usec = pa_bytes_to_usec(u->hwbuf_size, &u->sink->sample_spec);
|
usec = pa_bytes_to_usec(u->hwbuf_size, &u->sink->sample_spec);
|
||||||
|
|
||||||
/* pa_log_debug("hw buffer time: %u ms", (unsigned) (usec / PA_USEC_PER_MSEC)); */
|
/* pa_log_debug("hw buffer time: %u ms", (unsigned) (usec / PA_USEC_PER_MSEC)); */
|
||||||
|
|
@ -488,6 +488,11 @@ static pa_usec_t hw_sleep_time(struct userdata *u) {
|
||||||
else
|
else
|
||||||
usec /= 2;
|
usec /= 2;
|
||||||
|
|
||||||
|
if (u->first) {
|
||||||
|
pa_log_debug("Decreasing wakeup time for the first iteration by half.");
|
||||||
|
usec /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* pa_log_debug("after watermark: %u ms", (unsigned) (usec / PA_USEC_PER_MSEC)); */
|
/* pa_log_debug("after watermark: %u ms", (unsigned) (usec / PA_USEC_PER_MSEC)); */
|
||||||
|
|
||||||
return usec;
|
return usec;
|
||||||
|
|
@ -503,10 +508,10 @@ static int update_sw_params(struct userdata *u) {
|
||||||
u->hwbuf_unused_frames = 0;
|
u->hwbuf_unused_frames = 0;
|
||||||
|
|
||||||
if (u->use_tsched)
|
if (u->use_tsched)
|
||||||
if ((latency = pa_sink_get_requested_latency_within_thread(u->sink)) > 0) {
|
if ((latency = pa_sink_get_requested_latency_within_thread(u->sink)) != (pa_usec_t) -1) {
|
||||||
size_t b;
|
size_t b;
|
||||||
|
|
||||||
pa_log("latency set to %llu", (unsigned long long) latency);
|
pa_log_debug("latency set to %llu", (unsigned long long) latency);
|
||||||
|
|
||||||
b = pa_usec_to_bytes(latency, &u->sink->sample_spec);
|
b = pa_usec_to_bytes(latency, &u->sink->sample_spec);
|
||||||
|
|
||||||
|
|
@ -520,7 +525,7 @@ static int update_sw_params(struct userdata *u) {
|
||||||
((u->hwbuf_size - b) / u->frame_size) : 0;
|
((u->hwbuf_size - b) / u->frame_size) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_log("hwbuf_unused_frames=%lu", (unsigned long) u->hwbuf_unused_frames);
|
pa_log_debug("hwbuf_unused_frames=%lu", (unsigned long) u->hwbuf_unused_frames);
|
||||||
|
|
||||||
/* We need at last one frame in the used part of the buffer */
|
/* We need at last one frame in the used part of the buffer */
|
||||||
u->avail_min_frames = u->hwbuf_unused_frames + 1;
|
u->avail_min_frames = u->hwbuf_unused_frames + 1;
|
||||||
|
|
@ -533,7 +538,7 @@ static int update_sw_params(struct userdata *u) {
|
||||||
u->avail_min_frames += (pa_usec_to_bytes(usec, &u->sink->sample_spec) / u->frame_size);
|
u->avail_min_frames += (pa_usec_to_bytes(usec, &u->sink->sample_spec) / u->frame_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_log("setting avail_min=%lu", (unsigned long) u->avail_min_frames);
|
pa_log_debug("setting avail_min=%lu", (unsigned long) u->avail_min_frames);
|
||||||
|
|
||||||
if ((err = pa_alsa_set_sw_params(u->pcm_handle, u->avail_min_frames)) < 0) {
|
if ((err = pa_alsa_set_sw_params(u->pcm_handle, u->avail_min_frames)) < 0) {
|
||||||
pa_log("Failed to set software parameters: %s", snd_strerror(err));
|
pa_log("Failed to set software parameters: %s", snd_strerror(err));
|
||||||
|
|
@ -918,7 +923,6 @@ static void thread_func(void *userdata) {
|
||||||
if (u->first) {
|
if (u->first) {
|
||||||
pa_log_info("Starting playback.");
|
pa_log_info("Starting playback.");
|
||||||
snd_pcm_start(u->pcm_handle);
|
snd_pcm_start(u->pcm_handle);
|
||||||
u->first = FALSE;
|
|
||||||
|
|
||||||
pa_smoother_resume(u->smoother, pa_rtclock_usec());
|
pa_smoother_resume(u->smoother, pa_rtclock_usec());
|
||||||
}
|
}
|
||||||
|
|
@ -946,6 +950,8 @@ static void thread_func(void *userdata) {
|
||||||
pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(usec, cusec));
|
pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(usec, cusec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u->first = FALSE;
|
||||||
|
|
||||||
} else if (u->use_tsched)
|
} else if (u->use_tsched)
|
||||||
|
|
||||||
/* OK, we're in an invalid state, let's disable our timers */
|
/* OK, we're in an invalid state, let's disable our timers */
|
||||||
|
|
@ -1018,7 +1024,7 @@ static void thread_func(void *userdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revents)
|
if (revents)
|
||||||
pa_log_info("Wakeup from ALSA! (%i)", revents);
|
pa_log_debug("Wakeup from ALSA! (%i)", revents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -415,7 +415,7 @@ static pa_usec_t hw_sleep_time(struct userdata *u) {
|
||||||
|
|
||||||
usec = pa_source_get_requested_latency_within_thread(u->source);
|
usec = pa_source_get_requested_latency_within_thread(u->source);
|
||||||
|
|
||||||
if (usec <= 0)
|
if (usec == (pa_usec_t) -1)
|
||||||
usec = pa_bytes_to_usec(u->hwbuf_size, &u->source->sample_spec);
|
usec = pa_bytes_to_usec(u->hwbuf_size, &u->source->sample_spec);
|
||||||
|
|
||||||
pa_log_debug("hw buffer time: %u ms", (unsigned) (usec / PA_USEC_PER_MSEC));
|
pa_log_debug("hw buffer time: %u ms", (unsigned) (usec / PA_USEC_PER_MSEC));
|
||||||
|
|
@ -850,6 +850,9 @@ static void thread_func(void *userdata) {
|
||||||
|
|
||||||
snd_pcm_start(u->pcm_handle);
|
snd_pcm_start(u->pcm_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (revents)
|
||||||
|
pa_log_debug("Wakeup from ALSA! (%i)", revents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ pa_sink_input* pa_sink_input_new(
|
||||||
i->thread_info.resampler = resampler;
|
i->thread_info.resampler = resampler;
|
||||||
i->thread_info.volume = i->volume;
|
i->thread_info.volume = i->volume;
|
||||||
i->thread_info.muted = i->muted;
|
i->thread_info.muted = i->muted;
|
||||||
i->thread_info.requested_sink_latency = 0;
|
i->thread_info.requested_sink_latency = (pa_usec_t) -1;
|
||||||
i->thread_info.rewrite_nbytes = 0;
|
i->thread_info.rewrite_nbytes = 0;
|
||||||
i->thread_info.since_underrun = 0;
|
i->thread_info.since_underrun = 0;
|
||||||
i->thread_info.ignore_rewind = FALSE;
|
i->thread_info.ignore_rewind = FALSE;
|
||||||
|
|
@ -534,8 +534,6 @@ int pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa
|
||||||
if (do_volume_adj_here && !volume_is_norm) {
|
if (do_volume_adj_here && !volume_is_norm) {
|
||||||
pa_memchunk_make_writable(&wchunk, 0);
|
pa_memchunk_make_writable(&wchunk, 0);
|
||||||
|
|
||||||
pa_log_debug("adjusting volume!");
|
|
||||||
|
|
||||||
if (i->thread_info.muted)
|
if (i->thread_info.muted)
|
||||||
pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
|
pa_silence_memchunk(&wchunk, &i->thread_info.sample_spec);
|
||||||
else
|
else
|
||||||
|
|
@ -682,7 +680,7 @@ void pa_sink_input_update_max_rewind(pa_sink_input *i, size_t nbytes /* in the
|
||||||
pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
|
pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec) {
|
||||||
pa_sink_input_assert_ref(i);
|
pa_sink_input_assert_ref(i);
|
||||||
|
|
||||||
if (usec > 0) {
|
if (usec != (pa_usec_t) -1) {
|
||||||
|
|
||||||
if (i->sink->max_latency > 0 && usec > i->sink->max_latency)
|
if (i->sink->max_latency > 0 && usec > i->sink->max_latency)
|
||||||
usec = i->sink->max_latency;
|
usec = i->sink->max_latency;
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ pa_sink* pa_sink_new(
|
||||||
s->thread_info.state = s->state;
|
s->thread_info.state = s->state;
|
||||||
s->thread_info.rewind_nbytes = 0;
|
s->thread_info.rewind_nbytes = 0;
|
||||||
s->thread_info.max_rewind = 0;
|
s->thread_info.max_rewind = 0;
|
||||||
s->thread_info.requested_latency_valid = TRUE;
|
s->thread_info.requested_latency_valid = FALSE;
|
||||||
s->thread_info.requested_latency = 0;
|
s->thread_info.requested_latency = 0;
|
||||||
|
|
||||||
pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
|
pa_assert_se(pa_idxset_put(core->sinks, s, &s->index) >= 0);
|
||||||
|
|
@ -236,7 +236,7 @@ pa_sink* pa_sink_new(
|
||||||
source_data.module = data->module;
|
source_data.module = data->module;
|
||||||
|
|
||||||
dn = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
|
dn = pa_proplist_gets(s->proplist, PA_PROP_DEVICE_DESCRIPTION);
|
||||||
pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Monitor Source of %s", dn ? dn : s->name);
|
pa_proplist_setf(source_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Monitor of %s", dn ? dn : s->name);
|
||||||
pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "monitor");
|
pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_CLASS, "monitor");
|
||||||
|
|
||||||
s->monitor_source = pa_source_new(core, &source_data, 0);
|
s->monitor_source = pa_source_new(core, &source_data, 0);
|
||||||
|
|
@ -1257,7 +1257,7 @@ void pa_sink_request_rewind(pa_sink*s, size_t nbytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
|
pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
|
||||||
pa_usec_t result = 0;
|
pa_usec_t result = (pa_usec_t) -1;
|
||||||
pa_sink_input *i;
|
pa_sink_input *i;
|
||||||
void *state = NULL;
|
void *state = NULL;
|
||||||
|
|
||||||
|
|
@ -1268,11 +1268,11 @@ pa_usec_t pa_sink_get_requested_latency_within_thread(pa_sink *s) {
|
||||||
|
|
||||||
while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
|
while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
|
||||||
|
|
||||||
if (i->thread_info.requested_sink_latency > 0 &&
|
if (i->thread_info.requested_sink_latency != (pa_usec_t) -1 &&
|
||||||
(!result || result > i->thread_info.requested_sink_latency))
|
(result == (pa_usec_t) -1 || result > i->thread_info.requested_sink_latency))
|
||||||
result = i->thread_info.requested_sink_latency;
|
result = i->thread_info.requested_sink_latency;
|
||||||
|
|
||||||
if (result > 0) {
|
if (result != (pa_usec_t) -1) {
|
||||||
if (s->max_latency > 0 && result > s->max_latency)
|
if (s->max_latency > 0 && result > s->max_latency)
|
||||||
result = s->max_latency;
|
result = s->max_latency;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ pa_source_output* pa_source_output_new(
|
||||||
o->thread_info.attached = FALSE;
|
o->thread_info.attached = FALSE;
|
||||||
o->thread_info.sample_spec = o->sample_spec;
|
o->thread_info.sample_spec = o->sample_spec;
|
||||||
o->thread_info.resampler = resampler;
|
o->thread_info.resampler = resampler;
|
||||||
o->thread_info.requested_source_latency = 0;
|
o->thread_info.requested_source_latency = (pa_usec_t) -1;
|
||||||
|
|
||||||
o->thread_info.delay_memblockq = pa_memblockq_new(
|
o->thread_info.delay_memblockq = pa_memblockq_new(
|
||||||
0,
|
0,
|
||||||
|
|
@ -449,7 +449,7 @@ void pa_source_output_update_max_rewind(pa_source_output *o, size_t nbytes /* i
|
||||||
pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t usec) {
|
pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t usec) {
|
||||||
pa_source_output_assert_ref(o);
|
pa_source_output_assert_ref(o);
|
||||||
|
|
||||||
if (usec > 0) {
|
if (usec != (pa_usec_t) -1) {
|
||||||
|
|
||||||
if (o->source->max_latency > 0 && usec > o->source->max_latency)
|
if (o->source->max_latency > 0 && usec > o->source->max_latency)
|
||||||
usec = o->source->max_latency;
|
usec = o->source->max_latency;
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ pa_source* pa_source_new(
|
||||||
s->thread_info.soft_muted = s->muted;
|
s->thread_info.soft_muted = s->muted;
|
||||||
s->thread_info.state = s->state;
|
s->thread_info.state = s->state;
|
||||||
s->thread_info.max_rewind = 0;
|
s->thread_info.max_rewind = 0;
|
||||||
s->thread_info.requested_latency_valid = TRUE;
|
s->thread_info.requested_latency_valid = FALSE;
|
||||||
s->thread_info.requested_latency = 0;
|
s->thread_info.requested_latency = 0;
|
||||||
|
|
||||||
pa_assert_se(pa_idxset_put(core->sources, s, &s->index) >= 0);
|
pa_assert_se(pa_idxset_put(core->sources, s, &s->index) >= 0);
|
||||||
|
|
@ -713,7 +713,7 @@ void pa_source_attach_within_thread(pa_source *s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {
|
pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {
|
||||||
pa_usec_t result = 0;
|
pa_usec_t result = (pa_usec_t) -1;
|
||||||
pa_source_output *o;
|
pa_source_output *o;
|
||||||
void *state = NULL;
|
void *state = NULL;
|
||||||
|
|
||||||
|
|
@ -724,11 +724,11 @@ pa_usec_t pa_source_get_requested_latency_within_thread(pa_source *s) {
|
||||||
|
|
||||||
while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
|
while ((o = pa_hashmap_iterate(s->thread_info.outputs, &state, NULL)))
|
||||||
|
|
||||||
if (o->thread_info.requested_source_latency > 0 &&
|
if (o->thread_info.requested_source_latency != (pa_usec_t) -1 &&
|
||||||
(!result || result > o->thread_info.requested_source_latency))
|
(result == (pa_usec_t) -1 || result > o->thread_info.requested_source_latency))
|
||||||
result = o->thread_info.requested_source_latency;
|
result = o->thread_info.requested_source_latency;
|
||||||
|
|
||||||
if (result > 0) {
|
if (result != (pa_usec_t) -1) {
|
||||||
if (s->max_latency > 0 && result > s->max_latency)
|
if (s->max_latency > 0 && result > s->max_latency)
|
||||||
result = s->max_latency;
|
result = s->max_latency;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue