[alsa-devel] 1.0.16->1.0.17 regression for some HDA NVidia's
Takashi Iwai
tiwai at suse.de
Tue Jul 15 12:46:39 CEST 2008
At Sun, 13 Jul 2008 08:45:55 +0200,
Hans-Frieder Vogt wrote:
>
> Just a few more things to add (maybe it gets clearer):
> On a GeForce 8200 board (MCP78S), using the pcm example program from alsa-lib-1.0.17rc2/test,
> kernel driver version 1.0.17rc3:
> (ignoring my general sound distortion problem which I will address again in another post)
>
> bdl_pos_adj=0
> both devices "default" and "plughw:0,0" work, i.e. give continuous sound
>
> bdl_pos_adj=1
> bdl_pos_adj=2
> bdl_pos_adj=8
> no sound, pcm seems to gets stuck (example program does not return)
>
> bdl_pos_adj=16
> bdl_pos_adj=32
> bdl_pos_adj=64
> bdl_pos_adj=128
> bdl_pos_adj=256
> bdl_pos_adj=512
> bdl_pos_adj=1024
> bdl_pos_adj=2048
> default device: works, i.e. sound
> plughw:0,0: no sound, pcm gets stuck
>
> bdl_pos_adj=4096
> bdl_pos_adj=8192
> ALSA /home/haef/Treiber/alsa-driver-1.0.17rc3/pci/hda/../../alsa-kernel/pci/hda/hda_intel.c:1056: Too big adjustment 4096
> default device: works, i.e. sound
> plughw:0,0: just one beep (approx. 0.5s of sound), then pcm gets stuck
>
> Any ideas?
Thanks, that's really good to know. Does this happen with aplay, too?
Now you don't need to play so many bdl_pos_adj values any more.
Checking 1 and 32 should suffice.
Could you check /proc/asound/card0/pcm0p/sub0/* at non-working time
with bdl_pos_adj=32?
Also, try the patch below. If my guess is right, the problem is
unaligned period size.
Takashi
---
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 16715a6..ef9f072 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1047,9 +1047,13 @@ static int azx_setup_periods(struct azx *chip,
pos_adj = bdl_pos_adj[chip->dev_index];
if (pos_adj > 0) {
struct snd_pcm_runtime *runtime = substream->runtime;
+ int pos_align = pos_adj;
pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
if (!pos_adj)
- pos_adj = 1;
+ pos_adj = pos_align;
+ else
+ pos_adj = ((pos_adj + pos_align - 1) / pos_align) *
+ pos_align;
pos_adj = frames_to_bytes(runtime, pos_adj);
if (pos_adj >= period_bytes) {
snd_printk(KERN_WARNING "Too big adjustment %d\n",
More information about the Alsa-devel
mailing list