xref: /aosp_15_r20/external/oboe/docs/FAQ.md (revision 05767d913155b055644481607e6fa1e35e2fe72c)
1*05767d91SRobert Wu# Frequently Asked Questions (FAQ)
2*05767d91SRobert Wu
3*05767d91SRobert Wu## Can I write audio data from Java/Kotlin to Oboe?
4*05767d91SRobert Wu
5*05767d91SRobert WuOboe is a native library written in C++ which uses the Android NDK. To move data from Java to C++ you can use [JNI](https://developer.android.com/training/articles/perf-jni).
6*05767d91SRobert Wu
7*05767d91SRobert WuIf you're generating audio data in Java or Kotlin you should consider whether the reduced latency which Oboe gives you (particularly on high-end devices) is worth the extra complexity of passing data via JNI. An alternative is to use [Java AudioTrack](https://developer.android.com/reference/android/media/AudioTrack). This can be created with low latency using the AudioTrack.Builder method [`setPerformanceMode(AudioTrack.PERFORMANCE_MODE_LOW_LATENCY)`](https://developer.android.com/reference/android/media/AudioTrack#PERFORMANCE_MODE_LOW_LATENCY).
8*05767d91SRobert Wu
9*05767d91SRobert WuYou can dynamically tune the latency of the stream just like in Oboe using [`setBufferSizeInFrames(int)`](https://developer.android.com/reference/android/media/AudioTrack.html#setBufferSizeInFrames(int))
10*05767d91SRobert WuAlso you can use blocking writes with the Java AudioTrack and still get a low latency stream.
11*05767d91SRobert WuOboe requires a data callback to get a low latency stream and that does not work well with Java.
12*05767d91SRobert Wu
13*05767d91SRobert WuNote that [`AudioTrack.PERFORMANCE_MODE_LOW_LATENCY`](https://developer.android.com/reference/android/media/AudioTrack#PERFORMANCE_MODE_LOW_LATENCY) was added in API 26, For API 24 or 25 use [`AudioAttributes.FLAG_LOW_LATENCY`](https://developer.android.com/reference/kotlin/android/media/AudioAttributes#flag_low_latency). That was deprecated but will still work with later APIs.
14*05767d91SRobert Wu
15*05767d91SRobert Wu## Can I use Oboe to play compressed audio files, such as MP3 or AAC?
16*05767d91SRobert WuOboe only works with PCM data. It does not include any extraction or decoding classes. However, the [RhythmGame sample](https://github.com/google/oboe/tree/main/samples/RhythmGame) includes extractors for both NDK and FFmpeg.
17*05767d91SRobert Wu
18*05767d91SRobert WuFor more information on using FFmpeg in your app [check out this article](https://medium.com/@donturner/using-ffmpeg-for-faster-audio-decoding-967894e94e71).
19*05767d91SRobert Wu
20*05767d91SRobert Wu## Android Studio doesn't find the Oboe symbols, how can I fix this?
21*05767d91SRobert WuStart by ensuring that your project builds successfully. The main thing to do is ensure that the Oboe include paths are set correctly in your project's `CMakeLists.txt`. [Full instructions here](https://github.com/google/oboe/blob/main/docs/GettingStarted.md#2-update-cmakeliststxt).
22*05767d91SRobert Wu
23*05767d91SRobert WuIf that doesn't fix it try the following:
24*05767d91SRobert Wu
25*05767d91SRobert Wu1) Invalidate the Android Studio cache by going to File->Invalidate Caches / Restart
26*05767d91SRobert Wu2) Delete the contents of `$HOME/Library/Caches/AndroidStudio<version>`
27*05767d91SRobert Wu
28*05767d91SRobert WuWe have had several reports of this happening and are keen to understand the root cause. If this happens to you please file an issue with your Android Studio version and we'll investigate further.
29*05767d91SRobert Wu
30*05767d91SRobert Wu## I requested a stream with `PerformanceMode::LowLatency`, but didn't get it. Why not?
31*05767d91SRobert WuUsually if you call `builder.setPerformanceMode(PerformanceMode::LowLatency)` and don't specify other stream properties you will get a `LowLatency` stream. The most common reasons for not receiving one are:
32*05767d91SRobert Wu
33*05767d91SRobert Wu- You are opening an output stream and did not specify a **data callback**.
34*05767d91SRobert Wu- You requested a **sample** rate which does not match the audio device's native sample rate. For playback streams, this means the audio data you write into the stream must be resampled before it's sent to the audio device. For recording streams, the  audio data must be resampled before you can read it. In both cases the resampling process (performed by the Android audio framework) adds latency and therefore providing a `LowLatency` stream is not possible. To avoid the resampler on API 26 and below you can specify a default value for the sample rate [as detailed here](https://github.com/google/oboe/blob/main/docs/GettingStarted.md#obtaining-optimal-latency).  Or you can enable sample rate conversion by calling [AudioStreamBuilder::setSampleRateConversionQuality()](https://google.github.io/oboe/classoboe_1_1_audio_stream_builder.html#a0c98d21da654da6d197b004d29d8499c) in Oboe, which allows the lower level code to run at the optimal rate and provide lower latency.
35*05767d91SRobert Wu- If you request **AudioFormat::Float on an Input** stream before Android 9.0 then you will **not** get a FAST track. You need to either request AudioFormat::Int16 or enable format conversion by calling [AudioStreamBuilder::setFormatConversionAllowed()](https://google.github.io/oboe/classoboe_1_1_audio_stream_builder.html#aa30150d2d0b3c925b545646962dffca0) in Oboe.
36*05767d91SRobert Wu- The audio **device** does not support `LowLatency` streams, for example Bluetooth.
37*05767d91SRobert Wu- You requested a **channel count** which is not supported natively by the audio device. On most devices and Android API levels it is possible to obtain a `LowLatency` stream for both mono and stereo, however, there are a few exceptions, some of which are listed [here](https://github.com/google/oboe/blob/main/docs/AndroidAudioHistory.md).
38*05767d91SRobert Wu- The **maximum number** of `LowLatency` streams has been reached. This could be by your app, or by other apps. This is often caused by opening multiple playback streams for different "tracks". To avoid this open a single audio stream and perform
39*05767d91SRobert Wuyour own mixing in the app.
40*05767d91SRobert Wu- You are on Android 7.0 or below and are receiving `PerformanceMode::None`. The ability to query the performance mode of a stream was added in Android 7.1 (Nougat MR1). Low latency streams (aka FAST tracks) _are available_ on Android 7.0 and below but there is no programmatic way of knowing whether yours is one. [Question on StackOverflow](https://stackoverflow.com/questions/56828501/does-opensl-es-support-performancemodelowlatency/5683499)
41*05767d91SRobert Wu
42*05767d91SRobert Wu## My question isn't listed, where can I ask it?
43*05767d91SRobert WuPlease ask questions on [Stack Overflow](https://stackoverflow.com/questions/ask) with the [Oboe tag](https://stackoverflow.com/tags/oboe) or in the GitHub Issues tab.
44