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