xref: /aosp_15_r20/frameworks/av/media/libaudiofoundation/AudioGain.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2015 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 #define LOG_TAG "AudioGain"
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker //#define VERY_VERBOSE_LOGGING
21*ec779b8eSAndroid Build Coastguard Worker #ifdef VERY_VERBOSE_LOGGING
22*ec779b8eSAndroid Build Coastguard Worker #define ALOGVV ALOGV
23*ec779b8eSAndroid Build Coastguard Worker #else
24*ec779b8eSAndroid Build Coastguard Worker #define ALOGVV(a...) do { } while(0)
25*ec779b8eSAndroid Build Coastguard Worker #endif
26*ec779b8eSAndroid Build Coastguard Worker 
27*ec779b8eSAndroid Build Coastguard Worker #include <math.h>
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker #include <algorithm>
30*ec779b8eSAndroid Build Coastguard Worker 
31*ec779b8eSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
32*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioGain.h>
33*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
34*ec779b8eSAndroid Build Coastguard Worker 
35*ec779b8eSAndroid Build Coastguard Worker namespace android {
36*ec779b8eSAndroid Build Coastguard Worker 
AudioGain(int index,bool isInput)37*ec779b8eSAndroid Build Coastguard Worker AudioGain::AudioGain(int index, bool isInput)
38*ec779b8eSAndroid Build Coastguard Worker         : mIndex(index), mIsInput(isInput) {}
39*ec779b8eSAndroid Build Coastguard Worker 
getDefaultConfig(struct audio_gain_config * config)40*ec779b8eSAndroid Build Coastguard Worker void AudioGain::getDefaultConfig(struct audio_gain_config *config)
41*ec779b8eSAndroid Build Coastguard Worker {
42*ec779b8eSAndroid Build Coastguard Worker     config->index = mIndex;
43*ec779b8eSAndroid Build Coastguard Worker     config->mode = mGain.mode;
44*ec779b8eSAndroid Build Coastguard Worker     config->channel_mask = mGain.channel_mask;
45*ec779b8eSAndroid Build Coastguard Worker     if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
46*ec779b8eSAndroid Build Coastguard Worker         config->values[0] = mGain.default_value;
47*ec779b8eSAndroid Build Coastguard Worker     } else {
48*ec779b8eSAndroid Build Coastguard Worker         const uint32_t numValues = mIsInput ?
49*ec779b8eSAndroid Build Coastguard Worker                 audio_channel_count_from_in_mask(mGain.channel_mask) :
50*ec779b8eSAndroid Build Coastguard Worker                 audio_channel_count_from_out_mask(mGain.channel_mask);
51*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < numValues; i++) {
52*ec779b8eSAndroid Build Coastguard Worker             config->values[i] = mGain.default_value;
53*ec779b8eSAndroid Build Coastguard Worker         }
54*ec779b8eSAndroid Build Coastguard Worker     }
55*ec779b8eSAndroid Build Coastguard Worker     if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
56*ec779b8eSAndroid Build Coastguard Worker         config->ramp_duration_ms = mGain.min_ramp_ms;
57*ec779b8eSAndroid Build Coastguard Worker     }
58*ec779b8eSAndroid Build Coastguard Worker }
59*ec779b8eSAndroid Build Coastguard Worker 
checkConfig(const struct audio_gain_config * config)60*ec779b8eSAndroid Build Coastguard Worker status_t AudioGain::checkConfig(const struct audio_gain_config *config)
61*ec779b8eSAndroid Build Coastguard Worker {
62*ec779b8eSAndroid Build Coastguard Worker     if ((config->mode & ~mGain.mode) != 0) {
63*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
64*ec779b8eSAndroid Build Coastguard Worker     }
65*ec779b8eSAndroid Build Coastguard Worker     if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
66*ec779b8eSAndroid Build Coastguard Worker         if ((config->values[0] < mGain.min_value) ||
67*ec779b8eSAndroid Build Coastguard Worker                     (config->values[0] > mGain.max_value)) {
68*ec779b8eSAndroid Build Coastguard Worker             return BAD_VALUE;
69*ec779b8eSAndroid Build Coastguard Worker         }
70*ec779b8eSAndroid Build Coastguard Worker     } else {
71*ec779b8eSAndroid Build Coastguard Worker         if ((config->channel_mask & ~mGain.channel_mask) != 0) {
72*ec779b8eSAndroid Build Coastguard Worker             return BAD_VALUE;
73*ec779b8eSAndroid Build Coastguard Worker         }
74*ec779b8eSAndroid Build Coastguard Worker         const uint32_t numValues = mIsInput ?
75*ec779b8eSAndroid Build Coastguard Worker                 audio_channel_count_from_in_mask(config->channel_mask) :
76*ec779b8eSAndroid Build Coastguard Worker                 audio_channel_count_from_out_mask(config->channel_mask);
77*ec779b8eSAndroid Build Coastguard Worker         for (size_t i = 0; i < numValues; i++) {
78*ec779b8eSAndroid Build Coastguard Worker             if ((config->values[i] < mGain.min_value) ||
79*ec779b8eSAndroid Build Coastguard Worker                     (config->values[i] > mGain.max_value)) {
80*ec779b8eSAndroid Build Coastguard Worker                 return BAD_VALUE;
81*ec779b8eSAndroid Build Coastguard Worker             }
82*ec779b8eSAndroid Build Coastguard Worker         }
83*ec779b8eSAndroid Build Coastguard Worker     }
84*ec779b8eSAndroid Build Coastguard Worker     if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
85*ec779b8eSAndroid Build Coastguard Worker         if ((config->ramp_duration_ms < mGain.min_ramp_ms) ||
86*ec779b8eSAndroid Build Coastguard Worker                     (config->ramp_duration_ms > mGain.max_ramp_ms)) {
87*ec779b8eSAndroid Build Coastguard Worker             return BAD_VALUE;
88*ec779b8eSAndroid Build Coastguard Worker         }
89*ec779b8eSAndroid Build Coastguard Worker     }
90*ec779b8eSAndroid Build Coastguard Worker     return NO_ERROR;
91*ec779b8eSAndroid Build Coastguard Worker }
92*ec779b8eSAndroid Build Coastguard Worker 
dump(std::string * dst,int spaces,int index) const93*ec779b8eSAndroid Build Coastguard Worker void AudioGain::dump(std::string *dst, int spaces, int index) const
94*ec779b8eSAndroid Build Coastguard Worker {
95*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*sGain %d:\n", spaces, "", index+1));
96*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*s- mode: %08x\n", spaces, "", mGain.mode));
97*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask));
98*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*s- min_value: %d mB\n", spaces, "", mGain.min_value));
99*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*s- max_value: %d mB\n", spaces, "", mGain.max_value));
100*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*s- default_value: %d mB\n", spaces, "", mGain.default_value));
101*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*s- step_value: %d mB\n", spaces, "", mGain.step_value));
102*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms));
103*ec779b8eSAndroid Build Coastguard Worker     dst->append(base::StringPrintf("%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms));
104*ec779b8eSAndroid Build Coastguard Worker }
105*ec779b8eSAndroid Build Coastguard Worker 
equals(const sp<AudioGain> & other) const106*ec779b8eSAndroid Build Coastguard Worker bool AudioGain::equals(const sp<AudioGain>& other) const
107*ec779b8eSAndroid Build Coastguard Worker {
108*ec779b8eSAndroid Build Coastguard Worker     return other != nullptr &&
109*ec779b8eSAndroid Build Coastguard Worker            mIsInput == other->mIsInput &&
110*ec779b8eSAndroid Build Coastguard Worker            mUseForVolume == other->mUseForVolume &&
111*ec779b8eSAndroid Build Coastguard Worker            // Compare audio gain
112*ec779b8eSAndroid Build Coastguard Worker            mGain.mode == other->mGain.mode &&
113*ec779b8eSAndroid Build Coastguard Worker            mGain.channel_mask == other->mGain.channel_mask &&
114*ec779b8eSAndroid Build Coastguard Worker            mGain.min_value == other->mGain.min_value &&
115*ec779b8eSAndroid Build Coastguard Worker            mGain.max_value == other->mGain.max_value &&
116*ec779b8eSAndroid Build Coastguard Worker            mGain.default_value == other->mGain.default_value &&
117*ec779b8eSAndroid Build Coastguard Worker            mGain.step_value == other->mGain.step_value &&
118*ec779b8eSAndroid Build Coastguard Worker            mGain.min_ramp_ms == other->mGain.min_ramp_ms &&
119*ec779b8eSAndroid Build Coastguard Worker            mGain.max_ramp_ms == other->mGain.max_ramp_ms;
120*ec779b8eSAndroid Build Coastguard Worker }
121*ec779b8eSAndroid Build Coastguard Worker 
toParcelable() const122*ec779b8eSAndroid Build Coastguard Worker ConversionResult<AudioGain::Aidl> AudioGain::toParcelable() const {
123*ec779b8eSAndroid Build Coastguard Worker     media::audio::common::AudioGain aidl = VALUE_OR_RETURN(
124*ec779b8eSAndroid Build Coastguard Worker             legacy2aidl_audio_gain_AudioGain(mGain, mIsInput));
125*ec779b8eSAndroid Build Coastguard Worker     aidl.useForVolume = mUseForVolume;
126*ec779b8eSAndroid Build Coastguard Worker     media::AudioGainSys aidlSys;
127*ec779b8eSAndroid Build Coastguard Worker     aidlSys.index = VALUE_OR_RETURN(convertIntegral<int32_t>(mIndex));
128*ec779b8eSAndroid Build Coastguard Worker     aidlSys.isInput = mIsInput;
129*ec779b8eSAndroid Build Coastguard Worker     return std::make_pair(aidl, aidlSys);
130*ec779b8eSAndroid Build Coastguard Worker }
131*ec779b8eSAndroid Build Coastguard Worker 
fromParcelable(const AudioGain::Aidl & aidl)132*ec779b8eSAndroid Build Coastguard Worker ConversionResult<sp<AudioGain>> AudioGain::fromParcelable(const AudioGain::Aidl& aidl) {
133*ec779b8eSAndroid Build Coastguard Worker     const media::audio::common::AudioGain& hal = aidl.first;
134*ec779b8eSAndroid Build Coastguard Worker     const media::AudioGainSys& sys = aidl.second;
135*ec779b8eSAndroid Build Coastguard Worker     auto index = VALUE_OR_RETURN(convertIntegral<int>(sys.index));
136*ec779b8eSAndroid Build Coastguard Worker     sp<AudioGain> legacy = sp<AudioGain>::make(index, sys.isInput);
137*ec779b8eSAndroid Build Coastguard Worker     legacy->mGain = VALUE_OR_RETURN(aidl2legacy_AudioGain_audio_gain(hal, sys.isInput));
138*ec779b8eSAndroid Build Coastguard Worker     legacy->mUseForVolume = hal.useForVolume;
139*ec779b8eSAndroid Build Coastguard Worker     return legacy;
140*ec779b8eSAndroid Build Coastguard Worker }
141*ec779b8eSAndroid Build Coastguard Worker 
equals(const AudioGains & other) const142*ec779b8eSAndroid Build Coastguard Worker bool AudioGains::equals(const AudioGains &other) const
143*ec779b8eSAndroid Build Coastguard Worker {
144*ec779b8eSAndroid Build Coastguard Worker     return std::equal(begin(), end(), other.begin(), other.end(),
145*ec779b8eSAndroid Build Coastguard Worker                       [](const sp<AudioGain>& left, const sp<AudioGain>& right) {
146*ec779b8eSAndroid Build Coastguard Worker                           return left->equals(right);
147*ec779b8eSAndroid Build Coastguard Worker                       });
148*ec779b8eSAndroid Build Coastguard Worker }
149*ec779b8eSAndroid Build Coastguard Worker 
150*ec779b8eSAndroid Build Coastguard Worker ConversionResult<sp<AudioGain>>
aidl2legacy_AudioGain(const AudioGain::Aidl & aidl)151*ec779b8eSAndroid Build Coastguard Worker aidl2legacy_AudioGain(const AudioGain::Aidl& aidl) {
152*ec779b8eSAndroid Build Coastguard Worker     return AudioGain::fromParcelable(aidl);
153*ec779b8eSAndroid Build Coastguard Worker }
154*ec779b8eSAndroid Build Coastguard Worker 
155*ec779b8eSAndroid Build Coastguard Worker ConversionResult<AudioGain::Aidl>
legacy2aidl_AudioGain(const sp<AudioGain> & legacy)156*ec779b8eSAndroid Build Coastguard Worker legacy2aidl_AudioGain(const sp<AudioGain>& legacy) {
157*ec779b8eSAndroid Build Coastguard Worker     return legacy->toParcelable();
158*ec779b8eSAndroid Build Coastguard Worker }
159*ec779b8eSAndroid Build Coastguard Worker 
160*ec779b8eSAndroid Build Coastguard Worker ConversionResult<AudioGains>
aidl2legacy_AudioGains(const AudioGains::Aidl & aidl)161*ec779b8eSAndroid Build Coastguard Worker aidl2legacy_AudioGains(const AudioGains::Aidl& aidl) {
162*ec779b8eSAndroid Build Coastguard Worker     return convertContainers<AudioGains>(aidl.first, aidl.second,
163*ec779b8eSAndroid Build Coastguard Worker             [](const media::audio::common::AudioGain& g,
164*ec779b8eSAndroid Build Coastguard Worker                const media::AudioGainSys& gs) {
165*ec779b8eSAndroid Build Coastguard Worker                 return aidl2legacy_AudioGain(std::make_pair(g, gs));
166*ec779b8eSAndroid Build Coastguard Worker             });
167*ec779b8eSAndroid Build Coastguard Worker }
168*ec779b8eSAndroid Build Coastguard Worker 
169*ec779b8eSAndroid Build Coastguard Worker ConversionResult<AudioGains::Aidl>
legacy2aidl_AudioGains(const AudioGains & legacy)170*ec779b8eSAndroid Build Coastguard Worker legacy2aidl_AudioGains(const AudioGains& legacy) {
171*ec779b8eSAndroid Build Coastguard Worker     return convertContainerSplit<
172*ec779b8eSAndroid Build Coastguard Worker             std::vector<media::audio::common::AudioGain>,
173*ec779b8eSAndroid Build Coastguard Worker             std::vector<media::AudioGainSys>>(legacy, legacy2aidl_AudioGain);
174*ec779b8eSAndroid Build Coastguard Worker }
175*ec779b8eSAndroid Build Coastguard Worker 
176*ec779b8eSAndroid Build Coastguard Worker } // namespace android
177