You are here

understanding the playback model


To learn about multi-track playback, I've been reading the code, actually staring at it for quite a few days, tracing what happens when the user pushes play. I'm now stuck at
qtractorAudioClip::process(). I don't understand what is going on here...My main hurdle is understanding why each qtractorAudioBuffer has a file, ringbuffer, and thread, and how these three are related.... I don't get what all the methods concerning "sync" in the qtractorAudioBuffer class are for. I read the whitepaper recent;y released under the section "Engines and Buses", but I'm still very lost about how playback actually works. It would be so great if someone could give an explanation of the playback model....I hope I'm not asking too much.... :)

Is the qtractor playback model the same one that is used in Ardour?


rncbc's picture

In summary, audio playback in qtractor goes like this:

  1. each audio clip refers to a region of an audio file
  2. each audio file is handled through one audio buffer (ringbuffer)
  3. each audio (ring)buffer is served by one dedicated thread, filling the ringbuffer from disk, doing sample-rate conversion and time-stretching when applicable
  4. the real-time thread, on each jackd callback, reads from each audio clip ringbuffer, processes plugins, mix-down and finally writes the result jack output port buffers; the nested chain of command is qtractorAudioEngine::process() -> qtractorSession::process() -> [for each audio track: qtractorTrack::process() -> [for each current clip: qtractorAudioClip::process()]]

Although the bare fundamentals are the same (ie. jackd programming model) I doubt whether ardour follows the same approach, specially regarding the one thread per clip (a region in ardour slang). I believe ardour is way more streamlined (and stand correct) in this and most regards ;)

Note: the term "sync", splintered all over the code path, is just my own call for trying to (book)keeping all threads in time.

rncbc aka Rui Nuno Capela

That overview clarifies a few things. Thanks a lot. I'm pretty sure Ardour uses a ring buffer for each track, and there is dedicated IO thread that makes sure each track's ring buffer always has data. The process thread can just loop through each ring buffer to mix everything and send it out. I wonder what the advantages of one over the other are?

These seem to be the two main solutions...

Add new comment