roc-toolkit
roc-toolkit copied to clipboard
Android / Oboe sink and source
Last revised: Oct 2023
Currently our Android support lacks audio I/O support. For now this is good because C library does not do I/O yet, and CLI tools, which do I/O, are not needed on Android. However later we'll need to add I/O capabilities to the C library as well.
The recommended way for doing audio I/O in C++ on Android is Oboe library, which under the hood uses either AAudio or OpenSL ES.
We'll need to add target_oboe
target directory to roc_sndio with three new classes:
- OboeSink
- OboeSource
- OboeBackend
(OboeSink and OboeSource will probably be similar; in this case we can extract a helper or a base class).
And then we should register OboeBackend in sndio::BackendDispatcher.
The overall structure will be similar to roc_sndio/target_pulseaudio.
Some notes:
- we likely should use Oboe callback mode, which provides a lower latency;
- we should also implement onErrorAfterClose callback and restart stream if it's disconnected;
- we should use oboe::PerformanceMode::LowLatency and oboe::InputPreset::Unprocessed modes;
- we should ensure to perform resampling only once: either in Oboe or in Roc; so if resampling is enabled in Roc, it should be disabled in Oboe, and vice versa.
As a first step we can test the new sink and source using roc-send and roc-recv command-line tools running under Termux. That is still not convenient for the user, but is easier to start with.
Further info:
- #222 describes how to build Roc in Termux
- #231 is similar to this issue, but for ALSA backend
- #251 provides an overview of roc_sndio concepts
- #246 provides instructions for adding new audio backend
This issue will also allow to decrease latency in roc-droid, if we move I/O completely into roc.