From 5d4769b7dd9467ee7c9475fad689918cbae216a4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 1 Jul 2009 20:20:06 +0200 Subject: alsa: fix a few comments --- src/modules/alsa/alsa-sink.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/modules/alsa/alsa-sink.c') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index c584362d..0cde694c 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -169,10 +169,10 @@ static int reserve_init(struct userdata *u, const char *dname) { if (pa_in_system_mode()) return 0; - /* We are resuming, try to lock the device */ if (!(rname = pa_alsa_get_reserve_name(dname))) return 0; + /* We are resuming, try to lock the device */ u->reserve = pa_reserve_wrapper_get(u->core, rname); pa_xfree(rname); @@ -222,7 +222,6 @@ static int reserve_monitor_init(struct userdata *u, const char *dname) { if (pa_in_system_mode()) return 0; - /* We are resuming, try to lock the device */ if (!(rname = pa_alsa_get_reserve_name(dname))) return 0; -- cgit From 7e2afffb81ab8b495d4f769858a855c2df2c0610 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 22 Jul 2009 22:38:38 +0200 Subject: alsa: deal properly with IO functions asking us to write 0 bytes --- src/modules/alsa/alsa-sink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/modules/alsa/alsa-sink.c') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 0cde694c..e7925902 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -494,6 +494,9 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle if (frames > pa_mempool_block_size_max(u->sink->core->mempool)/u->frame_size) frames = pa_mempool_block_size_max(u->sink->core->mempool)/u->frame_size; + if (frames == 0) + break; + /* Check these are multiples of 8 bit */ pa_assert((areas[0].first & 7) == 0); pa_assert((areas[0].step & 7)== 0); @@ -631,7 +634,8 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle frames = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, (snd_pcm_uframes_t) frames); pa_memblock_release(u->memchunk.memblock); - pa_assert(frames != 0); + if (frames == 0) + break; if (PA_UNLIKELY(frames < 0)) { -- cgit From 18433c19b690432179e9a0ed83eff611f5cecc67 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 24 Jul 2009 13:45:59 +0200 Subject: alsa: handle correctly if alsa returns us 0 or EAGAIN on snd_pcm_mmap_begin if we didn't call snd_pcm_avail immediately before --- src/modules/alsa/alsa-sink.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src/modules/alsa/alsa-sink.c') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index e7925902..46562cbd 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -401,6 +401,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle snd_pcm_sframes_t n; size_t n_bytes; int r; + pa_bool_t after_avail = TRUE; /* First we determine how many samples are missing to fill the * buffer up to 100% */ @@ -484,6 +485,9 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle if (PA_UNLIKELY((err = pa_alsa_safe_mmap_begin(u->pcm_handle, &areas, &offset, &frames, u->hwbuf_size, &u->sink->sample_spec)) < 0)) { + if (!after_avail && err == -EAGAIN) + break; + if ((r = try_recover(u, "snd_pcm_mmap_begin", err)) == 0) continue; @@ -494,9 +498,12 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle if (frames > pa_mempool_block_size_max(u->sink->core->mempool)/u->frame_size) frames = pa_mempool_block_size_max(u->sink->core->mempool)/u->frame_size; - if (frames == 0) + if (!after_avail && frames == 0) break; + pa_assert(frames > 0); + after_avail = FALSE; + /* Check these are multiples of 8 bit */ pa_assert((areas[0].first & 7) == 0); pa_assert((areas[0].step & 7)== 0); @@ -617,6 +624,7 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle for (;;) { snd_pcm_sframes_t frames; void *p; + pa_bool_t after_avail = TRUE; /* pa_log_debug("%lu frames to write", (unsigned long) frames); */ @@ -634,17 +642,23 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polle frames = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, (snd_pcm_uframes_t) frames); pa_memblock_release(u->memchunk.memblock); - if (frames == 0) - break; - if (PA_UNLIKELY(frames < 0)) { + if (!after_avail && (int) frames == -EAGAIN) + break; + if ((r = try_recover(u, "snd_pcm_writei", (int) frames)) == 0) continue; return r; } + if (!after_avail && frames == 0) + break; + + pa_assert(frames > 0); + after_avail = FALSE; + u->memchunk.index += (size_t) frames * u->frame_size; u->memchunk.length -= (size_t) frames * u->frame_size; -- cgit From 5efb07281d5be1cddaed5b0610325fedd7f599ec Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 24 Jul 2009 20:13:52 +0200 Subject: alsa: throw timing data away after device resume --- src/modules/alsa/alsa-sink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/modules/alsa/alsa-sink.c') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 46562cbd..7fc602be 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -899,9 +899,13 @@ static int unsuspend(struct userdata *u) { if (build_pollfd(u) < 0) goto fail; + u->write_count = 0; + pa_smoother_reset(u->smoother, pa_rtclock_now(), TRUE); + u->first = TRUE; u->since_start = 0; + pa_log_info("Resumed successfully..."); return 0; @@ -1204,7 +1208,7 @@ static int process_rewind(struct userdata *u) { if (rewind_nbytes <= 0) pa_log_info("Tried rewind, but was apparently not possible."); else { - u->write_count -= out_frames * u->frame_size; + u->write_count -= rewind_nbytes; pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes); pa_sink_process_rewind(u->sink, rewind_nbytes); -- cgit From 34f31f666e2a2c301e0735e48e48da44ff503acc Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sun, 2 Aug 2009 17:52:05 +0200 Subject: Recover stream when it's suspended upon rewind Error from snd_pcm_rewind() might mean we just woke up from suspend and didn't have a chance to try to recover the stream since we didn't write to it in between. Call try_recover() in such cases. Note that for this to work kernel must return ESTRPIPE instead of EBADF for rewind/forward attempts on suspended streams, so that snd_pcm_recover() can recognize it should snd_pcm_resume() the stream. This is not the case yet (2.6.31-rc5), patch is available. Signed-off-by: Lubomir Rintel --- src/modules/alsa/alsa-sink.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/modules/alsa/alsa-sink.c') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 7fc602be..2a734e35 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -340,6 +340,9 @@ static int try_recover(struct userdata *u, const char *call, int err) { if (err == -EPIPE) pa_log_debug("%s: Buffer underrun!", call); + if (err == -EBADFD) + pa_log_debug("%s: Stream suspended!", call); + if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) < 0) { pa_log("%s: %s", call, pa_alsa_strerror(err)); return -1; @@ -1199,8 +1202,11 @@ static int process_rewind(struct userdata *u) { pa_log_debug("before: %lu", (unsigned long) in_frames); if ((out_frames = snd_pcm_rewind(u->pcm_handle, (snd_pcm_uframes_t) in_frames)) < 0) { pa_log("snd_pcm_rewind() failed: %s", pa_alsa_strerror((int) out_frames)); - return -1; + if (try_recover(u, "process_rewind", out_frames) < 0) + return -1; + out_frames = 0; } + pa_log_debug("after: %lu", (unsigned long) out_frames); rewind_nbytes = (size_t) out_frames * u->frame_size; -- cgit From 9b2534b6d0667589f69bf36702f9b998841d3d80 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 4 Aug 2009 00:23:43 +0200 Subject: alsa: properly treat ESTRPIPE as system suspend --- src/modules/alsa/alsa-sink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/modules/alsa/alsa-sink.c') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 2a734e35..1c38430f 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -340,8 +340,8 @@ static int try_recover(struct userdata *u, const char *call, int err) { if (err == -EPIPE) pa_log_debug("%s: Buffer underrun!", call); - if (err == -EBADFD) - pa_log_debug("%s: Stream suspended!", call); + if (err == -ESTRPIPE) + pa_log_debug("%s: System suspended!", call); if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) < 0) { pa_log("%s: %s", call, pa_alsa_strerror(err)); -- cgit From 58d441f7ea7994d5a0e8bc5397e2986707eb466b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 15 Aug 2009 00:16:25 +0200 Subject: log: place more rate limit invocations --- src/modules/alsa/alsa-sink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/modules/alsa/alsa-sink.c') diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 1c38430f..a91b4b8a 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1292,7 +1292,8 @@ static void thread_func(void *userdata) { * we have filled the buffer at least once * completely.*/ - pa_log_debug("Cutting sleep time for the initial iterations by half."); + if (pa_log_ratelimit()) + pa_log_debug("Cutting sleep time for the initial iterations by half."); sleep_usec /= 2; } -- cgit