On Tue, 20 Jan 2004, Michel Dänzer wrote:

> 
> I'm basically very happy with http://penguinppc.org/~daenzer/asound.conf
> and alsa-oss, kudos to all ALSA developers who made this possible.
> 
> The only problem I'm having is that xine doesn't work well. Do you agree
> with the analysis in
> http://sourceforge.net/mailarchive/message.php?msg_id=6793623 ? Can
> snd_pcm_delay() be changed to behave as expected by xine? If so, I can
> look into it, but I'd need some pointers.

Could you try the attached patch? If you add a line 'slowptr yes' to your 
dmix pcm definition, the snd_pcm_delay() function should be more precise.

                                                Jaroslav

-----
Jaroslav Kysela <[EMAIL PROTECTED]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs
? a
? out.txt
? pcm.c.engine
Index: pcm_direct.h
===================================================================
RCS file: /cvsroot/alsa/alsa-lib/src/pcm/pcm_direct.h,v
retrieving revision 1.6
diff -u -r1.6 pcm_direct.h
--- pcm_direct.h        7 Dec 2003 09:30:47 -0000       1.6
+++ pcm_direct.h        20 Jan 2004 15:29:06 -0000
@@ -99,6 +99,7 @@
        pid_t server_pid;
        snd_timer_t *timer;             /* timer used as poll_fd */
        int interleaved;                /* we have interleaved buffer */
+       int slowptr;                    /* use slow but more precise ptr updates */
        unsigned int channels;          /* client's channels */
        unsigned int *bindings;
        union {
Index: pcm_dmix.c
===================================================================
RCS file: /cvsroot/alsa/alsa-lib/src/pcm/pcm_dmix.c,v
retrieving revision 1.46
diff -u -r1.46 pcm_dmix.c
--- pcm_dmix.c  19 Jan 2004 19:48:27 -0000      1.46
+++ pcm_dmix.c  20 Jan 2004 15:29:07 -0000
@@ -394,6 +394,8 @@
        default:
                break;
        }
+       if (dmix->slowptr)
+               snd_pcm_hwsync(dmix->spcm);
        old_slave_hw_ptr = dmix->slave_hw_ptr;
        slave_hw_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
        diff = slave_hw_ptr - old_slave_hw_ptr;
@@ -759,6 +761,8 @@
  * \param ipc_key IPC key for semaphore and shared memory
  * \param ipc_perm IPC permissions for semaphore and shared memory
  * \param params Parameters for slave
+ * \param bindings Channel bindings
+ * \param slowptr Slow but more precise pointer updates
  * \param root Configuration root
  * \param sconf Slave configuration
  * \param stream PCM Direction (stream)
@@ -772,6 +776,7 @@
                      key_t ipc_key, mode_t ipc_perm,
                      struct slave_params *params,
                      snd_config_t *bindings,
+                     int slowptr,
                      snd_config_t *root, snd_config_t *sconf,
                      snd_pcm_stream_t stream, int mode)
 {
@@ -833,6 +838,7 @@
        pcm->fast_ops = &snd_pcm_dmix_fast_ops;
        pcm->private_data = dmix;
        dmix->state = SND_PCM_STATE_OPEN;
+       dmix->slowptr = slowptr;
 
        if (first_instance) {
                ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
@@ -1082,7 +1088,7 @@
        snd_config_iterator_t i, next;
        snd_config_t *slave = NULL, *bindings = NULL, *sconf;
        struct slave_params params;
-       int bsize, psize, ipc_key_add_uid = 0;
+       int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
        key_t ipc_key = 0;
        mode_t ipc_perm = 0600;
        int err;
@@ -1142,6 +1148,22 @@
                        bindings = n;
                        continue;
                }
+               if (strcmp(id, "slowptr") == 0) {
+                       char *tmp;
+                       err = snd_config_get_ascii(n, &tmp);
+                       if (err < 0) {
+                               SNDERR("The field slowptr must be a boolean type");
+                               return err;
+                       }
+                       err = snd_config_get_bool_ascii(tmp);
+                       free(tmp);
+                       if (err < 0) {
+                               SNDERR("The field slowptr must be a boolean type");
+                               return err;
+                       }
+                       slowptr = err;
+                       continue;
+               }
                SNDERR("Unknown field %s", id);
                return -EINVAL;
        }
@@ -1179,7 +1201,7 @@
        params.period_size = psize;
        params.buffer_size = bsize;
 
-       err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, 
root, sconf, stream, mode);
+       err = snd_pcm_dmix_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, 
slowptr, root, sconf, stream, mode);
        if (err < 0)
                snd_config_delete(sconf);
        return err;
Index: pcm_dshare.c
===================================================================
RCS file: /cvsroot/alsa/alsa-lib/src/pcm/pcm_dshare.c,v
retrieving revision 1.12
diff -u -r1.12 pcm_dshare.c
--- pcm_dshare.c        19 Jan 2004 19:48:28 -0000      1.12
+++ pcm_dshare.c        20 Jan 2004 15:29:07 -0000
@@ -141,6 +141,8 @@
        default:
                break;
        }
+       if (dshare->slowptr)
+               snd_pcm_hwsync(dshare->spcm);
        old_slave_hw_ptr = dshare->slave_hw_ptr;
        slave_hw_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr;
        diff = slave_hw_ptr - old_slave_hw_ptr;
@@ -509,6 +511,8 @@
  * \param ipc_key IPC key for semaphore and shared memory
  * \param ipc_mode IPC permissions for semaphore and shared memory
  * \param params Parameters for slave
+ * \param bindings Channel bindings
+ * \param slowptr Slow but more precise pointer updates
  * \param root Configuration root
  * \param sconf Slave configuration
  * \param stream PCM Direction (stream)
@@ -522,6 +526,7 @@
                        key_t ipc_key, mode_t ipc_perm,
                        struct slave_params *params,
                        snd_config_t *bindings,
+                       int slowptr,
                        snd_config_t *root, snd_config_t *sconf,
                        snd_pcm_stream_t stream, int mode)
 {
@@ -590,6 +595,7 @@
        pcm->fast_ops = &snd_pcm_dshare_fast_ops;
        pcm->private_data = dshare;
        dshare->state = SND_PCM_STATE_OPEN;
+       dshare->slowptr = slowptr;
 
        if (first_instance) {
                ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
@@ -771,7 +777,7 @@
        snd_config_iterator_t i, next;
        snd_config_t *slave = NULL, *bindings = NULL, *sconf;
        struct slave_params params;
-       int bsize, psize, ipc_key_add_uid = 0;
+       int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
        key_t ipc_key = 0;
        mode_t ipc_perm = 0600;
        
@@ -832,6 +838,22 @@
                        bindings = n;
                        continue;
                }
+               if (strcmp(id, "slowptr") == 0) {
+                       char *tmp;
+                       err = snd_config_get_ascii(n, &tmp);
+                       if (err < 0) {
+                               SNDERR("The field slowptr must be a boolean type");
+                               return err;
+                       }
+                       err = snd_config_get_bool_ascii(tmp);
+                       free(tmp);
+                       if (err < 0) {
+                               SNDERR("The field slowptr must be a boolean type");
+                               return err;
+                       }
+                       slowptr = err;
+                       continue;
+               }
                SNDERR("Unknown field %s", id);
                return -EINVAL;
        }
@@ -867,7 +889,7 @@
 
        params.period_size = psize;
        params.buffer_size = bsize;
-       err = snd_pcm_dshare_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, 
root, sconf, stream, mode);
+       err = snd_pcm_dshare_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, 
slowptr, root, sconf, stream, mode);
        if (err < 0)
                snd_config_delete(sconf);
        return err;
Index: pcm_dsnoop.c
===================================================================
RCS file: /cvsroot/alsa/alsa-lib/src/pcm/pcm_dsnoop.c,v
retrieving revision 1.12
diff -u -r1.12 pcm_dsnoop.c
--- pcm_dsnoop.c        19 Jan 2004 19:48:28 -0000      1.12
+++ pcm_dsnoop.c        20 Jan 2004 15:29:07 -0000
@@ -123,6 +123,8 @@
        default:
                break;
        }
+       if (dsnoop->slowptr)
+               snd_pcm_hwsync(dsnoop->spcm);
        old_slave_hw_ptr = dsnoop->slave_hw_ptr;
        slave_hw_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr;
        diff = slave_hw_ptr - old_slave_hw_ptr;
@@ -477,6 +479,8 @@
  * \param ipc_key IPC key for semaphore and shared memory
  * \param ipc_perm IPC permissions for semaphore and shared memory
  * \param params Parameters for slave
+ * \param bindings Channel bindings
+ * \param slowptr Slow but more precise pointer updates
  * \param root Configuration root
  * \param sconf Slave configuration
  * \param stream PCM Direction (stream)
@@ -490,6 +494,7 @@
                        key_t ipc_key, mode_t ipc_perm,
                        struct slave_params *params,
                        snd_config_t *bindings,
+                       int slowptr,
                        snd_config_t *root, snd_config_t *sconf,
                        snd_pcm_stream_t stream, int mode)
 {
@@ -550,6 +555,7 @@
        pcm->fast_ops = &snd_pcm_dsnoop_fast_ops;
        pcm->private_data = dsnoop;
        dsnoop->state = SND_PCM_STATE_OPEN;
+       dsnoop->slowptr = slowptr;
 
        if (first_instance) {
                ret = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
@@ -721,7 +727,7 @@
        snd_config_iterator_t i, next;
        snd_config_t *slave = NULL, *bindings = NULL, *sconf;
        struct slave_params params;
-       int bsize, psize, ipc_key_add_uid = 0;
+       int bsize, psize, ipc_key_add_uid = 0, slowptr = 0;
        key_t ipc_key = 0;
        mode_t ipc_perm = 0600;
        int err;
@@ -782,6 +788,22 @@
                        bindings = n;
                        continue;
                }
+               if (strcmp(id, "slowptr") == 0) {
+                       char *tmp;
+                       err = snd_config_get_ascii(n, &tmp);
+                       if (err < 0) {
+                               SNDERR("The field slowptr must be a boolean type");
+                               return err;
+                       }
+                       err = snd_config_get_bool_ascii(tmp);
+                       free(tmp);
+                       if (err < 0) {
+                               SNDERR("The field slowptr must be a boolean type");
+                               return err;
+                       }
+                       slowptr = err;
+                       continue;
+               }
                SNDERR("Unknown field %s", id);
                return -EINVAL;
        }
@@ -825,7 +847,7 @@
 
        params.period_size = psize;
        params.buffer_size = bsize;
-       err = snd_pcm_dsnoop_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, 
root, sconf, stream, mode);
+       err = snd_pcm_dsnoop_open(pcmp, name, ipc_key, ipc_perm, &params, bindings, 
slowptr, root, sconf, stream, mode);
        if (err < 0)
                snd_config_delete(sconf);
        return err;

Reply via email to