this patch makes ALSA treat the hammerfall the exact same way that
ASIO does, which makes sense to do given RME's claims about the card.

the hw pointer is reduced to essentially a 1 bit value - its either at
the start of the first period or at the start of the second. there are
no values between these two locations, as befits "ASIO poured in
hardware". AFAIK, no other solution will work until or unless RME
corrects their h/w design; even then, it wouldn't work correctly on
older hammerfalls. as i've noted several times, neither abramo's code
nor my own has ever worked correctly; this new code is simpler and
will work always. the only possible criticism is that it prevents
using the card with the RTC as the poll timer - fair point, buts that
because the h/w hasn't been designed to be used like that, so denying
that chance is in keeping with ALSA philosophy, IMHO.

There is one additional patch in here that displays the value of the
control register in /proc/asound/foo/rme9652.

--p

Index: card-rme9652.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/cards/card-rme9652.c,v
retrieving revision 1.126
diff -c -u -r1.126 card-rme9652.c
--- card-rme9652.c      2001/06/24 23:12:43     1.126
+++ card-rme9652.c      2001/11/16 18:32:38
@@ -213,10 +213,6 @@
 
        char *card_name;                /* hammerfall or hammerfall light names */
 
-        size_t hw_offsetmask;          /* &-with status register to get real 
hw_offset */
-       size_t prev_hw_offset;          /* previous hw offset */
-       size_t max_jitter;              /* maximum jitter in frames for 
-                                          hw pointer */
        size_t period_bytes;            /* guess what this is */
 
        unsigned char ds_channels;
@@ -346,54 +342,14 @@
 
        i = rme9652->control_register & RME9652_latency;
        rme9652->period_bytes = 1 << ((rme9652_decode_latency(i) + 8));
-       rme9652->hw_offsetmask = 
-               (rme9652->period_bytes * 2 - 1) & RME9652_buf_pos;
-       rme9652->max_jitter = 16 + (rme9652->period_bytes <= 1024 ? 32 : 64);
 }
 
 static inline snd_pcm_uframes_t rme9652_hw_pointer(rme9652_t *rme9652)
 {
-       int status;
-       int offset, frag;
-       snd_pcm_uframes_t period_size = rme9652->period_bytes / 4;
-       snd_pcm_sframes_t delta;
-
-       status = rme9652_read(rme9652, RME9652_status_register);
-       offset = status & RME9652_buf_pos;
-
-       /* The hardware may give a backward movement for up to 80 frames
-           Martin Kirst <[EMAIL PROTECTED]> knows the details.
-       */
-
-       delta = rme9652->prev_hw_offset - offset;
-       delta &= 0xffff;
-       if (delta <= rme9652->max_jitter * 4)
-               offset = rme9652->prev_hw_offset;
-       else
-               rme9652->prev_hw_offset = offset;
-       offset &= rme9652->hw_offsetmask;
-       offset /= 4;
-       frag = status & RME9652_buffer_id;
-
-       if (offset < period_size) {
-               if (offset > rme9652->max_jitter) {
-                       if (frag)
-                               printk("Unexpected hw_pointer position (bufid == 0): 
status: %x offset: %d\n", status, offset);
-               } else if (!frag)
-                       return 0;
-               offset -= rme9652->max_jitter;
-               if (offset < 0)
-                       offset += period_size * 2;
-       } else {
-               if (offset > period_size + rme9652->max_jitter) {
-                       if (!frag)
-                               printk("Unexpected hw_pointer position (bufid == 1): 
status: %x offset: %d\n", status, offset);
-               } else if (frag)
-                       return period_size;
-               offset -= rme9652->max_jitter;
-       }
-
-       return offset;
+       if (rme9652_read(rme9652, RME9652_status_register) & RME9652_buffer_id) 
+               return rme9652->period_bytes/4;
+       else    
+               return 0;
 }
 
 static inline void rme9652_reset_hw_pointer(rme9652_t *rme9652)
@@ -410,7 +366,6 @@
                rme9652_write(rme9652, i * 4, 0);
                udelay(10);
        }
-       rme9652->prev_hw_offset = 0;
 }
 
 static inline void rme9652_start(rme9652_t *s)
@@ -1617,6 +1572,7 @@
                    rme9652->capture_buffer, rme9652->playback_buffer);
        snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
                    rme9652->irq, rme9652->port, rme9652->iobase);
+       snd_iprintf(buffer, "Control register: %x\n", rme9652->control_register);
 
        snd_iprintf(buffer, "\n");
 


_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to