BelaPlatform / supercollider

an environment and programming language for real time audio synthesis and algorithmic composition
GNU General Public License v3.0
14 stars 8 forks source link

number of available audio buffers seems to be locked at 128 on Bela #74

Closed jreus closed 3 years ago

jreus commented 3 years ago

Environment

Steps to reproduce (for bugs)

Hello. There seems to be an issue with being unable to increase the number of available audio buffers in SuperCollider on the Bela. Normally this would be done by setting a number of buffers in ServerOptions.numBuffers before booting the server, like so:

s.options.numBuffers = 256; 

On the Bela this number seems to be totally ignored. What's worse, the default number of available buffers is only 128 on the Bela! This is significantly less than the usual 1024 that is the default on most SuperCollider builds. However when I print the results of s.options.numBuffers it does report 1024.

The hard limit is shown by running the following code, which counts to 127 and then throws an error.

s.waitForBoot {
    a = List.new;
    1027.do {|idx|
        var buf = Buffer.new(s);
        a.add(buf);
        idx.postln;
    }
};

Which gives the error ERROR: No more buffer numbers -- free some buffers before allocating more. (full stack trace below)

Any ideas on how to get more buffers? Or is this limit a conscious decision hard-coded somewhere?

Error message (for bugs)

127
ERROR: No more buffer numbers -- free some buffers before allocating more.
PROTECTED CALL STACK:
    Server:nextBufferNumber 0x10a9f20
        arg this = localhost
        arg n = 1
        var bufnum = nil
    Meta_Buffer:new 0x7a84a0
        arg this = Buffer
        arg server = localhost
        arg numFrames = nil
        arg numChannels = nil
        arg bufnum = nil
    a FunctionDef   0x14cead0
        sourceCode = "{|idx|
        var buf = Buffer.new(s);
        a.add(buf);
        idx.postln;
    }"
        arg idx = 128
        var buf = nil
    Integer:do  0xebc6e0
        arg this = 1027
        arg function = a Function
        var i = 128
    Routine:prStart 0xdc0e60
        arg this = a Routine
        arg inval = 7.837844712
CALL STACK:
    Exception:reportError
        arg this = 
    < closed FunctionDef >
        arg error = 
    Integer:forBy
        arg this = 0
        arg endval = 0
        arg stepval = 2
        arg function = 
        var i = 0
        var j = 0
    SequenceableCollection:pairsDo
        arg this = [*2]
        arg function = 
    Scheduler:seconds_
        arg this = 
        arg newSeconds = 14.491996382
    Meta_AppClock:tick
        arg this = 
        var saveClock = 
    Process:tick
        arg this = 
^^ The preceding error dump is for ERROR: No more buffer numbers -- free some buffers before allocating more.
giuliomoro commented 3 years ago

I guess the general approach with Sc on Bela should be: everything should work like normal Sc, BUT when running Sc from the IDE, there may be some assumptions that are not verified here, because the server is not booted automatically by the IDE. Could you post your full code? Where do you run it ? In the SC IDE or as a stand-alone program on Bela?

jreus commented 3 years ago

I guess the general approach with Sc on Bela should be: everything should work like normal Sc, BUT when running Sc from the IDE, there may be some assumptions that are not verified here, because the server is not booted automatically by the IDE. Could you post your full code? Where do you run it ? In the SC IDE or as a stand-alone program on Bela?

I'm encountering the same issue both when the buffers are loaded "on-board" the Bela, as well as via remote control in the IDE. The full program (running completely as a sketch on the Bela) is...

s = Server.default;
s.options.numAnalogInChannels = 8; // Analog channels active. can only be 2, 4 or 8
s.options.numAnalogOutChannels = 8;
s.options.numDigitalChannels = 16;
s.options.dacLevel = 0;
s.options.blockSize = 32;
s.options.numInputBusChannels = 2;
s.options.numOutputBusChannels = 10;

s.waitForBoot {
    a = List.new;
    1027.do {|idx|
        var buf = Buffer.new(s);
        a.add(buf);
        idx.postln;
    }
};
sensestage commented 3 years ago

As the error trace is from the language, I suspect the issue is here in Server.sc (in my slightly older version of SC):

newBufferAllocators {
        var bufferOffset;
        var offset = this.calcOffset;
        var n = options.maxLogins ? 1;
        var numBuffers = options.numBuffers div: n;
        bufferOffset = numBuffers * offset + options.reservedNumBuffers;
        bufferAllocator =
        ContiguousBlockAllocator.new(numBuffers, bufferOffset);
    }

The number of available buffers is divided by the number of possible logins. What is your s.options.maxLogins?

giuliomoro commented 3 years ago

we use various different values in our examples

Bela/examples/SuperCollider//7-remote-control/remote.scd:s.options.maxLogins = 4; // should match the settings on the Bela
Bela/examples/SuperCollider//7-remote-control/_main.scd:s.options.maxLogins = 4;
Bela/examples/SuperCollider//6-pattern-control/_main.scd:s.options.maxLogins = 8;      // set max number of clients
Bela/examples/SuperCollider//2-digital-in/_main.scd:s.options.maxLogins = 16;      // set max number of clients
Bela/examples/SuperCollider//1-digital-out/_main.scd:s.options.maxLogins = 16;         // set max number of clients
Bela/examples/SuperCollider//4-analog-out/_main.scd:s.options.maxLogins = 16;      // set max number of clients
Bela/examples/SuperCollider//5-sample-scrub/_main.scd:s.options.maxLogins = 4;         // set max number of clients
Bela/examples/SuperCollider//3-analog-in/_main.scd:s.options.maxLogins = 16;       // set max number of clients
Bela/examples/SuperCollider//0-hello-sc/_main.scd:s.options.maxLogins = 4;
elgiano commented 3 years ago

I have tried it as well and I can confirm that the issue looks intended and is about s.options.maxLogins. With this setting, OP's example can count correctly to 255:

s.options.numBuffers = 256 * s.options.maxLogins;

I've tried also with 1024 buffers/login and it doesn't show any hard limit, counting correctly until 1023.

giuliomoro commented 3 years ago

This seems to require no further intervention from us. Closing it.