[pulseaudio-commits] r2221 - in /branches/glitch-free/src/modules: module-alsa-sink.c module-alsa-source.c

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Mon Apr 7 10:19:54 PDT 2008


Author: lennart
Date: Mon Apr  7 19:19:51 2008
New Revision: 2221

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=2221&root=pulseaudio&view=rev
Log:
call snd_pcm_hwsync() expclicitly before we access any of the status fields, since this seems to be necessary. try to find the right mixer device via the card index

Modified:
    branches/glitch-free/src/modules/module-alsa-sink.c
    branches/glitch-free/src/modules/module-alsa-source.c

Modified: branches/glitch-free/src/modules/module-alsa-sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/glitch-free/src/modules/module-alsa-sink.c?rev=2221&root=pulseaudio&r1=2220&r2=2221&view=diff
==============================================================================
--- branches/glitch-free/src/modules/module-alsa-sink.c (original)
+++ branches/glitch-free/src/modules/module-alsa-sink.c Mon Apr  7 19:19:51 2008
@@ -74,7 +74,7 @@
 
 #define DEFAULT_DEVICE "default"
 #define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC)
-#define DEFAULT_TSCHED_WATERMARK_USEC (100*PA_USEC_PER_MSEC)
+#define DEFAULT_TSCHED_WATERMARK_USEC (10*PA_USEC_PER_MSEC)
 
 struct userdata {
     pa_core *core;
@@ -145,27 +145,29 @@
         const snd_pcm_channel_area_t *areas;
         snd_pcm_uframes_t offset, frames;
 
+        snd_pcm_hwsync(u->pcm_handle);
+
         /* First we determine how many samples are missing to fill the
          * buffer up to 100% */
 
         if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
 
             pa_log_debug("snd_pcm_avail_update: %s", snd_strerror(n));
-
-            if (n == -EPIPE) {
-                pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
-                u->first = TRUE;
-            }
-
-            if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0)
-                continue;
 
             if (err == -EAGAIN) {
                 pa_log_debug("EAGAIN");
                 return work_done;
             }
 
-            pa_log("snd_pcm_avail_update: %s", snd_strerror(err));
+            if (n == -EPIPE)
+                pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
+
+            if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0) {
+                u->first = TRUE;
+                continue;
+            }
+
+            pa_log("snd_pcm_recover: %s", snd_strerror(err));
             return -1;
         }
 
@@ -180,20 +182,20 @@
         if (PA_UNLIKELY((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0)) {
 
             pa_log_debug("snd_pcm_mmap_begin: %s", snd_strerror(err));
-
-            if (err == -EPIPE) {
-                pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!");
-                u->first = TRUE;
-            }
-
-            if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0)
-                continue;
 
             if (err == -EAGAIN) {
                 pa_log_debug("EAGAIN");
                 return work_done;
             }
 
+            if (err == -EPIPE)
+                pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!");
+
+            if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) {
+                u->first = TRUE;
+                continue;
+            }
+
             pa_log("Failed to write data to DSP: %s", snd_strerror(err));
             return -1;
         }
@@ -222,17 +224,17 @@
 
             pa_log_debug("snd_pcm_mmap_commit: %s", snd_strerror(err));
 
-            if (err == -EPIPE) {
-                pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!");
-                u->first = TRUE;
-            }
-
-            if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0)
-                continue;
-
             if (err == -EAGAIN) {
                 pa_log_debug("EAGAIN");
                 return work_done;
+            }
+
+            if (err == -EPIPE)
+                pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!");
+
+            if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) {
+                u->first = TRUE;
+                continue;
             }
 
             pa_log("Failed to write data to DSP: %s", snd_strerror(err));
@@ -264,6 +266,8 @@
         snd_pcm_sframes_t n, frames;
         int err;
 
+        snd_pcm_hwsync(u->pcm_handle);
+
         if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0)) {
             pa_log("Failed to query DSP status data: %s", snd_strerror(err));
             return -1;
@@ -300,15 +304,17 @@
 
         if (PA_UNLIKELY(frames < 0)) {
 
-            if (frames == -EPIPE)
-                pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
-
-            if ((frames = snd_pcm_recover(u->pcm_handle, frames, 1)) == 0)
-                continue;
-
             if (frames == -EAGAIN) {
                 pa_log_debug("EAGAIN");
                 return work_done;
+            }
+
+            if (frames == -EPIPE)
+                pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
+
+            if ((frames = snd_pcm_recover(u->pcm_handle, frames, 1)) == 0) {
+                u->first = TRUE;
+                continue;
             }
 
             pa_log("Failed to write data to DSP: %s", snd_strerror(frames));
@@ -332,7 +338,7 @@
     }
 }
 
-static int update_smoother(struct userdata *u) {
+static void update_smoother(struct userdata *u) {
     snd_pcm_sframes_t delay  = 0;
     int64_t frames;
     int err;
@@ -343,11 +349,12 @@
 
     /* Let's update the time smoother */
 
+    snd_pcm_hwsync(u->pcm_handle);
     snd_pcm_avail_update(u->pcm_handle);
 
     if (PA_UNLIKELY((err = snd_pcm_delay(u->pcm_handle, &delay)) < 0)) {
-        pa_log("Failed to get delay: %s", snd_strerror(err));
-        return -1;
+        pa_log_warn("Failed to get delay: %s", snd_strerror(err));
+        return;
     }
 
     frames = u->frame_index - delay;
@@ -357,8 +364,6 @@
     now1 = pa_rtclock_usec();
     now2 = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec);
     pa_smoother_put(u->smoother, now1, now2);
-
-    return 0;
 }
 
 static pa_usec_t sink_get_latency(struct userdata *u) {
@@ -814,6 +819,7 @@
 
                 frames = u->sink->thread_info.rewind_nbytes / u->frame_size;
 
+                snd_pcm_hwsync(u->pcm_handle);
                 if ((unused = snd_pcm_avail_update(u->pcm_handle)) < 0) {
                     pa_log("snd_pcm_avail_update() failed: %s", snd_strerror(unused));
                     goto fail;
@@ -867,12 +873,11 @@
                     pa_smoother_resume(u->smoother, pa_rtclock_usec());
                 }
 
-                if (update_smoother(u) < 0)
-                    goto fail;
+                update_smoother(u);
             }
 
             if (u->use_tsched) {
-                pa_usec_t usec, cusec, sleep_usec;
+                pa_usec_t usec, cusec;
 
                 /* OK, the playback buffer is now full, let's
                  * calculate when to wake up next */
@@ -887,19 +892,14 @@
 
                 pa_log_debug("Waking up in %0.2fms (system clock).", (double) cusec / PA_USEC_PER_MSEC);
 
-                sleep_usec = PA_MIN(usec, cusec);
-
-                pa_log_debug("Waking up in %0.2fms (smaller value).", (double) sleep_usec / PA_USEC_PER_MSEC);
-
                 /* We don't trust the conversion, so we wake up whatever comes first */
-                pa_rtpoll_set_timer_relative(u->rtpoll, sleep_usec);
-            }
-
-        } else if (u->use_tsched) {
+                pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(usec, cusec));
+            }
+
+        } else if (u->use_tsched)
 
             /* OK, we're in an invalid state, let's disable our timers */
             pa_rtpoll_set_timer_disabled(u->rtpoll);
-        }
 
         /* Hmm, nothing to do. Let's sleep */
         if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0)
@@ -923,6 +923,7 @@
             }
 
             if (revents & (POLLERR|POLLNVAL|POLLHUP)) {
+                snd_pcm_state_t state;
 
                 if (revents & POLLERR)
                     pa_log_warn("Got POLLERR from ALSA");
@@ -931,9 +932,12 @@
                 if (revents & POLLHUP)
                     pa_log_warn("Got POLLHUP from ALSA");
 
+                state = snd_pcm_state(u->pcm_handle);
+                pa_log_warn("PCM state is %s", snd_pcm_state_name(state));
+
                 /* Try to recover from this error */
 
-                switch (snd_pcm_state(u->pcm_handle)) {
+                switch (state) {
 
                     case SND_PCM_STATE_XRUN:
                         if ((err = snd_pcm_recover(u->pcm_handle, -EPIPE, 1)) != 0) {
@@ -959,6 +963,8 @@
                         }
                         break;
                 }
+
+                u->first = TRUE;
             }
 
             pa_log_debug("alsa revents = %i", revents);
@@ -1132,14 +1138,25 @@
 
         if (pa_alsa_prepare_mixer(u->mixer_handle, u->device_name) >= 0)
             found = TRUE;
-        else if (dev_id) {
-            char *md = pa_sprintf_malloc("hw:%s", dev_id);
-
-            if (strcmp(u->device_name, md))
-                if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0)
-                    found = TRUE;
-
-            pa_xfree(md);
+        else {
+            snd_pcm_info_t *info;
+
+            snd_pcm_info_alloca(&info);
+
+            if (snd_pcm_info(u->pcm_handle, info) >= 0) {
+                char *md;
+                int card;
+
+                if ((card = snd_pcm_info_get_card(info)) >= 0) {
+
+                    md = pa_sprintf_malloc("hw:%i", card);
+
+                    if (strcmp(u->device_name, md))
+                        if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0)
+                            found = TRUE;
+                    pa_xfree(md);
+                }
+            }
         }
 
         if (found)
@@ -1304,6 +1321,8 @@
     } else
         u->mixer_fdl = NULL;
 
+    pa_alsa_dump(u->pcm_handle);
+
     if (!(u->thread = pa_thread_new(thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;

Modified: branches/glitch-free/src/modules/module-alsa-source.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/glitch-free/src/modules/module-alsa-source.c?rev=2221&root=pulseaudio&r1=2220&r2=2221&view=diff
==============================================================================
--- branches/glitch-free/src/modules/module-alsa-source.c (original)
+++ branches/glitch-free/src/modules/module-alsa-source.c Mon Apr  7 19:19:51 2008
@@ -141,18 +141,26 @@
         pa_memchunk chunk;
         void *p;
 
+        snd_pcm_hwsync(u->pcm_handle);
+
         if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
+
+            pa_log_debug("snd_pcm_avail_update: %s", snd_strerror(n));
+
+            if (err == -EAGAIN) {
+                pa_log_debug("EAGAIN");
+                return work_done;
+            }
 
             if (n == -EPIPE)
                 pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
 
-            if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0)
+            if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0) {
+                snd_pcm_start(u->pcm_handle);
                 continue;
-
-            if (err == -EAGAIN)
-                return work_done;
-
-            pa_log("snd_pcm_avail_update: %s", snd_strerror(err));
+            }
+
+            pa_log("snd_pcm_recover: %s", snd_strerror(err));
             return -1;
         }
 
@@ -163,14 +171,20 @@
 
         if (PA_UNLIKELY((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0)) {
 
+            pa_log_debug("snd_pcm_mmap_begin: %s", snd_strerror(err));
+
+            if (err == -EAGAIN) {
+                pa_log_debug("EAGAIN");
+                return work_done;
+            }
+
             if (err == -EPIPE)
                 pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!");
 
-            if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0)
+            if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) {
+                snd_pcm_start(u->pcm_handle);
                 continue;
-
-            if (err == -EAGAIN)
-                return work_done;
+            }
 
             pa_log("Failed to write data to DSP: %s", snd_strerror(err));
             return -1;
@@ -198,14 +212,20 @@
 
         if (PA_UNLIKELY((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
 
+            pa_log_debug("snd_pcm_mmap_commit: %s", snd_strerror(err));
+
+            if (err == -EAGAIN) {
+                pa_log_debug("EAGAIN");
+                return work_done;
+            }
+
             if (err == -EPIPE)
                 pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!");
 
-            if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0)
+            if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) {
+                snd_pcm_start(u->pcm_handle);
                 continue;
-
-            if (err == -EAGAIN)
-                return work_done;
+            }
 
             pa_log("Failed to write data to DSP: %s", snd_strerror(err));
             return -1;
@@ -214,6 +234,8 @@
         work_done = 1;
 
         u->frame_index += frames;
+
+        pa_log_debug("read %llu frames", (unsigned long long) frames);
 
         if (PA_LIKELY(frames >= (snd_pcm_uframes_t) n))
             return work_done;
@@ -235,6 +257,8 @@
         int err;
         pa_memchunk chunk;
 
+        snd_pcm_hwsync(u->pcm_handle);
+
         if (PA_UNLIKELY((err = snd_pcm_status(u->pcm_handle, status)) < 0)) {
             pa_log("Failed to query DSP status data: %s", snd_strerror(err));
             return -1;
@@ -264,11 +288,17 @@
         if (PA_UNLIKELY(frames < 0)) {
             pa_memblock_unref(chunk.memblock);
 
+            if (frames == -EAGAIN) {
+                pa_log_debug("EAGAIN");
+                return work_done;
+            }
+
+            if (frames == -EPIPE)
+                pa_log_debug("snd_pcm_avail_update: Buffer overrun!");
+
             if ((frames = snd_pcm_recover(u->pcm_handle, frames, 1)) == 0)
+                snd_pcm_start(u->pcm_handle);
                 continue;
-
-            if (frames == -EAGAIN)
-                return work_done;
 
             pa_log("Failed to read data from DSP: %s", snd_strerror(frames));
             return -1;
@@ -289,7 +319,7 @@
     }
 }
 
-static int update_smoother(struct userdata *u) {
+static void update_smoother(struct userdata *u) {
     snd_pcm_sframes_t delay = 0;
     int64_t frames;
     int err;
@@ -300,11 +330,12 @@
 
     /* Let's update the time smoother */
 
+    snd_pcm_hwsync(u->pcm_handle);
     snd_pcm_avail_update(u->pcm_handle);
 
     if (PA_UNLIKELY((err = snd_pcm_delay(u->pcm_handle, &delay)) < 0)) {
-        pa_log("Failed to get delay: %s", snd_strerror(err));
-        return -1;
+        pa_log_warn("Failed to get delay: %s", snd_strerror(err));
+        return;
     }
 
     frames = u->frame_index + delay;
@@ -312,8 +343,6 @@
     now1 = pa_rtclock_usec();
     now2 = pa_bytes_to_usec(frames * u->frame_size, &u->source->sample_spec);
     pa_smoother_put(u->smoother, now1, now2);
-
-    return 0;
 }
 
 static pa_usec_t source_get_latency(struct userdata *u) {
@@ -728,8 +757,7 @@
             }
 
             if (work_done)
-                if (update_smoother(u) < 0)
-                    goto fail;
+                update_smoother(u);
 
             if (u->use_tsched) {
                 pa_usec_t usec, cusec;
@@ -750,11 +778,10 @@
                 /* We don't trust the conversion, so we wake up whatever comes first */
                 pa_rtpoll_set_timer_relative(u->rtpoll, PA_MIN(usec, cusec));
             }
-        } else if (u->use_tsched) {
+        } else if (u->use_tsched)
 
             /* OK, we're in an invalid state, let's disable our timers */
             pa_rtpoll_set_timer_disabled(u->rtpoll);
-        }
 
         /* Hmm, nothing to do. Let's sleep */
         if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0)
@@ -778,6 +805,7 @@
             }
 
             if (revents & (POLLERR|POLLNVAL|POLLHUP)) {
+                snd_pcm_state_t state;
 
                 if (revents & POLLERR)
                     pa_log_warn("Got POLLERR from ALSA");
@@ -786,9 +814,12 @@
                 if (revents & POLLHUP)
                     pa_log_warn("Got POLLHUP from ALSA");
 
+                state = snd_pcm_state(u->pcm_handle);
+                pa_log_warn("PCM state is %s", snd_pcm_state_name(state));
+
                 /* Try to recover from this error */
 
-                switch (snd_pcm_state(u->pcm_handle)) {
+                switch (state) {
 
                     case SND_PCM_STATE_XRUN:
                         if ((err = snd_pcm_recover(u->pcm_handle, -EPIPE, 1)) != 0) {
@@ -814,6 +845,8 @@
                         }
                         break;
                 }
+
+                snd_pcm_start(u->pcm_handle);
             }
         }
     }
@@ -979,14 +1012,25 @@
 
         if (pa_alsa_prepare_mixer(u->mixer_handle, u->device_name) >= 0)
             found = TRUE;
-        else if (dev_id) {
-            char *md = pa_sprintf_malloc("hw:%s", dev_id);
-
-            if (strcmp(u->device_name, md))
-                if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0)
-                    found = TRUE;
-
-            pa_xfree(md);
+        else {
+            snd_pcm_info_t* info;
+
+            snd_pcm_info_alloca(&info);
+
+            if (snd_pcm_info(u->pcm_handle, info) >= 0) {
+                char *md;
+                int card;
+
+                if ((card = snd_pcm_info_get_card(info)) >= 0) {
+
+                    md = pa_sprintf_malloc("hw:%i", card);
+
+                    if (strcmp(u->device_name, md))
+                        if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0)
+                            found = TRUE;
+                    pa_xfree(md);
+                }
+            }
         }
 
         if (found)
@@ -1138,6 +1182,8 @@
     } else
         u->mixer_fdl = NULL;
 
+    pa_alsa_dump(u->pcm_handle);
+
     if (!(u->thread = pa_thread_new(thread_func, u))) {
         pa_log("Failed to create thread.");
         goto fail;




More information about the pulseaudio-commits mailing list