• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <aidl/android/hardware/audio/effect/DynamicsProcessing.h>
18 #include <aidl/android/hardware/audio/effect/Range.h>
19 
20 #include "EffectRangeSpecific.h"
21 #include "effect-impl/EffectRange.h"
22 
23 namespace aidl::android::hardware::audio::effect {
24 
25 namespace DynamicsProcessingRanges {
26 
isInputGainConfigInRange(const std::vector<DynamicsProcessing::InputGain> & cfgs,const DynamicsProcessing::InputGain & min,const DynamicsProcessing::InputGain & max)27 static bool isInputGainConfigInRange(const std::vector<DynamicsProcessing::InputGain>& cfgs,
28                                      const DynamicsProcessing::InputGain& min,
29                                      const DynamicsProcessing::InputGain& max) {
30     auto func = [](const DynamicsProcessing::InputGain& arg) {
31         return std::make_tuple(arg.channel, arg.gainDb);
32     };
33     return isTupleInRange(cfgs, min, max, func);
34 }
35 
isLimiterConfigInRange(const std::vector<DynamicsProcessing::LimiterConfig> & cfgs,const DynamicsProcessing::LimiterConfig & min,const DynamicsProcessing::LimiterConfig & max)36 static bool isLimiterConfigInRange(const std::vector<DynamicsProcessing::LimiterConfig>& cfgs,
37                                    const DynamicsProcessing::LimiterConfig& min,
38                                    const DynamicsProcessing::LimiterConfig& max) {
39     auto func = [](const DynamicsProcessing::LimiterConfig& arg) {
40         return std::make_tuple(arg.channel, arg.enable, arg.linkGroup, arg.attackTimeMs,
41                                arg.releaseTimeMs, arg.ratio, arg.thresholdDb, arg.postGainDb);
42     };
43     return isTupleInRange(cfgs, min, max, func);
44 }
45 
isMbcBandConfigInRange(const std::vector<DynamicsProcessing::MbcBandConfig> & cfgs,const DynamicsProcessing::MbcBandConfig & min,const DynamicsProcessing::MbcBandConfig & max)46 static bool isMbcBandConfigInRange(const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
47                                    const DynamicsProcessing::MbcBandConfig& min,
48                                    const DynamicsProcessing::MbcBandConfig& max) {
49     auto func = [](const DynamicsProcessing::MbcBandConfig& arg) {
50         return std::make_tuple(arg.channel, arg.band, arg.enable, arg.cutoffFrequencyHz,
51                                arg.attackTimeMs, arg.releaseTimeMs, arg.ratio, arg.thresholdDb,
52                                arg.kneeWidthDb, arg.noiseGateThresholdDb, arg.expanderRatio,
53                                arg.preGainDb, arg.postGainDb);
54     };
55     return isTupleInRange(cfgs, min, max, func);
56 }
57 
isEqBandConfigInRange(const std::vector<DynamicsProcessing::EqBandConfig> & cfgs,const DynamicsProcessing::EqBandConfig & min,const DynamicsProcessing::EqBandConfig & max)58 static bool isEqBandConfigInRange(const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
59                                   const DynamicsProcessing::EqBandConfig& min,
60                                   const DynamicsProcessing::EqBandConfig& max) {
61     auto func = [](const DynamicsProcessing::EqBandConfig& arg) {
62         return std::make_tuple(arg.channel, arg.band, arg.enable, arg.cutoffFrequencyHz,
63                                arg.gainDb);
64     };
65     return isTupleInRange(cfgs, min, max, func);
66 }
67 
isChannelConfigInRange(const std::vector<DynamicsProcessing::ChannelConfig> & cfgs,const DynamicsProcessing::ChannelConfig & min,const DynamicsProcessing::ChannelConfig & max)68 static bool isChannelConfigInRange(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,
69                                    const DynamicsProcessing::ChannelConfig& min,
70                                    const DynamicsProcessing::ChannelConfig& max) {
71     auto func = [](const DynamicsProcessing::ChannelConfig& arg) {
72         return std::make_tuple(arg.channel, arg.enable);
73     };
74     return isTupleInRange(cfgs, min, max, func);
75 }
76 
isEngineConfigInRange(const DynamicsProcessing::EngineArchitecture & cfg,const DynamicsProcessing::EngineArchitecture & min,const DynamicsProcessing::EngineArchitecture & max)77 static bool isEngineConfigInRange(const DynamicsProcessing::EngineArchitecture& cfg,
78                                   const DynamicsProcessing::EngineArchitecture& min,
79                                   const DynamicsProcessing::EngineArchitecture& max) {
80     auto func = [](const DynamicsProcessing::EngineArchitecture& arg) {
81         return std::make_tuple(arg.resolutionPreference, arg.preferredProcessingDurationMs,
82                                arg.preEqStage.inUse, arg.preEqStage.bandCount,
83                                arg.postEqStage.inUse, arg.postEqStage.bandCount, arg.mbcStage.inUse,
84                                arg.mbcStage.bandCount, arg.limiterInUse);
85     };
86     return isTupleInRange(func(cfg), func(min), func(max));
87 }
88 
locateMinMaxForTag(DynamicsProcessing::Tag tag,const std::vector<Range::DynamicsProcessingRange> & ranges)89 static int locateMinMaxForTag(DynamicsProcessing::Tag tag,
90                               const std::vector<Range::DynamicsProcessingRange>& ranges) {
91     for (int i = 0; i < (int)ranges.size(); i++) {
92         if (tag == ranges[i].min.getTag() && tag == ranges[i].max.getTag()) {
93             return i;
94         }
95     }
96     return -1;
97 }
98 
isParamInRange(const DynamicsProcessing & dp,const std::vector<Range::DynamicsProcessingRange> & ranges)99 bool isParamInRange(const DynamicsProcessing& dp,
100                     const std::vector<Range::DynamicsProcessingRange>& ranges) {
101     auto tag = dp.getTag();
102     int i = locateMinMaxForTag(tag, ranges);
103     if (i == -1) return true;
104 
105     switch (tag) {
106         case DynamicsProcessing::engineArchitecture: {
107             return isEngineConfigInRange(
108                     dp.get<DynamicsProcessing::engineArchitecture>(),
109                     ranges[i].min.get<DynamicsProcessing::engineArchitecture>(),
110                     ranges[i].max.get<DynamicsProcessing::engineArchitecture>());
111         }
112         case DynamicsProcessing::preEq: {
113             return isChannelConfigInRange(dp.get<DynamicsProcessing::preEq>(),
114                                           ranges[i].min.get<DynamicsProcessing::preEq>()[0],
115                                           ranges[i].max.get<DynamicsProcessing::preEq>()[0]);
116         }
117         case DynamicsProcessing::postEq: {
118             return isChannelConfigInRange(dp.get<DynamicsProcessing::postEq>(),
119                                           ranges[i].min.get<DynamicsProcessing::postEq>()[0],
120                                           ranges[i].max.get<DynamicsProcessing::postEq>()[0]);
121         }
122         case DynamicsProcessing::mbc: {
123             return isChannelConfigInRange(dp.get<DynamicsProcessing::mbc>(),
124                                           ranges[i].min.get<DynamicsProcessing::mbc>()[0],
125                                           ranges[i].max.get<DynamicsProcessing::mbc>()[0]);
126         }
127         case DynamicsProcessing::preEqBand: {
128             return isEqBandConfigInRange(dp.get<DynamicsProcessing::preEqBand>(),
129                                          ranges[i].min.get<DynamicsProcessing::preEqBand>()[0],
130                                          ranges[i].max.get<DynamicsProcessing::preEqBand>()[0]);
131         }
132         case DynamicsProcessing::postEqBand: {
133             return isEqBandConfigInRange(dp.get<DynamicsProcessing::postEqBand>(),
134                                          ranges[i].min.get<DynamicsProcessing::postEqBand>()[0],
135                                          ranges[i].max.get<DynamicsProcessing::postEqBand>()[0]);
136         }
137         case DynamicsProcessing::mbcBand: {
138             return isMbcBandConfigInRange(dp.get<DynamicsProcessing::mbcBand>(),
139                                           ranges[i].min.get<DynamicsProcessing::mbcBand>()[0],
140                                           ranges[i].max.get<DynamicsProcessing::mbcBand>()[0]);
141         }
142         case DynamicsProcessing::limiter: {
143             return isLimiterConfigInRange(dp.get<DynamicsProcessing::limiter>(),
144                                           ranges[i].min.get<DynamicsProcessing::limiter>()[0],
145                                           ranges[i].max.get<DynamicsProcessing::limiter>()[0]);
146         }
147         case DynamicsProcessing::inputGain: {
148             return isInputGainConfigInRange(dp.get<DynamicsProcessing::inputGain>(),
149                                             ranges[i].min.get<DynamicsProcessing::inputGain>()[0],
150                                             ranges[i].max.get<DynamicsProcessing::inputGain>()[0]);
151         }
152         default: {
153             return true;
154         }
155     }
156     return true;
157 }
158 
159 }  // namespace DynamicsProcessingRanges
160 
161 }  // namespace aidl::android::hardware::audio::effect