Git Product home page Git Product logo

Comments (13)

philburk avatar philburk commented on May 3, 2024

Thanks for asking. The Thread Safety section is pretty confusing. Some of it is inaccurate. Oboe does use some mutexes for non-time-critical functions like start()/stop().

There are some things you CAN do.

  • You can call AudioStream::stop(), requestStop() , pause() or requestPause() from an application thread while a callback is running in a system thread. That will stop the callback thread.

  • You can call AudioStream::close() from an application thread while a callback is running in a system thread. It will stop the callback before closing or deleting any stream resources.

There are some things you CANNOT do.

  • Never call AudioStream::stop(), requestStop() , pause(), requestPause() or close() from a callback method. Return oboe::DataCallbackResult::Stop if you want the callback to stop.

  • Never call AudioStream::read() or AudioStream::write() on a stream from that stream's own callback method. You should use the audioData array instead. You can read() or write() another stream from a callback as long as that stream does not have an active callback. We recommend that if you have data flowing between multiple streams then only one of them should use a callback.

In general you should only modify the stream from one application thread. From the callback methods try to only use get*() methods.

Please ask more questions. When we have an explanation that makes sense then we will update the docs.

from oboe.

svenoaks avatar svenoaks commented on May 3, 2024

Thanks, what about getBufferSizeInFrames() calling which could be concurrent with the LatencyTuner->tune() in the callback?

from oboe.

philburk avatar philburk commented on May 3, 2024

You can safely call getBufferSizeInFrames() from as many threads as you want. You may be sampling a changing value. So only use the information for non-critical purposes, such as a fullness display.

Only call setBufferSizeInFrames() from one thread. So if latency tuning is active in the callback, do not call it from the application.

from oboe.

svenoaks avatar svenoaks commented on May 3, 2024

Thanks. As far as I understand, getBufferSizeInFrames() is an ever increasing value, then should become stable when it's no longer possible to glitch the audio. I'm saving this value in SharedPreferences for use in next session so it won't have to retune, exposing user to audio glitches again. Is there a recommended setting for bufferSizeInFrames to prevent glitching to start with, I'm finding it often shoots up to 4 or more times framesPerBurst.

from oboe.

svenoaks avatar svenoaks commented on May 3, 2024

Thinking aloud and off-topic - wouldn't it be good if LatencyTuner had a mode where it started from the maximum buffer size and worked down for some initial period of time like a minute, stopping lowering when it encounters drop-outs, then worked like it does currently, raising back up. That way user wouldn't be presented with lots of static when first opening an app, which can happen if there is heavy CPU load. I suppose this could be implemented in application too, but more suitable within LatencyTuner.

from oboe.

philburk avatar philburk commented on May 3, 2024

As far as I understand, getBufferSizeInFrames() is an ever increasing value, then should
become stable when it's no longer possible to glitch the audio.

Not necessarily. It depends on the latency tuning algorithm. Suppose a glitch was caused by some transient activity. After a while it may be safe to lower the latency again. Some apps might be willing to risk a glitch in order to minimize latency. Some apps will not want to take that risk. This is why we left the tuning out of the OS. Apps can decide.

An app can calculate output buffer fullness as framesWritten minus framesRead.
If the buffer stays relatively full for a long time then an app might decide it is safe to lower the buffer size back down.

I'm saving this value in SharedPreferences for use in next session so it won't have to retune

Excellent. We hoped that apps would do that.

Is there a recommended setting for bufferSizeInFrames to prevent glitching to start
with, I'm finding it often shoots up to 4 or more times framesPerBurst.

The behavior can vary a lot by device.

wouldn't it be good if LatencyTuner had a mode where it started from the maximum buffer size

That could be a good strategy for some apps. But some apps, synthesizers for example, are often silent for a few seconds before the user starts playing. That is a good time for the LatencyTuner to glitch because the glitches are inaudible.

We encourage app developers to customize the LatencyTuner for their own purposes. And please share your experience.

Also please let use know if you post any apps in the Play Store. We can then use it for testing the OS.

from oboe.

svenoaks avatar svenoaks commented on May 3, 2024

I was planning on rolling out update https://play.google.com/store/apps/details?id=com.smp.musicspeed with Oboe as the default sound output this weekend. I was a little hesitant because it is developer preview, but it seems to be behaving perfectly so far. My use is simple, only an output stream. I wanted to start using AAudio as soon as possible. Do you think it is relatively safe to use for production? I was thinking the preview aspects of it would be obvious things like unimplemented functions.

from oboe.

philburk avatar philburk commented on May 3, 2024

Do you think it is relatively safe to use for production?

Until you filed #40, I would have said yes. We are now investigating that as a high priority.

Let's leave this open until we clarify the thread safety issues in the docs.

from oboe.

dturner avatar dturner commented on May 3, 2024

Any update here @philburk?

from oboe.

philburk avatar philburk commented on May 3, 2024

#40 has been addressed by not using AAudio on 8.0.

We need to add the restrictions and caveats from this discussion to the autodocs for AudioStreamCallback. Then reference those restrictions in AudioStreamBuilder::setCallback() docs. Then we can close this.

from oboe.

dturner avatar dturner commented on May 3, 2024

AI: Clarify this in the docs

from oboe.

dturner avatar dturner commented on May 3, 2024

Phil to update docs. Don to regenerate API reference.

from oboe.

dturner avatar dturner commented on May 3, 2024

Docs have been updated, specifically here: file:///Users/donturner/Code/workspace-android/oboe/docs/reference/classoboe_1_1_audio_stream_callback.html

from oboe.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.