From 6c655321e6b04b8648802e296bb5ca11d290ae68 Mon Sep 17 00:00:00 2001 From: swurl Date: Sat, 31 May 2025 02:33:02 -0400 Subject: Move dead submodules in-tree Signed-off-by: swurl --- .../hello-oboe/src/main/cpp/HelloOboeEngine.cpp | 175 +++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 externals/oboe/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp (limited to 'externals/oboe/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp') diff --git a/externals/oboe/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp b/externals/oboe/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp new file mode 100644 index 0000000000..c27d5a419c --- /dev/null +++ b/externals/oboe/samples/hello-oboe/src/main/cpp/HelloOboeEngine.cpp @@ -0,0 +1,175 @@ +/** + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include + +#include + +#include "HelloOboeEngine.h" +#include "SoundGenerator.h" + + +/** + * Main audio engine for the HelloOboe sample. It is responsible for: + * + * - Creating a callback object which is supplied when constructing the audio stream, and will be + * called when the stream starts + * - Restarting the stream when user-controllable properties (Audio API, channel count etc) are + * changed, and when the stream is disconnected (e.g. when headphones are attached) + * - Calculating the audio latency of the stream + * + */ +HelloOboeEngine::HelloOboeEngine() + : mLatencyCallback(std::make_shared()), + mErrorCallback(std::make_shared(*this)) { +} + +double HelloOboeEngine::getCurrentOutputLatencyMillis() { + if (!mIsLatencyDetectionSupported) return -1.0; + + std::lock_guard lock(mLock); + if (!mStream) return -1.0; + + oboe::ResultWithValue latencyResult = mStream->calculateLatencyMillis(); + if (latencyResult) { + return latencyResult.value(); + } else { + LOGE("Error calculating latency: %s", oboe::convertToText(latencyResult.error())); + return -1.0; + } +} + +void HelloOboeEngine::setBufferSizeInBursts(int32_t numBursts) { + std::lock_guard lock(mLock); + if (!mStream) return; + + mLatencyCallback->setBufferTuneEnabled(numBursts == kBufferSizeAutomatic); + auto result = mStream->setBufferSizeInFrames( + numBursts * mStream->getFramesPerBurst()); + if (result) { + LOGD("Buffer size successfully changed to %d", result.value()); + } else { + LOGW("Buffer size could not be changed, %d", result.error()); + } +} + +bool HelloOboeEngine::isLatencyDetectionSupported() { + return mIsLatencyDetectionSupported; +} + +bool HelloOboeEngine::isAAudioRecommended() { + return oboe::AudioStreamBuilder::isAAudioRecommended(); +} + +void HelloOboeEngine::tap(bool isDown) { + if (mAudioSource) { + mAudioSource->tap(isDown); + } +} + +oboe::Result HelloOboeEngine::openPlaybackStream() { + oboe::AudioStreamBuilder builder; + oboe::Result result = builder.setSharingMode(oboe::SharingMode::Exclusive) + ->setPerformanceMode(oboe::PerformanceMode::LowLatency) + ->setFormat(oboe::AudioFormat::Float) + ->setFormatConversionAllowed(true) + ->setDataCallback(mLatencyCallback) + ->setErrorCallback(mErrorCallback) + ->setAudioApi(mAudioApi) + ->setChannelCount(mChannelCount) + ->setDeviceId(mDeviceId) + ->openStream(mStream); + if (result == oboe::Result::OK) { + mChannelCount = mStream->getChannelCount(); + } + return result; +} + +void HelloOboeEngine::restart() { + // The stream will have already been closed by the error callback. + mLatencyCallback->reset(); + start(); +} + +oboe::Result HelloOboeEngine::start(oboe::AudioApi audioApi, int deviceId, int channelCount) { + mAudioApi = audioApi; + mDeviceId = deviceId; + mChannelCount = channelCount; + return start(); +} + +oboe::Result HelloOboeEngine::start() { + std::lock_guard lock(mLock); + oboe::Result result = oboe::Result::OK; + // It is possible for a stream's device to become disconnected during the open or between + // the Open and the Start. + // So if it fails to start, close the old stream and try again. + int tryCount = 0; + do { + if (tryCount > 0) { + usleep(20 * 1000); // Sleep between tries to give the system time to settle. + } + mIsLatencyDetectionSupported = false; + result = openPlaybackStream(); + if (result == oboe::Result::OK) { + mAudioSource = std::make_shared(mStream->getSampleRate(), + mStream->getChannelCount()); + mLatencyCallback->setSource( + std::dynamic_pointer_cast(mAudioSource)); + + LOGD("Stream opened: AudioAPI = %d, channelCount = %d, deviceID = %d", + mStream->getAudioApi(), + mStream->getChannelCount(), + mStream->getDeviceId()); + + result = mStream->requestStart(); + if (result != oboe::Result::OK) { + LOGE("Error starting playback stream. Error: %s", oboe::convertToText(result)); + mStream->close(); + mStream.reset(); + } else { + mIsLatencyDetectionSupported = (mStream->getTimestamp((CLOCK_MONOTONIC)) != + oboe::Result::ErrorUnimplemented); + } + } else { + LOGE("Error creating playback stream. Error: %s", oboe::convertToText(result)); + } + } while (result != oboe::Result::OK && tryCount++ < 3); + return result; +} + +oboe::Result HelloOboeEngine::stop() { + oboe::Result result = oboe::Result::OK; + // Stop, close and delete in case not already closed. + std::lock_guard lock(mLock); + if (mStream) { + result = mStream->stop(); + mStream->close(); + mStream.reset(); + } + return result; +} + +oboe::Result HelloOboeEngine::reopenStream() { + if (mStream) { + stop(); + return start(); + } else { + return oboe::Result::OK; + } +} -- cgit v1.2.3