Jaroslav:

I posted this a couple of months ago. This patch it critical to preventing
mmap-based applications from misbehaving with the hammerfall. What is
shown below is a completely new version of the hw_pointer routine for
the hammerfall. it doesn't completely eliminate spurious ptr values,
but it reduces them dramatically, and more importantly, it seems to
more or less eliminate errors caused by the hw_pointer function
indicating incorrect values.

i spent an hour or two at a recording studio this morning trying to
figure out why we get "disk stream errors" in ardour there, but not at
my home. it ultimately traces back to this routine, which causes
snd_pcm_mmap_begin() to return incorrect numbers.

please let me know when its applied. i'm still waiting to hear from
RME about the real nature of this problem, since its evidently more
subtle and/or complex than they originally explained to abramo.

--p


static inline snd_pcm_uframes_t rme9652_hw_pointer(rme9652_t *rme9652)
{
        int status;
        int frame_offset, bufid;
        snd_pcm_uframes_t period_size = rme9652->period_bytes / 4;
        snd_pcm_uframes_t period_size_twice = period_size * 2;
        int loval, hival;

        status = rme9652_read(rme9652, RME9652_status_register);
        
        frame_offset = (status & rme9652->hw_offsetmask);
        frame_offset /= 4;
        
        bufid = status & RME9652_buffer_id;
        
        /* The offset value in the status register is not always in
           sync with the buffer ID. Because RME designed the card
           around ASIO, in which only the buffer ID value really
           matters, we treat the buffer ID as the master value. We
           will use the offset value as given if its within the normal
           range for the "buf". If its within max_jitter of the
           normal range, we'll use the start of the relevant buf.
        */
        
        if (bufid) {

                if ((frame_offset >= period_size) && (frame_offset < 
period_size_twice)) {
                        return frame_offset;
                } 
                
                /*  BUFFER ID 1: offset not in area, so require it to 
                    be close to the start of the area

                     0               ps-maxjit ps                                 ps*2
                     |                  *       |                                  |
                                        /////////

                     acceptable jitter area: ////

                */

                if ((frame_offset >= (period_size - rme9652->max_jitter)) && 
(frame_offset <= period_size)) {
                        return period_size;
                }

                loval = period_size - rme9652->max_jitter;
                hival = period_size;

        } else {

                if ((frame_offset >= 0) && (frame_offset < period_size)) {
                        return frame_offset;
                } 


                
                /*  BUFFER ID 0: offset not in area, so require it to 
                    be close to the start of the area

                     0                         ps                   ps*2-maxjit   ps*2
                     |                          |                        *        |
                                                                         //////////

                     acceptable jitter area: ////

                */

                if ((frame_offset >= (period_size_twice - rme9652->max_jitter)) && 
(frame_offset < period_size_twice)) {
                        return 0;
                }
                
                loval = period_size_twice - rme9652->max_jitter;
                hival = period_size_twice;
        }
        
        printk ("RME9652: buffer offset and buffer ID do not match; %d: acceptable 
range: %d-%d, actual: %d\n", 
                bufid ? 1 : 0,
                loval, 
                hival, 
                frame_offset);
        
        frame_offset = 0; /* XXX what to do ? */
        return frame_offset;
}

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

Reply via email to