Skip to contentSkip to conversation

ALSA: ctxfi - Work around emu20k1 glitch to prevent buffered sound data loss

PATCH Applied Sarah Bessmer 2 participants 2 messages Jan 9, 2014 – Jan 10, 2014 Sound

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ALSA: ctxfi - Work around emu20k1 glitch to prevent buffered sound data loss

Occasionally, on playback stream ringbuffer wraparound, the EMU20K1 hardware will momentarily return 0 instead of the proper current(loop) address. This patch handles that case, fixing the problem of playback position corruption and subsequent loss of buffered sound data, that occurs with some common buffering layout patterns(e.g. multiple simultaneous output streams with differently-sized or non-power-of-2-sized buffers).

An alternate means of fixing the problem would be to read the ca register continuously, until two sequential reads return the same value; however, that would be a more invasive change, has performance implications, and isn't necessary unless there are also issues with the value not being updated atomically in regards to individual bits or something similar(which I have not encountered through light testing).

I have no EMU20K2 hardware to confirm if the issue is present there, but even if it's not, this change shouldn't break anything that's not already broken.

---

sound/pci/ctxfi/ctatc.c renamed from sound/pci/ctxfi/ctatc.c.orig +5 -0
@@ -433,10 +433,15 @@ atc_pcm_playback_position(struct ct_atc
 
 	if (!src)
 		return 0;
 	position = src->ops->get_ca(src);
 
+	if(position < apcm->vm_block->addr) {
+		snd_printdd("ctxfi: bad ca - ca=0x%08x, vba=0x%08x, vbs=0x%08x\n", position, apcm->vm_block->addr, apcm->vm_block->size);
+		position = apcm->vm_block->addr;
+	}
+
 	size = apcm->vm_block->size;
 	max_cisz = src->multi * src->rsc.msr;
 	max_cisz = 128 * (max_cisz < 8 ? max_cisz : 8);
 
 	return (position + size - max_cisz - apcm->vm_block->addr) % size;
Applied
#1 lore raw

At Thu, 9 Jan 2014 11:36:31 -0800,

Quoted 16 lines · Sarah Bessmer

Occasionally, on playback stream ringbuffer wraparound, the EMU20K1 hardware will momentarily return 0 instead of the proper current(loop) address. This patch handles that case, fixing the problem of playback position corruption and subsequent loss of buffered sound data, that occurs with some common buffering layout patterns(e.g. multiple simultaneous output streams with differently-sized or non-power-of-2-sized buffers).

An alternate means of fixing the problem would be to read the ca register continuously, until two sequential reads return the same value; however, that would be a more invasive change, has performance implications, and isn't necessary unless there are also issues with the value not being updated atomically in regards to individual bits or something similar(which I have not encountered through light testing).

Quoted 6 lines

I have no EMU20K2 hardware to confirm if the issue is present there, but even if it's not, this change shouldn't break anything that's not already broken.

Thanks, applied with a space fix.

Takashi

Quoted 24 lines

---

sound/pci/ctxfi/ctatc.c renamed from sound/pci/ctxfi/ctatc.c.orig +5 -0
@@ -433,10 +433,15 @@ atc_pcm_playback_position(struct ct_atc
 
 	if (!src)
 		return 0;
 	position = src->ops->get_ca(src);
 
+	if(position < apcm->vm_block->addr) {
+		snd_printdd("ctxfi: bad ca - ca=0x%08x, vba=0x%08x, vbs=0x%08x\n", position, apcm->vm_block->addr, apcm->vm_block->size);
+		position = apcm->vm_block->addr;
+	}
+
 	size = apcm->vm_block->size;
 	max_cisz = src->multi * src->rsc.msr;
 	max_cisz = 128 * (max_cisz < 8 ? max_cisz : 8);
 
 	return (position + size - max_cisz - apcm->vm_block->addr) % size;

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel