[Clam-devel] Lock free audio file IO

David García Garzón dgarcia at iua.upf.edu
Thu May 28 04:00:15 PDT 2009

Context: There is an experimental plugin in clam started by Ferran called 
'sndfile'. Is an effort to overcome some limitations of the current audiofileio 
processings. Namely adding:
 - Better interface for multi channel processings
 - Lockfree disk access
 - Seeking on playback
 - Floating point formats
 - Simpler architecture
 - Sample rate conversion
This plugin is still under development and thus it misses some features of the 
current ones such as ogg/mp3 support, full format set from sndfile, text tags, 
access to header... So, at some point we should move code from one 
implementation to the other to get the full support. Now i am trying to push 
the process forward to use seeking+mp3 in chordata.

Lock free disk write works pretty well in the new plugin but there are some 
problems on lockfree playback. The processing currently understand xruns as 
end of file condition and stalls untill you seek. As the buffering is just one 
block (Do), this happens often. Looking for a solution i found the following 
conflicting forces:
1. The realtime thread must not lock waiting for disk access
2. The realtime thread should have enough audio available each Do
3. Seeking should take place as soon as posible (seek latency)
4. The position outcontrol should match the audio being played.
To solve 1 we should separate disk access in a thread and communicate data to 
the processing thread via a ring buffer. It also means that seeking and looping 
should be controled by the disk thread, not by the processing thread as now 
(this is also the root cause of current bug). This implies some way to 
communicate thread save seek and loop controls to the disk thread.

To solve 2 we should enqueue more data than a single Do to reduce the 
likelyhood of xrun. But then 3 implies a method to invalidate the queued data 
or accepting a given latency. when a seek happens. 2 also conflicts with 4, 
buffering more than a Do implies that the current position is not the last read 
by the disk thread but the one read from the ringbuffer. 

The best solution i found right now is still a compromise: Having two 
ringbuffers one for the audio data and another for the current position to be 
able to output the correct position on the control. Invalidating the queue 
seems something complex to handle in multithreading, so, instead of validating 
the queue, i propose accepting a given seek latency which could be configured 
on the processing. Also the seek control should affect the disk thread but 
should be communicated in asynchronous way. Not sure on how to solve this.

Any ideas?

David García Garzón
(Work) dgarcia at iua dot upf anotherdot edu

More information about the clam-devel mailing list