>>How this all is done in Ardour? I browsed the source but there are >>a lot of stuff there. How about LinuxSampler? >> >> > >We use a very simple approach in LinuxSampler: in the disk thread if all
Ardour also uses a simple mechanism, but the overall result is a bit more complex. Basically, the disk/butler thread blocks on a pthread_cond. Yes, I know, I said they weren't safe for RT use :) I have made several attempts at using a FIFO, but every time I ran into a subtlety that I had failed to anticipate. I would still like to do this at some point. Ardour has a lot (*) of things for the butler/disk thread to do. Transport requests and disk i/o are intimately related and require a fairly tight interlocking. When the user requests a change in the transport state, the GUI queues an event in a (lock free) ringbuffer. The audio thread checks this ringbuffer every process() cycle, and when it finds a request, it divides into up to 3 distinct parts (function calls) "pre" RT, post-RT part and "final" RT part. The audio thread executes the pre RT part, and then sets a bitfield to indicate the work required for the non-RT part, and then signals the butler to start up again. Whenever the butler is awake, it is constantly checking to see if there is non-disk-I/O work to be done (i.e. in between reads/writes for particular tracks). If it finds that there is work to do, it does it, and then marks the work as done. On the next process() cycle after this, the audio thread will execute the final-RT function (if there is one, and there generally isn't), and at that point, the transport state change is done. code is in libs/ardour/session_{butler,transport,events}.cc (*) These are things that have to be divided across the audio and butler threads: PostTransportStop PostTransportDisableRecord PostTransportPosition PostTransportDidRecord PostTransportDuration PostTransportLocate PostTransportRoll PostTransportAbort PostTransportOverWrite PostTransportSpeed PostTransportAudition PostTransportScrub PostTransportReverse PostTransportInputChange PostTransportCurveRealloc