DAW recording buffer strategy


#1

Those of you who’ve written a DAW … what was your strategy for recording audio? It’d be convenient to allocate a huge chunk of memory and just write straight from the audio thread but this would assume infinite memory, limited recording length and risks data lose if there’s a crash.

I’m thinking:

  • FIFO the data out of the audio thread through a buffer that’ll hold a few seconds of audio
  • Copy it to a pre-write buffer that I expand on the heap as required pre-writing to disk
  • Swap the pre-write buffer for a new one and write the old one to disk every five or six seconds

This allows for the disk access to be delay by any amount, and allows the size of the FIFO buffer for memory allocation (and possibly copying of data) to complete.

Or maybe it’s easier to go with just the FIFO and make it bigger…


#2

I think in Tracktion we just have a big pool of blocks which the audio thread writes into, and then a background thread runs along flushing them to disk. Unlike a fifo, that makes it quite easy to allocate a few more in an emergency if things get too far behind.


#3

That’s a better strategy I think.


#4

However - I’ve got it working with a FIFO for now because I was half way there by the time you replied. But it’s done in a way that’s left the door open for your improved multi-buffer approach.

So I’ve got this cracking class now that does recording from an audio thread, it’s got some summarisation, a FIFO for displaying the latest data super-quick zoomed in in real time while recording, a fifo for writing to disk, and if you’re zooming in further back and not following the audio in realtime it goes to disk to read. It’s getting quite sexy.

My only real remaining niggle is that there’s no way to re-read the WAV header to get a new length without re-opening the WAV file. And you can’t read past the stated end of the WAV. How about AudioFormatReader::refresh() to just re-read the header :slight_smile:


#5

I’m just using a AudioFormatWriter::ThreadedWriter per each track. To display what’s happening I use an AudioThumbnail connected to the the threaded writer via setDataReceiver(thumbnail). I.e nothing fancy, just Juce classes with some glue…


#6

Maybe I should have done that :slight_smile: But the audio thumbnail class didn’t really support zooming in fully when i tried it? And I hadnt spotted the IncomingDataReciever stuff :frowning:


#7
void AudioThumbnail::drawChannel	(	Graphics & 	g,
const Rectangle< int > & 	area,
double 	startTimeSeconds,
double 	endTimeSeconds,
int 	channelNum,
float 	verticalZoomFactor 
)

“The waveform will be drawn within the specified rectangle, where startTime and endTime specify the times within the audio file that should be positioned at the left and right edges of the rectangle.”

just change the start and end times every time you call drawChannel() if you want to zoom in.


#8

Yeaps! And if you fancy microscopical zoom levels you might like this small update :slight_smile: A better AudioThumbnail?