From 51b170b470ed587f99a7c2a773e4464687f0d07a Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 4 Aug 2025 04:50:14 +0200 Subject: [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 --- .../oboe/src/common/DataConversionFlowGraph.cpp | 266 --------------------- 1 file changed, 266 deletions(-) delete mode 100644 externals/oboe/src/common/DataConversionFlowGraph.cpp (limited to 'externals/oboe/src/common/DataConversionFlowGraph.cpp') diff --git a/externals/oboe/src/common/DataConversionFlowGraph.cpp b/externals/oboe/src/common/DataConversionFlowGraph.cpp deleted file mode 100644 index 0bb51ae2eb..0000000000 --- a/externals/oboe/src/common/DataConversionFlowGraph.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "OboeDebug.h" -#include "DataConversionFlowGraph.h" -#include "SourceFloatCaller.h" -#include "SourceI16Caller.h" -#include "SourceI24Caller.h" -#include "SourceI32Caller.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace oboe; -using namespace flowgraph; -using namespace resampler; - -void DataConversionFlowGraph::setSource(const void *buffer, int32_t numFrames) { - mSource->setData(buffer, numFrames); -} - -static MultiChannelResampler::Quality convertOboeSRQualityToMCR(SampleRateConversionQuality quality) { - switch (quality) { - case SampleRateConversionQuality::Fastest: - return MultiChannelResampler::Quality::Fastest; - case SampleRateConversionQuality::Low: - return MultiChannelResampler::Quality::Low; - default: - case SampleRateConversionQuality::Medium: - return MultiChannelResampler::Quality::Medium; - case SampleRateConversionQuality::High: - return MultiChannelResampler::Quality::High; - case SampleRateConversionQuality::Best: - return MultiChannelResampler::Quality::Best; - } -} - -// Chain together multiple processors. -// Callback Output -// Use SourceCaller that calls original app callback from the flowgraph. -// The child callback from FilteredAudioStream read()s from the flowgraph. -// Callback Input -// Child callback from FilteredAudioStream writes()s to the flowgraph. -// The output of the flowgraph goes through a BlockWriter to the app callback. -// Blocking Write -// Write buffer is set on an AudioSource. -// Data is pulled through the graph and written to the child stream. -// Blocking Read -// Reads in a loop from the flowgraph Sink to fill the read buffer. -// A SourceCaller then does a blocking read from the child Stream. -// -Result DataConversionFlowGraph::configure(AudioStream *sourceStream, AudioStream *sinkStream) { - - FlowGraphPortFloatOutput *lastOutput = nullptr; - - bool isOutput = sourceStream->getDirection() == Direction::Output; - bool isInput = !isOutput; - mFilterStream = isOutput ? sourceStream : sinkStream; - - AudioFormat sourceFormat = sourceStream->getFormat(); - int32_t sourceChannelCount = sourceStream->getChannelCount(); - int32_t sourceSampleRate = sourceStream->getSampleRate(); - int32_t sourceFramesPerCallback = sourceStream->getFramesPerDataCallback(); - - AudioFormat sinkFormat = sinkStream->getFormat(); - int32_t sinkChannelCount = sinkStream->getChannelCount(); - int32_t sinkSampleRate = sinkStream->getSampleRate(); - int32_t sinkFramesPerCallback = sinkStream->getFramesPerDataCallback(); - - LOGI("%s() flowgraph converts channels: %d to %d, format: %s to %s" - ", rate: %d to %d, cbsize: %d to %d, qual = %s", - __func__, - sourceChannelCount, sinkChannelCount, - oboe::convertToText(sourceFormat), oboe::convertToText(sinkFormat), - sourceSampleRate, sinkSampleRate, - sourceFramesPerCallback, sinkFramesPerCallback, - oboe::convertToText(sourceStream->getSampleRateConversionQuality())); - - // Source - // IF OUTPUT and using a callback then call back to the app using a SourceCaller. - // OR IF INPUT and NOT using a callback then read from the child stream using a SourceCaller. - bool isDataCallbackSpecified = sourceStream->isDataCallbackSpecified(); - if ((isDataCallbackSpecified && isOutput) - || (!isDataCallbackSpecified && isInput)) { - int32_t actualSourceFramesPerCallback = (sourceFramesPerCallback == kUnspecified) - ? sourceStream->getFramesPerBurst() - : sourceFramesPerCallback; - switch (sourceFormat) { - case AudioFormat::Float: - mSourceCaller = std::make_unique(sourceChannelCount, - actualSourceFramesPerCallback); - break; - case AudioFormat::I16: - mSourceCaller = std::make_unique(sourceChannelCount, - actualSourceFramesPerCallback); - break; - case AudioFormat::I24: - mSourceCaller = std::make_unique(sourceChannelCount, - actualSourceFramesPerCallback); - break; - case AudioFormat::I32: - mSourceCaller = std::make_unique(sourceChannelCount, - actualSourceFramesPerCallback); - break; - default: - LOGE("%s() Unsupported source caller format = %d", __func__, static_cast(sourceFormat)); - return Result::ErrorIllegalArgument; - } - mSourceCaller->setStream(sourceStream); - lastOutput = &mSourceCaller->output; - } else { - // IF OUTPUT and NOT using a callback then write to the child stream using a BlockWriter. - // OR IF INPUT and using a callback then write to the app using a BlockWriter. - switch (sourceFormat) { - case AudioFormat::Float: - mSource = std::make_unique(sourceChannelCount); - break; - case AudioFormat::I16: - mSource = std::make_unique(sourceChannelCount); - break; - case AudioFormat::I24: - mSource = std::make_unique(sourceChannelCount); - break; - case AudioFormat::I32: - mSource = std::make_unique(sourceChannelCount); - break; - default: - LOGE("%s() Unsupported source format = %d", __func__, static_cast(sourceFormat)); - return Result::ErrorIllegalArgument; - } - if (isInput) { - int32_t actualSinkFramesPerCallback = (sinkFramesPerCallback == kUnspecified) - ? sinkStream->getFramesPerBurst() - : sinkFramesPerCallback; - // The BlockWriter is after the Sink so use the SinkStream size. - mBlockWriter.open(actualSinkFramesPerCallback * sinkStream->getBytesPerFrame()); - mAppBuffer = std::make_unique( - kDefaultBufferSize * sinkStream->getBytesPerFrame()); - } - lastOutput = &mSource->output; - } - - // If we are going to reduce the number of channels then do it before the - // sample rate converter. - if (sourceChannelCount > sinkChannelCount) { - if (sinkChannelCount == 1) { - mMultiToMonoConverter = std::make_unique(sourceChannelCount); - lastOutput->connect(&mMultiToMonoConverter->input); - lastOutput = &mMultiToMonoConverter->output; - } else { - mChannelCountConverter = std::make_unique( - sourceChannelCount, - sinkChannelCount); - lastOutput->connect(&mChannelCountConverter->input); - lastOutput = &mChannelCountConverter->output; - } - } - - // Sample Rate conversion - if (sourceSampleRate != sinkSampleRate) { - // Create a resampler to do the math. - mResampler.reset(MultiChannelResampler::make(lastOutput->getSamplesPerFrame(), - sourceSampleRate, - sinkSampleRate, - convertOboeSRQualityToMCR( - sourceStream->getSampleRateConversionQuality()))); - // Make a flowgraph node that uses the resampler. - mRateConverter = std::make_unique(lastOutput->getSamplesPerFrame(), - *mResampler.get()); - lastOutput->connect(&mRateConverter->input); - lastOutput = &mRateConverter->output; - } - - // Expand the number of channels if required. - if (sourceChannelCount < sinkChannelCount) { - if (sourceChannelCount == 1) { - mMonoToMultiConverter = std::make_unique(sinkChannelCount); - lastOutput->connect(&mMonoToMultiConverter->input); - lastOutput = &mMonoToMultiConverter->output; - } else { - mChannelCountConverter = std::make_unique( - sourceChannelCount, - sinkChannelCount); - lastOutput->connect(&mChannelCountConverter->input); - lastOutput = &mChannelCountConverter->output; - } - } - - // Sink - switch (sinkFormat) { - case AudioFormat::Float: - mSink = std::make_unique(sinkChannelCount); - break; - case AudioFormat::I16: - mSink = std::make_unique(sinkChannelCount); - break; - case AudioFormat::I24: - mSink = std::make_unique(sinkChannelCount); - break; - case AudioFormat::I32: - mSink = std::make_unique(sinkChannelCount); - break; - default: - LOGE("%s() Unsupported sink format = %d", __func__, static_cast(sinkFormat)); - return Result::ErrorIllegalArgument;; - } - lastOutput->connect(&mSink->input); - - return Result::OK; -} - -int32_t DataConversionFlowGraph::read(void *buffer, int32_t numFrames, int64_t timeoutNanos) { - if (mSourceCaller) { - mSourceCaller->setTimeoutNanos(timeoutNanos); - } - int32_t numRead = mSink->read(buffer, numFrames); - return numRead; -} - -// This is similar to pushing data through the flowgraph. -int32_t DataConversionFlowGraph::write(void *inputBuffer, int32_t numFrames) { - // Put the data from the input at the head of the flowgraph. - mSource->setData(inputBuffer, numFrames); - while (true) { - // Pull and read some data in app format into a small buffer. - int32_t framesRead = mSink->read(mAppBuffer.get(), flowgraph::kDefaultBufferSize); - if (framesRead <= 0) break; - // Write to a block adapter, which will call the destination whenever it has enough data. - int32_t bytesRead = mBlockWriter.write(mAppBuffer.get(), - framesRead * mFilterStream->getBytesPerFrame()); - if (bytesRead < 0) return bytesRead; // TODO review - } - return numFrames; -} - -int32_t DataConversionFlowGraph::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) { - int32_t numFrames = numBytes / mFilterStream->getBytesPerFrame(); - mCallbackResult = mFilterStream->getDataCallback()->onAudioReady(mFilterStream, buffer, numFrames); - // TODO handle STOP from callback, process data remaining in the block adapter - return numBytes; -} -- cgit v1.2.3