sample_stream.h
Playing a file from disk instead of from memory.
#include <sonore/sample_stream.h>- 1type
On this page
Design notes
audiostream.h can read frame N of a file without loading the rest. It cannot be called from an audio callback: a seek and an fread block for as long as the disk feels like, and "as long as the disk feels like" on a laptop that has just decided to index something is tens of milliseconds.
So there are two sides, and the whole design is the boundary between them:
A WORKER thread does the reading, into a window that runs ahead of where playback is. The AUDIO thread reads out of that window and never touches the file.
The window is double-buffered rather than a ring, deliberately. A ring gives back a range in two pieces when it wraps, and every caller then has to handle the split -- including an interpolator that wants four contiguous samples and would otherwise need a special case at exactly the point where a bug is least visible. Two buffers cost twice the memory of one and give back a plain pointer every time.
What it does NOT do is hide an underrun. If playback reaches frames the worker has not fetched, the read returns short and the counter goes up. Papering over it with silence and saying nothing would turn a disk that cannot keep up into a plugin that sounds broken for no stated reason.
Types 1
One file, one playback position, streamed.
ONE position: a second voice playing the same file at a different point needs a second streamer, with its own file handle. Serving two positions from one window would mean a window big enough to span them, which for two notes at opposite ends of a five-minute recording is the whole file: the thing this exists to avoid.