diff options
| author | Lennart Poettering <lennart@poettering.net> | 2007-08-03 23:48:52 +0000 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2007-08-03 23:48:52 +0000 | 
| commit | 95fab184d5448bff9f262589390c7374fb1370c8 (patch) | |
| tree | cf4ef1071c62bfa5492655243d105972494867a4 /src/modules/module-alsa-source.c | |
| parent | a6c44c0e508ede5c25ebac534642d93d101be21e (diff) | |
Don't stop hardware on buffer underruns. Instead continue playing to guarantee that our time function stays as linear as possible.
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1566 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/modules/module-alsa-source.c')
| -rw-r--r-- | src/modules/module-alsa-source.c | 48 | 
1 files changed, 29 insertions, 19 deletions
diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 0fd7bca0..9a5d5acb 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -533,19 +533,25 @@ static void thread_func(void *userdata) {                      goto fail;              } else { -                ssize_t l; -                if ((err = snd_pcm_status(u->pcm_handle, status)) >= 0) -                    l = snd_pcm_status_get_avail(status) * u->frame_size; -                else -                    l = u->fragment_size; - -                while (l > 0) { +                for (;;) {                      void *p;                      snd_pcm_sframes_t t; +                    ssize_t l; -                    pa_assert(l > 0); +                    if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) { +                        pa_log("Failed to query DSP status data: %s", snd_strerror(t)); +                        goto fail; +                    } +                    if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size) +                        pa_log_debug("Buffer overrun!"); +                     +                    l = snd_pcm_status_get_avail(status) * u->frame_size; + +                    if (l <= 0) +                        break; +                                          chunk.memblock = pa_memblock_new(u->core->mempool, l);                      p = pa_memblock_acquire(chunk.memblock); @@ -559,8 +565,7 @@ static void thread_func(void *userdata) {                      if (t < 0) {                          pa_memblock_unref(chunk.memblock); -                        if (t == -EPIPE) -                            pa_log_debug("Buffer underrun!"); +                        pa_assert(t != -EPIPE);                          if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0)                              continue; @@ -573,18 +578,18 @@ static void thread_func(void *userdata) {                              goto fail;                          } -                    } else { +                    }  -                        chunk.index = 0; -                        chunk.length = t * u->frame_size; +                    chunk.index = 0; +                    chunk.length = t * u->frame_size; -                        pa_source_post(u->source, &chunk); -                        pa_memblock_unref(chunk.memblock); -                         -                        l -= t * u->frame_size; +                    pa_source_post(u->source, &chunk); +                    pa_memblock_unref(chunk.memblock); +                     +                    work_done = 1; -                        work_done = 1; -                    } +                    if (t * u->frame_size >= (unsigned) l) +                        break;                  }               } @@ -730,6 +735,11 @@ int pa__init(pa_core *c, pa_module*m) {      if (u->use_mmap)          pa_log_info("Successfully enabled mmap() mode."); + +    if ((err = pa_alsa_set_sw_params(u->pcm_handle)) < 0) { +        pa_log("Failed to set software parameters: %s", snd_strerror(err)); +        goto fail; +    }      /* ALSA might tweak the sample spec, so recalculate the frame size */      frame_size = pa_frame_size(&ss);  | 
