diff options
| author | swurl <swurl@swurl.xyz> | 2025-05-31 02:33:02 -0400 |
|---|---|---|
| committer | swurl <swurl@swurl.xyz> | 2025-05-31 02:33:02 -0400 |
| commit | 6c655321e6b04b8648802e296bb5ca11d290ae68 (patch) | |
| tree | 5c906511e4a2910ce8b806bb9d763b524c28619e /externals/oboe/samples/hello-oboe/src/main/cpp | |
| parent | c0cceff365f754f8859f4c9a0362ebdba7ea388b (diff) | |
Move dead submodules in-tree
Signed-off-by: swurl <swurl@swurl.xyz>
Diffstat (limited to 'externals/oboe/samples/hello-oboe/src/main/cpp')
8 files changed, 641 insertions, 0 deletions
diff --git a/externals/oboe/samples/hello-oboe/src/main/cpp/CMakeLists.txt b/externals/oboe/samples/hello-oboe/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000..48fc94ef5e --- /dev/null +++ b/externals/oboe/samples/hello-oboe/src/main/cpp/CMakeLists.txt @@ -0,0 +1,60 @@ +# +# 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. +# + +cmake_minimum_required(VERSION 3.4.1) + +### INCLUDE OBOE LIBRARY ### + +# Set the path to the Oboe library directory +set (OBOE_DIR ../../../../../) + +# Add the Oboe library as a subproject. Since Oboe is an out-of-tree source library we must also +# specify a binary directory +add_subdirectory(${OBOE_DIR} ./oboe-bin) + +# Include the Oboe headers and shared sample code +include_directories(${OBOE_DIR}/include ${OBOE_DIR}/samples/shared) + +# Debug utilities +set (DEBUG_UTILS_PATH "${OBOE_DIR}/samples/debug-utils") +set (DEBUG_UTILS_SOURCES ${DEBUG_UTILS_PATH}/trace.cpp) +include_directories(${DEBUG_UTILS_PATH}) + + +### END OBOE INCLUDE SECTION ### + + +# App specific sources +set (APP_SOURCES + jni_bridge.cpp + HelloOboeEngine.cpp + SoundGenerator.cpp + LatencyTuningCallback.cpp +) + +# Build the libhello-oboe library +add_library(hello-oboe SHARED + ${DEBUG_UTILS_SOURCES} + ${APP_SOURCES} + ) + +# Specify the libraries needed for hello-oboe +target_link_libraries(hello-oboe android log oboe) +target_link_options(hello-oboe PRIVATE "-Wl,-z,max-page-size=16384") + +# Enable optimization flags: if having problems with source level debugging, +# disable -Ofast ( and debug ), re-enable after done debugging. +target_compile_options(hello-oboe PRIVATE -Wall -Werror "$<$<CONFIG:RELEASE>:-Ofast>") 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 <inttypes.h> +#include <memory> + +#include <Oscillator.h> + +#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<LatencyTuningCallback>()), + mErrorCallback(std::make_shared<DefaultErrorCallback>(*this)) { +} + +double HelloOboeEngine::getCurrentOutputLatencyMillis() { + if (!mIsLatencyDetectionSupported) return -1.0; + + std::lock_guard<std::mutex> lock(mLock); + if (!mStream) return -1.0; + + oboe::ResultWithValue<double> 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<std::mutex> 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<std::mutex> 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<SoundGenerator>(mStream->getSampleRate(), + mStream->getChannelCount()); + mLatencyCallback->setSource( + std::dynamic_pointer_cast<IRenderableAudio>(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<std::mutex> 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; + } +} diff --git a/externals/oboe/samples/hello-oboe/src/main/cpp/HelloOboeEngine.h b/externals/oboe/samples/hello-oboe/src/main/cpp/HelloOboeEngine.h new file mode 100644 index 0000000000..ea535b15ef --- /dev/null +++ b/externals/oboe/samples/hello-oboe/src/main/cpp/HelloOboeEngine.h @@ -0,0 +1,95 @@ +/* + * 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. + */ + +#ifndef OBOE_HELLO_OBOE_ENGINE_H +#define OBOE_HELLO_OBOE_ENGINE_H + +#include <oboe/Oboe.h> + +#include "SoundGenerator.h" +#include "LatencyTuningCallback.h" +#include "IRestartable.h" +#include "DefaultErrorCallback.h" + +constexpr int32_t kBufferSizeAutomatic = 0; + +class HelloOboeEngine : public IRestartable { + +public: + HelloOboeEngine(); + + virtual ~HelloOboeEngine() = default; + + void tap(bool isDown); + + /** + * Open and start a stream. + * @param deviceId the audio device id, can be obtained through an {@link AudioDeviceInfo} object + * using Java/JNI. + * @return error or OK + */ + oboe::Result start(oboe::AudioApi audioApi, int deviceId, int channelCount); + /* Start using current settings. */ + oboe::Result start(); + + /** + * Stop and close the stream. + */ + oboe::Result stop(); + + // From IRestartable + void restart() override; + + void setBufferSizeInBursts(int32_t numBursts); + + /** + * Calculate the current latency between writing a frame to the output stream and + * the same frame being presented to the audio hardware. + * + * Here's how the calculation works: + * + * 1) Get the time a particular frame was presented to the audio hardware + * @see AudioStream::getTimestamp + * 2) From this extrapolate the time which the *next* audio frame written to the stream + * will be presented + * 3) Assume that the next audio frame is written at the current time + * 4) currentLatency = nextFramePresentationTime - nextFrameWriteTime + * + * @return Output Latency in Milliseconds + */ + double getCurrentOutputLatencyMillis(); + + bool isLatencyDetectionSupported(); + + bool isAAudioRecommended(); + +private: + oboe::Result reopenStream(); + oboe::Result openPlaybackStream(); + + std::shared_ptr<oboe::AudioStream> mStream; + std::shared_ptr<LatencyTuningCallback> mLatencyCallback; + std::shared_ptr<DefaultErrorCallback> mErrorCallback; + std::shared_ptr<SoundGenerator> mAudioSource; + bool mIsLatencyDetectionSupported = false; + + int32_t mDeviceId = oboe::Unspecified; + int32_t mChannelCount = oboe::Unspecified; + oboe::AudioApi mAudioApi = oboe::AudioApi::Unspecified; + std::mutex mLock; +}; + +#endif //OBOE_HELLO_OBOE_ENGINE_H diff --git a/externals/oboe/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.cpp b/externals/oboe/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.cpp new file mode 100644 index 0000000000..7d53c43047 --- /dev/null +++ b/externals/oboe/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.cpp @@ -0,0 +1,45 @@ +/** + * 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 "LatencyTuningCallback.h" + +oboe::DataCallbackResult LatencyTuningCallback::onAudioReady( + oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) { + if (oboeStream != mStream) { + mStream = oboeStream; + mLatencyTuner = std::make_unique<oboe::LatencyTuner>(*oboeStream); + } + if (mBufferTuneEnabled + && mLatencyTuner + && oboeStream->getAudioApi() == oboe::AudioApi::AAudio) { + mLatencyTuner->tune(); + } + auto underrunCountResult = oboeStream->getXRunCount(); + int bufferSize = oboeStream->getBufferSizeInFrames(); + /** + * The following output can be seen by running a systrace. Tracing is preferable to logging + * inside the callback since tracing does not block. + * + * See https://developer.android.com/studio/profile/systrace-commandline.html + */ + if (Trace::isEnabled()) Trace::beginSection("numFrames %d, Underruns %d, buffer size %d", + numFrames, underrunCountResult.value(), bufferSize); + auto result = DefaultDataCallback::onAudioReady(oboeStream, audioData, numFrames); + if (Trace::isEnabled()) Trace::endSection(); + return result; +} + + diff --git a/externals/oboe/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.h b/externals/oboe/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.h new file mode 100644 index 0000000000..16051546e9 --- /dev/null +++ b/externals/oboe/samples/hello-oboe/src/main/cpp/LatencyTuningCallback.h @@ -0,0 +1,67 @@ +/** + * 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. + */ + + +#ifndef SAMPLES_LATENCY_TUNING_CALLBACK_H +#define SAMPLES_LATENCY_TUNING_CALLBACK_H + +#include <oboe/Oboe.h> +#include <oboe/LatencyTuner.h> + +#include <TappableAudioSource.h> +#include <DefaultDataCallback.h> +#include <trace.h> + +/** + * This callback object extends the functionality of `DefaultDataCallback` by automatically + * tuning the latency of the audio stream. @see onAudioReady for more details on this. + * + * It also demonstrates how to use tracing functions for logging inside the audio callback without + * blocking. + */ +class LatencyTuningCallback: public DefaultDataCallback { +public: + LatencyTuningCallback() : DefaultDataCallback() { + + // Initialize the trace functions, this enables you to output trace statements without + // blocking. See https://developer.android.com/studio/profile/systrace-commandline.html + Trace::initialize(); + } + + /** + * Every time the playback stream requires data this method will be called. + * + * @param audioStream the audio stream which is requesting data, this is the mPlayStream object + * @param audioData an empty buffer into which we can write our audio data + * @param numFrames the number of audio frames which are required + * @return Either oboe::DataCallbackResult::Continue if the stream should continue requesting data + * or oboe::DataCallbackResult::Stop if the stream should stop. + */ + oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override; + + void setBufferTuneEnabled(bool enabled) {mBufferTuneEnabled = enabled;} + + void useStream(std::shared_ptr<oboe::AudioStream> stream); + +private: + bool mBufferTuneEnabled = true; + + // This will be used to automatically tune the buffer size of the stream, obtaining optimal latency + std::unique_ptr<oboe::LatencyTuner> mLatencyTuner; + oboe::AudioStream *mStream = nullptr; +}; + +#endif //SAMPLES_LATENCY_TUNING_CALLBACK_H diff --git a/externals/oboe/samples/hello-oboe/src/main/cpp/SoundGenerator.cpp b/externals/oboe/samples/hello-oboe/src/main/cpp/SoundGenerator.cpp new file mode 100644 index 0000000000..1de9030f28 --- /dev/null +++ b/externals/oboe/samples/hello-oboe/src/main/cpp/SoundGenerator.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2018 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 "SoundGenerator.h" + +SoundGenerator::SoundGenerator(int32_t sampleRate, int32_t channelCount) : + TappableAudioSource(sampleRate, channelCount) + , mOscillators(std::make_unique<Oscillator[]>(channelCount)){ + + double frequency = 440.0; + constexpr double interval = 110.0; + constexpr float amplitude = 1.0; + + // Set up the oscillators + for (int i = 0; i < mChannelCount; ++i) { + mOscillators[i].setFrequency(frequency); + mOscillators[i].setSampleRate(mSampleRate); + mOscillators[i].setAmplitude(amplitude); + frequency += interval; + } +} + +void SoundGenerator::renderAudio(float *audioData, int32_t numFrames) { + // Render each oscillator into its own channel + std::fill_n(mBuffer.get(), kSharedBufferSize, 0); + for (int i = 0; i < mChannelCount; ++i) { + mOscillators[i].renderAudio(mBuffer.get(), numFrames); + for (int j = 0; j < numFrames; ++j) { + audioData[(j * mChannelCount) + i] = mBuffer[j]; + } + } +} + +void SoundGenerator::tap(bool isOn) { + for (int i = 0; i < mChannelCount; ++i) { + mOscillators[i].setWaveOn(isOn); + } +} diff --git a/externals/oboe/samples/hello-oboe/src/main/cpp/SoundGenerator.h b/externals/oboe/samples/hello-oboe/src/main/cpp/SoundGenerator.h new file mode 100644 index 0000000000..1ffae37f0f --- /dev/null +++ b/externals/oboe/samples/hello-oboe/src/main/cpp/SoundGenerator.h @@ -0,0 +1,58 @@ +/* + * Copyright 2018 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. + */ + +#ifndef SAMPLES_SOUNDGENERATOR_H +#define SAMPLES_SOUNDGENERATOR_H + + +#include <Oscillator.h> +#include <TappableAudioSource.h> + +/** + * Generates a fixed frequency tone for each channel. + * Implements RenderableTap (sound source with toggle) which is required for AudioEngines. + */ +class SoundGenerator : public TappableAudioSource { + static constexpr size_t kSharedBufferSize = 1024; +public: + /** + * Create a new SoundGenerator object. + * + * @param sampleRate - The output sample rate. + * @param maxFrames - The maximum number of audio frames which will be rendered, this is used to + * calculate this object's internal buffer size. + * @param channelCount - The number of channels in the output, one tone will be created for each + * channel, the output will be interlaced. + * + */ + SoundGenerator(int32_t sampleRate, int32_t channelCount); + ~SoundGenerator() = default; + + SoundGenerator(SoundGenerator&& other) = default; + SoundGenerator& operator= (SoundGenerator&& other) = default; + + // Switch the tones on + void tap(bool isOn) override; + + void renderAudio(float *audioData, int32_t numFrames) override; + +private: + std::unique_ptr<Oscillator[]> mOscillators; + std::unique_ptr<float[]> mBuffer = std::make_unique<float[]>(kSharedBufferSize); +}; + + +#endif //SAMPLES_SOUNDGENERATOR_H diff --git a/externals/oboe/samples/hello-oboe/src/main/cpp/jni_bridge.cpp b/externals/oboe/samples/hello-oboe/src/main/cpp/jni_bridge.cpp new file mode 100644 index 0000000000..8d049c5aee --- /dev/null +++ b/externals/oboe/samples/hello-oboe/src/main/cpp/jni_bridge.cpp @@ -0,0 +1,90 @@ +/* + * 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 <jni.h> +#include <oboe/Oboe.h> +#include "HelloOboeEngine.h" +#include "logging_macros.h" + +extern "C" { +/* We only need one HelloOboeEngine and it is needed for the entire time. + * So just allocate one statically. */ +static HelloOboeEngine sEngine; + +JNIEXPORT jint JNICALL +Java_com_google_oboe_samples_hellooboe_PlaybackEngine_startEngine( + JNIEnv *env, + jclass, + int audioApi, int deviceId, int channelCount) { + return static_cast<jint>(sEngine.start((oboe::AudioApi)audioApi, deviceId, channelCount)); +} + +JNIEXPORT jint JNICALL +Java_com_google_oboe_samples_hellooboe_PlaybackEngine_stopEngine( + JNIEnv *env, + jclass) { + return static_cast<jint>(sEngine.stop()); +} + +JNIEXPORT void JNICALL +Java_com_google_oboe_samples_hellooboe_PlaybackEngine_setToneOn( + JNIEnv *env, + jclass, + jboolean isToneOn) { + + sEngine.tap(isToneOn); +} + + +JNIEXPORT void JNICALL +Java_com_google_oboe_samples_hellooboe_PlaybackEngine_setBufferSizeInBursts( + JNIEnv *env, + jclass, + jint bufferSizeInBursts) { + sEngine.setBufferSizeInBursts(bufferSizeInBursts); +} + +JNIEXPORT jdouble JNICALL +Java_com_google_oboe_samples_hellooboe_PlaybackEngine_getCurrentOutputLatencyMillis( + JNIEnv *env, + jclass) { + return static_cast<jdouble>(sEngine.getCurrentOutputLatencyMillis()); +} + +JNIEXPORT jboolean JNICALL +Java_com_google_oboe_samples_hellooboe_PlaybackEngine_isLatencyDetectionSupported( + JNIEnv *env, + jclass) { + return (sEngine.isLatencyDetectionSupported() ? JNI_TRUE : JNI_FALSE); +} + +JNIEXPORT jboolean JNICALL +Java_com_google_oboe_samples_hellooboe_PlaybackEngine_isAAudioRecommended( + JNIEnv *env, + jclass) { + return (sEngine.isAAudioRecommended() ? JNI_TRUE : JNI_FALSE); +} + +JNIEXPORT void JNICALL +Java_com_google_oboe_samples_hellooboe_PlaybackEngine_setDefaultStreamValues( + JNIEnv *env, + jclass, + jint sampleRate, + jint framesPerBurst) { + oboe::DefaultStreamValues::SampleRate = (int32_t) sampleRate; + oboe::DefaultStreamValues::FramesPerBurst = (int32_t) framesPerBurst; +} +} // extern "C" |
