android: oboe driver error handling. Set buffer size to burst size
oboe: handle lost of audio and recording streams and attempt reopen. When using aaudio, set the oboe buffer size to the burst size. gui: really ignore AutomaticLatency for oboe driver Issue #182
This commit is contained in:
parent
6dfa9f7786
commit
5dd15e2942
|
@ -31,22 +31,35 @@ static cResetEvent pushWait;
|
|||
static std::shared_ptr<oboe::AudioStream> stream;
|
||||
static std::shared_ptr<oboe::AudioStream> recordStream;
|
||||
|
||||
static void audio_init();
|
||||
static void audio_term();
|
||||
|
||||
class AudioCallback : public oboe::AudioStreamDataCallback
|
||||
{
|
||||
public:
|
||||
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames)
|
||||
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) override
|
||||
{
|
||||
if (!ringBuffer.read((u8 *)audioData, numFrames * 4))
|
||||
// underrun
|
||||
memset(audioData, 0, numFrames * 4);
|
||||
else
|
||||
pushWait.Set();
|
||||
pushWait.Set();
|
||||
|
||||
return oboe::DataCallbackResult::Continue;
|
||||
}
|
||||
};
|
||||
static AudioCallback audioCallback;
|
||||
|
||||
class AudioErrorCallback : public oboe::AudioStreamErrorCallback
|
||||
{
|
||||
public:
|
||||
void onErrorAfterClose(oboe::AudioStream *stream, oboe::Result error) override {
|
||||
WARN_LOG(AUDIO, "Audio device lost. Attempting to reopen the audio stream");
|
||||
audio_term();
|
||||
audio_init();
|
||||
}
|
||||
};
|
||||
static AudioErrorCallback errorCallback;
|
||||
|
||||
static void audio_init()
|
||||
{
|
||||
// Actual capacity is size-1 to avoid overrun so add one buffer
|
||||
|
@ -61,15 +74,20 @@ static void audio_init()
|
|||
->setSampleRate(44100)
|
||||
->setFramesPerCallback(SAMPLE_COUNT)
|
||||
->setDataCallback(&audioCallback)
|
||||
->setErrorCallback(&errorCallback)
|
||||
->setUsage(oboe::Usage::Game)
|
||||
->openStream(stream);
|
||||
if (result != oboe::Result::OK)
|
||||
{
|
||||
ERROR_LOG(AUDIO, "Oboe open stream failed: %s", oboe::convertToText(result));
|
||||
return;
|
||||
}
|
||||
if (stream->getAudioApi() == oboe::AudioApi::AAudio)
|
||||
stream->setBufferSizeInFrames(stream->getFramesPerBurst());
|
||||
stream->requestStart();
|
||||
NOTICE_LOG(AUDIO, "Oboe driver started. stream capacity: %d frames, frames/callback: %d, frames/burst: %d",
|
||||
stream->getBufferCapacityInFrames(), stream->getFramesPerCallback(), stream->getFramesPerBurst());
|
||||
NOTICE_LOG(AUDIO, "Oboe driver started. stream capacity: %d frames, size: %d frames, frames/callback: %d, frames/burst: %d",
|
||||
stream->getBufferCapacityInFrames(), stream->getBufferSizeInFrames(),
|
||||
stream->getFramesPerCallback(), stream->getFramesPerBurst());
|
||||
}
|
||||
|
||||
static void audio_term()
|
||||
|
@ -125,8 +143,17 @@ static bool init_record(u32 sampling_freq)
|
|||
|
||||
static u32 record(void *data, u32 samples)
|
||||
{
|
||||
if (recordStream == nullptr)
|
||||
return 0;
|
||||
oboe::ResultWithValue<int32_t> result = recordStream->read(data, samples, 0);
|
||||
return result.value();
|
||||
if (result == oboe::Result::ErrorDisconnected)
|
||||
{
|
||||
WARN_LOG(AUDIO, "Recording device lost. Attempting to reopen the audio stream");
|
||||
u32 sampleRate = recordStream->getSampleRate();
|
||||
term_record();
|
||||
init_record(sampleRate);
|
||||
}
|
||||
return std::max(0, result.value());
|
||||
}
|
||||
|
||||
static audiobackend_t audiobackend_oboe = {
|
||||
|
|
|
@ -1402,7 +1402,8 @@ static void gui_display_settings()
|
|||
OptionCheckbox("Automatic Latency", config::AutoLatency,
|
||||
"Automatically set audio latency. Recommended");
|
||||
#endif
|
||||
if (!config::AutoLatency)
|
||||
if (!config::AutoLatency
|
||||
|| (config::AudioBackend.get() != "auto" && config::AudioBackend.get() != "android"))
|
||||
{
|
||||
int latency = (int)roundf(config::AudioBufferSize * 1000.f / 44100.f);
|
||||
ImGui::SliderInt("Latency", &latency, 12, 512, "%d ms");
|
||||
|
|
Loading…
Reference in New Issue