/* * Copyright (C) 2022 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. */ #pragma once #include #include #include #include #include #include #include "EffectTypes.h" namespace aidl::android::hardware::audio::effect { class EffectContext { public: typedef ::android::AidlMessageQueue< IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> StatusMQ; typedef ::android::AidlMessageQueue< float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ; EffectContext(size_t statusDepth, const Parameter::Common& common) { auto& input = common.input; auto& output = common.output; LOG_ALWAYS_FATAL_IF( input.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT, "inputFormatNotFloat"); LOG_ALWAYS_FATAL_IF(output.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT, "outputFormatNotFloat"); mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes( input.base.format, input.base.channelMask); mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes( output.base.format, output.base.channelMask); // in/outBuffer size in float (FMQ data format defined for DataMQ) size_t inBufferSizeInFloat = input.frameCount * mInputFrameSize / sizeof(float); size_t outBufferSizeInFloat = output.frameCount * mOutputFrameSize / sizeof(float); // only status FMQ use the EventFlag mStatusMQ = std::make_shared(statusDepth, true /*configureEventFlagWord*/); mInputMQ = std::make_shared(inBufferSizeInFloat); mOutputMQ = std::make_shared(outBufferSizeInFloat); if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) { LOG(ERROR) << __func__ << " created invalid FMQ"; } mWorkBuffer.reserve(std::max(inBufferSizeInFloat, outBufferSizeInFloat)); mCommon = common; } virtual ~EffectContext() {} std::shared_ptr getStatusFmq() { return mStatusMQ; } std::shared_ptr getInputDataFmq() { return mInputMQ; } std::shared_ptr getOutputDataFmq() { return mOutputMQ; } float* getWorkBuffer() { return static_cast(mWorkBuffer.data()); } // reset buffer status by abandon input data in FMQ void resetBuffer() { auto buffer = static_cast(mWorkBuffer.data()); std::vector status(mStatusMQ->availableToRead()); mInputMQ->read(buffer, mInputMQ->availableToRead()); } void dupeFmq(IEffect::OpenEffectReturn* effectRet) { if (effectRet) { effectRet->statusMQ = mStatusMQ->dupeDesc(); effectRet->inputDataMQ = mInputMQ->dupeDesc(); effectRet->outputDataMQ = mOutputMQ->dupeDesc(); } } size_t getInputFrameSize() { return mInputFrameSize; } size_t getOutputFrameSize() { return mOutputFrameSize; } int getSessionId() { return mCommon.session; } int getIoHandle() { return mCommon.ioHandle; } virtual RetCode setOutputDevice( const std::vector& device) { mOutputDevice = device; return RetCode::SUCCESS; } virtual std::vector getOutputDevice() { return mOutputDevice; } virtual RetCode setAudioMode(const aidl::android::media::audio::common::AudioMode& mode) { mMode = mode; return RetCode::SUCCESS; } virtual aidl::android::media::audio::common::AudioMode getAudioMode() { return mMode; } virtual RetCode setAudioSource(const aidl::android::media::audio::common::AudioSource& source) { mSource = source; return RetCode::SUCCESS; } virtual aidl::android::media::audio::common::AudioSource getAudioSource() { return mSource; } virtual RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) { mVolumeStereo = volumeStereo; return RetCode::SUCCESS; } virtual Parameter::VolumeStereo getVolumeStereo() { return mVolumeStereo; } virtual RetCode setCommon(const Parameter::Common& common) { mCommon = common; LOG(INFO) << __func__ << mCommon.toString(); return RetCode::SUCCESS; } virtual Parameter::Common getCommon() { LOG(DEBUG) << __func__ << mCommon.toString(); return mCommon; } protected: // common parameters size_t mInputFrameSize; size_t mOutputFrameSize; Parameter::Common mCommon; std::vector mOutputDevice; aidl::android::media::audio::common::AudioMode mMode; aidl::android::media::audio::common::AudioSource mSource; Parameter::VolumeStereo mVolumeStereo; private: // fmq and buffers std::shared_ptr mStatusMQ; std::shared_ptr mInputMQ; std::shared_ptr mOutputMQ; // TODO handle effect process input and output // work buffer set by effect instances, the access and update are in same thread std::vector mWorkBuffer; }; } // namespace aidl::android::hardware::audio::effect