[ALSA] [ML403-AC97CR] Fix capture/periodic overrun bug
authorJoachim Foerster <JOFT@gmx.de>
Mon, 5 Nov 2007 14:48:36 +0000 (15:48 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 31 Jan 2008 16:29:15 +0000 (17:29 +0100)
We have to do fairly accurate counting of the minimal periods, instead
of being lazy and just setting the number to zero as soon as one period
elapses.

Signed-off-by: Joachim Foerster <JOFT@gmx.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
sound/drivers/ml403-ac97cr.c
sound/drivers/pcm-indirect2.c

index 22223152a347ef14bed6d958e15d8b98e507f032..c76a24e337f9a08164c1dffd6d7a6bba87fa9b40 100644 (file)
  * accesses to a minimum, because after a variable amount of accesses, the AC97
  * controller doesn't raise the register access finished bit anymore ...
  *
- * - Capture support works - basically, but after ~30s (with rates > ~20kHz)
- * ALSA stops reading captured samples from the intermediate buffer and
- * therefore a overrun happens - ATM I don't know what's wrong.
- *
  * - Playback support seems to be pretty stable - no issues here.
+ * - Capture support "works" now, too. Overruns don't happen any longer so often.
+ *   But there might still be some ...
  */
 
 #include <sound/driver.h>
index 6a829cd03dde4033cdad586f9144cdb4611d4df7..660157d4942272cfd245ee10cfb003ec4fd0e32b 100644 (file)
@@ -403,7 +403,7 @@ snd_pcm_indirect2_playback_interrupt(struct snd_pcm_substream *substream,
                                          rec->min_multiple);
                rec->mul_elapsed++;
 #endif
-               rec->min_periods = 0;
+               rec->min_periods = (rec->min_periods % rec->min_multiple);
                snd_pcm_period_elapsed(substream);
        }
 }
@@ -568,24 +568,8 @@ snd_pcm_indirect2_capture_interrupt(struct snd_pcm_substream *substream,
                rec->mul_elapsed_real += (rec->min_periods /
                                          rec->min_multiple);
                rec->mul_elapsed++;
-
-               if (!(rec->mul_elapsed % 4)) {
-                       struct snd_pcm_runtime *runtime = substream->runtime;
-                       unsigned int appl_ptr =
-                           frames_to_bytes(runtime,
-                                           (unsigned int)runtime->control->
-                                           appl_ptr) % rec->sw_buffer_size;
-                       int diff = rec->sw_data - appl_ptr;
-                       if (diff < 0)
-                               diff += rec->sw_buffer_size;
-                       snd_printk(KERN_DEBUG
-                                  "STAT: mul_elapsed: %d, sw_data: %u, "
-                                  "appl_ptr (bytes): %u, diff: %d\n",
-                                  rec->mul_elapsed, rec->sw_data, appl_ptr,
-                                  diff);
-               }
 #endif
-               rec->min_periods = 0;
+               rec->min_periods = (rec->min_periods % rec->min_multiple);
                snd_pcm_period_elapsed(substream);
        }
 }