aboutsummaryrefslogtreecommitdiff
path: root/externals/oboe/src/common/DataConversionFlowGraph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'externals/oboe/src/common/DataConversionFlowGraph.cpp')
-rw-r--r--externals/oboe/src/common/DataConversionFlowGraph.cpp266
1 files changed, 0 insertions, 266 deletions
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 <memory>
-
-#include "OboeDebug.h"
-#include "DataConversionFlowGraph.h"
-#include "SourceFloatCaller.h"
-#include "SourceI16Caller.h"
-#include "SourceI24Caller.h"
-#include "SourceI32Caller.h"
-
-#include <flowgraph/MonoToMultiConverter.h>
-#include <flowgraph/MultiToMonoConverter.h>
-#include <flowgraph/RampLinear.h>
-#include <flowgraph/SinkFloat.h>
-#include <flowgraph/SinkI16.h>
-#include <flowgraph/SinkI24.h>
-#include <flowgraph/SinkI32.h>
-#include <flowgraph/SourceFloat.h>
-#include <flowgraph/SourceI16.h>
-#include <flowgraph/SourceI24.h>
-#include <flowgraph/SourceI32.h>
-#include <flowgraph/SampleRateConverter.h>
-
-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<SourceFloatCaller>(sourceChannelCount,
- actualSourceFramesPerCallback);
- break;
- case AudioFormat::I16:
- mSourceCaller = std::make_unique<SourceI16Caller>(sourceChannelCount,
- actualSourceFramesPerCallback);
- break;
- case AudioFormat::I24:
- mSourceCaller = std::make_unique<SourceI24Caller>(sourceChannelCount,
- actualSourceFramesPerCallback);
- break;
- case AudioFormat::I32:
- mSourceCaller = std::make_unique<SourceI32Caller>(sourceChannelCount,
- actualSourceFramesPerCallback);
- break;
- default:
- LOGE("%s() Unsupported source caller format = %d", __func__, static_cast<int>(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<SourceFloat>(sourceChannelCount);
- break;
- case AudioFormat::I16:
- mSource = std::make_unique<SourceI16>(sourceChannelCount);
- break;
- case AudioFormat::I24:
- mSource = std::make_unique<SourceI24>(sourceChannelCount);
- break;
- case AudioFormat::I32:
- mSource = std::make_unique<SourceI32>(sourceChannelCount);
- break;
- default:
- LOGE("%s() Unsupported source format = %d", __func__, static_cast<int>(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<uint8_t[]>(
- 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<MultiToMonoConverter>(sourceChannelCount);
- lastOutput->connect(&mMultiToMonoConverter->input);
- lastOutput = &mMultiToMonoConverter->output;
- } else {
- mChannelCountConverter = std::make_unique<ChannelCountConverter>(
- 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<SampleRateConverter>(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<MonoToMultiConverter>(sinkChannelCount);
- lastOutput->connect(&mMonoToMultiConverter->input);
- lastOutput = &mMonoToMultiConverter->output;
- } else {
- mChannelCountConverter = std::make_unique<ChannelCountConverter>(
- sourceChannelCount,
- sinkChannelCount);
- lastOutput->connect(&mChannelCountConverter->input);
- lastOutput = &mChannelCountConverter->output;
- }
- }
-
- // Sink
- switch (sinkFormat) {
- case AudioFormat::Float:
- mSink = std::make_unique<SinkFloat>(sinkChannelCount);
- break;
- case AudioFormat::I16:
- mSink = std::make_unique<SinkI16>(sinkChannelCount);
- break;
- case AudioFormat::I24:
- mSink = std::make_unique<SinkI24>(sinkChannelCount);
- break;
- case AudioFormat::I32:
- mSink = std::make_unique<SinkI32>(sinkChannelCount);
- break;
- default:
- LOGE("%s() Unsupported sink format = %d", __func__, static_cast<int>(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;
-}