xref: /aosp_15_r20/frameworks/av/media/libaudiohal/impl/EffectProxy.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #pragma once
18*ec779b8eSAndroid Build Coastguard Worker 
19*ec779b8eSAndroid Build Coastguard Worker #include <map>
20*ec779b8eSAndroid Build Coastguard Worker #include <memory>
21*ec779b8eSAndroid Build Coastguard Worker 
22*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/effect/BnEffect.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/hardware/audio/effect/BnFactory.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <fmq/AidlMessageQueue.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <system/audio_effect.h>
26*ec779b8eSAndroid Build Coastguard Worker 
27*ec779b8eSAndroid Build Coastguard Worker namespace android {
28*ec779b8eSAndroid Build Coastguard Worker namespace effect {
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker /**
31*ec779b8eSAndroid Build Coastguard Worker  * EffectProxy is the proxy for one or more effect AIDL implementations (sub effect) of same type.
32*ec779b8eSAndroid Build Coastguard Worker  * The audio framework use EffectProxy as a composite implementation of all sub effect
33*ec779b8eSAndroid Build Coastguard Worker  * implementations.
34*ec779b8eSAndroid Build Coastguard Worker  *
35*ec779b8eSAndroid Build Coastguard Worker  * At any given time, there is only one active effect which consuming and producing data for each
36*ec779b8eSAndroid Build Coastguard Worker  * proxy. All setter commands (except the legacy EFFECT_CMD_OFFLOAD, it will be handled by the audio
37*ec779b8eSAndroid Build Coastguard Worker  * framework directly) and parameters will be pass through to all sub effects, the getter commands
38*ec779b8eSAndroid Build Coastguard Worker  * and parameters will only passthrough to the active sub-effect.
39*ec779b8eSAndroid Build Coastguard Worker  *
40*ec779b8eSAndroid Build Coastguard Worker  */
41*ec779b8eSAndroid Build Coastguard Worker class EffectProxy final : public ::aidl::android::hardware::audio::effect::BnEffect {
42*ec779b8eSAndroid Build Coastguard Worker   public:
43*ec779b8eSAndroid Build Coastguard Worker     EffectProxy(
44*ec779b8eSAndroid Build Coastguard Worker             const ::aidl::android::media::audio::common::AudioUuid& uuid,
45*ec779b8eSAndroid Build Coastguard Worker             const std::vector<::aidl::android::hardware::audio::effect::Descriptor>& descriptors,
46*ec779b8eSAndroid Build Coastguard Worker             const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory>& factory);
47*ec779b8eSAndroid Build Coastguard Worker 
48*ec779b8eSAndroid Build Coastguard Worker     /**
49*ec779b8eSAndroid Build Coastguard Worker      * Handle offload parameter setting from framework.
50*ec779b8eSAndroid Build Coastguard Worker      */
51*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus setOffloadParam(const effect_offload_param_t* offload);
52*ec779b8eSAndroid Build Coastguard Worker 
53*ec779b8eSAndroid Build Coastguard Worker     /**
54*ec779b8eSAndroid Build Coastguard Worker      * Destroy all sub-effects via AIDL IFactory.
55*ec779b8eSAndroid Build Coastguard Worker      */
56*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus destroy();
57*ec779b8eSAndroid Build Coastguard Worker 
58*ec779b8eSAndroid Build Coastguard Worker     // IEffect interfaces override
59*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus open(
60*ec779b8eSAndroid Build Coastguard Worker             const ::aidl::android::hardware::audio::effect::Parameter::Common& common,
61*ec779b8eSAndroid Build Coastguard Worker             const std::optional<::aidl::android::hardware::audio::effect::Parameter::Specific>&
62*ec779b8eSAndroid Build Coastguard Worker                     specific,
63*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn* ret) override;
64*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus close() override;
65*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus reopen(
66*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::hardware::audio::effect::IEffect::OpenEffectReturn* ret) override;
67*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus getDescriptor(
68*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::hardware::audio::effect::Descriptor* desc) override;
69*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus command(::aidl::android::hardware::audio::effect::CommandId id) override;
70*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus getState(::aidl::android::hardware::audio::effect::State* state) override;
71*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus setParameter(
72*ec779b8eSAndroid Build Coastguard Worker             const ::aidl::android::hardware::audio::effect::Parameter& param) override;
73*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus getParameter(
74*ec779b8eSAndroid Build Coastguard Worker             const ::aidl::android::hardware::audio::effect::Parameter::Id& id,
75*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::hardware::audio::effect::Parameter* param) override;
76*ec779b8eSAndroid Build Coastguard Worker 
77*ec779b8eSAndroid Build Coastguard Worker     static ndk::ScopedAStatus buildDescriptor(
78*ec779b8eSAndroid Build Coastguard Worker             const ::aidl::android::media::audio::common::AudioUuid& uuid,
79*ec779b8eSAndroid Build Coastguard Worker             const std::vector<::aidl::android::hardware::audio::effect::Descriptor>& subEffectDescs,
80*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::hardware::audio::effect::Descriptor* desc);
81*ec779b8eSAndroid Build Coastguard Worker 
82*ec779b8eSAndroid Build Coastguard Worker     /**
83*ec779b8eSAndroid Build Coastguard Worker      * Get the const reference of the active sub-effect return parameters.
84*ec779b8eSAndroid Build Coastguard Worker      * Always use this interface to get the effect open return parameters (FMQs) after a success
85*ec779b8eSAndroid Build Coastguard Worker      * setOffloadParam() call.
86*ec779b8eSAndroid Build Coastguard Worker      */
87*ec779b8eSAndroid Build Coastguard Worker     using StatusMQ = ::android::AidlMessageQueue<
88*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::hardware::audio::effect::IEffect::Status,
89*ec779b8eSAndroid Build Coastguard Worker             ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>;
90*ec779b8eSAndroid Build Coastguard Worker     using DataMQ = ::android::AidlMessageQueue<
91*ec779b8eSAndroid Build Coastguard Worker             float, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>;
getStatusMQ()92*ec779b8eSAndroid Build Coastguard Worker     const std::shared_ptr<StatusMQ>& getStatusMQ() const {
93*ec779b8eSAndroid Build Coastguard Worker         return mSubEffects[mActiveSubIdx].effectMq.statusQ;
94*ec779b8eSAndroid Build Coastguard Worker     }
getInputMQ()95*ec779b8eSAndroid Build Coastguard Worker     const std::shared_ptr<DataMQ>& getInputMQ() const {
96*ec779b8eSAndroid Build Coastguard Worker         return mSubEffects[mActiveSubIdx].effectMq.inputQ;
97*ec779b8eSAndroid Build Coastguard Worker     }
getOutputMQ()98*ec779b8eSAndroid Build Coastguard Worker     const std::shared_ptr<DataMQ>& getOutputMQ() const {
99*ec779b8eSAndroid Build Coastguard Worker         return mSubEffects[mActiveSubIdx].effectMq.outputQ;
100*ec779b8eSAndroid Build Coastguard Worker     }
101*ec779b8eSAndroid Build Coastguard Worker 
102*ec779b8eSAndroid Build Coastguard Worker     bool isBypassing() const;
103*ec779b8eSAndroid Build Coastguard Worker     bool isTunnel() const;
104*ec779b8eSAndroid Build Coastguard Worker 
105*ec779b8eSAndroid Build Coastguard Worker     // call dump for all sub-effects
106*ec779b8eSAndroid Build Coastguard Worker     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
107*ec779b8eSAndroid Build Coastguard Worker 
108*ec779b8eSAndroid Build Coastguard Worker     std::string toString(size_t indent = 0) const;
109*ec779b8eSAndroid Build Coastguard Worker 
110*ec779b8eSAndroid Build Coastguard Worker   private:
111*ec779b8eSAndroid Build Coastguard Worker     // The shared capability of all sub-effects
112*ec779b8eSAndroid Build Coastguard Worker     const ::aidl::android::hardware::audio::effect::Capability mSharedCapability;
113*ec779b8eSAndroid Build Coastguard Worker     // Proxy descriptor common part, copy from one sub-effect, and update the implementation UUID to
114*ec779b8eSAndroid Build Coastguard Worker     // proxy UUID, proxy descriptor capability part comes from the active sub-effect capability
115*ec779b8eSAndroid Build Coastguard Worker     const ::aidl::android::hardware::audio::effect::Descriptor::Common mDescriptorCommon;
116*ec779b8eSAndroid Build Coastguard Worker 
117*ec779b8eSAndroid Build Coastguard Worker     struct EffectMQ {
118*ec779b8eSAndroid Build Coastguard Worker         std::shared_ptr<StatusMQ> statusQ;
119*ec779b8eSAndroid Build Coastguard Worker         std::shared_ptr<DataMQ> inputQ, outputQ;
120*ec779b8eSAndroid Build Coastguard Worker     };
121*ec779b8eSAndroid Build Coastguard Worker     struct SubEffect {
122*ec779b8eSAndroid Build Coastguard Worker         const ::aidl::android::hardware::audio::effect::Descriptor descriptor;
123*ec779b8eSAndroid Build Coastguard Worker         std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> handle;
124*ec779b8eSAndroid Build Coastguard Worker         EffectMQ effectMq;
125*ec779b8eSAndroid Build Coastguard Worker     };
126*ec779b8eSAndroid Build Coastguard Worker     std::vector<SubEffect> mSubEffects;
127*ec779b8eSAndroid Build Coastguard Worker 
128*ec779b8eSAndroid Build Coastguard Worker     const std::shared_ptr<::aidl::android::hardware::audio::effect::IFactory> mFactory;
129*ec779b8eSAndroid Build Coastguard Worker 
130*ec779b8eSAndroid Build Coastguard Worker     // index of the active sub-effects, by default use the first one (index 0)
131*ec779b8eSAndroid Build Coastguard Worker     // It's safe to assume there will always at least two SubEffects in mSubEffects
132*ec779b8eSAndroid Build Coastguard Worker     size_t mActiveSubIdx = 0;
133*ec779b8eSAndroid Build Coastguard Worker 
134*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus runWithActiveSubEffectThenOthers(
135*ec779b8eSAndroid Build Coastguard Worker             std::function<ndk::ScopedAStatus(
136*ec779b8eSAndroid Build Coastguard Worker                     const std::shared_ptr<
137*ec779b8eSAndroid Build Coastguard Worker                             ::aidl::android::hardware::audio::effect::IEffect>&)> const& func);
138*ec779b8eSAndroid Build Coastguard Worker 
139*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus runWithActiveSubEffect(
140*ec779b8eSAndroid Build Coastguard Worker             std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func);
141*ec779b8eSAndroid Build Coastguard Worker 
142*ec779b8eSAndroid Build Coastguard Worker     ndk::ScopedAStatus runWithAllSubEffects(
143*ec779b8eSAndroid Build Coastguard Worker             std::function<ndk::ScopedAStatus(std::shared_ptr<IEffect>&)> const& func);
144*ec779b8eSAndroid Build Coastguard Worker 
145*ec779b8eSAndroid Build Coastguard Worker     // build Descriptor.Common with all sub-effect descriptors
146*ec779b8eSAndroid Build Coastguard Worker     static ::aidl::android::hardware::audio::effect::Descriptor::Common buildDescriptorCommon(
147*ec779b8eSAndroid Build Coastguard Worker             const ::aidl::android::media::audio::common::AudioUuid& uuid,
148*ec779b8eSAndroid Build Coastguard Worker             const std::vector<::aidl::android::hardware::audio::effect::Descriptor>&
149*ec779b8eSAndroid Build Coastguard Worker                     subEffectDescs);
150*ec779b8eSAndroid Build Coastguard Worker 
151*ec779b8eSAndroid Build Coastguard Worker     // build a shared capability with all sub-effect descriptors
152*ec779b8eSAndroid Build Coastguard Worker     static ::aidl::android::hardware::audio::effect::Capability buildDescriptorCapability(
153*ec779b8eSAndroid Build Coastguard Worker             const std::vector<::aidl::android::hardware::audio::effect::Descriptor>&
154*ec779b8eSAndroid Build Coastguard Worker                     subEffectDescs);
155*ec779b8eSAndroid Build Coastguard Worker 
156*ec779b8eSAndroid Build Coastguard Worker     // close and release all sub-effects
157*ec779b8eSAndroid Build Coastguard Worker     ~EffectProxy();
158*ec779b8eSAndroid Build Coastguard Worker };
159*ec779b8eSAndroid Build Coastguard Worker 
160*ec779b8eSAndroid Build Coastguard Worker } // namespace effect
161*ec779b8eSAndroid Build Coastguard Worker } // namespace android
162