View | Details | Raw Unified | Return to bug 16300 | Differences between
and this patch

Collapse All | Expand All

(-)a/include/sound/emu10k1.h (+3 lines)
Lines 1539-1544 struct snd_emu10k1_pcm { Link Here
1539
	unsigned int capture_cr_val2;	/* control value2 (for audigy) */
1539
	unsigned int capture_cr_val2;	/* control value2 (for audigy) */
1540
	unsigned int capture_bs_val;	/* buffer size value */
1540
	unsigned int capture_bs_val;	/* buffer size value */
1541
	unsigned int capture_bufsize;	/* buffer size in bytes */
1541
	unsigned int capture_bufsize;	/* buffer size in bytes */
1542
	/* position to be corrected at period interrupt; see emupcm.c */
1543
	unsigned int position_fix;
1544
	unsigned int next_position;
1542
};
1545
};
1543
1546
1544
struct snd_emu10k1_pcm_mixer {
1547
struct snd_emu10k1_pcm_mixer {
(-)a/sound/pci/emu10k1/emupcm.c (+32 lines)
Lines 38-54 static void snd_emu10k1_pcm_interrupt(struct snd_emu10k1 *emu, Link Here
38
				      struct snd_emu10k1_voice *voice)
38
				      struct snd_emu10k1_voice *voice)
39
{
39
{
40
	struct snd_emu10k1_pcm *epcm;
40
	struct snd_emu10k1_pcm *epcm;
41
	struct snd_pcm_runtime *runtime;
41
42
42
	if ((epcm = voice->epcm) == NULL)
43
	if ((epcm = voice->epcm) == NULL)
43
		return;
44
		return;
44
	if (epcm->substream == NULL)
45
	if (epcm->substream == NULL)
45
		return;
46
		return;
47
	runtime = epcm->substream->runtime;
48
	if (!runtime)
49
		return;
46
#if 0
50
#if 0
47
	printk(KERN_DEBUG "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
51
	printk(KERN_DEBUG "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
48
			epcm->substream->runtime->hw->pointer(emu, epcm->substream),
52
			epcm->substream->runtime->hw->pointer(emu, epcm->substream),
49
			snd_pcm_lib_period_bytes(epcm->substream),
53
			snd_pcm_lib_period_bytes(epcm->substream),
50
			snd_pcm_lib_buffer_bytes(epcm->substream));
54
			snd_pcm_lib_buffer_bytes(epcm->substream));
51
#endif
55
#endif
56
	/* update the next expected position */
57
	epcm->next_position += runtime->period_size;
58
	/* correct up to two samples behind period boundary */
59
	epcm->position_fix = epcm->next_position - 2;
60
	epcm->next_position %= runtime->buffer_size;
61
	epcm->position_fix %= runtime->buffer_size;
62
52
	snd_pcm_period_elapsed(epcm->substream);
63
	snd_pcm_period_elapsed(epcm->substream);
53
}
64
}
54
65
Lines 514-519 static int snd_emu10k1_playback_prepare(struct snd_pcm_substream *substream) Link Here
514
		snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1],
525
		snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1],
515
					   start_addr, end_addr,
526
					   start_addr, end_addr,
516
					   &emu->pcm_mixer[substream->number]);
527
					   &emu->pcm_mixer[substream->number]);
528
	epcm->position_fix = -1;
529
	epcm->next_position = 0;
517
	return 0;
530
	return 0;
518
}
531
}
519
532
Lines 628-633 static int snd_emu10k1_capture_prepare(struct snd_pcm_substream *substream) Link Here
628
			snd_emu10k1_audigy_capture_rate_reg(runtime->rate) :
641
			snd_emu10k1_audigy_capture_rate_reg(runtime->rate) :
629
			snd_emu10k1_capture_rate_reg(runtime->rate);
642
			snd_emu10k1_capture_rate_reg(runtime->rate);
630
	}
643
	}
644
	epcm->position_fix = -1;
645
	epcm->next_position = 0;
631
	return 0;
646
	return 0;
632
}
647
}
633
648
Lines 872-877 static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream * Link Here
872
	       "ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n",
887
	       "ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n",
873
	       ptr, runtime->buffer_size, runtime->period_size);
888
	       ptr, runtime->buffer_size, runtime->period_size);
874
	*/
889
	*/
890
891
	if (epcm->position_fix != -1) {
892
		/* if it's the marked position, correct it */
893
		unsigned int next = epcm->next_position;
894
		unsigned int xptr = ptr;
895
		if (next < epcm->position_fix)
896
			next += runtime->buffer_size;
897
		if (xptr < epcm->position_fix)
898
			xptr += runtime->buffer_size;
899
		if (xptr < next) {
900
			printk(KERN_DEBUG "XXX emu10k1: position corrected %d -> %d\n", ptr, epcm->next_position);
901
			ptr = epcm->next_position;
902
		} else {
903
			printk(KERN_DEBUG "XXX emu10k1: position passed %d (marked %d)\n", ptr, epcm->position_fix);
904
			epcm->position_fix = -1;
905
		}
906
	}
875
	return ptr;
907
	return ptr;
876
}
908
}
877
909

Return to bug 16300