aboutsummaryrefslogtreecommitdiff
path: root/externals/oboe/samples/RhythmGame/src/main/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'externals/oboe/samples/RhythmGame/src/main/cpp')
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/Game.cpp241
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/Game.h85
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/GameConstants.h60
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/AAssetDataSource.cpp86
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/AAssetDataSource.h50
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/DataSource.h32
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/FFMpegExtractor.cpp318
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/FFMpegExtractor.h55
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/NDKExtractor.cpp199
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/NDKExtractor.h33
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/Player.cpp59
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/audio/Player.h60
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/native-lib.cpp93
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/ui/OpenGLFunctions.cpp33
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/ui/OpenGLFunctions.h58
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/utils/LockFreeQueue.h154
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/utils/UtilityFunctions.cpp40
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/utils/UtilityFunctions.h42
-rw-r--r--externals/oboe/samples/RhythmGame/src/main/cpp/utils/logging.h32
19 files changed, 0 insertions, 1730 deletions
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/Game.cpp b/externals/oboe/samples/RhythmGame/src/main/cpp/Game.cpp
deleted file mode 100644
index 199f4cce14..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/Game.cpp
+++ /dev/null
@@ -1,241 +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 <utils/logging.h>
-#include <thread>
-#include <cinttypes>
-
-#include "Game.h"
-
-Game::Game(AAssetManager &assetManager): mAssetManager(assetManager) {
-}
-
-void Game::load() {
-
- if (!openStream()) {
- mGameState = GameState::FailedToLoad;
- return;
- }
-
- if (!setupAudioSources()) {
- mGameState = GameState::FailedToLoad;
- return;
- }
-
- scheduleSongEvents();
-
- Result result = mAudioStream->requestStart();
- if (result != Result::OK){
- LOGE("Failed to start stream. Error: %s", convertToText(result));
- mGameState = GameState::FailedToLoad;
- return;
- }
-
- mGameState = GameState::Playing;
-}
-
-void Game::start() {
-
- // async returns a future, we must store this future to avoid blocking. It's not sufficient
- // to store this in a local variable as its destructor will block until Game::load completes.
- mLoadingResult = std::async(&Game::load, this);
-}
-
-void Game::stop(){
-
- if (mAudioStream){
- mAudioStream->stop();
- mAudioStream->close();
- mAudioStream.reset();
- }
-}
-
-void Game::tap(int64_t eventTimeAsUptime) {
-
- if (mGameState != GameState::Playing){
- LOGW("Game not in playing state, ignoring tap event");
- } else {
- mClap->setPlaying(true);
-
- int64_t nextClapWindowTimeMs;
- if (mClapWindows.pop(nextClapWindowTimeMs)){
-
- // Convert the tap time to a song position
- int64_t tapTimeInSongMs = mSongPositionMs + (eventTimeAsUptime - mLastUpdateTime);
- TapResult result = getTapResult(tapTimeInSongMs, nextClapWindowTimeMs);
- mUiEvents.push(result);
- }
- }
-}
-
-void Game::tick(){
-
- switch (mGameState){
- case GameState::Playing:
- TapResult r;
- if (mUiEvents.pop(r)) {
- renderEvent(r);
- } else {
- SetGLScreenColor(kPlayingColor);
- }
- break;
-
- case GameState::Loading:
- SetGLScreenColor(kLoadingColor);
- break;
-
- case GameState::FailedToLoad:
- SetGLScreenColor(kLoadingFailedColor);
- break;
- }
-}
-
-void Game::onSurfaceCreated() {
- SetGLScreenColor(kLoadingColor);
-}
-
-void Game::onSurfaceChanged(int widthInPixels, int heightInPixels) {
-}
-
-void Game::onSurfaceDestroyed() {
-}
-
-DataCallbackResult Game::onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) {
-
- auto *outputBuffer = static_cast<float *>(audioData);
-
- int64_t nextClapEventMs;
-
- for (int i = 0; i < numFrames; ++i) {
-
- mSongPositionMs = convertFramesToMillis(
- mCurrentFrame,
- mAudioStream->getSampleRate());
-
- if (mClapEvents.peek(nextClapEventMs) && mSongPositionMs >= nextClapEventMs){
- mClap->setPlaying(true);
- mClapEvents.pop(nextClapEventMs);
- }
- mMixer.renderAudio(outputBuffer+(oboeStream->getChannelCount()*i), 1);
- mCurrentFrame++;
- }
-
- mLastUpdateTime = nowUptimeMillis();
-
- return DataCallbackResult::Continue;
-}
-
-void Game::onErrorAfterClose(AudioStream *audioStream, Result error) {
- if (error == Result::ErrorDisconnected){
- mGameState = GameState::Loading;
- mAudioStream.reset();
- mMixer.removeAllTracks();
- mCurrentFrame = 0;
- mSongPositionMs = 0;
- mLastUpdateTime = 0;
- start();
- } else {
- LOGE("Stream error: %s", convertToText(error));
- }
-}
-
-/**
- * Get the result of a tap
- *
- * @param tapTimeInMillis - The time the tap occurred in milliseconds
- * @param tapWindowInMillis - The time at the middle of the "tap window" in milliseconds
- * @return TapResult can be Early, Late or Success
- */
-TapResult Game::getTapResult(int64_t tapTimeInMillis, int64_t tapWindowInMillis){
- LOGD("Tap time %" PRId64 ", tap window time: %" PRId64, tapTimeInMillis, tapWindowInMillis);
- if (tapTimeInMillis <= tapWindowInMillis + kWindowCenterOffsetMs) {
- if (tapTimeInMillis >= tapWindowInMillis - kWindowCenterOffsetMs) {
- return TapResult::Success;
- } else {
- return TapResult::Early;
- }
- } else {
- return TapResult::Late;
- }
-}
-
-bool Game::openStream() {
-
- // Create an audio stream
- AudioStreamBuilder builder;
- builder.setFormat(AudioFormat::Float);
- builder.setFormatConversionAllowed(true);
- builder.setPerformanceMode(PerformanceMode::LowLatency);
- builder.setSharingMode(SharingMode::Exclusive);
- builder.setSampleRate(48000);
- builder.setSampleRateConversionQuality(
- SampleRateConversionQuality::Medium);
- builder.setChannelCount(2);
- builder.setDataCallback(this);
- builder.setErrorCallback(this);
- Result result = builder.openStream(mAudioStream);
- if (result != Result::OK){
- LOGE("Failed to open stream. Error: %s", convertToText(result));
- return false;
- }
-
- mMixer.setChannelCount(mAudioStream->getChannelCount());
-
- return true;
-}
-
-bool Game::setupAudioSources() {
-
- // Set the properties of our audio source(s) to match that of our audio stream
- AudioProperties targetProperties {
- .channelCount = mAudioStream->getChannelCount(),
- .sampleRate = mAudioStream->getSampleRate()
- };
-
- // Create a data source and player for the clap sound
- std::shared_ptr<AAssetDataSource> mClapSource {
- AAssetDataSource::newFromCompressedAsset(mAssetManager, kClapFilename, targetProperties)
- };
- if (mClapSource == nullptr){
- LOGE("Could not load source data for clap sound");
- return false;
- }
- mClap = std::make_unique<Player>(mClapSource);
-
- // Create a data source and player for our backing track
- std::shared_ptr<AAssetDataSource> backingTrackSource {
- AAssetDataSource::newFromCompressedAsset(mAssetManager, kBackingTrackFilename, targetProperties)
- };
- if (backingTrackSource == nullptr){
- LOGE("Could not load source data for backing track");
- return false;
- }
- mBackingTrack = std::make_unique<Player>(backingTrackSource);
- mBackingTrack->setPlaying(true);
- mBackingTrack->setLooping(true);
-
- // Add both players to a mixer
- mMixer.addTrack(mClap.get());
- mMixer.addTrack(mBackingTrack.get());
-
- return true;
-}
-
-void Game::scheduleSongEvents() {
-
- for (auto t : kClapEvents) mClapEvents.push(t);
- for (auto t : kClapWindows) mClapWindows.push(t);
-}
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/Game.h b/externals/oboe/samples/RhythmGame/src/main/cpp/Game.h
deleted file mode 100644
index d9cb2ef7f0..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/Game.h
+++ /dev/null
@@ -1,85 +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.
- */
-
-#ifndef RHYTHMGAME_GAME_H
-#define RHYTHMGAME_GAME_H
-
-#include <future>
-
-#include <android/asset_manager.h>
-#include <oboe/Oboe.h>
-
-#include "shared/Mixer.h"
-
-#include "audio/Player.h"
-#include "audio/AAssetDataSource.h"
-#include "ui/OpenGLFunctions.h"
-#include "utils/LockFreeQueue.h"
-#include "utils/UtilityFunctions.h"
-#include "GameConstants.h"
-
-using namespace oboe;
-
-
-enum class GameState {
- Loading,
- Playing,
- FailedToLoad
-};
-
-class Game : public AudioStreamDataCallback, AudioStreamErrorCallback {
-public:
- explicit Game(AAssetManager&);
- void start();
- void stop();
- void onSurfaceCreated();
- void onSurfaceDestroyed();
- void onSurfaceChanged(int widthInPixels, int heightInPixels);
- void tick();
- void tap(int64_t eventTimeAsUptime);
-
- // Inherited from oboe::AudioStreamDataCallback.
- DataCallbackResult
- onAudioReady(AudioStream *oboeStream, void *audioData, int32_t numFrames) override;
-
- // Inherited from oboe::AudioStreamErrorCallback.
- void onErrorAfterClose(AudioStream *oboeStream, Result error) override;
-
-private:
- AAssetManager& mAssetManager;
- std::shared_ptr<AudioStream> mAudioStream;
- std::unique_ptr<Player> mClap;
- std::unique_ptr<Player> mBackingTrack;
- Mixer mMixer;
-
- LockFreeQueue<int64_t, kMaxQueueItems> mClapEvents;
- std::atomic<int64_t> mCurrentFrame { 0 };
- std::atomic<int64_t> mSongPositionMs { 0 };
- LockFreeQueue<int64_t, kMaxQueueItems> mClapWindows;
- LockFreeQueue<TapResult, kMaxQueueItems> mUiEvents;
- std::atomic<int64_t> mLastUpdateTime { 0 };
- std::atomic<GameState> mGameState { GameState::Loading };
- std::future<void> mLoadingResult;
-
- void load();
- TapResult getTapResult(int64_t tapTimeInMillis, int64_t tapWindowInMillis);
- bool openStream();
- bool setupAudioSources();
- void scheduleSongEvents();
-};
-
-
-#endif //RHYTHMGAME_GAME_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/GameConstants.h b/externals/oboe/samples/RhythmGame/src/main/cpp/GameConstants.h
deleted file mode 100644
index 288159279e..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/GameConstants.h
+++ /dev/null
@@ -1,60 +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.
- */
-
-#ifndef SAMPLES_GAMECONSTANTS_H
-#define SAMPLES_GAMECONSTANTS_H
-
-#include "ui/OpenGLFunctions.h"
-
-constexpr int kBufferSizeInBursts = 2; // Use 2 bursts as the buffer size (double buffer)
-constexpr int kMaxQueueItems = 4; // Must be power of 2
-
-// Colors for game states and visual feedback for taps
-constexpr ScreenColor kPlayingColor = GREY;
-constexpr ScreenColor kLoadingColor = YELLOW;
-constexpr ScreenColor kLoadingFailedColor = RED;
-constexpr ScreenColor kTapSuccessColor = GREEN;
-constexpr ScreenColor kTapEarlyColor = ORANGE;
-constexpr ScreenColor kTapLateColor = PURPLE;
-
-// This defines the size of the tap window in milliseconds. For example, if defined at 100ms the
-// player will have 100ms before and after the centre of the tap window to tap on the screen and
-// be successful
-constexpr int kWindowCenterOffsetMs = 100;
-
-// Filename for clap sound asset (in assets folder)
-constexpr char kClapFilename[] { "CLAP.mp3" };
-
-// Filename for the backing track asset (in assets folder)
-constexpr char kBackingTrackFilename[] { "FUNKY_HOUSE.mp3" };
-
-// The game will first demonstrate the pattern which the user should copy. It does this by
-// "clapping" (playing a clap sound) at certain times during the song. We can specify these times
-// here in milliseconds. Our backing track has a tempo of 120 beats per minute, which is 2 beats per
-// second. This means a pattern of 3 claps starting on the first beat of the first bar would mean
-// playing claps at 0ms, 500ms and 1000ms
-constexpr int64_t kClapEvents[] { 0, 500, 1000 };
-
-// We then want the user to tap on the screen exactly 4 beats after the first clap so we add clap
-// windows at 2000ms, 2500ms and 3000ms (or 2, 2.5 and 3 seconds). @see getTapResult for more info.
-constexpr int64_t kClapWindows[] { 2000, 2500, 3000 };
-
-struct AudioProperties {
- int32_t channelCount;
- int32_t sampleRate;
-};
-
-#endif //SAMPLES_GAMECONSTANTS_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/AAssetDataSource.cpp b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/AAssetDataSource.cpp
deleted file mode 100644
index 1c697878c2..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/AAssetDataSource.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 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 <utils/logging.h>
-#include <oboe/Oboe.h>
-
-#include "AAssetDataSource.h"
-
-#if !defined(USE_FFMPEG)
-#error USE_FFMPEG should be defined in app.gradle
-#endif
-
-#if USE_FFMPEG==1
-#include "FFMpegExtractor.h"
-#else
-#include "NDKExtractor.h"
-#endif
-
-
-constexpr int kMaxCompressionRatio { 12 };
-
-AAssetDataSource* AAssetDataSource::newFromCompressedAsset(
- AAssetManager &assetManager,
- const char *filename,
- const AudioProperties targetProperties) {
-
- AAsset *asset = AAssetManager_open(&assetManager, filename, AASSET_MODE_UNKNOWN);
- if (!asset) {
- LOGE("Failed to open asset %s", filename);
- return nullptr;
- }
-
- off_t assetSize = AAsset_getLength(asset);
- LOGD("Opened %s, size %ld", filename, assetSize);
-
- // Allocate memory to store the decompressed audio. We don't know the exact
- // size of the decoded data until after decoding so we make an assumption about the
- // maximum compression ratio and the decoded sample format (float for FFmpeg, int16 for NDK).
-#if USE_FFMPEG==true
- const long maximumDataSizeInBytes = kMaxCompressionRatio * assetSize * sizeof(float);
- auto decodedData = new uint8_t[maximumDataSizeInBytes];
-
- int64_t bytesDecoded = FFMpegExtractor::decode(asset, decodedData, targetProperties);
- auto numSamples = bytesDecoded / sizeof(float);
-#else
- const long maximumDataSizeInBytes = kMaxCompressionRatio * assetSize * sizeof(int16_t);
- auto decodedData = new uint8_t[maximumDataSizeInBytes];
-
- int64_t bytesDecoded = NDKExtractor::decode(asset, decodedData, targetProperties);
- auto numSamples = bytesDecoded / sizeof(int16_t);
-#endif
-
- // Now we know the exact number of samples we can create a float array to hold the audio data
- auto outputBuffer = std::make_unique<float[]>(numSamples);
-
-#if USE_FFMPEG==1
- memcpy(outputBuffer.get(), decodedData, (size_t)bytesDecoded);
-#else
- // The NDK decoder can only decode to int16, we need to convert to floats
- oboe::convertPcm16ToFloat(
- reinterpret_cast<int16_t*>(decodedData),
- outputBuffer.get(),
- bytesDecoded / sizeof(int16_t));
-#endif
-
- delete[] decodedData;
- AAsset_close(asset);
-
- return new AAssetDataSource(std::move(outputBuffer),
- numSamples,
- targetProperties);
-}
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/AAssetDataSource.h b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/AAssetDataSource.h
deleted file mode 100644
index cbcb433a34..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/AAssetDataSource.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 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 RHYTHMGAME_AASSETDATASOURCE_H
-#define RHYTHMGAME_AASSETDATASOURCE_H
-
-#include <android/asset_manager.h>
-#include <GameConstants.h>
-#include "DataSource.h"
-
-class AAssetDataSource : public DataSource {
-
-public:
- int64_t getSize() const override { return mBufferSize; }
- AudioProperties getProperties() const override { return mProperties; }
- const float* getData() const override { return mBuffer.get(); }
-
- static AAssetDataSource* newFromCompressedAsset(
- AAssetManager &assetManager,
- const char *filename,
- AudioProperties targetProperties);
-
-private:
-
- AAssetDataSource(std::unique_ptr<float[]> data, size_t size,
- const AudioProperties properties)
- : mBuffer(std::move(data))
- , mBufferSize(size)
- , mProperties(properties) {
- }
-
- const std::unique_ptr<float[]> mBuffer;
- const int64_t mBufferSize;
- const AudioProperties mProperties;
-
-};
-#endif //RHYTHMGAME_AASSETDATASOURCE_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/DataSource.h b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/DataSource.h
deleted file mode 100644
index 90284536bb..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/DataSource.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 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 RHYTHMGAME_AUDIOSOURCE_H
-#define RHYTHMGAME_AUDIOSOURCE_H
-
-#include <cstdint>
-#include <GameConstants.h>
-
-class DataSource {
-public:
- virtual ~DataSource(){};
- virtual int64_t getSize() const = 0;
- virtual AudioProperties getProperties() const = 0;
- virtual const float* getData() const = 0;
-};
-
-
-#endif //RHYTHMGAME_AUDIOSOURCE_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/FFMpegExtractor.cpp b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/FFMpegExtractor.cpp
deleted file mode 100644
index 97d212f369..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/FFMpegExtractor.cpp
+++ /dev/null
@@ -1,318 +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 <memory>
-#include <oboe/Definitions.h>
-#include "FFMpegExtractor.h"
-#include "utils/logging.h"
-
-constexpr int kInternalBufferSize = 1152; // Use MP3 block size. https://wiki.hydrogenaud.io/index.php?title=MP3
-
-int read(void *opaque, uint8_t *buf, int buf_size) {
-
- auto asset = (AAsset *) opaque;
- int bytesRead = AAsset_read(asset, buf, (size_t)buf_size);
- return bytesRead;
-}
-
-int64_t seek(void *opaque, int64_t offset, int whence){
-
- auto asset = (AAsset*)opaque;
-
- // See https://www.ffmpeg.org/doxygen/3.0/avio_8h.html#a427ff2a881637b47ee7d7f9e368be63f
- if (whence == AVSEEK_SIZE) return AAsset_getLength(asset);
- if (AAsset_seek(asset, offset, whence) == -1){
- return -1;
- } else {
- return 0;
- }
-}
-
-bool FFMpegExtractor::createAVIOContext(AAsset *asset, uint8_t *buffer, uint32_t bufferSize,
- AVIOContext **avioContext) {
-
- constexpr int isBufferWriteable = 0;
-
- *avioContext = avio_alloc_context(
- buffer, // internal buffer for FFmpeg to use
- bufferSize, // For optimal decoding speed this should be the protocol block size
- isBufferWriteable,
- asset, // Will be passed to our callback functions as a (void *)
- read, // Read callback function
- nullptr, // Write callback function (not used)
- seek); // Seek callback function
-
- if (*avioContext == nullptr){
- LOGE("Failed to create AVIO context");
- return false;
- } else {
- return true;
- }
-}
-
-bool
-FFMpegExtractor::createAVFormatContext(AVIOContext *avioContext, AVFormatContext **avFormatContext) {
-
- *avFormatContext = avformat_alloc_context();
- (*avFormatContext)->pb = avioContext;
-
- if (*avFormatContext == nullptr){
- LOGE("Failed to create AVFormatContext");
- return false;
- } else {
- return true;
- }
-}
-
-bool FFMpegExtractor::openAVFormatContext(AVFormatContext *avFormatContext) {
-
- int result = avformat_open_input(&avFormatContext,
- "", /* URL is left empty because we're providing our own I/O */
- nullptr /* AVInputFormat *fmt */,
- nullptr /* AVDictionary **options */
- );
-
- if (result == 0) {
- return true;
- } else {
- LOGE("Failed to open file. Error code %s", av_err2str(result));
- return false;
- }
-}
-
-bool FFMpegExtractor::getStreamInfo(AVFormatContext *avFormatContext) {
-
- int result = avformat_find_stream_info(avFormatContext, nullptr);
- if (result == 0 ){
- return true;
- } else {
- LOGE("Failed to find stream info. Error code %s", av_err2str(result));
- return false;
- }
-}
-
-AVStream *FFMpegExtractor::getBestAudioStream(AVFormatContext *avFormatContext) {
-
- int streamIndex = av_find_best_stream(avFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);
-
- if (streamIndex < 0){
- LOGE("Could not find stream");
- return nullptr;
- } else {
- return avFormatContext->streams[streamIndex];
- }
-}
-
-int64_t FFMpegExtractor::decode(
- AAsset *asset,
- uint8_t *targetData,
- AudioProperties targetProperties) {
-
- LOGI("Decoder: FFMpeg");
-
- int returnValue = -1; // -1 indicates error
-
- // Create a buffer for FFmpeg to use for decoding (freed in the custom deleter below)
- auto buffer = reinterpret_cast<uint8_t*>(av_malloc(kInternalBufferSize));
-
- // Create an AVIOContext with a custom deleter
- std::unique_ptr<AVIOContext, void(*)(AVIOContext *)> ioContext {
- nullptr,
- [](AVIOContext *c) {
- av_free(c->buffer);
- avio_context_free(&c);
- }
- };
- {
- AVIOContext *tmp = nullptr;
- if (!createAVIOContext(asset, buffer, kInternalBufferSize, &tmp)){
- LOGE("Could not create an AVIOContext");
- return returnValue;
- }
- ioContext.reset(tmp);
- }
-
- // Create an AVFormatContext using the avformat_free_context as the deleter function
- std::unique_ptr<AVFormatContext, decltype(&avformat_free_context)> formatContext {
- nullptr,
- &avformat_free_context
- };
- {
- AVFormatContext *tmp;
- if (!createAVFormatContext(ioContext.get(), &tmp)) return returnValue;
- formatContext.reset(tmp);
- }
-
- if (!openAVFormatContext(formatContext.get())) return returnValue;
-
- if (!getStreamInfo(formatContext.get())) return returnValue;
-
- // Obtain the best audio stream to decode
- AVStream *stream = getBestAudioStream(formatContext.get());
- if (stream == nullptr || stream->codecpar == nullptr){
- LOGE("Could not find a suitable audio stream to decode");
- return returnValue;
- }
-
- printCodecParameters(stream->codecpar);
-
- // Find the codec to decode this stream
- AVCodec *codec = avcodec_find_decoder(stream->codecpar->codec_id);
- if (!codec){
- LOGE("Could not find codec with ID: %d", stream->codecpar->codec_id);
- return returnValue;
- }
-
- // Create the codec context, specifying the deleter function
- std::unique_ptr<AVCodecContext, void(*)(AVCodecContext *)> codecContext {
- nullptr,
- [](AVCodecContext *c) { avcodec_free_context(&c); }
- };
- {
- AVCodecContext *tmp = avcodec_alloc_context3(codec);
- if (!tmp){
- LOGE("Failed to allocate codec context");
- return returnValue;
- }
- codecContext.reset(tmp);
- }
-
- // Copy the codec parameters into the context
- if (avcodec_parameters_to_context(codecContext.get(), stream->codecpar) < 0){
- LOGE("Failed to copy codec parameters to codec context");
- return returnValue;
- }
-
- // Open the codec
- if (avcodec_open2(codecContext.get(), codec, nullptr) < 0){
- LOGE("Could not open codec");
- return returnValue;
- }
-
- // prepare resampler
- int32_t outChannelLayout = (1 << targetProperties.channelCount) - 1;
- LOGD("Channel layout %d", outChannelLayout);
-
- SwrContext *swr = swr_alloc();
- av_opt_set_int(swr, "in_channel_count", stream->codecpar->channels, 0);
- av_opt_set_int(swr, "out_channel_count", targetProperties.channelCount, 0);
- av_opt_set_int(swr, "in_channel_layout", stream->codecpar->channel_layout, 0);
- av_opt_set_int(swr, "out_channel_layout", outChannelLayout, 0);
- av_opt_set_int(swr, "in_sample_rate", stream->codecpar->sample_rate, 0);
- av_opt_set_int(swr, "out_sample_rate", targetProperties.sampleRate, 0);
- av_opt_set_int(swr, "in_sample_fmt", stream->codecpar->format, 0);
- av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
- av_opt_set_int(swr, "force_resampling", 1, 0);
-
- // Check that resampler has been inited
- int result = swr_init(swr);
- if (result != 0){
- LOGE("swr_init failed. Error: %s", av_err2str(result));
- return returnValue;
- };
- if (!swr_is_initialized(swr)) {
- LOGE("swr_is_initialized is false\n");
- return returnValue;
- }
-
- // Prepare to read data
- int bytesWritten = 0;
- AVPacket avPacket; // Stores compressed audio data
- av_init_packet(&avPacket);
- AVFrame *decodedFrame = av_frame_alloc(); // Stores raw audio data
- int bytesPerSample = av_get_bytes_per_sample((AVSampleFormat)stream->codecpar->format);
-
- LOGD("Bytes per sample %d", bytesPerSample);
-
- LOGD("DECODE START");
-
- // While there is more data to read, read it into the avPacket
- while (av_read_frame(formatContext.get(), &avPacket) == 0){
-
- if (avPacket.stream_index == stream->index && avPacket.size > 0) {
-
- // Pass our compressed data into the codec
- result = avcodec_send_packet(codecContext.get(), &avPacket);
- if (result != 0) {
- LOGE("avcodec_send_packet error: %s", av_err2str(result));
- goto cleanup;
- }
-
- // Retrieve our raw data from the codec
- result = avcodec_receive_frame(codecContext.get(), decodedFrame);
- if (result == AVERROR(EAGAIN)) {
- // The codec needs more data before it can decode
- LOGI("avcodec_receive_frame returned EAGAIN");
- av_packet_unref(&avPacket);
- continue;
- } else if (result != 0) {
- LOGE("avcodec_receive_frame error: %s", av_err2str(result));
- goto cleanup;
- }
-
- // DO RESAMPLING
- auto dst_nb_samples = (int32_t) av_rescale_rnd(
- swr_get_delay(swr, decodedFrame->sample_rate) + decodedFrame->nb_samples,
- targetProperties.sampleRate,
- decodedFrame->sample_rate,
- AV_ROUND_UP);
-
- short *buffer1;
- av_samples_alloc(
- (uint8_t **) &buffer1,
- nullptr,
- targetProperties.channelCount,
- dst_nb_samples,
- AV_SAMPLE_FMT_FLT,
- 0);
- int frame_count = swr_convert(
- swr,
- (uint8_t **) &buffer1,
- dst_nb_samples,
- (const uint8_t **) decodedFrame->data,
- decodedFrame->nb_samples);
-
- int64_t bytesToWrite = frame_count * sizeof(float) * targetProperties.channelCount;
- memcpy(targetData + bytesWritten, buffer1, (size_t)bytesToWrite);
- bytesWritten += bytesToWrite;
- av_freep(&buffer1);
-
- av_packet_unref(&avPacket);
- }
- }
-
- av_frame_free(&decodedFrame);
- LOGD("DECODE END");
-
- returnValue = bytesWritten;
-
- cleanup:
- return returnValue;
-}
-
-void FFMpegExtractor::printCodecParameters(AVCodecParameters *params) {
-
- LOGD("Stream properties");
- LOGD("Channels: %d", params->channels);
- LOGD("Channel layout: %" PRId64, params->channel_layout);
- LOGD("Sample rate: %d", params->sample_rate);
- LOGD("Format: %s", av_get_sample_fmt_name((AVSampleFormat)params->format));
- LOGD("Frame size: %d", params->frame_size);
-}
-
-
-
-
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/FFMpegExtractor.h b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/FFMpegExtractor.h
deleted file mode 100644
index a439b37c0a..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/FFMpegExtractor.h
+++ /dev/null
@@ -1,55 +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.
- */
-
-#ifndef FFMPEG_FFMPEGEXTRACTOR_H
-#define FFMPEG_FFMPEGEXTRACTOR_H
-
-
-extern "C" {
-#include <libavformat/avformat.h>
-#include <libswresample/swresample.h>
-#include <libavutil/opt.h>
-}
-
-#include <cstdint>
-#include <android/asset_manager.h>
-#include <GameConstants.h>
-
-class FFMpegExtractor {
-public:
- static int64_t decode(AAsset *asset, uint8_t *targetData, AudioProperties targetProperties);
-
-private:
- static bool createAVIOContext(AAsset *asset, uint8_t *buffer, uint32_t bufferSize,
- AVIOContext **avioContext);
-
- static bool createAVFormatContext(AVIOContext *avioContext, AVFormatContext **avFormatContext);
-
- static bool openAVFormatContext(AVFormatContext *avFormatContext);
-
- static int32_t cleanup(AVIOContext *avioContext, AVFormatContext *avFormatContext);
-
- static bool getStreamInfo(AVFormatContext *avFormatContext);
-
- static AVStream *getBestAudioStream(AVFormatContext *avFormatContext);
-
- static AVCodec *findCodec(AVCodecID id);
-
- static void printCodecParameters(AVCodecParameters *params);
-};
-
-
-#endif //FFMPEG_FFMPEGEXTRACTOR_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/NDKExtractor.cpp b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/NDKExtractor.cpp
deleted file mode 100644
index ac50940d91..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/NDKExtractor.cpp
+++ /dev/null
@@ -1,199 +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 <sys/types.h>
-
-#include <cstring>
-
-#include <media/NdkMediaExtractor.h>
-#include <utils/logging.h>
-#include <cinttypes>
-
-#include "NDKExtractor.h"
-
-int32_t NDKExtractor::decode(AAsset *asset, uint8_t *targetData, AudioProperties targetProperties) {
-
- LOGD("Using NDK decoder");
-
- // open asset as file descriptor
- off_t start, length;
- int fd = AAsset_openFileDescriptor(asset, &start, &length);
-
- // Extract the audio frames
- AMediaExtractor *extractor = AMediaExtractor_new();
- media_status_t amresult = AMediaExtractor_setDataSourceFd(extractor, fd,
- static_cast<off64_t>(start),
- static_cast<off64_t>(length));
- if (amresult != AMEDIA_OK){
- LOGE("Error setting extractor data source, err %d", amresult);
- return 0;
- }
-
- // Specify our desired output format by creating it from our source
- AMediaFormat *format = AMediaExtractor_getTrackFormat(extractor, 0);
-
- int32_t sampleRate;
- if (AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate)){
- LOGD("Source sample rate %d", sampleRate);
- if (sampleRate != targetProperties.sampleRate){
- LOGE("Input (%d) and output (%d) sample rates do not match. "
- "NDK decoder does not support resampling.",
- sampleRate,
- targetProperties.sampleRate);
- return 0;
- }
- } else {
- LOGE("Failed to get sample rate");
- return 0;
- };
-
- int32_t channelCount;
- if (AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount)){
- LOGD("Got channel count %d", channelCount);
- if (channelCount != targetProperties.channelCount){
- LOGE("NDK decoder does not support different "
- "input (%d) and output (%d) channel counts",
- channelCount,
- targetProperties.channelCount);
- }
- } else {
- LOGE("Failed to get channel count");
- return 0;
- }
-
- const char *formatStr = AMediaFormat_toString(format);
- LOGD("Output format %s", formatStr);
-
- const char *mimeType;
- if (AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mimeType)) {
- LOGD("Got mime type %s", mimeType);
- } else {
- LOGE("Failed to get mime type");
- return 0;
- }
-
- // Obtain the correct decoder
- AMediaCodec *codec = nullptr;
- AMediaExtractor_selectTrack(extractor, 0);
- codec = AMediaCodec_createDecoderByType(mimeType);
- AMediaCodec_configure(codec, format, nullptr, nullptr, 0);
- AMediaCodec_start(codec);
-
- // DECODE
-
- bool isExtracting = true;
- bool isDecoding = true;
- int32_t bytesWritten = 0;
-
- while(isExtracting || isDecoding){
-
- if (isExtracting){
-
- // Obtain the index of the next available input buffer
- ssize_t inputIndex = AMediaCodec_dequeueInputBuffer(codec, 2000);
- //LOGV("Got input buffer %d", inputIndex);
-
- // The input index acts as a status if its negative
- if (inputIndex < 0){
- if (inputIndex == AMEDIACODEC_INFO_TRY_AGAIN_LATER){
- // LOGV("Codec.dequeueInputBuffer try again later");
- } else {
- LOGE("Codec.dequeueInputBuffer unknown error status");
- }
- } else {
-
- // Obtain the actual buffer and read the encoded data into it
- size_t inputSize;
- uint8_t *inputBuffer = AMediaCodec_getInputBuffer(codec, inputIndex, &inputSize);
- //LOGV("Sample size is: %d", inputSize);
-
- ssize_t sampleSize = AMediaExtractor_readSampleData(extractor, inputBuffer, inputSize);
- auto presentationTimeUs = AMediaExtractor_getSampleTime(extractor);
-
- if (sampleSize > 0){
-
- // Enqueue the encoded data
- AMediaCodec_queueInputBuffer(codec, inputIndex, 0, sampleSize,
- presentationTimeUs,
- 0);
- AMediaExtractor_advance(extractor);
-
- } else {
- LOGD("End of extractor data stream");
- isExtracting = false;
-
- // We need to tell the codec that we've reached the end of the stream
- AMediaCodec_queueInputBuffer(codec, inputIndex, 0, 0,
- presentationTimeUs,
- AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
- }
- }
- }
-
- if (isDecoding){
- // Dequeue the decoded data
- AMediaCodecBufferInfo info;
- ssize_t outputIndex = AMediaCodec_dequeueOutputBuffer(codec, &info, 0);
-
- if (outputIndex >= 0){
-
- // Check whether this is set earlier
- if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM){
- LOGD("Reached end of decoding stream");
- isDecoding = false;
- }
-
- // Valid index, acquire buffer
- size_t outputSize;
- uint8_t *outputBuffer = AMediaCodec_getOutputBuffer(codec, outputIndex, &outputSize);
-
- /*LOGV("Got output buffer index %d, buffer size: %d, info size: %d writing to pcm index %d",
- outputIndex,
- outputSize,
- info.size,
- m_writeIndex);*/
-
- // copy the data out of the buffer
- memcpy(targetData + bytesWritten, outputBuffer, info.size);
- bytesWritten+=info.size;
- AMediaCodec_releaseOutputBuffer(codec, outputIndex, false);
- } else {
-
- // The outputIndex doubles as a status return if its value is < 0
- switch(outputIndex){
- case AMEDIACODEC_INFO_TRY_AGAIN_LATER:
- LOGD("dequeueOutputBuffer: try again later");
- break;
- case AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED:
- LOGD("dequeueOutputBuffer: output buffers changed");
- break;
- case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED:
- LOGD("dequeueOutputBuffer: output outputFormat changed");
- format = AMediaCodec_getOutputFormat(codec);
- LOGD("outputFormat changed to: %s", AMediaFormat_toString(format));
- break;
- }
- }
- }
- }
-
- // Clean up
- AMediaFormat_delete(format);
- AMediaCodec_delete(codec);
- AMediaExtractor_delete(extractor);
-
- return bytesWritten;
-}
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/NDKExtractor.h b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/NDKExtractor.h
deleted file mode 100644
index 0073f7262d..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/NDKExtractor.h
+++ /dev/null
@@ -1,33 +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.
- */
-
-#ifndef FFMPEG_NDKMEDIAEXTRACTOR_H
-#define FFMPEG_NDKMEDIAEXTRACTOR_H
-
-
-#include <cstdint>
-#include <android/asset_manager.h>
-#include <GameConstants.h>
-
-
-class NDKExtractor {
-
-public:
- static int32_t decode(AAsset *asset, uint8_t *targetData, AudioProperties targetProperties);
-};
-
-
-#endif //FFMPEG_NDKMEDIAEXTRACTOR_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/Player.cpp b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/Player.cpp
deleted file mode 100644
index e73a9c351a..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/Player.cpp
+++ /dev/null
@@ -1,59 +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 "Player.h"
-#include "utils/logging.h"
-
-void Player::renderAudio(float *targetData, int32_t numFrames){
-
- const AudioProperties properties = mSource->getProperties();
-
- if (mIsPlaying){
-
- int64_t framesToRenderFromData = numFrames;
- int64_t totalSourceFrames = mSource->getSize() / properties.channelCount;
- const float *data = mSource->getData();
-
- // Check whether we're about to reach the end of the recording
- if (!mIsLooping && mReadFrameIndex + numFrames >= totalSourceFrames){
- framesToRenderFromData = totalSourceFrames - mReadFrameIndex;
- mIsPlaying = false;
- }
-
- for (int i = 0; i < framesToRenderFromData; ++i) {
- for (int j = 0; j < properties.channelCount; ++j) {
- targetData[(i*properties.channelCount)+j] = data[(mReadFrameIndex*properties.channelCount)+j];
- }
-
- // Increment and handle wraparound
- if (++mReadFrameIndex >= totalSourceFrames) mReadFrameIndex = 0;
- }
-
- if (framesToRenderFromData < numFrames){
- // fill the rest of the buffer with silence
- renderSilence(&targetData[framesToRenderFromData], numFrames * properties.channelCount);
- }
-
- } else {
- renderSilence(targetData, numFrames * properties.channelCount);
- }
-}
-
-void Player::renderSilence(float *start, int32_t numSamples){
- for (int i = 0; i < numSamples; ++i) {
- start[i] = 0;
- }
-}
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/Player.h b/externals/oboe/samples/RhythmGame/src/main/cpp/audio/Player.h
deleted file mode 100644
index 9c7eebace2..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/audio/Player.h
+++ /dev/null
@@ -1,60 +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.
- */
-
-#ifndef RHYTHMGAME_SOUNDRECORDING_H
-#define RHYTHMGAME_SOUNDRECORDING_H
-
-#include <cstdint>
-#include <array>
-
-#include <chrono>
-#include <memory>
-#include <atomic>
-
-#include <android/asset_manager.h>
-
-#include "shared/IRenderableAudio.h"
-#include "DataSource.h"
-
-class Player : public IRenderableAudio{
-
-public:
- /**
- * Construct a new Player from the given DataSource. Players can share the same data source.
- * For example, you could play two identical sounds concurrently by creating 2 Players with the
- * same data source.
- *
- * @param source
- */
- Player(std::shared_ptr<DataSource> source)
- : mSource(source)
- {};
-
- void renderAudio(float *targetData, int32_t numFrames);
- void resetPlayHead() { mReadFrameIndex = 0; };
- void setPlaying(bool isPlaying) { mIsPlaying = isPlaying; resetPlayHead(); };
- void setLooping(bool isLooping) { mIsLooping = isLooping; };
-
-private:
- int32_t mReadFrameIndex = 0;
- std::atomic<bool> mIsPlaying { false };
- std::atomic<bool> mIsLooping { false };
- std::shared_ptr<DataSource> mSource;
-
- void renderSilence(float*, int32_t);
-};
-
-#endif //RHYTHMGAME_SOUNDRECORDING_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/native-lib.cpp b/externals/oboe/samples/RhythmGame/src/main/cpp/native-lib.cpp
deleted file mode 100644
index 456b64837d..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/native-lib.cpp
+++ /dev/null
@@ -1,93 +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 <jni.h>
-#include <memory>
-
-#include <android/asset_manager_jni.h>
-
-#include "utils/logging.h"
-#include "Game.h"
-
-
-extern "C" {
-
-std::unique_ptr<Game> game;
-
-JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_rhythmgame_MainActivity_native_1onStart(JNIEnv *env, jobject instance,
- jobject jAssetManager) {
-
- AAssetManager *assetManager = AAssetManager_fromJava(env, jAssetManager);
- if (assetManager == nullptr) {
- LOGE("Could not obtain the AAssetManager");
- return;
- }
-
- game = std::make_unique<Game>(*assetManager);
- game->start();
-}
-
-JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_rhythmgame_RendererWrapper_native_1onSurfaceCreated(JNIEnv *env,
- jobject instance) {
- game->onSurfaceCreated();
-}
-
-JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_rhythmgame_RendererWrapper_native_1onSurfaceChanged(JNIEnv *env,
- jclass type,
- jint width,
- jint height) {
- game->onSurfaceChanged(width, height);
-}
-
-JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_rhythmgame_RendererWrapper_native_1onDrawFrame(JNIEnv *env,
- jclass type) {
- game->tick();
-}
-
-JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_rhythmgame_GameSurfaceView_native_1onTouchInput(JNIEnv *env,
- jclass type,
- jint event_type,
- jlong time_since_boot_ms,
- jint pixel_x,
- jint pixel_y) {
- game->tap(time_since_boot_ms);
-}
-
-JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_rhythmgame_GameSurfaceView_native_1surfaceDestroyed__(JNIEnv *env,
- jclass type) {
- game->onSurfaceDestroyed();
-}
-
-JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_rhythmgame_MainActivity_native_1onStop(JNIEnv *env, jobject instance) {
-
- game->stop();
-}
-
-JNIEXPORT void JNICALL
-Java_com_google_oboe_samples_rhythmgame_MainActivity_native_1setDefaultStreamValues(JNIEnv *env,
- jclass type,
- jint sampleRate,
- jint framesPerBurst) {
- oboe::DefaultStreamValues::SampleRate = (int32_t) sampleRate;
- oboe::DefaultStreamValues::FramesPerBurst = (int32_t) framesPerBurst;
-}
-} // extern "C"
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/ui/OpenGLFunctions.cpp b/externals/oboe/samples/RhythmGame/src/main/cpp/ui/OpenGLFunctions.cpp
deleted file mode 100644
index 3662f6b217..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/ui/OpenGLFunctions.cpp
+++ /dev/null
@@ -1,33 +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 "OpenGLFunctions.h"
-#include "utils/logging.h"
-
-void CheckOpenGLError(const char* stmt, const char* fname, int line)
-{
- GLenum err = glGetError();
- if (err != GL_NO_ERROR)
- {
- LOGW("OpenGL error %08x, at %s:%i - for %s\n", err, fname, line, stmt);
- assert(false);
- }
-}
-
-void SetGLScreenColor(ScreenColor color){
- glClearColor(color.red, color.green, color.blue, color.alpha);
- glClear(GL_COLOR_BUFFER_BIT);
-}
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/ui/OpenGLFunctions.h b/externals/oboe/samples/RhythmGame/src/main/cpp/ui/OpenGLFunctions.h
deleted file mode 100644
index cd6ef2050f..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/ui/OpenGLFunctions.h
+++ /dev/null
@@ -1,58 +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.
- */
-
-#ifndef ANDROID_OGL_H
-#define ANDROID_OGL_H
-
-#include <assert.h>
-
-struct ScreenColor {
- float red;
- float green;
- float blue;
- float alpha;
-};
-
-constexpr ScreenColor RED { 1.0f, 0.0f, 0.0f, 1.0f };
-constexpr ScreenColor GREEN { 0.0f, 1.0f, 0.0f, 1.0f };
-constexpr ScreenColor BLUE { 0.0f, 0.0f, 1.0f, 1.0f };
-constexpr ScreenColor PURPLE { 1.0f, 0.0f, 1.0f, 1.0f };
-constexpr ScreenColor ORANGE { 1.0f, 0.5f, 0.0f, 1.0f };
-constexpr ScreenColor GREY { 0.3f, 0.3f, 0.3f, 0.3f };
-constexpr ScreenColor YELLOW { 1.0f, 1.0f, 0.0f, 1.0f };
-
-#ifdef GL3
-#include <GLES3/gl3.h>
-#elif GL3_2
-#include <GLES3/gl32.h>
-#else
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#endif
-
-void CheckOpenGLError(const char* stmt, const char* fname, int line);
-
-#ifndef NDEBUG
-#define GL_CHECK(stmt) \
- stmt;\
- CheckOpenGLError(#stmt, __FILE__, __LINE__);
-#else
-#define GL_CHECK(stmt) stmt
-#endif
-
-void SetGLScreenColor(ScreenColor color);
-
-#endif //ANDROID_OGL_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/utils/LockFreeQueue.h b/externals/oboe/samples/RhythmGame/src/main/cpp/utils/LockFreeQueue.h
deleted file mode 100644
index fa9f7168bb..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/utils/LockFreeQueue.h
+++ /dev/null
@@ -1,154 +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.
- */
-
-
-#ifndef RHYTHMGAME_LOCKFREEQUEUE_H
-#define RHYTHMGAME_LOCKFREEQUEUE_H
-
-#include <cstdint>
-#include <atomic>
-
-/**
- * A lock-free queue for single consumer, single producer. Not thread-safe when using multiple
- * consumers or producers.
- *
- * Example code:
- *
- * LockFreeQueue<int, 1024> myQueue;
- * int value = 123;
- * myQueue.push(value);
- * myQueue.pop(value);
- *
- * @tparam T - The item type
- * @tparam CAPACITY - Maximum number of items which can be held in the queue. Must be a power of 2.
- * Must be less than the maximum value permissible in INDEX_TYPE
- * @tparam INDEX_TYPE - The internal index type, defaults to uint32_t. Changing this will affect
- * the maximum capacity. Included for ease of unit testing because testing queue lengths of
- * UINT32_MAX can be time consuming and is not always possible.
- */
-
-template <typename T, uint32_t CAPACITY, typename INDEX_TYPE = uint32_t>
-class LockFreeQueue {
-public:
-
- /**
- * Implementation details:
- *
- * We have 2 counters: readCounter and writeCounter. Each will increment until it reaches
- * INDEX_TYPE_MAX, then wrap to zero. Unsigned integer overflow is defined behaviour in C++.
- *
- * Each time we need to access our data array we call mask() which gives us the index into the
- * array. This approach avoids having a "dead item" in the buffer to distinguish between full
- * and empty states. It also allows us to have a size() method which is easily calculated.
- *
- * IMPORTANT: This implementation is only thread-safe with a single reader thread and a single
- * writer thread. Have more than one of either will result in Bad Thingsā„¢.
- */
-
- static constexpr bool isPowerOfTwo(uint32_t n) { return (n & (n - 1)) == 0; }
- static_assert(isPowerOfTwo(CAPACITY), "Capacity must be a power of 2");
- static_assert(std::is_unsigned<INDEX_TYPE>::value, "Index type must be unsigned");
-
- /**
- * Pop a value off the head of the queue
- *
- * @param val - element will be stored in this variable
- * @return true if value was popped successfully, false if the queue is empty
- */
- bool pop(T &val) {
- if (isEmpty()){
- return false;
- } else {
- val = buffer[mask(readCounter)];
- ++readCounter;
- return true;
- }
- }
-
- /**
- * Add an item to the back of the queue
- *
- * @param item - The item to add
- * @return true if item was added, false if the queue was full
- */
- bool push(const T& item) {
- if (isFull()){
- return false;
- } else {
- buffer[mask(writeCounter)] = item;
- ++writeCounter;
- return true;
- }
- }
-
- /**
- * Get the item at the front of the queue but do not remove it
- *
- * @param item - item will be stored in this variable
- * @return true if item was stored, false if the queue was empty
- */
- bool peek(T &item) const {
- if (isEmpty()){
- return false;
- } else {
- item = buffer[mask(readCounter)];
- return true;
- }
- }
-
- /**
- * Get the number of items in the queue
- *
- * @return number of items in the queue
- */
- INDEX_TYPE size() const {
-
- /**
- * This is worth some explanation:
- *
- * Whilst writeCounter is greater than readCounter the result of (write - read) will always
- * be positive. Simple.
- *
- * But when writeCounter is equal to INDEX_TYPE_MAX (e.g. UINT32_MAX) the next push will
- * wrap it around to zero, the start of the buffer, making writeCounter less than
- * readCounter so the result of (write - read) will be negative.
- *
- * But because we're returning an unsigned type return value will be as follows:
- *
- * returnValue = INDEX_TYPE_MAX - (write - read)
- *
- * e.g. if write is 0, read is 150 and the INDEX_TYPE is uint8_t where the max value is
- * 255 the return value will be (255 - (0 - 150)) = 105.
- *
- */
- return writeCounter - readCounter;
- };
-
-private:
-
- bool isEmpty() const { return readCounter == writeCounter; }
-
- bool isFull() const { return size() == CAPACITY; }
-
- INDEX_TYPE mask(INDEX_TYPE n) const { return static_cast<INDEX_TYPE>(n & (CAPACITY - 1)); }
-
- T buffer[CAPACITY];
- std::atomic<INDEX_TYPE> writeCounter { 0 };
- std::atomic<INDEX_TYPE> readCounter { 0 };
-
-};
-
-#endif //RHYTHMGAME_LOCKFREEQUEUE_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/utils/UtilityFunctions.cpp b/externals/oboe/samples/RhythmGame/src/main/cpp/utils/UtilityFunctions.cpp
deleted file mode 100644
index 431f607374..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/utils/UtilityFunctions.cpp
+++ /dev/null
@@ -1,40 +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 <chrono>
-#include <ui/OpenGLFunctions.h>
-#include <GameConstants.h>
-#include "UtilityFunctions.h"
-#include "logging.h"
-
-int64_t nowUptimeMillis() {
- using namespace std::chrono;
- return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
-}
-
-void renderEvent(TapResult r){
- switch (r) {
- case TapResult::Success:
- SetGLScreenColor(kTapSuccessColor);
- break;
- case TapResult::Early:
- SetGLScreenColor(kTapEarlyColor);
- break;
- case TapResult::Late:
- SetGLScreenColor(kTapLateColor);
- break;
- }
-}
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/utils/UtilityFunctions.h b/externals/oboe/samples/RhythmGame/src/main/cpp/utils/UtilityFunctions.h
deleted file mode 100644
index 659cd109b9..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/utils/UtilityFunctions.h
+++ /dev/null
@@ -1,42 +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.
- */
-
-#ifndef RHYTHMGAME_UTILITYFUNCTIONS_H
-#define RHYTHMGAME_UTILITYFUNCTIONS_H
-
-#include <stdint.h>
-
-constexpr int64_t kMillisecondsInSecond = 1000;
-constexpr int64_t kNanosecondsInMillisecond = 1000000;
-
-enum class TapResult {
- Early,
- Late,
- Success
-};
-
-int64_t nowUptimeMillis();
-
-constexpr int64_t convertFramesToMillis(const int64_t frames, const int sampleRate){
- return static_cast<int64_t>((static_cast<double>(frames)/ sampleRate) * kMillisecondsInSecond);
-}
-
-TapResult getTapResult(int64_t tapTimeInMillis, int64_t tapWindowInMillis);
-
-void renderEvent(TapResult r);
-
-
-#endif //RHYTHMGAME_UTILITYFUNCTIONS_H
diff --git a/externals/oboe/samples/RhythmGame/src/main/cpp/utils/logging.h b/externals/oboe/samples/RhythmGame/src/main/cpp/utils/logging.h
deleted file mode 100644
index cc04619805..0000000000
--- a/externals/oboe/samples/RhythmGame/src/main/cpp/utils/logging.h
+++ /dev/null
@@ -1,32 +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.
- */
-
-#ifndef ANDROID_LOGGING_H
-#define ANDROID_LOGGING_H
-
-#include <stdio.h>
-#include <android/log.h>
-#include <vector>
-
-#define APP_NAME "RhythmGame"
-#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, APP_NAME, __VA_ARGS__))
-#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__))
-#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, APP_NAME, __VA_ARGS__))
-#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
-
-
-
-#endif //ANDROID_LOGGING_H