Android oboe::StabilizedCallback

How should I implement oboe::StabilizedCallback ?
My understanding is that I should modify juce_android_oboe.cpp but I can’t figure out how to do this. I’m not so comfortable with hacking the JUCE code.

I’m hoping that this will solve a CPU scaling issue on android which I believe is causing the audio glitching issues on some devices when not touching the screen. This only seems to occur on higher end devices such as the Galaxy S9.

Thanks !

1 Like


1 Like

I opened an issue that implementation of stabilzedCallback is missing and glitches are produced:

1 Like

@Don_Turner are you aware of any JUCE implementation of stabilzedCallback?

Now that the VST is released for my app (spacecraft granular synth) I have returned my attention to the Android version. The only thing that’s stopping me from releasing this right now is the dreaded CPU scaling that only happens on a subset of devices. I’m finding that a low-cost basic device such as Xiaomi Mi is able to run my app flawlessly, but a powerful flagship such as the Note 8 has audio glitches which are corelated to downward spikes in the CPU frequency (I’ve ruled out GUI/resolution as the culprit).

After lots of optimisation of the DSP, one of the last remaining possible fixes for this that I’m aware of is the Oboe ‘StabilizedCallback’, thanks to @donturner for pointing me in the right direction. After many failed attempts, I’ve finally managed to get this to work (I think) in JUCE.

Here’s my implementation (modifications to juce_android_Oboe.cpp). Note that this is just a prototype implementation with a standard pointer, I still need to figure out what happens with object destruction and whether or not smart pointers are needed (any suggestions welcome).

Declaration of a pointer to an AudioStreamCallback object in the OboeStream class:

oboe::AudioStreamCallback * asc;

Replace this line of code in the same class…

builder.setCallback (callback); 


if ( callback != NULL ) 
    asc = new oboe::StabilizedCallback(callback); 
    builder.setCallback (asc); 
    builder.setCallback (callback); 

Jucer config:

  • Release build
  • Link-time optimisation enabled
  • Optimisation: Ofast
  • Oboe release v1.2.0

By adding the check for NULL I can finally run my app without crashing on start-up. The stabilized callback appears to be working; however, although as the cpu frequency profile and audio glitches appear to be improved, there are still sporadic drops in cpu freq and corresponding audio dropouts. Saying that, there is a huge number of settings (such as optimisation settings in jucer etc.) that I need to try before it can be conclusive.

So, I have a couple of questions going forward for @donturner.

Firstly, I notice that in StabilizedCallback.cpp there are some hardcoded parameters:

constexpr int32_t kLoadGenerationStepSizeNanos = 20000;
constexpr float kPercentageOfCallbackToUse = 0.8;

Can these parameters be thought of as tuning parameters for the stabilized callback? If I increase those numbers, does the stabilized callback become more ‘stabilisy’? If so, do you have any guidelines for tuning (max limits etc.)?

Secondly, in the scenario that the StabilizedCallback alone does not fix the issue, an additional modification could be for Oboe to use a larger buffer (latency is not so important in my app as it’s predominantly generative). Perhaps this, in combination with the StabilizedCallback, would help me find a sweet spot which would eliminate dropouts on my Galaxy Note 8. Questions relating to this:

  1. What is the proper way to increase the buffer size in Oboe? I’ve tried changing oboe::PerformanceMode::LowLatency to oboe::PerformanceMode::None or oboe::PerformanceMode::PowerSaving however, this results in very large audio dropouts (even with a barebones hello world JUCE app generating a sine wave)
  2. If buffer size modifications are possible, how could I control this within my app? (this might be more a question for the JUCE devs)


Hi there. I’m having exactly same issue with Android app - I’m getting glitched playback on Note 8, but everything goes smoothly on cheaper devices. I’m aware that the problem is related to CPU scaling. I’ve tried to modify juce_android_Oboe.cpp as @MarkWatt recommended but still the same. Is there anything else i’m missing? Are there any plans about integrating this implementation to official Juce release, or at least develop branch?

@Don_Turner, in this article you are pointing bug related to optimization flags. Is it solved in latest Android Studio / NDK? Can I be sure that if i’m setting Ofast in Projucer it is taken into account by CMake? Any other advices from you?