1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 #include <memory> 19 #include <vector> 20 21 #include <Utils.h> 22 #include <android-base/logging.h> 23 #include <fmq/AidlMessageQueue.h> 24 25 #include <aidl/android/hardware/audio/effect/BnEffect.h> 26 #include "EffectTypes.h" 27 28 namespace aidl::android::hardware::audio::effect { 29 30 class EffectContext { 31 public: 32 typedef ::android::AidlMessageQueue< 33 IEffect::Status, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> 34 StatusMQ; 35 typedef ::android::AidlMessageQueue< 36 float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> 37 DataMQ; 38 EffectContext(size_t statusDepth,const Parameter::Common & common)39 EffectContext(size_t statusDepth, const Parameter::Common& common) { 40 auto& input = common.input; 41 auto& output = common.output; 42 43 LOG_ALWAYS_FATAL_IF( 44 input.base.format.pcm != aidl::android::media::audio::common::PcmType::FLOAT_32_BIT, 45 "inputFormatNotFloat"); 46 LOG_ALWAYS_FATAL_IF(output.base.format.pcm != 47 aidl::android::media::audio::common::PcmType::FLOAT_32_BIT, 48 "outputFormatNotFloat"); 49 mInputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes( 50 input.base.format, input.base.channelMask); 51 mOutputFrameSize = ::aidl::android::hardware::audio::common::getFrameSizeInBytes( 52 output.base.format, output.base.channelMask); 53 // in/outBuffer size in float (FMQ data format defined for DataMQ) 54 size_t inBufferSizeInFloat = input.frameCount * mInputFrameSize / sizeof(float); 55 size_t outBufferSizeInFloat = output.frameCount * mOutputFrameSize / sizeof(float); 56 57 // only status FMQ use the EventFlag 58 mStatusMQ = std::make_shared<StatusMQ>(statusDepth, true /*configureEventFlagWord*/); 59 mInputMQ = std::make_shared<DataMQ>(inBufferSizeInFloat); 60 mOutputMQ = std::make_shared<DataMQ>(outBufferSizeInFloat); 61 62 if (!mStatusMQ->isValid() || !mInputMQ->isValid() || !mOutputMQ->isValid()) { 63 LOG(ERROR) << __func__ << " created invalid FMQ"; 64 } 65 mWorkBuffer.reserve(std::max(inBufferSizeInFloat, outBufferSizeInFloat)); 66 mCommon = common; 67 } ~EffectContext()68 virtual ~EffectContext() {} 69 getStatusFmq()70 std::shared_ptr<StatusMQ> getStatusFmq() { return mStatusMQ; } getInputDataFmq()71 std::shared_ptr<DataMQ> getInputDataFmq() { return mInputMQ; } getOutputDataFmq()72 std::shared_ptr<DataMQ> getOutputDataFmq() { return mOutputMQ; } 73 getWorkBuffer()74 float* getWorkBuffer() { return static_cast<float*>(mWorkBuffer.data()); } 75 76 // reset buffer status by abandon input data in FMQ resetBuffer()77 void resetBuffer() { 78 auto buffer = static_cast<float*>(mWorkBuffer.data()); 79 std::vector<IEffect::Status> status(mStatusMQ->availableToRead()); 80 mInputMQ->read(buffer, mInputMQ->availableToRead()); 81 } 82 dupeFmq(IEffect::OpenEffectReturn * effectRet)83 void dupeFmq(IEffect::OpenEffectReturn* effectRet) { 84 if (effectRet) { 85 effectRet->statusMQ = mStatusMQ->dupeDesc(); 86 effectRet->inputDataMQ = mInputMQ->dupeDesc(); 87 effectRet->outputDataMQ = mOutputMQ->dupeDesc(); 88 } 89 } getInputFrameSize()90 size_t getInputFrameSize() { return mInputFrameSize; } getOutputFrameSize()91 size_t getOutputFrameSize() { return mOutputFrameSize; } getSessionId()92 int getSessionId() { return mCommon.session; } getIoHandle()93 int getIoHandle() { return mCommon.ioHandle; } 94 setOutputDevice(const std::vector<aidl::android::media::audio::common::AudioDeviceDescription> & device)95 virtual RetCode setOutputDevice( 96 const std::vector<aidl::android::media::audio::common::AudioDeviceDescription>& 97 device) { 98 mOutputDevice = device; 99 return RetCode::SUCCESS; 100 } 101 102 virtual std::vector<aidl::android::media::audio::common::AudioDeviceDescription> getOutputDevice()103 getOutputDevice() { 104 return mOutputDevice; 105 } 106 setAudioMode(const aidl::android::media::audio::common::AudioMode & mode)107 virtual RetCode setAudioMode(const aidl::android::media::audio::common::AudioMode& mode) { 108 mMode = mode; 109 return RetCode::SUCCESS; 110 } getAudioMode()111 virtual aidl::android::media::audio::common::AudioMode getAudioMode() { return mMode; } 112 setAudioSource(const aidl::android::media::audio::common::AudioSource & source)113 virtual RetCode setAudioSource(const aidl::android::media::audio::common::AudioSource& source) { 114 mSource = source; 115 return RetCode::SUCCESS; 116 } getAudioSource()117 virtual aidl::android::media::audio::common::AudioSource getAudioSource() { return mSource; } 118 setVolumeStereo(const Parameter::VolumeStereo & volumeStereo)119 virtual RetCode setVolumeStereo(const Parameter::VolumeStereo& volumeStereo) { 120 mVolumeStereo = volumeStereo; 121 return RetCode::SUCCESS; 122 } getVolumeStereo()123 virtual Parameter::VolumeStereo getVolumeStereo() { return mVolumeStereo; } 124 setCommon(const Parameter::Common & common)125 virtual RetCode setCommon(const Parameter::Common& common) { 126 mCommon = common; 127 LOG(VERBOSE) << __func__ << mCommon.toString(); 128 return RetCode::SUCCESS; 129 } getCommon()130 virtual Parameter::Common getCommon() { 131 LOG(VERBOSE) << __func__ << mCommon.toString(); 132 return mCommon; 133 } 134 135 protected: 136 // common parameters 137 size_t mInputFrameSize; 138 size_t mOutputFrameSize; 139 Parameter::Common mCommon; 140 std::vector<aidl::android::media::audio::common::AudioDeviceDescription> mOutputDevice; 141 aidl::android::media::audio::common::AudioMode mMode; 142 aidl::android::media::audio::common::AudioSource mSource; 143 Parameter::VolumeStereo mVolumeStereo; 144 145 private: 146 // fmq and buffers 147 std::shared_ptr<StatusMQ> mStatusMQ; 148 std::shared_ptr<DataMQ> mInputMQ; 149 std::shared_ptr<DataMQ> mOutputMQ; 150 // TODO handle effect process input and output 151 // work buffer set by effect instances, the access and update are in same thread 152 std::vector<float> mWorkBuffer; 153 }; 154 } // namespace aidl::android::hardware::audio::effect 155