Re: being serious about the NG of zinf

Sam Varshavchik <[email protected]>
Newsgroups gmane.comp.audio.zinf.devel
Message-ID <[email protected]>
Ed Sweetman writes:

> Right now I'm opposed to using threads for the main player.
> Threads could possibly be used in the situation where we're streaming or 
> playing from the internet. This is because of a couple reasons. We could 
> have a large output buffer which may make reading from the stream be in 
> longer intervals than ip allows for timeouts, thus losing our 
> connection. Also, for streams, we may miss packets during our requests 
> for more data.

With most desktop environment, X-Windows, or MS-Windows, sometimes certain 
operations will lock the entire display, and any process that requests any 
kind of a UI-related operation will be blocked.  The most common example 
would be resizing a desktop window.  The entire display will be locked so 
that the display manager can scribble over the entire display with the 
rubberband outline of the resizing window.

If your main application thread is multiplexing between pushing audio out, 
and updating the display, the audio playback is going to come to a 
screeching halt pretty quickly.  Not nice.

From a purely theoretical design, I think that audio playback needs a 
minimum of two threads.

The first thread's only job would be to push audio out.  No other I/O.  No 
dynamic memory allocation from the heap.  It's going to be reading from a 
reasonably sized memory buffer that the second thread will be filling, and 
writing the data out to the audio device.  Where possible, it's going to 
be set to run as a high priority process.  No other syscalls or I/O 
interaction except for audio out.  You want to minimize any possibility of 
something else getting in the way.  It's going to be reading from the memory 
buffer, and periodically updating an output counter that indicates how much 
audio was played so far.

The second thread would be reading the audio source; be it a file or an 
Internet stream, translating it to the native audio format, and constantly 
filling the input buffer to the first thread.

Everything else: all user interface and any other ancillary processing, can 
go into the main application thread.  When the main application wants to 
start playing a file or a thread, the second thread gets appropriately 
notified, then it begins reading the audio source and filling the first 
thread's input buffer.  Then, the main application's remaining task is to 
periodically update the display based on the fist thread's output counter.

The main application would have a facility to signal the first thread to 
pause and resume playback.  Fast-Forward and Rewind is implemented by 
signaling the first thread to pause, waiting until it indicates that it's 
paused, then signaling the second thread to reset an refill the input buffer 
from a different position in the audio stream; then signaling the first 
thread to resume.

The first thread needs to be aware of the particular buffering behavior of 
the operating system's audio-out driver.  When audio-out is paused, the 
first thread needs to also flush the audio-out device, so that the audio is 
muted immediately, then calculate its best estimate of how much audio data 
was left buffered up, so if its signaled to resume playback from the same 
point the playback will pick up exactly where it was stopped; and all the 
time its output counters reflect its best estimate on what's actually coming 
out of the speakers.  One of my biggest annoyances with some of the last 
versions of Freeamp is that it was blissfully unaware of audio buffering by 
/dev/dsp. Each time you started playing the track timer immediately jumped 
from 00:00 to 00:04 seconds, then began counting off seconds normally, and 
once it reached the end of the song it remained stuck on the final second 
for a little while until /dev/dsp finished flushing everything out.  It was 
even worse with ESound.  I think the current Zinf's much better in this 
regard, at least I haven't noticed anything.



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.