OpenSLES audio device latency calculation bug (with fix)


#1

For certain devices, reporting a large minBufferSize, it can lead to an integer arithmetic overflow. Changing the code in the constructor to:


    OpenSLAudioIODevice (const String& deviceName)
        : AudioIODevice (deviceName, openSLTypeName),
          Thread ("OpenSL"),
          callback (nullptr), sampleRate (0), deviceOpen (false),
          inputBuffer (2, 2), outputBuffer (2, 2)
    {
        // OpenSL has piss-poor support for determining latency, so the only way I can find to
        // get a number for this is by asking the AudioTrack/AudioRecord classes..
        AndroidAudioIODevice javaDevice (String::empty);
        // this is a total guess about how to calculate the latency, but seems to vaguely agree
        // with the devices I've tested.. YMMV
        inputLatency  = ((javaDevice.minBufferSizeIn  * 2) / 3);
        outputLatency = ((javaDevice.minBufferSizeOut * 2) / 3);
        const int64 longestLatency = jmax (inputLatency, outputLatency);
        const int64 totalLatency = inputLatency + outputLatency;
        inputLatency  = (int)((longestLatency * inputLatency)  / totalLatency) & ~15;
        outputLatency = (int)((longestLatency * outputLatency) / totalLatency) & ~15;
    }

fixes this.

 


#2

Wow, those must be some huge buffer sizes! Thanks for the heads-up, I'll change that!


#3

Yep, the buffer size on the output was 77824 bytes (with a Bluetooth speaker). Speaking of which... I don't know really how to decipher the latency calculations :)

With 77824 bytes stereo 16 bit, it would amount to 19456 samples ~ 0.4 s output latency @48000 sample rate, which seems reasonable for a BT unit.