diff options
| author | crueter <crueter@eden-emu.dev> | 2025-08-04 04:50:14 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2025-08-04 04:50:14 +0200 |
| commit | 51b170b470ed587f99a7c2a773e4464687f0d07a (patch) | |
| tree | 4c03c510cfb17a5f5d6233df490d78f06dcfa7f7 /externals/oboe/samples/RhythmGame/src/main/cpp/audio | |
| parent | 04e5e6453875ffa5c79cdb421a29bc19985b1049 (diff) | |
[cmake] refactor: Use CPM over submodules (#143)
Transfers the majority of submodules and large externals to CPM, using source archives rather than full Git clones. Not only does this save massive amounts of clone and configure time, but dependencies are grabbed on-demand rather than being required by default. Additionally, CPM will (generally) automatically search for system dependencies, though certain dependencies have options to control this.
Testing shows gains ranging from 5x to 10x in terms of overall clone/configure time.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/143
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Diffstat (limited to 'externals/oboe/samples/RhythmGame/src/main/cpp/audio')
9 files changed, 0 insertions, 892 deletions
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 |
