| Shunkai Yao | 725af21 | 2023-01-05 23:01:40 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2023 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 |  | 
|  | 19 | #include <android-base/thread_annotations.h> | 
|  | 20 | #include <audio_effects/effect_dynamicsprocessing.h> | 
|  | 21 |  | 
|  | 22 | #include "effect-impl/EffectContext.h" | 
|  | 23 |  | 
|  | 24 | #include <any> | 
|  | 25 | #include <cstddef> | 
|  | 26 | #include <dsp/DPBase.h> | 
|  | 27 | #include <dsp/DPFrequency.h> | 
|  | 28 |  | 
|  | 29 | namespace aidl::android::hardware::audio::effect { | 
|  | 30 |  | 
|  | 31 | enum DynamicsProcessingState { | 
|  | 32 | DYNAMICS_PROCESSING_STATE_UNINITIALIZED, | 
|  | 33 | DYNAMICS_PROCESSING_STATE_INITIALIZED, | 
|  | 34 | DYNAMICS_PROCESSING_STATE_ACTIVE, | 
|  | 35 | }; | 
|  | 36 |  | 
|  | 37 | class DynamicsProcessingContext final : public EffectContext { | 
|  | 38 | public: | 
|  | 39 | DynamicsProcessingContext(int statusDepth, const Parameter::Common& common); | 
|  | 40 | ~DynamicsProcessingContext(); | 
|  | 41 |  | 
|  | 42 | RetCode enable(); | 
|  | 43 | RetCode disable(); | 
|  | 44 | void reset(); | 
|  | 45 |  | 
|  | 46 | // override EffectContext::setCommon to update mChannelCount | 
|  | 47 | RetCode setCommon(const Parameter::Common& common) override; | 
|  | 48 |  | 
|  | 49 | RetCode setEngineArchitecture(const DynamicsProcessing::EngineArchitecture& engineArchitecture); | 
|  | 50 | RetCode setPreEq(const std::vector<DynamicsProcessing::ChannelConfig>& eqChannels); | 
|  | 51 | RetCode setPostEq(const std::vector<DynamicsProcessing::ChannelConfig>& eqChannels); | 
|  | 52 | RetCode setPreEqBand(const std::vector<DynamicsProcessing::EqBandConfig>& eqBands); | 
|  | 53 | RetCode setPostEqBand(const std::vector<DynamicsProcessing::EqBandConfig>& eqBands); | 
|  | 54 | RetCode setMbc(const std::vector<DynamicsProcessing::ChannelConfig>& mbcChannels); | 
|  | 55 | RetCode setMbcBand(const std::vector<DynamicsProcessing::MbcBandConfig>& eqBands); | 
|  | 56 | RetCode setLimiter(const std::vector<DynamicsProcessing::LimiterConfig>& limiters); | 
|  | 57 | RetCode setInputGain(const std::vector<DynamicsProcessing::InputGain>& gain); | 
|  | 58 |  | 
|  | 59 | DynamicsProcessing::EngineArchitecture getEngineArchitecture(); | 
|  | 60 | std::vector<DynamicsProcessing::ChannelConfig> getPreEq(); | 
|  | 61 | std::vector<DynamicsProcessing::ChannelConfig> getPostEq(); | 
|  | 62 | std::vector<DynamicsProcessing::EqBandConfig> getPreEqBand(); | 
|  | 63 | std::vector<DynamicsProcessing::EqBandConfig> getPostEqBand(); | 
|  | 64 | std::vector<DynamicsProcessing::ChannelConfig> getMbc(); | 
|  | 65 | std::vector<DynamicsProcessing::MbcBandConfig> getMbcBand(); | 
|  | 66 | std::vector<DynamicsProcessing::LimiterConfig> getLimiter(); | 
|  | 67 | std::vector<DynamicsProcessing::InputGain> getInputGain(); | 
|  | 68 |  | 
|  | 69 | IEffect::Status lvmProcess(float* in, float* out, int samples); | 
|  | 70 |  | 
|  | 71 | private: | 
|  | 72 | static constexpr float kPreferredProcessingDurationMs = 10.0f; | 
|  | 73 | static constexpr int kBandCount = 5; | 
|  | 74 | std::mutex mMutex; | 
|  | 75 | size_t mChannelCount GUARDED_BY(mMutex) = 0; | 
|  | 76 | DynamicsProcessingState mState GUARDED_BY(mMutex) = DYNAMICS_PROCESSING_STATE_UNINITIALIZED; | 
|  | 77 | std::unique_ptr<dp_fx::DPFrequency> mDpFreq GUARDED_BY(mMutex) = nullptr; | 
|  | 78 | bool mEngineInited GUARDED_BY(mMutex) = false; | 
|  | 79 | DynamicsProcessing::EngineArchitecture mEngineArchitecture GUARDED_BY(mMutex) = { | 
|  | 80 | .resolutionPreference = | 
|  | 81 | DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION, | 
|  | 82 | .preferredProcessingDurationMs = kPreferredProcessingDurationMs, | 
|  | 83 | .preEqStage = {.inUse = true, .bandCount = kBandCount}, | 
|  | 84 | .postEqStage = {.inUse = true, .bandCount = kBandCount}, | 
|  | 85 | .mbcStage = {.inUse = true, .bandCount = kBandCount}, | 
|  | 86 | .limiterInUse = true, | 
|  | 87 | }; | 
|  | 88 |  | 
|  | 89 | enum class StageType { PREEQ, POSTEQ, MBC, LIMITER, INPUTGAIN }; | 
|  | 90 |  | 
|  | 91 | void init(); | 
|  | 92 |  | 
|  | 93 | void dpSetFreqDomainVariant_l(const DynamicsProcessing::EngineArchitecture& engine) | 
|  | 94 | REQUIRES(mMutex); | 
|  | 95 | dp_fx::DPChannel* getChannel_l(int ch) REQUIRES(mMutex); | 
|  | 96 | dp_fx::DPEq* getPreEq_l(int ch) REQUIRES(mMutex); | 
|  | 97 | dp_fx::DPEq* getPostEq_l(int ch) REQUIRES(mMutex); | 
|  | 98 | dp_fx::DPMbc* getMbc_l(int ch) REQUIRES(mMutex); | 
|  | 99 | dp_fx::DPLimiter* getLimiter_l(int ch) REQUIRES(mMutex); | 
|  | 100 | dp_fx::DPBandStage* getStageWithType_l(StageType type, int ch) REQUIRES(mMutex); | 
|  | 101 | dp_fx::DPEq* getEqWithType_l(StageType type, int ch) REQUIRES(mMutex); | 
|  | 102 | template <typename D> | 
|  | 103 | RetCode setDpChannels_l(const std::vector<DynamicsProcessing::ChannelConfig>& channels, | 
|  | 104 | bool stageInUse, StageType type) REQUIRES(mMutex); | 
|  | 105 | template <typename T /* BandConfig */> | 
|  | 106 | RetCode setBands_l(const std::vector<T>& bands, int maxBand, StageType type) REQUIRES(mMutex); | 
|  | 107 | RetCode setDpChannelBand_l(const std::any& anyConfig, StageType type, int maxCh, int maxBand, | 
|  | 108 | std::set<std::pair<int, int>>& chBandSet) REQUIRES(mMutex); | 
|  | 109 |  | 
|  | 110 | std::vector<DynamicsProcessing::EqBandConfig> getEqBandConfigs(StageType type); | 
|  | 111 | std::vector<DynamicsProcessing::ChannelConfig> getChannelConfig(StageType type); | 
|  | 112 |  | 
|  | 113 | bool validateStageEnablement(const DynamicsProcessing::StageEnablement& enablement); | 
|  | 114 | bool validateEngineConfig(const DynamicsProcessing::EngineArchitecture& engine); | 
|  | 115 | bool validateEqBandConfig(const DynamicsProcessing::EqBandConfig& band, int maxChannel, | 
|  | 116 | int maxBand); | 
|  | 117 | bool validateMbcBandConfig(const DynamicsProcessing::MbcBandConfig& band, int maxChannel, | 
|  | 118 | int maxBand); | 
|  | 119 | bool validateLimiterConfig(const DynamicsProcessing::LimiterConfig& limiter, int maxChannel); | 
|  | 120 | bool validateInputGainConfig(const DynamicsProcessing::InputGain& gain, int maxChannel); | 
|  | 121 |  | 
|  | 122 | inline bool validateCutoffFrequency(float freq); | 
|  | 123 | inline bool validateChannel(int ch, int maxCh) { return ch >= 0 && ch < maxCh; } | 
|  | 124 | inline bool validateBand(int band, int maxBand) { return band >= 0 && band < maxBand; } | 
|  | 125 | inline bool validateTime(int time) { return time >= 0; } | 
|  | 126 | inline bool validateRatio(int ratio) { return ratio >= 0; } | 
|  | 127 | inline bool validateBandDb(int db) { return db <= 0; } | 
|  | 128 | }; | 
|  | 129 |  | 
|  | 130 | }  // namespace aidl::android::hardware::audio::effect |