Buffer Paradoxon

DSP, Plug-in and Host development discussion.
KVRist
49 posts since 27 Dec, 2009 from Berlin

Post Fri Dec 20, 2013 11:37 am

This needs a little explanation:

Suppose you have a pull based audio graph, where every node has a method to read the current buffer. The Read method returns the same buffer until the engine calls Reset and requests to calculate a new buffer. This is necessary because there can be multiple other nodes downstream which are connected to the output of a node:

Code: Select all

protected bool FNeedsRead = true;
protected float[] FReadBuffer = new float[1];
public int Read(float[] buffer, int offset, int count)
{
    //first call per frame
    if(FNeedsRead)
    {
        //the FillBuffer method does the actual work
        this.FillBuffer(FReadBuffer, offset, count);
        FNeedsRead = false;
    }
	    		
    //every call
    Array.Copy(FReadBuffer, offset, buffer, offset, count);
    return count;
}

//will read new data on next Read call
public void Reset()
{
    FNeedsRead = true;
}
Now the problem is the following: What happens if there is e.g. a sample rate converter connected to the output which calls for buffers at another frame rate? You could think, easy then the sample rate converter has to call the Reset on its own and should somehow tell the engine not to call it. But now it gets tricky, what if there is another node connected to the same output which calls at engine frame rate, and maybe even another buffer size?

Is this some kind of design flaw, or is it simply not possible? Any ideas?

KVRist
80 posts since 13 Aug, 2007 from Montréal, QC

Post Fri Dec 20, 2013 1:03 pm

First observation:
Are you sure that you want FReadBuffer to be a buffer of length 1?

Second observation:
Why don't you do all of your processing at the "converted-to" sample rate? Or why don't you have the sample rate conversion processor maintain buffers of "converted-from" and "converted-to" lengths? - This way the other processors only need to know about what they are being sent and the sample rate at which their samples are being sent to them.

KVRist

Topic Starter

49 posts since 27 Dec, 2009 from Berlin

Post Fri Dec 20, 2013 1:54 pm

Jimbrowski-one wrote:First observation:
Are you sure that you want FReadBuffer to be a buffer of length 1?
Ha :-) no, i just left out some code which was not relevant to the problem, of course there are some lines which take care of the size:

Code: Select all

//ensure internal buffer size and shrink size if too large
if (FReadBuffer.Length < count || FReadBuffer.Length > (count * 2))
{
    FReadBuffer = new float[count];
}
Jimbrowski-one wrote: Second observation:
Why don't you do all of your processing at the "converted-to" sample rate? Or why don't you have the sample rate conversion processor maintain buffers of "converted-from" and "converted-to" lengths? - This way the other processors only need to know about what they are being sent and the sample rate at which their samples are being sent to them.
Until now, everything is done in the sample rate of the engine which itself is synced to the sound card, but then i thought it may be smart to have a processor which converts sample rates as a node in the graph that one can build sub graphs which run in different rates. But now i found this problem and i am thinking that the idea wasn't that great. At the end i have no influence on what the user does with the nodes and what kind of graph he builds and where a converter might be placed.

The idea originated from letting the user decide at which point he wants to convert to engine rate if he is playing files which have a different rate. For example if the engine runs in 44100 and the user plays lots of 96000 files he may want to keep the high rate during all his effect treatment until it gets mixed with other audio signals at a lower rate.

The problem i described earlier comes from links between sub-graphs which run at a different rate...

Return to “DSP and Plug-in Development”