diff options
Diffstat (limited to 'externals/oboe/samples/RhythmGame/src/main/cpp')
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 |
