sound(4) vs alsa oss plugin

Andriy Gapon avg at FreeBSD.org
Sun Feb 3 10:43:47 UTC 2013


on 29/01/2013 20:12 Alexander Motin said the following:
> I am not sure how it supposed to work in Linux, but IMHO it is obvious
> that single ptr field is not sufficient in such conditions to identify
> full buffer wrap. Additional checks for bytes or blocks fields could
> help, but that is user-level side. I am not sure what kernel can do
> about it.

I have a very nasty local kernel-side hack that "fixes up" 'ptr' wrap-around
based on a check of 'blocks'.
But root causes are, of course:
- an application using sleep and GET*PTR for interacting with OSS
- ALSA OSS using just 'ptr'
- a 10 millisecond sleep taking e.g. 100 milliseconds once in a while (or under
some circumstances)

> From the other side, case when buffer wrapped completely is IMHO already
> fatal situation. It means that we are already late -- hardware already
> started to either play or overwrite previous buffer. That is probably
> not much better then if we would woke up some samples later.

Well, some sound distortion/corruption is very bad, but completely blocked sound
is even worse.

I have the following patch for ALSA OSS, but haven't tested it yet:
diff --git a/oss/pcm_oss.c b/oss/pcm_oss.c
index d43b44c..4729962 100644
--- a/oss/pcm_oss.c
+++ b/oss/pcm_oss.c
@@ -83,7 +83,13 @@ static snd_pcm_sframes_t oss_pointer(snd_pcm_ioplug_t *io)
 		fprintf(stderr, "*** OSS: oss_pointer error\n");
 		return 0;
 	}
-	ptr = snd_pcm_bytes_to_frames(io->pcm, info.ptr);
+
+	/*
+	 * Note that the following calculations will produce a temporary glitch
+	 * when info.bytes wraps around UINT_MAX or INT_MAX depending on type
+	 * of info.bytes in an OSS implementation.
+	 */
+	ptr = snd_pcm_bytes_to_frames(io->pcm, info.bytes) % io->buffer_size;
 	return ptr;
 }


-- 
Andriy Gapon


More information about the freebsd-multimedia mailing list