• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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