diff --git a/audio-echo/README.md b/audio-echo/README.md
index 67bae273e..0ebe5cc35 100644
--- a/audio-echo/README.md
+++ b/audio-echo/README.md
@@ -1,77 +1,6 @@
-# Audio-Echo
+# Sample removed
-The sample demos how to use OpenSL ES to create a player and recorder in Android
-Fast Audio Path, and connect them to loopback audio. On most android devices,
-there is a optimized audio path that is tuned up for low latency purpose. The
-sample creates player/recorder to work in this highly optimized audio
-path(sometimes called native audio path,
-[low latency path](http://stackoverflow.com/questions/14842803/low-latency-audio-playback-on-android?rq=1),
-or fast audio path).
+This sample has been removed because the API it demonstrated (OpenSLES) is
+deprecated. New apps should instead use [Oboe], which has its own samples.
-***Note that OpenSL ES is
-[deprecated from Android 11](https://developer.android.com/preview/features#deprecate-opensl),
-developers are recommended to use [Oboe](https://github.com/google/oboe) library
-instead.***
-
-## Usage
-
-App will capture audio from android devices and playback on the same device; the
-playback on speaker will be captured immediately and played back...! So to
-verify it, it is recommended to "mute" the playback audio with a
-earspeaker/earphone/earbug so it does not get looped back. Some device like
-Nexus 9, once you plug in an external headphone/headspeaker, it stops to use
-onboard microphone AND speaker anymore -- in this case, you need turn on the
-microphone coming with your headphone. Another point, when switching between
-external headphone and internal one, the volume is sometimes very low/muted;
-recommend to increase the playback volume with volume buttons on the phone/pad
-after plugging external headphone.
-
-## Low Latency Verification
-
-1. execute "adb shell dumpsys media.audio_flinger". Find a list of the running
- processes
-
- Name Active Client Type Fmt Chn mask Session fCount S F SRate L dB R dB
- Server Main buf Aux Buf Flags UndFrmCnt\
- F 2 no 704 1 00000001 00000003 562
- 13248 S 1 48000 -inf -inf 000033C0 0xabab8480 0x0 0x600 0\
- F 6 yes 9345 3
- 00000001 00000001 576 128 A 1 48000 0 0 0376AA00 0xabab8480 0x0 0x400 256
-
-1. execute adb shell ps | grep echo
-
-- find the sample app pid
-- check with result on step 1.\
- if there is one "F" in the front of your echo
- pid, **player** is on fast audio path\
- For fast audio capture \[it is totally
- different story\], if you do **NOT** see\
- com.example.nativeaudio
- W/AudioRecordīš AUDIO_INPUT_FLAG_FAST denied by client\
- in your logcat output
- when you are creating audio recorder, you could "assume" you are on the fast
- path.\
- If your system image was built with muted ALOGW, you will not be able
- to see the above warning message.
-
-## Tune-ups
-
-A couple of knobs in the code for lower latency purpose:
-
-- audio buffer size
-- number of audio buffers cached before kicking start player The lower you go
- with them, the lower latency you get and also the lower budget for audio
- processing. All audio processing has to be completed in the time period they
- are captured / played back, plus extra time needed for:
-- audio driver
-- audio flinger framework,
-- bufferqueue callbacks etc Besides those, the irregularity of the buffer queue
- player/capture callback time is another factor. The callback from openSL may
- not as regular as you assumed, the more irregularity it is, the more likely
- have choopy audio. To fight that, more buffering is needed, which defeats the
- low-latency purpose! The low latency path is highly tuned up so you have
- better chance to get more regular callbacks. You may experiment with your
- platform to find the best parameters for lower latency and continuously
- playback audio experience. The app capture and playback on the same device
- \[most of times the same chip\], capture and playback clocks are assumed
- synchronized naturally \[so we are not dealing with it\]
+[Oboe]: https://github.com/google/oboe
diff --git a/audio-echo/app/build.gradle b/audio-echo/app/build.gradle
deleted file mode 100644
index efc5a7554..000000000
--- a/audio-echo/app/build.gradle
+++ /dev/null
@@ -1,31 +0,0 @@
-plugins {
- id "ndksamples.android.application"
-}
-
-android {
- defaultConfig {
- applicationId 'com.google.sample.echo'
- versionCode 1
- versionName '1.0'
- externalNativeBuild {
- cmake {
- arguments '-DANDROID_STL=c++_static'
- }
- }
- }
- externalNativeBuild {
- cmake {
- path 'src/main/cpp/CMakeLists.txt'
- }
- }
- namespace 'com.google.sample.echo'
-
- buildFeatures {
- prefab true
- }
-}
-
-dependencies {
- implementation libs.appcompat
- implementation project(":base")
-}
diff --git a/audio-echo/app/src/main/AndroidManifest.xml b/audio-echo/app/src/main/AndroidManifest.xml
deleted file mode 100644
index cac51786f..000000000
--- a/audio-echo/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/audio-echo/app/src/main/cpp/CMakeLists.txt b/audio-echo/app/src/main/cpp/CMakeLists.txt
deleted file mode 100644
index a71365f83..000000000
--- a/audio-echo/app/src/main/cpp/CMakeLists.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-cmake_minimum_required(VERSION 3.22.1)
-project(echo LANGUAGES C CXX)
-
-include(AppLibrary)
-find_package(base CONFIG REQUIRED)
-
-add_app_library(echo
- SHARED
- audio_main.cpp
- audio_player.cpp
- audio_recorder.cpp
- audio_effect.cpp
- audio_common.cpp
- debug_utils.cpp
- jni.cpp
-)
-
-target_link_libraries(echo
- PRIVATE
- base::base
- OpenSLES
- android
- log
- atomic
-)
-
-if(ANDROID_ABI STREQUAL riscv64)
- # This sample uses OpenSLES, which was deprecated in API 26. Our
- # minSdkVersion is 21, but we also build for riscv64, which isn't a
- # supported ABI yet and so that configuration is built for the latest API
- # level supported by the NDK.
- #
- # Longer term, this sample should probably be deleted. App developers
- # should be using Oboe rather than OpenSLES, and we already have a separate
- # sample for Oboe. There is some potentially useful audio latency
- # measurement in this sample that should be moved to the Oboe sample before
- # we delete it though.
- target_compile_options(echo PRIVATE -Wno-deprecated-declarations)
-endif()
diff --git a/audio-echo/app/src/main/cpp/android_debug.h b/audio-echo/app/src/main/cpp/android_debug.h
deleted file mode 100644
index 8ea56c00b..000000000
--- a/audio-echo/app/src/main/cpp/android_debug.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 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 NATIVE_AUDIO_ANDROID_DEBUG_H_H
-#define NATIVE_AUDIO_ANDROID_DEBUG_H_H
-#include
-
-#if 1
-
-#define MODULE_NAME "AUDIO-ECHO"
-#define LOGV(...) \
- __android_log_print(ANDROID_LOG_VERBOSE, MODULE_NAME, __VA_ARGS__)
-#define LOGD(...) \
- __android_log_print(ANDROID_LOG_DEBUG, MODULE_NAME, __VA_ARGS__)
-#define LOGI(...) \
- __android_log_print(ANDROID_LOG_INFO, MODULE_NAME, __VA_ARGS__)
-#define LOGW(...) \
- __android_log_print(ANDROID_LOG_WARN, MODULE_NAME, __VA_ARGS__)
-#define LOGE(...) \
- __android_log_print(ANDROID_LOG_ERROR, MODULE_NAME, __VA_ARGS__)
-#define LOGF(...) \
- __android_log_print(ANDROID_LOG_FATAL, MODULE_NAME, __VA_ARGS__)
-
-#else
-
-#define LOGV(...)
-#define LOGD(...)
-#define LOGI(...)
-#define LOGW(...)
-#define LOGE(...)
-#define LOGF(...)
-#endif
-
-#endif // NATIVE_AUDIO_ANDROID_DEBUG_H_H
diff --git a/audio-echo/app/src/main/cpp/audio_common.cpp b/audio-echo/app/src/main/cpp/audio_common.cpp
deleted file mode 100644
index f56f39774..000000000
--- a/audio-echo/app/src/main/cpp/audio_common.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2015 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 "audio_common.h"
-
-void ConvertToSLSampleFormat(SLAndroidDataFormat_PCM_EX* pFormat,
- SampleFormat* pSampleInfo_) {
- assert(pFormat);
- memset(pFormat, 0, sizeof(*pFormat));
-
- pFormat->formatType = SL_DATAFORMAT_PCM;
- // Only support 2 channels
- // For channelMask, refer to wilhelm/src/android/channels.c for details
- if (pSampleInfo_->channels_ <= 1) {
- pFormat->numChannels = 1;
- pFormat->channelMask = SL_SPEAKER_FRONT_LEFT;
- } else {
- pFormat->numChannels = 2;
- pFormat->channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
- }
- pFormat->sampleRate = pSampleInfo_->sampleRate_;
-
- pFormat->endianness = SL_BYTEORDER_LITTLEENDIAN;
- pFormat->bitsPerSample = pSampleInfo_->pcmFormat_;
- pFormat->containerSize = pSampleInfo_->pcmFormat_;
-
- /*
- * fixup for android extended representations...
- */
- pFormat->representation = pSampleInfo_->representation_;
- switch (pFormat->representation) {
- case SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT:
- pFormat->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8;
- pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_8;
- pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
- break;
- case SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT:
- pFormat->bitsPerSample =
- SL_PCMSAMPLEFORMAT_FIXED_16; // supports 16, 24, and 32
- pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
- pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
- break;
- case SL_ANDROID_PCM_REPRESENTATION_FLOAT:
- pFormat->bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32;
- pFormat->containerSize = SL_PCMSAMPLEFORMAT_FIXED_32;
- pFormat->formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
- break;
- case 0:
- break;
- default:
- assert(0);
- }
-}
diff --git a/audio-echo/app/src/main/cpp/audio_common.h b/audio-echo/app/src/main/cpp/audio_common.h
deleted file mode 100644
index 88232b8dd..000000000
--- a/audio-echo/app/src/main/cpp/audio_common.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2015 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 NATIVE_AUDIO_AUDIO_COMMON_H
-#define NATIVE_AUDIO_AUDIO_COMMON_H
-
-#include
-#include
-
-#include "android_debug.h"
-#include "buf_manager.h"
-#include "debug_utils.h"
-
-/*
- * Audio Sample Controls...
- */
-#define AUDIO_SAMPLE_CHANNELS 1
-
-/*
- * Sample Buffer Controls...
- */
-#define RECORD_DEVICE_KICKSTART_BUF_COUNT 2
-#define PLAY_KICKSTART_BUFFER_COUNT 3
-#define DEVICE_SHADOW_BUFFER_QUEUE_LEN 4
-#define BUF_COUNT 16
-
-struct SampleFormat {
- uint32_t sampleRate_;
- uint32_t framesPerBuf_;
- uint16_t channels_;
- uint16_t pcmFormat_; // 8 bit, 16 bit, 24 bit ...
- uint32_t representation_; // android extensions
-};
-extern void ConvertToSLSampleFormat(SLAndroidDataFormat_PCM_EX* pFormat,
- SampleFormat* format);
-
-/*
- * GetSystemTicks(void): return the time in micro sec
- */
-__inline__ uint64_t GetSystemTicks(void) {
- struct timeval Time;
- gettimeofday(&Time, NULL);
-
- return (static_cast(1000000) * Time.tv_sec + Time.tv_usec);
-}
-
-#define SLASSERT(x) \
- do { \
- assert(SL_RESULT_SUCCESS == (x)); \
- (void)(x); \
- } while (0)
-
-/*
- * Interface for player and recorder to communicate with engine
- */
-#define ENGINE_SERVICE_MSG_KICKSTART_PLAYER 1
-#define ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS 2
-#define ENGINE_SERVICE_MSG_RECORDED_AUDIO_AVAILABLE 3
-typedef bool (*ENGINE_CALLBACK)(void* pCTX, uint32_t msg, void* pData);
-
-/*
- * flag to enable file dumping
- */
-// #define ENABLE_LOG 1
-
-#endif // NATIVE_AUDIO_AUDIO_COMMON_H
diff --git a/audio-echo/app/src/main/cpp/audio_effect.cpp b/audio-echo/app/src/main/cpp/audio_effect.cpp
deleted file mode 100644
index 903a9ee8a..000000000
--- a/audio-echo/app/src/main/cpp/audio_effect.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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 "audio_effect.h"
-
-#include
-#include
-
-#include "audio_common.h"
-
-/*
- * Mixing Audio in integer domain to avoid FP calculation
- * (FG * ( MixFactor * 16 ) + BG * ( (1.0f-MixFactor) * 16 )) / 16
- */
-static const int32_t kFloatToIntMapFactor = 128;
-static const uint32_t kMsPerSec = 1000;
-/**
- * Constructor for AudioDelay
- * @param sampleRate
- * @param channelCount
- * @param format
- * @param delayTimeInMs
- */
-AudioDelay::AudioDelay(int32_t sampleRate, int32_t channelCount,
- SLuint32 format, size_t delayTimeInMs, float decayWeight)
- : AudioFormat(sampleRate, channelCount, format),
- delayTime_(delayTimeInMs),
- decayWeight_(decayWeight) {
- feedbackFactor_ = static_cast(decayWeight_ * kFloatToIntMapFactor);
- liveAudioFactor_ = kFloatToIntMapFactor - feedbackFactor_;
- allocateBuffer();
-}
-
-/**
- * Destructor
- */
-AudioDelay::~AudioDelay() {
- if (buffer_) delete static_cast(buffer_);
-}
-
-/**
- * Configure for delay time ( in miliseconds ), dynamically adjustable
- * @param delayTimeInMS in miliseconds
- * @return true if delay time is set successfully
- */
-bool AudioDelay::setDelayTime(size_t delayTimeInMS) {
- if (delayTimeInMS == delayTime_) return true;
-
- std::lock_guard lock(lock_);
-
- if (buffer_) {
- delete static_cast(buffer_);
- buffer_ = nullptr;
- }
-
- delayTime_ = delayTimeInMS;
- allocateBuffer();
- return buffer_ != nullptr;
-}
-
-/**
- * Internal helper function to allocate buffer for the delay
- * - calculate the buffer size for the delay time
- * - allocate and zero out buffer (0 means silent audio)
- * - configure bufSize_ to be size of audioFrames
- */
-void AudioDelay::allocateBuffer(void) {
- float floatDelayTime = (float)delayTime_ / kMsPerSec;
- float fNumFrames = floatDelayTime * (float)sampleRate_ / kMsPerSec;
- size_t sampleCount = static_cast(fNumFrames + 0.5f) * channelCount_;
-
- uint32_t bytePerSample = format_ / 8;
- assert(bytePerSample <= 4 && bytePerSample);
-
- uint32_t bytePerFrame = channelCount_ * bytePerSample;
-
- // get bufCapacity in bytes
- bufCapacity_ = sampleCount * bytePerSample;
- bufCapacity_ =
- ((bufCapacity_ + bytePerFrame - 1) / bytePerFrame) * bytePerFrame;
-
- buffer_ = new uint8_t[bufCapacity_];
- assert(buffer_);
-
- memset(buffer_, 0, bufCapacity_);
- curPos_ = 0;
-
- // bufSize_ is in Frames ( not samples, not bytes )
- bufSize_ = bufCapacity_ / bytePerFrame;
-}
-
-size_t AudioDelay::getDelayTime(void) const { return delayTime_; }
-
-/**
- * setDecayWeight(): set the decay factor
- * ratio: value of 0.0 -- 1.0f;
- *
- * the calculation is in integer ( not in float )
- * for performance purpose
- */
-void AudioDelay::setDecayWeight(float weight) {
- if (weight > 0.0f && weight < 1.0f) {
- float feedback = (weight * kFloatToIntMapFactor + 0.5f);
- feedbackFactor_ = static_cast(feedback);
- liveAudioFactor_ = kFloatToIntMapFactor - feedbackFactor_;
- }
-}
-
-float AudioDelay::getDecayWeight(void) const { return decayWeight_; }
-
-/**
- * process() filter live audio with "echo" effect:
- * delay time is run-time adjustable
- * decay time could also be adjustable, but not used
- * in this sample, hardcoded to .5
- *
- * @param liveAudio is recorded audio stream
- * @param channelCount for liveAudio, must be 2 for stereo
- * @param numFrames is length of liveAudio in Frames ( not in byte )
- */
-void AudioDelay::process(int16_t* liveAudio, uint32_t numFrames) {
- if (feedbackFactor_ == 0 || bufSize_ < numFrames) {
- return;
- }
-
- if (!lock_.try_lock()) {
- return;
- }
-
- if (numFrames + curPos_ > bufSize_) {
- curPos_ = 0;
- }
-
- // process every sample
- auto sampleCount = channelCount_ * numFrames;
- int16_t* samples = &static_cast(buffer_)[curPos_ * channelCount_];
- for (size_t idx = 0; idx < sampleCount; idx++) {
-#if 1
- int32_t curSample =
- (samples[idx] * feedbackFactor_ + liveAudio[idx] * liveAudioFactor_) /
- kFloatToIntMapFactor;
- if (curSample > SHRT_MAX)
- curSample = SHRT_MAX;
- else if (curSample < SHRT_MIN)
- curSample = SHRT_MIN;
-
- liveAudio[idx] = samples[idx];
- samples[idx] = static_cast(curSample);
-#else
- // Pure delay
- int16_t tmp = liveAudio[idx];
- liveAudio[idx] = samples[idx];
- samples[idx] = tmp;
-#endif
- }
-
- curPos_ += numFrames;
- lock_.unlock();
-}
diff --git a/audio-echo/app/src/main/cpp/audio_effect.h b/audio-echo/app/src/main/cpp/audio_effect.h
deleted file mode 100644
index 98b1d05c8..000000000
--- a/audio-echo/app/src/main/cpp/audio_effect.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 EFFECT_PROCESSOR_H
-#define EFFECT_PROCESSOR_H
-
-#include
-
-#include
-#include
-#include
-
-class AudioFormat {
- protected:
- int32_t sampleRate_ = SL_SAMPLINGRATE_48;
- int32_t channelCount_ = 2;
- SLuint32 format_ = SL_PCMSAMPLEFORMAT_FIXED_16;
-
- AudioFormat(int32_t sampleRate, int32_t channelCount, SLuint32 format)
- : sampleRate_(sampleRate), channelCount_(channelCount), format_(format){};
-
- virtual ~AudioFormat() {}
-};
-
-/**
- * An audio delay effect:
- * - decay is for feedback(echo)weight
- * - delay time is adjustable
- */
-class AudioDelay : public AudioFormat {
- public:
- ~AudioDelay();
-
- explicit AudioDelay(int32_t sampleRate, int32_t channelCount, SLuint32 format,
- size_t delayTimeInMs, float Weight);
- bool setDelayTime(size_t delayTimeInMiliSec);
- size_t getDelayTime(void) const;
- void setDecayWeight(float weight);
- float getDecayWeight(void) const;
- void process(int16_t* liveAudio, uint32_t numFrames);
-
- private:
- size_t delayTime_ = 0;
- float decayWeight_ = 0.5;
- void* buffer_ = nullptr;
- size_t bufCapacity_ = 0;
- size_t bufSize_ = 0;
- size_t curPos_ = 0;
- std::mutex lock_;
- int32_t feedbackFactor_;
- int32_t liveAudioFactor_;
- void allocateBuffer(void);
-};
-#endif // EFFECT_PROCESSOR_H
diff --git a/audio-echo/app/src/main/cpp/audio_main.cpp b/audio-echo/app/src/main/cpp/audio_main.cpp
deleted file mode 100644
index 43d0b54db..000000000
--- a/audio-echo/app/src/main/cpp/audio_main.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2015 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
-#include
-
-#include "audio_common.h"
-#include "audio_effect.h"
-#include "audio_player.h"
-#include "audio_recorder.h"
-#include "jni_interface.h"
-
-struct EchoAudioEngine {
- SLmilliHertz fastPathSampleRate_;
- uint32_t fastPathFramesPerBuf_;
- uint16_t sampleChannels_;
- uint16_t bitsPerSample_;
-
- SLObjectItf slEngineObj_;
- SLEngineItf slEngineItf_;
-
- AudioRecorder* recorder_;
- AudioPlayer* player_;
- AudioQueue* freeBufQueue_; // Owner of the queue
- AudioQueue* recBufQueue_; // Owner of the queue
-
- sample_buf* bufs_;
- uint32_t bufCount_;
- uint32_t frameCount_;
- int64_t echoDelay_;
- float echoDecay_;
- AudioDelay* delayEffect_;
-};
-static EchoAudioEngine engine;
-
-bool EngineService(void* ctx, uint32_t msg, void* data);
-
-void CreateSlEngine(JNIEnv*, jclass, jint sampleRate, jint framesPerBuf,
- jlong delayInMs, jfloat decay) {
- SLresult result;
- memset(&engine, 0, sizeof(engine));
-
- engine.fastPathSampleRate_ = static_cast(sampleRate) * 1000;
- engine.fastPathFramesPerBuf_ = static_cast(framesPerBuf);
- engine.sampleChannels_ = AUDIO_SAMPLE_CHANNELS;
- engine.bitsPerSample_ = SL_PCMSAMPLEFORMAT_FIXED_16;
-
- result = slCreateEngine(&engine.slEngineObj_, 0, NULL, 0, NULL, NULL);
- SLASSERT(result);
-
- result =
- (*engine.slEngineObj_)->Realize(engine.slEngineObj_, SL_BOOLEAN_FALSE);
- SLASSERT(result);
-
- result = (*engine.slEngineObj_)
- ->GetInterface(engine.slEngineObj_, SL_IID_ENGINE,
- &engine.slEngineItf_);
- SLASSERT(result);
-
- // compute the RECOMMENDED fast audio buffer size:
- // the lower latency required
- // *) the smaller the buffer should be (adjust it here) AND
- // *) the less buffering should be before starting player AFTER
- // receiving the recorder buffer
- // Adjust the bufSize here to fit your bill [before it busts]
- uint32_t bufSize = engine.fastPathFramesPerBuf_ * engine.sampleChannels_ *
- engine.bitsPerSample_;
- bufSize = (bufSize + 7) >> 3; // bits --> byte
- engine.bufCount_ = BUF_COUNT;
- engine.bufs_ = allocateSampleBufs(engine.bufCount_, bufSize);
- assert(engine.bufs_);
-
- engine.freeBufQueue_ = new AudioQueue(engine.bufCount_);
- engine.recBufQueue_ = new AudioQueue(engine.bufCount_);
- assert(engine.freeBufQueue_ && engine.recBufQueue_);
- for (uint32_t i = 0; i < engine.bufCount_; i++) {
- engine.freeBufQueue_->push(&engine.bufs_[i]);
- }
-
- engine.echoDelay_ = delayInMs;
- engine.echoDecay_ = decay;
- engine.delayEffect_ = new AudioDelay(
- engine.fastPathSampleRate_, engine.sampleChannels_, engine.bitsPerSample_,
- engine.echoDelay_, engine.echoDecay_);
- assert(engine.delayEffect_);
-}
-
-jboolean ConfigureEcho(JNIEnv*, jclass, jint delayInMs, jfloat decay) {
- engine.echoDelay_ = delayInMs;
- engine.echoDecay_ = decay;
-
- engine.delayEffect_->setDelayTime(delayInMs);
- engine.delayEffect_->setDecayWeight(decay);
- return JNI_FALSE;
-}
-
-jboolean CreateSlBufferQueueAudioPlayer(JNIEnv*, jclass) {
- SampleFormat sampleFormat;
- memset(&sampleFormat, 0, sizeof(sampleFormat));
- sampleFormat.pcmFormat_ = (uint16_t)engine.bitsPerSample_;
- sampleFormat.framesPerBuf_ = engine.fastPathFramesPerBuf_;
-
- // SampleFormat.representation_ = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
- sampleFormat.channels_ = (uint16_t)engine.sampleChannels_;
- sampleFormat.sampleRate_ = engine.fastPathSampleRate_;
-
- engine.player_ = new AudioPlayer(&sampleFormat, engine.slEngineItf_);
- assert(engine.player_);
- if (engine.player_ == nullptr) return JNI_FALSE;
-
- engine.player_->SetBufQueue(engine.recBufQueue_, engine.freeBufQueue_);
- engine.player_->RegisterCallback(EngineService, (void*)&engine);
-
- return JNI_TRUE;
-}
-
-void DeleteSlBufferQueueAudioPlayer(JNIEnv*, jclass) {
- if (engine.player_) {
- delete engine.player_;
- engine.player_ = nullptr;
- }
-}
-
-jboolean CreateAudioRecorder(JNIEnv*, jclass) {
- SampleFormat sampleFormat;
- memset(&sampleFormat, 0, sizeof(sampleFormat));
- sampleFormat.pcmFormat_ = static_cast(engine.bitsPerSample_);
-
- // SampleFormat.representation_ = SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
- sampleFormat.channels_ = engine.sampleChannels_;
- sampleFormat.sampleRate_ = engine.fastPathSampleRate_;
- sampleFormat.framesPerBuf_ = engine.fastPathFramesPerBuf_;
- engine.recorder_ = new AudioRecorder(&sampleFormat, engine.slEngineItf_);
- if (!engine.recorder_) {
- return JNI_FALSE;
- }
- engine.recorder_->SetBufQueues(engine.freeBufQueue_, engine.recBufQueue_);
- engine.recorder_->RegisterCallback(EngineService, (void*)&engine);
- return JNI_TRUE;
-}
-
-void DeleteAudioRecorder(JNIEnv*, jclass) {
- if (engine.recorder_) delete engine.recorder_;
-
- engine.recorder_ = nullptr;
-}
-
-void StartPlay(JNIEnv*, jclass) {
- engine.frameCount_ = 0;
- /*
- * start player: make it into waitForData state
- */
- if (SL_BOOLEAN_FALSE == engine.player_->Start()) {
- LOGE("====%s failed", __FUNCTION__);
- return;
- }
- engine.recorder_->Start();
-}
-
-void StopPlay(JNIEnv*, jclass) {
- engine.recorder_->Stop();
- engine.player_->Stop();
-
- delete engine.recorder_;
- delete engine.player_;
- engine.recorder_ = NULL;
- engine.player_ = NULL;
-}
-
-void DeleteSlEngine(JNIEnv*, jclass) {
- delete engine.recBufQueue_;
- delete engine.freeBufQueue_;
- releaseSampleBufs(engine.bufs_, engine.bufCount_);
- if (engine.slEngineObj_ != NULL) {
- (*engine.slEngineObj_)->Destroy(engine.slEngineObj_);
- engine.slEngineObj_ = NULL;
- engine.slEngineItf_ = NULL;
- }
-
- if (engine.delayEffect_) {
- delete engine.delayEffect_;
- engine.delayEffect_ = nullptr;
- }
-}
-
-uint32_t dbgEngineGetBufCount(void) {
- uint32_t count = engine.player_->dbgGetDevBufCount();
- count += engine.recorder_->dbgGetDevBufCount();
- count += engine.freeBufQueue_->size();
- count += engine.recBufQueue_->size();
-
- LOGE(
- "Buf Disrtibutions: PlayerDev=%d, RecDev=%d, FreeQ=%d, "
- "RecQ=%d",
- engine.player_->dbgGetDevBufCount(),
- engine.recorder_->dbgGetDevBufCount(), engine.freeBufQueue_->size(),
- engine.recBufQueue_->size());
- if (count != engine.bufCount_) {
- LOGE("====Lost Bufs among the queue(supposed = %d, found = %d)", BUF_COUNT,
- count);
- }
- return count;
-}
-
-/*
- * simple message passing for player/recorder to communicate with engine
- */
-bool EngineService([[maybe_unused]] void* ctx, uint32_t msg, void* data) {
- assert(ctx == &engine);
- switch (msg) {
- case ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS: {
- *(static_cast(data)) = dbgEngineGetBufCount();
- break;
- }
- case ENGINE_SERVICE_MSG_RECORDED_AUDIO_AVAILABLE: {
- // adding audio delay effect
- sample_buf* buf = static_cast(data);
- assert(engine.fastPathFramesPerBuf_ ==
- buf->size_ / engine.sampleChannels_ / (engine.bitsPerSample_ / 8));
- engine.delayEffect_->process(reinterpret_cast(buf->buf_),
- engine.fastPathFramesPerBuf_);
- break;
- }
- default:
- assert(false);
- return false;
- }
-
- return true;
-}
diff --git a/audio-echo/app/src/main/cpp/audio_player.cpp b/audio-echo/app/src/main/cpp/audio_player.cpp
deleted file mode 100644
index 259679fdc..000000000
--- a/audio-echo/app/src/main/cpp/audio_player.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright 2015 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 "audio_player.h"
-
-#include
-
-/*
- * Called by OpenSL SimpleBufferQueue for every audio buffer played
- * directly pass thru to our handler.
- * The regularity of this callback from openSL/Android System affects
- * playback continuity. If it does not callback in the regular time
- * slot, you are under big pressure for audio processing[here we do
- * not do any filtering/mixing]. Callback from fast audio path are
- * much more regular than other audio paths by my observation. If it
- * very regular, you could buffer much less audio samples between
- * recorder and player, hence lower latency.
- */
-void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* ctx) {
- (static_cast(ctx))->ProcessSLCallback(bq);
-}
-void AudioPlayer::ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq) {
-#ifdef ENABLE_LOG
- logFile_->logTime();
-#endif
- std::lock_guard lock(stopMutex_);
-
- // retrieve the finished device buf and put onto the free queue
- // so recorder could re-use it
- sample_buf* buf;
- if (!devShadowQueue_->front(&buf)) {
- /*
- * This should not happen: we got a callback,
- * but we have no buffer in deviceShadowedQueue
- * we lost buffers this way...(ERROR)
- */
- if (callback_) {
- uint32_t count;
- callback_(ctx_, ENGINE_SERVICE_MSG_RETRIEVE_DUMP_BUFS, &count);
- }
- return;
- }
- devShadowQueue_->pop();
-
- if (buf != &silentBuf_) {
- buf->size_ = 0;
- freeQueue_->push(buf);
-
- if (!playQueue_->front(&buf)) {
-#ifdef ENABLE_LOG
- logFile_->log("%s", "====Warning: running out of the Audio buffers");
-#endif
- return;
- }
-
- devShadowQueue_->push(buf);
- (*bq)->Enqueue(bq, buf->buf_, buf->size_);
- playQueue_->pop();
- return;
- }
-
- if (playQueue_->size() < PLAY_KICKSTART_BUFFER_COUNT) {
- (*bq)->Enqueue(bq, buf->buf_, buf->size_);
- devShadowQueue_->push(&silentBuf_);
- return;
- }
-
- assert(PLAY_KICKSTART_BUFFER_COUNT <=
- (DEVICE_SHADOW_BUFFER_QUEUE_LEN - devShadowQueue_->size()));
- for (int32_t idx = 0; idx < PLAY_KICKSTART_BUFFER_COUNT; idx++) {
- playQueue_->front(&buf);
- playQueue_->pop();
- devShadowQueue_->push(buf);
- (*bq)->Enqueue(bq, buf->buf_, buf->size_);
- }
-}
-
-AudioPlayer::AudioPlayer(SampleFormat* sampleFormat, SLEngineItf slEngine)
- : freeQueue_(nullptr),
- playQueue_(nullptr),
- devShadowQueue_(nullptr),
- callback_(nullptr) {
- SLresult result;
- assert(sampleFormat);
- sampleInfo_ = *sampleFormat;
-
- result = (*slEngine)->CreateOutputMix(slEngine, &outputMixObjectItf_, 0, NULL,
- NULL);
- SLASSERT(result);
-
- // realize the output mix
- result =
- (*outputMixObjectItf_)->Realize(outputMixObjectItf_, SL_BOOLEAN_FALSE);
- SLASSERT(result);
-
- // configure audio source
- SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
- SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, DEVICE_SHADOW_BUFFER_QUEUE_LEN};
-
- SLAndroidDataFormat_PCM_EX format_pcm;
- ConvertToSLSampleFormat(&format_pcm, &sampleInfo_);
- SLDataSource audioSrc = {&loc_bufq, &format_pcm};
-
- // configure audio sink
- SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX,
- outputMixObjectItf_};
- SLDataSink audioSnk = {&loc_outmix, NULL};
- /*
- * create fast path audio player: SL_IID_BUFFERQUEUE and SL_IID_VOLUME
- * and other non-signal processing interfaces are ok.
- */
- SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
- SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
- result = (*slEngine)->CreateAudioPlayer(
- slEngine, &playerObjectItf_, &audioSrc, &audioSnk,
- sizeof(ids) / sizeof(ids[0]), ids, req);
- SLASSERT(result);
-
- // realize the player
- result = (*playerObjectItf_)->Realize(playerObjectItf_, SL_BOOLEAN_FALSE);
- SLASSERT(result);
-
- // get the play interface
- result = (*playerObjectItf_)
- ->GetInterface(playerObjectItf_, SL_IID_PLAY, &playItf_);
- SLASSERT(result);
-
- // get the buffer queue interface
- result = (*playerObjectItf_)
- ->GetInterface(playerObjectItf_, SL_IID_BUFFERQUEUE,
- &playBufferQueueItf_);
- SLASSERT(result);
-
- // register callback on the buffer queue
- result = (*playBufferQueueItf_)
- ->RegisterCallback(playBufferQueueItf_, bqPlayerCallback, this);
- SLASSERT(result);
-
- result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
- SLASSERT(result);
-
- // create an empty queue to track deviceQueue
- devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN);
- assert(devShadowQueue_);
-
- silentBuf_.cap_ = (format_pcm.containerSize >> 3) * format_pcm.numChannels *
- sampleInfo_.framesPerBuf_;
- silentBuf_.buf_ = new uint8_t[silentBuf_.cap_];
- memset(silentBuf_.buf_, 0, silentBuf_.cap_);
- silentBuf_.size_ = silentBuf_.cap_;
-
-#ifdef ENABLE_LOG
- std::string name = "play";
- logFile_ = new AndroidLog(name);
-#endif
-}
-
-AudioPlayer::~AudioPlayer() {
- std::lock_guard lock(stopMutex_);
-
- // destroy buffer queue audio player object, and invalidate all associated
- // interfaces
- if (playerObjectItf_ != NULL) {
- (*playerObjectItf_)->Destroy(playerObjectItf_);
- }
- // Consume all non-completed audio buffers
- sample_buf* buf = NULL;
- while (devShadowQueue_->front(&buf)) {
- buf->size_ = 0;
- devShadowQueue_->pop();
- if (buf != &silentBuf_) {
- freeQueue_->push(buf);
- }
- }
- delete devShadowQueue_;
-
- while (playQueue_->front(&buf)) {
- buf->size_ = 0;
- playQueue_->pop();
- freeQueue_->push(buf);
- }
-
- // destroy output mix object, and invalidate all associated interfaces
- if (outputMixObjectItf_) {
- (*outputMixObjectItf_)->Destroy(outputMixObjectItf_);
- }
-
- delete[] silentBuf_.buf_;
-}
-
-void AudioPlayer::SetBufQueue(AudioQueue* playQ, AudioQueue* freeQ) {
- playQueue_ = playQ;
- freeQueue_ = freeQ;
-}
-
-SLresult AudioPlayer::Start(void) {
- SLuint32 state;
- SLresult result = (*playItf_)->GetPlayState(playItf_, &state);
- if (result != SL_RESULT_SUCCESS) {
- return SL_BOOLEAN_FALSE;
- }
- if (state == SL_PLAYSTATE_PLAYING) {
- return SL_BOOLEAN_TRUE;
- }
-
- result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
- SLASSERT(result);
-
- result =
- (*playBufferQueueItf_)
- ->Enqueue(playBufferQueueItf_, silentBuf_.buf_, silentBuf_.size_);
- SLASSERT(result);
- devShadowQueue_->push(&silentBuf_);
-
- result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_PLAYING);
- SLASSERT(result);
- return SL_BOOLEAN_TRUE;
-}
-
-void AudioPlayer::Stop(void) {
- SLuint32 state;
-
- SLresult result = (*playItf_)->GetPlayState(playItf_, &state);
- SLASSERT(result);
-
- if (state == SL_PLAYSTATE_STOPPED) return;
-
- std::lock_guard lock(stopMutex_);
-
- result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
- SLASSERT(result);
- (*playBufferQueueItf_)->Clear(playBufferQueueItf_);
-
-#ifdef ENABLE_LOG
- if (logFile_) {
- delete logFile_;
- logFile_ = nullptr;
- }
-#endif
-}
-
-void AudioPlayer::RegisterCallback(ENGINE_CALLBACK cb, void* ctx) {
- callback_ = cb;
- ctx_ = ctx;
-}
-
-uint32_t AudioPlayer::dbgGetDevBufCount(void) {
- return (devShadowQueue_->size());
-}
\ No newline at end of file
diff --git a/audio-echo/app/src/main/cpp/audio_player.h b/audio-echo/app/src/main/cpp/audio_player.h
deleted file mode 100644
index 0fdf523b5..000000000
--- a/audio-echo/app/src/main/cpp/audio_player.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2015 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 NATIVE_AUDIO_AUDIO_PLAYER_H
-#define NATIVE_AUDIO_AUDIO_PLAYER_H
-#include
-
-#include "audio_common.h"
-#include "buf_manager.h"
-#include "debug_utils.h"
-
-class AudioPlayer {
- // buffer queue player interfaces
- SLObjectItf outputMixObjectItf_;
- SLObjectItf playerObjectItf_;
- SLPlayItf playItf_;
- SLAndroidSimpleBufferQueueItf playBufferQueueItf_;
-
- SampleFormat sampleInfo_;
- AudioQueue* freeQueue_; // user
- AudioQueue* playQueue_; // user
- AudioQueue* devShadowQueue_; // owner
-
- ENGINE_CALLBACK callback_;
- void* ctx_;
- sample_buf silentBuf_;
-#ifdef ENABLE_LOG
- AndroidLog* logFile_;
-#endif
- std::mutex stopMutex_;
-
- public:
- explicit AudioPlayer(SampleFormat* sampleFormat, SLEngineItf engine);
- ~AudioPlayer();
- void SetBufQueue(AudioQueue* playQ, AudioQueue* freeQ);
- SLresult Start(void);
- void Stop(void);
- void ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq);
- uint32_t dbgGetDevBufCount(void);
- void RegisterCallback(ENGINE_CALLBACK cb, void* ctx);
-};
-
-#endif // NATIVE_AUDIO_AUDIO_PLAYER_H
diff --git a/audio-echo/app/src/main/cpp/audio_recorder.cpp b/audio-echo/app/src/main/cpp/audio_recorder.cpp
deleted file mode 100644
index cf6793c7b..000000000
--- a/audio-echo/app/src/main/cpp/audio_recorder.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright 2015 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 "audio_recorder.h"
-
-#include
-#include
-/*
- * bqRecorderCallback(): called for every buffer is full;
- * pass directly to handler
- */
-void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void* rec) {
- (static_cast(rec))->ProcessSLCallback(bq);
-}
-
-void AudioRecorder::ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq) {
-#ifdef ENABLE_LOG
- recLog_->logTime();
-#endif
- assert(bq == recBufQueueItf_);
- sample_buf* dataBuf = NULL;
- devShadowQueue_->front(&dataBuf);
- devShadowQueue_->pop();
- dataBuf->size_ = dataBuf->cap_; // device only calls us when it is really
- // full
-
- callback_(ctx_, ENGINE_SERVICE_MSG_RECORDED_AUDIO_AVAILABLE, dataBuf);
- recQueue_->push(dataBuf);
-
- sample_buf* freeBuf;
- while (freeQueue_->front(&freeBuf) && devShadowQueue_->push(freeBuf)) {
- freeQueue_->pop();
- SLresult result = (*bq)->Enqueue(bq, freeBuf->buf_, freeBuf->cap_);
- SLASSERT(result);
- }
-
- ++audioBufCount;
-
- // should leave the device to sleep to save power if no buffers
- if (devShadowQueue_->size() == 0) {
- (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
- }
-}
-
-AudioRecorder::AudioRecorder(SampleFormat* sampleFormat, SLEngineItf slEngine)
- : freeQueue_(nullptr),
- recQueue_(nullptr),
- devShadowQueue_(nullptr),
- callback_(nullptr) {
- SLresult result;
- sampleInfo_ = *sampleFormat;
- SLAndroidDataFormat_PCM_EX format_pcm;
- ConvertToSLSampleFormat(&format_pcm, &sampleInfo_);
-
- // configure audio source
- SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE,
- SL_IODEVICE_AUDIOINPUT,
- SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
- SLDataSource audioSrc = {&loc_dev, NULL};
-
- // configure audio sink
- SLDataLocator_AndroidSimpleBufferQueue loc_bq = {
- SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, DEVICE_SHADOW_BUFFER_QUEUE_LEN};
-
- SLDataSink audioSnk = {&loc_bq, &format_pcm};
-
- // create audio recorder
- // (requires the RECORD_AUDIO permission)
- const SLInterfaceID id[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- SL_IID_ANDROIDCONFIGURATION};
- const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
- result = (*slEngine)->CreateAudioRecorder(
- slEngine, &recObjectItf_, &audioSrc, &audioSnk,
- sizeof(id) / sizeof(id[0]), id, req);
- SLASSERT(result);
-
- // Configure the voice recognition preset which has no
- // signal processing for lower latency.
- SLAndroidConfigurationItf inputConfig;
- result = (*recObjectItf_)
- ->GetInterface(recObjectItf_, SL_IID_ANDROIDCONFIGURATION,
- &inputConfig);
- if (SL_RESULT_SUCCESS == result) {
- SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
- (*inputConfig)
- ->SetConfiguration(inputConfig, SL_ANDROID_KEY_RECORDING_PRESET,
- &presetValue, sizeof(SLuint32));
- }
- result = (*recObjectItf_)->Realize(recObjectItf_, SL_BOOLEAN_FALSE);
- SLASSERT(result);
- result =
- (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_RECORD, &recItf_);
- SLASSERT(result);
-
- result = (*recObjectItf_)
- ->GetInterface(recObjectItf_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &recBufQueueItf_);
- SLASSERT(result);
-
- result = (*recBufQueueItf_)
- ->RegisterCallback(recBufQueueItf_, bqRecorderCallback, this);
- SLASSERT(result);
-
- devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN);
- assert(devShadowQueue_);
-#ifdef ENABLE_LOG
- std::string name = "rec";
- recLog_ = new AndroidLog(name);
-#endif
-}
-
-SLboolean AudioRecorder::Start(void) {
- if (!freeQueue_ || !recQueue_ || !devShadowQueue_) {
- LOGE("====NULL poiter to Start(%p, %p, %p)", freeQueue_, recQueue_,
- devShadowQueue_);
- return SL_BOOLEAN_FALSE;
- }
- audioBufCount = 0;
-
- SLresult result;
- // in case already recording, stop recording and clear buffer queue
- result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
- SLASSERT(result);
- result = (*recBufQueueItf_)->Clear(recBufQueueItf_);
- SLASSERT(result);
-
- for (int i = 0; i < RECORD_DEVICE_KICKSTART_BUF_COUNT; i++) {
- sample_buf* buf = NULL;
- if (!freeQueue_->front(&buf)) {
- LOGE("=====OutOfFreeBuffers @ startingRecording @ (%d)", i);
- break;
- }
- freeQueue_->pop();
- assert(buf->buf_ && buf->cap_ && !buf->size_);
-
- result = (*recBufQueueItf_)->Enqueue(recBufQueueItf_, buf->buf_, buf->cap_);
- SLASSERT(result);
- devShadowQueue_->push(buf);
- }
-
- result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_RECORDING);
- SLASSERT(result);
-
- return (result == SL_RESULT_SUCCESS ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE);
-}
-
-SLboolean AudioRecorder::Stop(void) {
- // in case already recording, stop recording and clear buffer queue
- SLuint32 curState;
-
- SLresult result = (*recItf_)->GetRecordState(recItf_, &curState);
- SLASSERT(result);
- if (curState == SL_RECORDSTATE_STOPPED) {
- return SL_BOOLEAN_TRUE;
- }
- result = (*recItf_)->SetRecordState(recItf_, SL_RECORDSTATE_STOPPED);
- SLASSERT(result);
- result = (*recBufQueueItf_)->Clear(recBufQueueItf_);
- SLASSERT(result);
-
-#ifdef ENABLE_LOG
- recLog_->flush();
-#endif
-
- return SL_BOOLEAN_TRUE;
-}
-
-AudioRecorder::~AudioRecorder() {
- // destroy audio recorder object, and invalidate all associated interfaces
- if (recObjectItf_ != NULL) {
- (*recObjectItf_)->Destroy(recObjectItf_);
- }
-
- if (devShadowQueue_) {
- sample_buf* buf = NULL;
- while (devShadowQueue_->front(&buf)) {
- devShadowQueue_->pop();
- freeQueue_->push(buf);
- }
- delete (devShadowQueue_);
- }
-#ifdef ENABLE_LOG
- if (recLog_) {
- delete recLog_;
- }
-#endif
-}
-
-void AudioRecorder::SetBufQueues(AudioQueue* freeQ, AudioQueue* recQ) {
- assert(freeQ && recQ);
- freeQueue_ = freeQ;
- recQueue_ = recQ;
-}
-
-void AudioRecorder::RegisterCallback(ENGINE_CALLBACK cb, void* ctx) {
- callback_ = cb;
- ctx_ = ctx;
-}
-int32_t AudioRecorder::dbgGetDevBufCount(void) {
- return devShadowQueue_->size();
-}
diff --git a/audio-echo/app/src/main/cpp/audio_recorder.h b/audio-echo/app/src/main/cpp/audio_recorder.h
deleted file mode 100644
index 2e29853bf..000000000
--- a/audio-echo/app/src/main/cpp/audio_recorder.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2015 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 NATIVE_AUDIO_AUDIO_RECORDER_H
-#define NATIVE_AUDIO_AUDIO_RECORDER_H
-#include
-#include
-#include
-
-#include "audio_common.h"
-#include "buf_manager.h"
-#include "debug_utils.h"
-
-class AudioRecorder {
- SLObjectItf recObjectItf_;
- SLRecordItf recItf_;
- SLAndroidSimpleBufferQueueItf recBufQueueItf_;
-
- SampleFormat sampleInfo_;
- AudioQueue* freeQueue_; // user
- AudioQueue* recQueue_; // user
- AudioQueue* devShadowQueue_; // owner
- uint32_t audioBufCount;
-
- ENGINE_CALLBACK callback_;
- void* ctx_;
-
- public:
- explicit AudioRecorder(SampleFormat*, SLEngineItf engineEngine);
- ~AudioRecorder();
- SLboolean Start(void);
- SLboolean Stop(void);
- void SetBufQueues(AudioQueue* freeQ, AudioQueue* recQ);
- void ProcessSLCallback(SLAndroidSimpleBufferQueueItf bq);
- void RegisterCallback(ENGINE_CALLBACK cb, void* ctx);
- int32_t dbgGetDevBufCount(void);
-
-#ifdef ENABLE_LOG
- AndroidLog* recLog_;
-#endif
-};
-
-#endif // NATIVE_AUDIO_AUDIO_RECORDER_H
diff --git a/audio-echo/app/src/main/cpp/buf_manager.h b/audio-echo/app/src/main/cpp/buf_manager.h
deleted file mode 100644
index 2810a4dfa..000000000
--- a/audio-echo/app/src/main/cpp/buf_manager.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2015 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 NATIVE_AUDIO_BUF_MANAGER_H
-#define NATIVE_AUDIO_BUF_MANAGER_H
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#ifndef CACHE_ALIGN
-#define CACHE_ALIGN 64
-#endif
-
-/*
- * ProducerConsumerQueue, borrowed from Ian NiLewis
- */
-template
-class ProducerConsumerQueue {
- public:
- explicit ProducerConsumerQueue(int size)
- : ProducerConsumerQueue(size, new T[size]) {}
-
- explicit ProducerConsumerQueue(int size, T* buffer)
- : size_(size), buffer_(buffer) {
- // This is necessary because we depend on twos-complement wraparound
- // to take care of overflow conditions.
- assert(size < std::numeric_limits::max());
- }
-
- bool push(const T& item) {
- return push([&](T* ptr) -> bool {
- *ptr = item;
- return true;
- });
- }
-
- // writer() can return false, which indicates that the caller
- // of push() changed its mind while writing (e.g. ran out of bytes)
- template
- bool push(const F& writer) {
- bool result = false;
- int readptr = read_.load(std::memory_order_acquire);
- int writeptr = write_.load(std::memory_order_relaxed);
-
- // note that while readptr and writeptr will eventually
- // wrap around, taking their difference is still valid as
- // long as size_ < MAXINT.
- int space = size_ - (int)(writeptr - readptr);
- if (space >= 1) {
- result = true;
-
- // writer
- if (writer(buffer_.get() + (writeptr % size_))) {
- ++writeptr;
- write_.store(writeptr, std::memory_order_release);
- }
- }
- return result;
- }
- // front out the queue, but not pop-out
- bool front(T* out_item) {
- return front([&](T* ptr) -> bool {
- *out_item = *ptr;
- return true;
- });
- }
-
- void pop(void) {
- int readptr = read_.load(std::memory_order_relaxed);
- ++readptr;
- read_.store(readptr, std::memory_order_release);
- }
-
- template
- bool front(const F& reader) {
- bool result = false;
-
- int writeptr = write_.load(std::memory_order_acquire);
- int readptr = read_.load(std::memory_order_relaxed);
-
- // As above, wraparound is ok
- int available = (int)(writeptr - readptr);
- if (available >= 1) {
- result = true;
- reader(buffer_.get() + (readptr % size_));
- }
-
- return result;
- }
- uint32_t size(void) {
- int writeptr = write_.load(std::memory_order_acquire);
- int readptr = read_.load(std::memory_order_relaxed);
-
- return (uint32_t)(writeptr - readptr);
- }
-
- private:
- int size_;
- std::unique_ptr buffer_;
-
- // forcing cache line alignment to eliminate false sharing of the
- // frequently-updated read and write pointers. The object is to never
- // let these get into the "shared" state where they'd cause a cache miss
- // for every write.
- alignas(CACHE_ALIGN) std::atomic read_{0};
- alignas(CACHE_ALIGN) std::atomic write_{0};
-};
-
-struct sample_buf {
- uint8_t* buf_; // audio sample container
- uint32_t cap_; // buffer capacity in byte
- uint32_t size_; // audio sample size (n buf) in byte
-};
-
-using AudioQueue = ProducerConsumerQueue;
-
-__inline__ void releaseSampleBufs(sample_buf* bufs, uint32_t& count) {
- if (!bufs || !count) {
- return;
- }
- for (uint32_t i = 0; i < count; i++) {
- if (bufs[i].buf_) delete[] bufs[i].buf_;
- }
- delete[] bufs;
-}
-__inline__ sample_buf* allocateSampleBufs(uint32_t count, uint32_t sizeInByte) {
- if (count <= 0 || sizeInByte <= 0) {
- return nullptr;
- }
- sample_buf* bufs = new sample_buf[count];
- assert(bufs);
- memset(bufs, 0, sizeof(sample_buf) * count);
-
- uint32_t allocSize = (sizeInByte + 3) & ~3; // padding to 4 bytes aligned
- uint32_t i;
- for (i = 0; i < count; i++) {
- bufs[i].buf_ = new uint8_t[allocSize];
- if (bufs[i].buf_ == nullptr) {
- LOGW("====Requesting %d buffers, allocated %d in %s", count, i,
- __FUNCTION__);
- break;
- }
- bufs[i].cap_ = sizeInByte;
- bufs[i].size_ = 0; // 0 data in it
- }
- if (i < 2) {
- releaseSampleBufs(bufs, i);
- bufs = nullptr;
- }
- count = i;
- return bufs;
-}
-
-#endif // NATIVE_AUDIO_BUF_MANAGER_H
diff --git a/audio-echo/app/src/main/cpp/debug_utils.cpp b/audio-echo/app/src/main/cpp/debug_utils.cpp
deleted file mode 100644
index 1dbeb233a..000000000
--- a/audio-echo/app/src/main/cpp/debug_utils.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2015 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 "debug_utils.h"
-
-#include
-#include
-
-#include
-
-#include "android_debug.h"
-
-static const char* FILE_PREFIX = "/sdcard/data/audio";
-
-volatile uint32_t AndroidLog::fileIdx_ = 0;
-AndroidLog::AndroidLog() : fp_(NULL), prevTick_(static_cast(0)) {
- fileName_ = FILE_PREFIX;
- openFile();
-}
-
-AndroidLog::AndroidLog(std::string& file_name)
- : fp_(NULL), prevTick_(static_cast(0)) {
- fileName_ = std::string(FILE_PREFIX) + std::string("_") + file_name;
- openFile();
-}
-
-AndroidLog::~AndroidLog() { flush(); }
-
-void AndroidLog::flush() {
- if (fp_) {
- fflush(fp_);
- fclose(fp_);
- fp_ = NULL;
- }
- prevTick_ = static_cast(0);
-}
-
-void AndroidLog::log(void* buf, uint32_t size) {
- Lock fileLock(&mutex_);
- if (!buf || !size) return;
-
- if (fp_ || openFile()) {
- fwrite(buf, size, 1, fp_);
- }
-}
-
-void AndroidLog::log(const char* fmt, ...) {
- Lock fileLock(&mutex_);
- if (!fmt) {
- return;
- }
- if (fp_ || openFile()) {
- va_list vp;
- va_start(vp, fmt);
- vfprintf(fp_, fmt, vp);
- va_end(vp);
- }
-}
-
-FILE* AndroidLog::openFile() {
- Lock fileLock(&mutex_);
-
- if (fp_) {
- return fp_;
- }
-
- char fileName[64];
- sprintf(fileName, "%s_%d", fileName_.c_str(), AndroidLog::fileIdx_++);
- fp_ = fopen(fileName, "wb");
- if (fp_ == NULL) {
- LOGE("====failed to open file %s", fileName);
- }
- return fp_;
-}
-void AndroidLog::logTime() {
- if (prevTick_ == static_cast(0)) {
- /*
- * init counter, bypass the first one
- */
- prevTick_ = getCurrentTicks();
- return;
- }
- uint64_t curTick = getCurrentTicks();
- uint64_t delta = curTick - prevTick_;
- log("%" PRIu64 " %" PRIu64 "\n", curTick, delta);
- prevTick_ = curTick;
-}
-
-uint64_t AndroidLog::getCurrentTicks() {
- struct timeval Time;
- gettimeofday(&Time, NULL);
-
- return (static_cast(1000000) * Time.tv_sec + Time.tv_usec);
-}
\ No newline at end of file
diff --git a/audio-echo/app/src/main/cpp/debug_utils.h b/audio-echo/app/src/main/cpp/debug_utils.h
deleted file mode 100644
index 95a06fc65..000000000
--- a/audio-echo/app/src/main/cpp/debug_utils.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2015 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 NATIVE_AUDIO_DEBUG_UTILS_H
-#define NATIVE_AUDIO_DEBUG_UTILS_H
-#include
-#include
-#include
-
-/*
- * debug_write_file()
- * Write given data to a file as binary file. File name is
- * "/sdcard/data/audio_%d", file_index++
- * requirement: must have /sdcard/data already created on android device
- */
-class Lock {
- public:
- explicit Lock(std::recursive_mutex* mtx) {
- mutex_ = mtx;
- mutex_->lock();
- }
- ~Lock() { mutex_->unlock(); }
-
- private:
- std::recursive_mutex* mutex_;
-};
-class AndroidLog {
- public:
- AndroidLog();
- AndroidLog(std::string& fileName);
- ~AndroidLog();
- void log(void* buf, uint32_t size);
- void log(const char* fmt, ...);
- void logTime();
- void flush();
- static volatile uint32_t fileIdx_;
-
- private:
- uint64_t getCurrentTicks();
- FILE* fp_;
- FILE* openFile();
- uint64_t prevTick_; // Tick in milisecond
- std::recursive_mutex mutex_;
- std::string fileName_;
-};
-
-void debug_write_file(void* buf, uint32_t size);
-
-#endif // NATIVE_AUDIO_DEBUG_UTILS_H
diff --git a/audio-echo/app/src/main/cpp/jni.cpp b/audio-echo/app/src/main/cpp/jni.cpp
deleted file mode 100644
index aa0441809..000000000
--- a/audio-echo/app/src/main/cpp/jni.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2025 The Android Open Source Project
-// SPDX-License-Identifier: Apache-2.0
-
-#include
-#include
-
-#include "jni_interface.h"
-
-extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* _Nonnull vm, void* _Nullable) {
- JNIEnv* env;
- if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) {
- return JNI_ERR;
- }
-
- jclass c = env->FindClass("com/google/sample/echo/MainActivity");
- if (c == nullptr) return JNI_ERR;
-
- static const JNINativeMethod methods[] = {
- {"createSLEngine", "(IIJF)V", reinterpret_cast(CreateSlEngine)},
- {"deleteSLEngine", "()V", reinterpret_cast(DeleteSlEngine)},
- {"createSLBufferQueueAudioPlayer", "()Z",
- reinterpret_cast(CreateSlBufferQueueAudioPlayer)},
- {"deleteSLBufferQueueAudioPlayer", "()V",
- reinterpret_cast(DeleteSlBufferQueueAudioPlayer)},
- {"createAudioRecorder", "()Z",
- reinterpret_cast(CreateAudioRecorder)},
- {"deleteAudioRecorder", "()V",
- reinterpret_cast(DeleteAudioRecorder)},
- {"startPlay", "()V", reinterpret_cast(StartPlay)},
- {"stopPlay", "()V", reinterpret_cast(StopPlay)},
- {"configureEcho", "(IF)Z", reinterpret_cast(ConfigureEcho)},
- };
- int rc = env->RegisterNatives(c, methods, arraysize(methods));
- if (rc != JNI_OK) return rc;
-
- return JNI_VERSION_1_6;
-}
diff --git a/audio-echo/app/src/main/cpp/jni_interface.h b/audio-echo/app/src/main/cpp/jni_interface.h
deleted file mode 100644
index 5dd4edd5f..000000000
--- a/audio-echo/app/src/main/cpp/jni_interface.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include
-
-void CreateSlEngine(JNIEnv* env, jclass, jint, jint, jlong delayInMs,
- jfloat decay);
-void DeleteSlEngine(JNIEnv* env, jclass type);
-jboolean CreateSlBufferQueueAudioPlayer(JNIEnv* env, jclass);
-void DeleteSlBufferQueueAudioPlayer(JNIEnv* env, jclass type);
-
-jboolean CreateAudioRecorder(JNIEnv* env, jclass type);
-void DeleteAudioRecorder(JNIEnv* env, jclass type);
-void StartPlay(JNIEnv* env, jclass type);
-void StopPlay(JNIEnv* env, jclass type);
-jboolean ConfigureEcho(JNIEnv* env, jclass type, jint delayInMs, jfloat decay);
diff --git a/audio-echo/app/src/main/cpp/libecho.map.txt b/audio-echo/app/src/main/cpp/libecho.map.txt
deleted file mode 100644
index a81ec0257..000000000
--- a/audio-echo/app/src/main/cpp/libecho.map.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-LIBECHO {
- global:
- JNI_OnLoad;
- local:
- *;
-};
diff --git a/audio-echo/app/src/main/java/com/google/sample/echo/MainActivity.java b/audio-echo/app/src/main/java/com/google/sample/echo/MainActivity.java
deleted file mode 100644
index 9258a6e02..000000000
--- a/audio-echo/app/src/main/java/com/google/sample/echo/MainActivity.java
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * 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.
- */
-
-package com.google.sample.echo;
-
-import android.Manifest;
-import android.app.Activity;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.media.AudioFormat;
-import android.media.AudioManager;
-import android.media.AudioRecord;
-import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.core.app.ActivityCompat;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.Button;
-import android.widget.SeekBar;
-import android.widget.TextView;
-import android.widget.Toast;
-
-public class MainActivity extends Activity
- implements ActivityCompat.OnRequestPermissionsResultCallback {
- private static final int AUDIO_ECHO_REQUEST = 0;
-
- private Button controlButton;
- private TextView statusView;
- private String nativeSampleRate;
- private String nativeSampleBufSize;
-
- private SeekBar delaySeekBar;
- private TextView curDelayTV;
- private int echoDelayProgress;
-
- private SeekBar decaySeekBar;
- private TextView curDecayTV;
- private float echoDecayProgress;
-
- private boolean supportRecording;
- private Boolean isPlaying = false;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- controlButton = (Button)findViewById((R.id.capture_control_button));
- statusView = (TextView)findViewById(R.id.statusView);
- queryNativeAudioParameters();
-
- delaySeekBar = (SeekBar)findViewById(R.id.delaySeekBar);
- curDelayTV = (TextView)findViewById(R.id.curDelay);
- echoDelayProgress = delaySeekBar.getProgress() * 1000 / delaySeekBar.getMax();
- delaySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- float curVal = (float)progress / delaySeekBar.getMax();
- curDelayTV.setText(String.format("%s", curVal));
- setSeekBarPromptPosition(delaySeekBar, curDelayTV);
- if (!fromUser) return;
-
- echoDelayProgress = progress * 1000 / delaySeekBar.getMax();
- configureEcho(echoDelayProgress, echoDecayProgress);
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {}
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {}
- });
- delaySeekBar.post(new Runnable() {
- @Override
- public void run() {
- setSeekBarPromptPosition(delaySeekBar, curDelayTV);
- }
- });
-
- decaySeekBar = (SeekBar)findViewById(R.id.decaySeekBar);
- curDecayTV = (TextView)findViewById(R.id.curDecay);
- echoDecayProgress = (float)decaySeekBar.getProgress() / decaySeekBar.getMax();
- decaySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- float curVal = (float)progress / seekBar.getMax();
- curDecayTV.setText(String.format("%s", curVal));
- setSeekBarPromptPosition(decaySeekBar, curDecayTV);
- if (!fromUser)
- return;
-
- echoDecayProgress = curVal;
- configureEcho(echoDelayProgress, echoDecayProgress);
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {}
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {}
- });
- decaySeekBar.post(new Runnable() {
- @Override
- public void run() {
- setSeekBarPromptPosition(decaySeekBar, curDecayTV);
- }
- });
-
- // initialize native audio system
- updateNativeAudioUI();
-
- if (supportRecording) {
- createSLEngine(
- Integer.parseInt(nativeSampleRate),
- Integer.parseInt(nativeSampleBufSize),
- echoDelayProgress,
- echoDecayProgress);
- }
- }
-
- private void setSeekBarPromptPosition(SeekBar seekBar, TextView label) {
- float thumbX = (float)seekBar.getProgress()/ seekBar.getMax() *
- seekBar.getWidth() + seekBar.getX();
- label.setX(thumbX - label.getWidth()/2.0f);
- }
-
- @Override
- protected void onDestroy() {
- if (supportRecording) {
- if (isPlaying) {
- stopPlay();
- }
- deleteSLEngine();
- isPlaying = false;
- }
- super.onDestroy();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
-
- //noinspection SimplifiableIfStatement
- if (id == R.id.action_settings) {
- return true;
- }
-
- return super.onOptionsItemSelected(item);
- }
-
- private void startEcho() {
- if(!supportRecording){
- return;
- }
- if (!isPlaying) {
- if(!createSLBufferQueueAudioPlayer()) {
- statusView.setText(getString(R.string.player_error_msg));
- return;
- }
- if(!createAudioRecorder()) {
- deleteSLBufferQueueAudioPlayer();
- statusView.setText(getString(R.string.recorder_error_msg));
- return;
- }
- startPlay(); // startPlay() triggers startRecording()
- statusView.setText(getString(R.string.echoing_status_msg));
- } else {
- stopPlay(); // stopPlay() triggers stopRecording()
- updateNativeAudioUI();
- deleteAudioRecorder();
- deleteSLBufferQueueAudioPlayer();
- }
- isPlaying = !isPlaying;
- controlButton.setText(getString(isPlaying ?
- R.string.cmd_stop_echo: R.string.cmd_start_echo));
- }
- public void onEchoClick(View view) {
- if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) !=
- PackageManager.PERMISSION_GRANTED) {
- statusView.setText(getString(R.string.request_permission_status_msg));
- ActivityCompat.requestPermissions(
- this,
- new String[] { Manifest.permission.RECORD_AUDIO },
- AUDIO_ECHO_REQUEST);
- return;
- }
- startEcho();
- }
-
- public void getLowLatencyParameters(View view) {
- updateNativeAudioUI();
- }
-
- private void queryNativeAudioParameters() {
- supportRecording = true;
- AudioManager myAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- if(myAudioMgr == null) {
- supportRecording = false;
- return;
- }
- nativeSampleRate = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
- nativeSampleBufSize =myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
-
- // hardcoded channel to mono: both sides -- C++ and Java sides
- int recBufSize = AudioRecord.getMinBufferSize(
- Integer.parseInt(nativeSampleRate),
- AudioFormat.CHANNEL_IN_MONO,
- AudioFormat.ENCODING_PCM_16BIT);
- if (recBufSize == AudioRecord.ERROR ||
- recBufSize == AudioRecord.ERROR_BAD_VALUE) {
- supportRecording = false;
- }
-
- }
- private void updateNativeAudioUI() {
- if (!supportRecording) {
- statusView.setText(getString(R.string.mic_error_msg));
- controlButton.setEnabled(false);
- return;
- }
-
- statusView.setText(getString(R.string.fast_audio_info_msg,
- nativeSampleRate, nativeSampleBufSize));
- }
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
- @NonNull int[] grantResults) {
- /*
- * if any permission failed, the sample could not play
- */
- if (AUDIO_ECHO_REQUEST != requestCode) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- return;
- }
-
- if (grantResults.length != 1 ||
- grantResults[0] != PackageManager.PERMISSION_GRANTED) {
- /*
- * When user denied permission, throw a Toast to prompt that RECORD_AUDIO
- * is necessary; also display the status on UI
- * Then application goes back to the original state: it behaves as if the button
- * was not clicked. The assumption is that user will re-click the "start" button
- * (to retry), or shutdown the app in normal way.
- */
- statusView.setText(getString(R.string.permission_error_msg));
- Toast.makeText(getApplicationContext(),
- getString(R.string.permission_prompt_msg),
- Toast.LENGTH_SHORT).show();
- return;
- }
-
- /*
- * When permissions are granted, we prompt the user the status. User would
- * re-try the "start" button to perform the normal operation. This saves us the extra
- * logic in code for async processing of the button listener.
- */
- statusView.setText(getString(R.string.permission_granted_msg,getString(R.string.cmd_start_echo)));
-
-
- // The callback runs on app's thread, so we are safe to resume the action
- startEcho();
- }
-
- /*
- * Loading our lib
- */
- static {
- System.loadLibrary("echo");
- }
-
- /*
- * jni function declarations
- */
- static native void createSLEngine(int rate, int framesPerBuf,
- long delayInMs, float decay);
- static native void deleteSLEngine();
- static native boolean configureEcho(int delayInMs, float decay);
- static native boolean createSLBufferQueueAudioPlayer();
- static native void deleteSLBufferQueueAudioPlayer();
-
- static native boolean createAudioRecorder();
- static native void deleteAudioRecorder();
- static native void startPlay();
- static native void stopPlay();
-}
diff --git a/audio-echo/app/src/main/res/layout/activity_main.xml b/audio-echo/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index 21eef87ea..000000000
--- a/audio-echo/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/audio-echo/app/src/main/res/menu/menu_main.xml b/audio-echo/app/src/main/res/menu/menu_main.xml
deleted file mode 100644
index e67d0e411..000000000
--- a/audio-echo/app/src/main/res/menu/menu_main.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/audio-echo/app/src/main/res/mipmap-hdpi/ic_launcher.png b/audio-echo/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index cde69bccc..000000000
Binary files a/audio-echo/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/audio-echo/app/src/main/res/mipmap-mdpi/ic_launcher.png b/audio-echo/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index c133a0cbd..000000000
Binary files a/audio-echo/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/audio-echo/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/audio-echo/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index bfa42f0e7..000000000
Binary files a/audio-echo/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/audio-echo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/audio-echo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 324e72cdd..000000000
Binary files a/audio-echo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/audio-echo/app/src/main/res/values-v21/styles.xml b/audio-echo/app/src/main/res/values-v21/styles.xml
deleted file mode 100644
index dba3c417b..000000000
--- a/audio-echo/app/src/main/res/values-v21/styles.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
diff --git a/audio-echo/app/src/main/res/values-w820dp/dimens.xml b/audio-echo/app/src/main/res/values-w820dp/dimens.xml
deleted file mode 100644
index 63fc81644..000000000
--- a/audio-echo/app/src/main/res/values-w820dp/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- 64dp
-
diff --git a/audio-echo/app/src/main/res/values/dimens.xml b/audio-echo/app/src/main/res/values/dimens.xml
deleted file mode 100644
index 47c822467..000000000
--- a/audio-echo/app/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- 16dp
- 16dp
-
diff --git a/audio-echo/app/src/main/res/values/strings.xml b/audio-echo/app/src/main/res/values/strings.xml
deleted file mode 100644
index 0cd5c0756..000000000
--- a/audio-echo/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
- audio-echo
- Starting Up
- "Requesting RECORD_AUDIO Permission..."
- Engine Echoing...
-
- Settings
- Start Echo
- Stop Echo
- FastPathInfo
- nativeSampleRate = %1$s\nnativeSampleBufSize = %2$s\n
-
- Failed to Create Audio Player
- Failed to Create Audio Recorder
- "Audio recording is not supported"
- "This sample needs RECORD_AUDIO permission"
- RECORD_AUDIO permission granted, touch %1$s to begin
- "Permission for RECORD_AUDIO was denied"
- delay(seconds)
- 0.1
-
- decay(decimal)
- 0.1
-
diff --git a/audio-echo/app/src/main/res/values/styles.xml b/audio-echo/app/src/main/res/values/styles.xml
deleted file mode 100644
index ff6c9d2c0..000000000
--- a/audio-echo/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
diff --git a/hello-oboe/.gitignore b/hello-oboe/.gitignore
deleted file mode 100644
index be21b5c16..000000000
--- a/hello-oboe/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-*.iml
-.gradle
-/local.properties
-/.idea/caches
-/.idea/libraries
-/.idea/modules.xml
-/.idea/workspace.xml
-/.idea/navEditor.xml
-/.idea/assetWizardSettings.xml
-.DS_Store
-/build
-/app/build
-/captures
-.externalNativeBuild
-.cxx
diff --git a/hello-oboe/README.md b/hello-oboe/README.md
index e7dab07ff..561816eac 100644
--- a/hello-oboe/README.md
+++ b/hello-oboe/README.md
@@ -1,28 +1,6 @@
-# Hello Oboe
+# Sample removed
-Hello Oboe is an Android sample that uses the
-[Oboe](https://github.com/google/oboe) library to play audio natively. Oboe
-wraps both AAudio and OpenSLES to help developers play and record audio in
-performance sensitive contexts across Android versions. The Oboe repository has
-more information about how to fully take advantage of the Oboe API, as well as
-more in-depth examples and documentation.
+This sample has been removed the upstream [Oboe] repository has is own (much
+better!) samples.
-This sample uses the Studio Prefab feature to download pre-built Oboe library
-from [Google Maven](https://maven.google.com/web/index.html), feel free to
-checkout Prefab steps in
-
-- gradle.properties
-- app/build.gradle
-- app/src/main/cpp/CMakeLists.txt
-
-If you like to build your app with the Oboe library source code, refer to the
-examples in the Oboe repository.
-
-## Screenshot
-
-
-
-## Using the App
-
-Tap and hold the screen to play audio. The app will render a 440Hz sine wave
-while the screen is being pressed.
+[Oboe]: https://github.com/google/oboe
diff --git a/hello-oboe/app/build.gradle b/hello-oboe/app/build.gradle
deleted file mode 100644
index c0147b368..000000000
--- a/hello-oboe/app/build.gradle
+++ /dev/null
@@ -1,40 +0,0 @@
-plugins {
- id "ndksamples.android.application"
- id "ndksamples.android.kotlin"
-}
-
-android {
- namespace 'com.google.example.hellooboe'
-
- defaultConfig {
- applicationId "com.google.example.hellooboe"
- versionCode 1
- versionName "1.0"
- externalNativeBuild.cmake {
- arguments "-DANDROID_STL=c++_shared"
- }
-
- ndk {
- // Oboe doesn't currently (August 2025) include riscv64 libraries.
- abiFilters.remove("riscv64")
- }
- }
-
- externalNativeBuild {
- cmake {
- path "src/main/cpp/CMakeLists.txt"
- }
- }
-
- buildFeatures {
- prefab = true
- viewBinding = true
- }
-}
-
-dependencies {
- implementation project(":base")
- implementation libs.appcompat
- implementation libs.androidx.constraintlayout
- implementation libs.oboe
-}
diff --git a/hello-oboe/app/src/main/AndroidManifest.xml b/hello-oboe/app/src/main/AndroidManifest.xml
deleted file mode 100644
index bdb1e58ce..000000000
--- a/hello-oboe/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/hello-oboe/app/src/main/cpp/CMakeLists.txt b/hello-oboe/app/src/main/cpp/CMakeLists.txt
deleted file mode 100644
index a255e9ac5..000000000
--- a/hello-oboe/app/src/main/cpp/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# 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.22.1)
-project(hello-oboe LANGUAGES CXX)
-
-include(AppLibrary)
-find_package(base CONFIG REQUIRED)
-
-# add oboe pre-release lib hosted at https://maven.google.com/web/index.html
-# under com.google.oboe:oboe. For documentation about oboe pre-built lib, refer to
-# https://github.com/google/oboe/blob/master/docs/GettingStarted.md#option-1-using-pre-built-binaries-and-headers
-find_package(oboe REQUIRED CONFIG)
-
-# build application with the oboe lib
-add_app_library(${PROJECT_NAME} SHARED hello-oboe.cpp)
-target_link_libraries(${PROJECT_NAME} base::base oboe::oboe android log)
-
-# Enable optimization flags: if having problems with source level debugging,
-# disable -Ofast ( and debug ), re-enable after done debugging.
-target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Werror "$<$:-Ofast>")
diff --git a/hello-oboe/app/src/main/cpp/OboeSinePlayer.h b/hello-oboe/app/src/main/cpp/OboeSinePlayer.h
deleted file mode 100644
index be4c9c87a..000000000
--- a/hello-oboe/app/src/main/cpp/OboeSinePlayer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019 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 HELLO_OBOE_OBOESINEPLAYER_H
-#define HELLO_OBOE_OBOESINEPLAYER_H
-
-#include
-#include
-
-#include
-
-/*
- * This class is responsible for creating an audio stream and starting it.
- * It specifies a callback function onAudioReady which is called each time
- * the audio stream needs more data.
- * Inside this callback either silence is rendered or if the isOn variable
- * is true a sine wave will be rendered.
- * The sine wave's frequency is hardcoded to 440Hz inside kFrequency.
- */
-class OboeSinePlayer : public oboe::AudioStreamCallback {
- public:
- OboeSinePlayer() {
- oboe::AudioStreamBuilder builder;
- // The builder set methods can be chained for convenience.
- builder.setSharingMode(oboe::SharingMode::Exclusive);
- builder.setPerformanceMode(oboe::PerformanceMode::LowLatency);
- builder.setFormat(oboe::AudioFormat::Float);
- builder.setCallback(this);
- builder.openManagedStream(outStream);
- // Typically, start the stream after querying some stream information, as
- // well as some input from the user
- channelCount = outStream->getChannelCount();
- mPhaseIncrement = kFrequency * kTwoPi / outStream->getSampleRate();
- outStream->requestStart();
- }
-
- // This class will also be used for the callback
- // For more complicated callbacks create a separate class
- oboe::DataCallbackResult onAudioReady(oboe::AudioStream*, void* audioData,
- int32_t numFrames) override {
- float* floatData = static_cast(audioData);
- if (isOn) {
- // Generate sine wave values
- for (int i = 0; i < numFrames; ++i) {
- float sampleValue = kAmplitude * sinf(mPhase);
- for (int j = 0; j < channelCount; j++) {
- floatData[i * channelCount + j] = sampleValue;
- }
- mPhase += mPhaseIncrement;
- if (mPhase >= kTwoPi) mPhase -= kTwoPi;
- }
- } else {
- // This will output silence
- std::fill_n(floatData, numFrames * channelCount, 0);
- }
- return oboe::DataCallbackResult::Continue;
- }
-
- void enable(bool toEnable) { isOn.store(toEnable); }
-
- private:
- // ManagedStream will release audio resources when destroyed.
- oboe::ManagedStream outStream;
-
- std::atomic_bool isOn{false};
- int channelCount;
- double mPhaseIncrement;
-
- // Wave params, these could be instance variables in order to modify at
- // runtime
- static float constexpr kAmplitude = 0.5f;
- static float constexpr kFrequency = 440;
-
- // Keeps track of where the wave is
- float mPhase = 0.0;
-
- static double constexpr kTwoPi = M_PI * 2;
-};
-
-#endif // HELLO_OBOE_OBOESINEPLAYER_H
diff --git a/hello-oboe/app/src/main/cpp/hello-oboe.cpp b/hello-oboe/app/src/main/cpp/hello-oboe.cpp
deleted file mode 100644
index 36caf2119..000000000
--- a/hello-oboe/app/src/main/cpp/hello-oboe.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 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 "OboeSinePlayer.h"
-
-static OboeSinePlayer* oboePlayer = nullptr;
-
-/* Create Oboe playback stream
- * Returns: 0 - success
- * -1 - failed
- */
-jint CreateStream(JNIEnv* /* env */, jobject /* this */) {
- oboePlayer = new OboeSinePlayer();
-
- return oboePlayer ? 0 : -1;
-}
-void DestroyStream(JNIEnv* /* env */, jobject /* this */) {
- if (oboePlayer) {
- delete oboePlayer;
- oboePlayer = nullptr;
- }
-}
-/*
- * Play sound with pre-created Oboe stream
- * returns: 0 - success
- * -1 - failed (stream has not created yet )
- */
-jint PlaySound(JNIEnv* /* env */, jobject /* this */, jboolean enable) {
- jint result = 0;
- if (oboePlayer) {
- oboePlayer->enable(enable);
- } else {
- result = -1;
- }
- return result;
-}
-
-extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* _Nonnull vm, void* _Nullable) {
- JNIEnv* env;
- if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) {
- return JNI_ERR;
- }
-
- jclass c = env->FindClass("com/google/example/hellooboe/MainActivity");
- if (c == nullptr) return JNI_ERR;
-
- static const JNINativeMethod methods[] = {
- {"createStream", "()I", reinterpret_cast(CreateStream)},
- {"destroyStream", "()V", reinterpret_cast(DestroyStream)},
- {"playSound", "(Z)I", reinterpret_cast(PlaySound)},
- };
- int rc = env->RegisterNatives(c, methods, arraysize(methods));
- if (rc != JNI_OK) return rc;
-
- return JNI_VERSION_1_6;
-}
diff --git a/hello-oboe/app/src/main/cpp/libhello-oboe.map.txt b/hello-oboe/app/src/main/cpp/libhello-oboe.map.txt
deleted file mode 100644
index 4afed90dc..000000000
--- a/hello-oboe/app/src/main/cpp/libhello-oboe.map.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-LIBHELLOOBOE {
- global:
- JNI_OnLoad;
- local:
- *;
-};
diff --git a/hello-oboe/app/src/main/java/com/google/example/hellooboe/MainActivity.kt b/hello-oboe/app/src/main/java/com/google/example/hellooboe/MainActivity.kt
deleted file mode 100644
index a64874f66..000000000
--- a/hello-oboe/app/src/main/java/com/google/example/hellooboe/MainActivity.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- *
- */
-
-package com.google.example.hellooboe
-
-import androidx.appcompat.app.AppCompatActivity
-import android.os.Bundle
-import android.view.MotionEvent
-import android.view.View
-import android.widget.Toast
-import com.google.example.hellooboe.databinding.ActivityMainBinding
-
-class MainActivity : AppCompatActivity() {
-
- private lateinit var binding: ActivityMainBinding
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityMainBinding.inflate(layoutInflater)
- val view = binding.root
- setContentView(view)
- }
-
- /*
- * Hook to user control to start / stop audio playback:
- * touch-down: start, and keeps on playing
- * touch-up: stop.
- * simply pass the events to native side.
- */
- override fun onTouchEvent(event: MotionEvent): Boolean {
- when (event.actionMasked) {
- MotionEvent.ACTION_DOWN -> playSound(true)
- MotionEvent.ACTION_UP -> playSound(false)
- }
- return super.onTouchEvent(event)
- }
-
- override fun onResume() {
- super.onResume()
- if (createStream() != 0) {
- val errorString : String = getString(R.string.error_msg)
- Toast.makeText(applicationContext, errorString,Toast.LENGTH_LONG).show()
- binding.sampleText.text = errorString
- }
- }
-
- override fun onPause() {
- destroyStream()
- super.onPause()
- }
-
- // Creates and starts Oboe stream to play audio
- private external fun createStream() : Int
-
- // Closes and destroys Oboe stream when app goes out of focus
- private external fun destroyStream()
-
- // Plays sound on user tap
- private external fun playSound(enable: Boolean) : Int
-
- companion object {
- // Used to load native code calling oboe on app startup.
- init {
- System.loadLibrary("hello-oboe")
- }
- }
-}
diff --git a/hello-oboe/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/hello-oboe/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index 1f6bb2906..000000000
--- a/hello-oboe/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hello-oboe/app/src/main/res/drawable/ic_launcher_background.xml b/hello-oboe/app/src/main/res/drawable/ic_launcher_background.xml
deleted file mode 100644
index 0d025f9bf..000000000
--- a/hello-oboe/app/src/main/res/drawable/ic_launcher_background.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hello-oboe/app/src/main/res/layout/activity_main.xml b/hello-oboe/app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index bca13ec20..000000000
--- a/hello-oboe/app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/hello-oboe/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/hello-oboe/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
deleted file mode 100644
index eca70cfe5..000000000
--- a/hello-oboe/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/hello-oboe/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/hello-oboe/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index eca70cfe5..000000000
--- a/hello-oboe/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/hello-oboe/app/src/main/res/mipmap-hdpi/ic_launcher.png b/hello-oboe/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 898f3ed59..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/hello-oboe/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index dffca3601..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-mdpi/ic_launcher.png b/hello-oboe/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 64ba76f75..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/hello-oboe/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index dae5e0823..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/hello-oboe/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index e5ed46597..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/hello-oboe/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index 14ed0af35..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/hello-oboe/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index b0907cac3..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/hello-oboe/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index d8ae03154..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/hello-oboe/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 2c18de9e6..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/hello-oboe/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index beed3cdd2..000000000
Binary files a/hello-oboe/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/hello-oboe/app/src/main/res/values/colors.xml b/hello-oboe/app/src/main/res/values/colors.xml
deleted file mode 100644
index 69b22338c..000000000
--- a/hello-oboe/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- #008577
- #00574B
- #D81B60
-
diff --git a/hello-oboe/app/src/main/res/values/strings.xml b/hello-oboe/app/src/main/res/values/strings.xml
deleted file mode 100644
index 45a8225a6..000000000
--- a/hello-oboe/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
- Hello Oboe
- Tap to play!
- Error: unable to create Oboe stream
- \nPlease report issue @ https://github.com/google/oboe
-
diff --git a/hello-oboe/app/src/main/res/values/styles.xml b/hello-oboe/app/src/main/res/values/styles.xml
deleted file mode 100644
index 5885930df..000000000
--- a/hello-oboe/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
diff --git a/hello-oboe/screenshot.png b/hello-oboe/screenshot.png
deleted file mode 100755
index 91f02fe7b..000000000
Binary files a/hello-oboe/screenshot.png and /dev/null differ
diff --git a/settings.gradle b/settings.gradle
index 3af713008..7044cee1b 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -21,7 +21,6 @@ dependencyResolutionManagement {
}
rootProject.name = "NDK Samples"
-include(":audio-echo:app")
include(":base")
include(":bitmap-plasma:app")
include(":camera:basic")
@@ -33,7 +32,6 @@ include(":gles3jni:app")
include(":hello-gl2:app")
include(":hello-jni:app")
include(":hello-jniCallback:app")
-include(":hello-oboe:app")
include(":hello-vulkan:app")
include(":native-activity:app")
include(":native-audio:app")