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 <cstdlib> 19 #include <memory> 20 21 #include <aidl/android/hardware/audio/effect/BnEffect.h> 22 #include <fmq/AidlMessageQueue.h> 23 24 #include "EffectContext.h" 25 #include "EffectThread.h" 26 #include "EffectTypes.h" 27 #include "effect-impl/EffectContext.h" 28 #include "effect-impl/EffectThread.h" 29 #include "effect-impl/EffectTypes.h" 30 31 extern "C" binder_exception_t destroyEffect( 32 const std::shared_ptr<aidl::android::hardware::audio::effect::IEffect>& instanceSp); 33 34 namespace aidl::android::hardware::audio::effect { 35 36 class EffectImpl : public BnEffect, public EffectThread { 37 public: 38 EffectImpl() = default; 39 virtual ~EffectImpl() = default; 40 41 virtual ndk::ScopedAStatus open(const Parameter::Common& common, 42 const std::optional<Parameter::Specific>& specific, 43 OpenEffectReturn* ret) override; 44 virtual ndk::ScopedAStatus close() override; 45 virtual ndk::ScopedAStatus command(CommandId id) override; 46 virtual ndk::ScopedAStatus reopen(OpenEffectReturn* ret) override; 47 48 virtual ndk::ScopedAStatus getState(State* state) override; 49 virtual ndk::ScopedAStatus setParameter(const Parameter& param) override; 50 virtual ndk::ScopedAStatus getParameter(const Parameter::Id& id, Parameter* param) override; 51 52 virtual ndk::ScopedAStatus setParameterCommon(const Parameter& param) REQUIRES(mImplMutex); 53 virtual ndk::ScopedAStatus getParameterCommon(const Parameter::Tag& tag, Parameter* param) 54 REQUIRES(mImplMutex); 55 56 /* Methods MUST be implemented by each effect instances */ 57 virtual ndk::ScopedAStatus getDescriptor(Descriptor* desc) = 0; 58 virtual ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) 59 REQUIRES(mImplMutex) = 0; 60 virtual ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id, 61 Parameter::Specific* specific) 62 REQUIRES(mImplMutex) = 0; 63 64 virtual std::string getEffectName() = 0; 65 virtual std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) 66 REQUIRES(mImplMutex); 67 virtual RetCode releaseContext() REQUIRES(mImplMutex) = 0; 68 69 /** 70 * @brief effectProcessImpl is running in worker thread which created in EffectThread. 71 * 72 * EffectThread will make sure effectProcessImpl only be called after startThread() successful 73 * and before stopThread() successful. 74 * 75 * effectProcessImpl implementation must not call any EffectThread interface, otherwise it will 76 * cause deadlock. 77 * 78 * @param in address of input float buffer. 79 * @param out address of output float buffer. 80 * @param samples number of samples to process. 81 * @return IEffect::Status 82 */ 83 virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0; 84 85 /** 86 * process() get data from data MQs, and call effectProcessImpl() for effect data processing. 87 * Its important for the implementation to use mImplMutex for context synchronization. 88 */ 89 void process() override; 90 91 protected: 92 // current Hal version 93 int mVersion = 0; 94 // Use kEventFlagNotEmpty for V1 HAL, kEventFlagDataMqNotEmpty for V2 and above 95 int mDataMqNotEmptyEf = aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty; 96 97 State mState GUARDED_BY(mImplMutex) = State::INIT; 98 99 IEffect::Status status(binder_status_t status, size_t consumed, size_t produced); 100 void cleanUp(); 101 102 std::mutex mImplMutex; 103 std::shared_ptr<EffectContext> mImplContext GUARDED_BY(mImplMutex); 104 105 /** 106 * Optional CommandId handling methods for effects to override. 107 * For CommandId::START, EffectImpl call commandImpl before starting the EffectThread 108 * processing. 109 * For CommandId::STOP and CommandId::RESET, EffectImpl call commandImpl after stop the 110 * EffectThread processing. 111 */ 112 virtual ndk::ScopedAStatus commandImpl(CommandId id) REQUIRES(mImplMutex); 113 114 RetCode notifyEventFlag(uint32_t flag); 115 getEffectNameWithVersion()116 std::string getEffectNameWithVersion() { 117 return getEffectName() + "V" + std::to_string(mVersion); 118 } 119 120 ::android::hardware::EventFlag* mEventFlag; 121 }; 122 } // namespace aidl::android::hardware::audio::effect 123