Red Hat Bugzilla – Bug 55877
Choppy sound with tcp socket in esound
Last modified: 2008-05-01 11:38:01 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.5+) Gecko/20011024
Description of problem:
When using a tcp socket with esound (private socket or public socket), the
sound is very choppy. There are repetitive snippets of noise over the top
of the normal sound.
This only seems to occur if I'm doing one of the following:
1. Playing something in xmms with the esound output plugin
2. Playing an Mp3 in mpg123
3. Getting the output of mpg123 via the -s (output to stdout) option, then
using the esdcat program to play this file.
If either of the following conditions are met there is no noise whatsoever:
1. Using esd with no options, or with the -unix option (unix-domain socket
2. Using esdplay (ie, it works correctly ALL the time if I use esdplay,
even with the -tcp option).
I have a Soundblaster 16 Value Edition. I am using devfs with /dev/dsp
symlinked to /dev/sound/dsp. Kernel is self-compiled 2.4.14.
Here are some version numbers:
$ rpm -q xmms esound mpg123
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. esd -tcp
2. mpg123 -s something.mp3 | esdcat
Actual Results: Choppy sound. The mp3 can still be heard in between the
snippets of noise.
Expected Results: Just the sound of the mp3 on its own.
Created attachment 37482 [details]
Force the esound server to fill its data buffer before processing it
I've had a bit of time to look into this problem myself today, and I think I've
tracked down the problem. When esdcat (or any other client that uses esdlib)
sends data to the esd server it sends it in 16k chunks. The server reads this in
4k chunks. This wouldn't be a problem except that every fourth chunk it reads is
slightly less than 4k. The data buffer's length is then not a multiple of the
sample size (4 bytes for 16-bit stereo), and this mucks up the calculations for
The result is that every four chunks the server gets out of sync with the
client. We get noise until the server reads enough chunks (some shortened) until
it is once again in sync. The result is the pulsing noise I described before.
I'm not quite sure why Linux decides to shorten the read() call every fourth
chunk (which coincides with the end of the 16k write() in the client). However
in any case the server should be able to cope properly with read() returning
fewer bytes than requested.
I've attached a patch that gets around the problem by trying to fill the whole
4k buffer before processing it. I'm not really sure if this is the right
solution to the problem, but it seems to work OK.
The patch also fixes what I believe to be a small typo in a debugging statement.
Oh and also, sometimes the server goes continually into noise if the client is
stopped (with Ctrl+Z) and then restarted. I'm pretty sure this is a
manifestation of the same bug.
I mailed the upstream esound author (email@example.com) and asked for
his advice on this patch. Thanks for investigating the problem!
Elliot, Owen, do either of you feel you have an educated opinion on the
correctness of this patch?
If the input stream is non-blocking, it loooks fine; if it's
blocking, then this looks like it might cause things to block
unnecessarily. (I don't see why the kernel would give a partial
read though if there is more data available, so I'd guess it
would do nothing one way or the other if it is non-blocking.)
My guess is tha the real problem lies elsewhere in the way
ESD is managing the buffers it is feeding to the sound card.
Sounds plausible, the guy has done his homework. I can't evaluate it further
without testing it, which I assume you have already done.
If you do use the patch, please stick it into esound cvs and make a new release
instead of just putting the patch in the RH package.
Patch applied to 0.2.24 upstream release, incorporated into rawhide.