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 only). 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 xmms-1.2.5-7 esound-0.2.22-5 mpg123-0.59r-10 Version-Release number of selected component (if applicable): How reproducible: Always 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. Additional info:
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 mixing. 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 (ericmit.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.