xref: /aosp_15_r20/system/media/audio_utils/MelAggregator.cpp (revision b9df5ad1c9ac98a7fefaac271a55f7ae3db05414)
1*b9df5ad1SAndroid Build Coastguard Worker /*
2*b9df5ad1SAndroid Build Coastguard Worker  * Copyright 2022 The Android Open Source Project
3*b9df5ad1SAndroid Build Coastguard Worker  *
4*b9df5ad1SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*b9df5ad1SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*b9df5ad1SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*b9df5ad1SAndroid Build Coastguard Worker  *
8*b9df5ad1SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*b9df5ad1SAndroid Build Coastguard Worker  *
10*b9df5ad1SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*b9df5ad1SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*b9df5ad1SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b9df5ad1SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*b9df5ad1SAndroid Build Coastguard Worker  * limitations under the License.
15*b9df5ad1SAndroid Build Coastguard Worker  */
16*b9df5ad1SAndroid Build Coastguard Worker 
17*b9df5ad1SAndroid Build Coastguard Worker // #define LOG_NDEBUG 0
18*b9df5ad1SAndroid Build Coastguard Worker #define LOG_TAG "audio_utils_MelAggregator"
19*b9df5ad1SAndroid Build Coastguard Worker 
20*b9df5ad1SAndroid Build Coastguard Worker #include <audio_utils/MelAggregator.h>
21*b9df5ad1SAndroid Build Coastguard Worker #include <audio_utils/power.h>
22*b9df5ad1SAndroid Build Coastguard Worker #include <cinttypes>
23*b9df5ad1SAndroid Build Coastguard Worker #include <iterator>
24*b9df5ad1SAndroid Build Coastguard Worker #include <utils/Log.h>
25*b9df5ad1SAndroid Build Coastguard Worker 
26*b9df5ad1SAndroid Build Coastguard Worker namespace android::audio_utils {
27*b9df5ad1SAndroid Build Coastguard Worker namespace {
28*b9df5ad1SAndroid Build Coastguard Worker 
29*b9df5ad1SAndroid Build Coastguard Worker /** Min value after which the MEL values are aggregated to CSD. */
30*b9df5ad1SAndroid Build Coastguard Worker constexpr float kMinCsdRecordToStore = 0.01f;
31*b9df5ad1SAndroid Build Coastguard Worker 
32*b9df5ad1SAndroid Build Coastguard Worker /** Threshold for 100% CSD expressed in Pa^2s. */
33*b9df5ad1SAndroid Build Coastguard Worker constexpr float kCsdThreshold = 5760.0f; // 1.6f(Pa^2h) * 3600.0f(s);
34*b9df5ad1SAndroid Build Coastguard Worker 
35*b9df5ad1SAndroid Build Coastguard Worker /** Reference energy used for dB calculation in Pa^2. */
36*b9df5ad1SAndroid Build Coastguard Worker constexpr float kReferenceEnergyPa = 4e-10;
37*b9df5ad1SAndroid Build Coastguard Worker 
38*b9df5ad1SAndroid Build Coastguard Worker /**
39*b9df5ad1SAndroid Build Coastguard Worker  * Checking the intersection of the time intervals of v1 and v2. Each MelRecord v
40*b9df5ad1SAndroid Build Coastguard Worker  * spawns an interval [t1, t2) if and only if:
41*b9df5ad1SAndroid Build Coastguard Worker  *    v.timestamp == t1 && v.mels.size() == t2 - t1
42*b9df5ad1SAndroid Build Coastguard Worker  **/
intersectRegion(const MelRecord & v1,const MelRecord & v2)43*b9df5ad1SAndroid Build Coastguard Worker std::pair<int64_t, int64_t> intersectRegion(const MelRecord& v1, const MelRecord& v2)
44*b9df5ad1SAndroid Build Coastguard Worker {
45*b9df5ad1SAndroid Build Coastguard Worker     const int64_t maxStart = std::max(v1.timestamp, v2.timestamp);
46*b9df5ad1SAndroid Build Coastguard Worker     const int64_t v1End = v1.timestamp + v1.mels.size();
47*b9df5ad1SAndroid Build Coastguard Worker     const int64_t v2End = v2.timestamp + v2.mels.size();
48*b9df5ad1SAndroid Build Coastguard Worker     const int64_t minEnd = std::min(v1End, v2End);
49*b9df5ad1SAndroid Build Coastguard Worker     return {maxStart, minEnd};
50*b9df5ad1SAndroid Build Coastguard Worker }
51*b9df5ad1SAndroid Build Coastguard Worker 
aggregateMels(const float mel1,const float mel2)52*b9df5ad1SAndroid Build Coastguard Worker float aggregateMels(const float mel1, const float mel2) {
53*b9df5ad1SAndroid Build Coastguard Worker     return audio_utils_power_from_energy(powf(10.f, mel1 / 10.f) + powf(10.f, mel2 / 10.f));
54*b9df5ad1SAndroid Build Coastguard Worker }
55*b9df5ad1SAndroid Build Coastguard Worker 
averageMelEnergy(const float mel1,const int64_t duration1,const float mel2,const int64_t duration2)56*b9df5ad1SAndroid Build Coastguard Worker float averageMelEnergy(const float mel1,
57*b9df5ad1SAndroid Build Coastguard Worker                        const int64_t duration1,
58*b9df5ad1SAndroid Build Coastguard Worker                        const float mel2,
59*b9df5ad1SAndroid Build Coastguard Worker                        const int64_t duration2) {
60*b9df5ad1SAndroid Build Coastguard Worker     return audio_utils_power_from_energy((powf(10.f, mel1 / 10.f) * duration1
61*b9df5ad1SAndroid Build Coastguard Worker         + powf(10.f, mel2 / 10.f) * duration2) / (duration1 + duration2));
62*b9df5ad1SAndroid Build Coastguard Worker }
63*b9df5ad1SAndroid Build Coastguard Worker 
melToCsd(float mel)64*b9df5ad1SAndroid Build Coastguard Worker float melToCsd(float mel) {
65*b9df5ad1SAndroid Build Coastguard Worker     float energy = powf(10.f, mel / 10.0f);
66*b9df5ad1SAndroid Build Coastguard Worker     return kReferenceEnergyPa * energy / kCsdThreshold;
67*b9df5ad1SAndroid Build Coastguard Worker }
68*b9df5ad1SAndroid Build Coastguard Worker 
createRevertedRecord(const CsdRecord & record)69*b9df5ad1SAndroid Build Coastguard Worker CsdRecord createRevertedRecord(const CsdRecord& record) {
70*b9df5ad1SAndroid Build Coastguard Worker     return {record.timestamp, record.duration, -record.value, record.averageMel};
71*b9df5ad1SAndroid Build Coastguard Worker }
72*b9df5ad1SAndroid Build Coastguard Worker 
73*b9df5ad1SAndroid Build Coastguard Worker }  // namespace
74*b9df5ad1SAndroid Build Coastguard Worker 
csdTimeIntervalStored_l()75*b9df5ad1SAndroid Build Coastguard Worker int64_t MelAggregator::csdTimeIntervalStored_l()
76*b9df5ad1SAndroid Build Coastguard Worker {
77*b9df5ad1SAndroid Build Coastguard Worker     return mCsdRecords.rbegin()->second.timestamp + mCsdRecords.rbegin()->second.duration
78*b9df5ad1SAndroid Build Coastguard Worker         - mCsdRecords.begin()->second.timestamp;
79*b9df5ad1SAndroid Build Coastguard Worker }
80*b9df5ad1SAndroid Build Coastguard Worker 
addNewestCsdRecord_l(int64_t timestamp,int64_t duration,float csdRecord,float averageMel)81*b9df5ad1SAndroid Build Coastguard Worker std::map<int64_t, CsdRecord>::iterator MelAggregator::addNewestCsdRecord_l(int64_t timestamp,
82*b9df5ad1SAndroid Build Coastguard Worker                                                                            int64_t duration,
83*b9df5ad1SAndroid Build Coastguard Worker                                                                            float csdRecord,
84*b9df5ad1SAndroid Build Coastguard Worker                                                                            float averageMel)
85*b9df5ad1SAndroid Build Coastguard Worker {
86*b9df5ad1SAndroid Build Coastguard Worker     ALOGV("%s: add new csd[%" PRId64 ", %" PRId64 "]=%f for MEL avg %f",
87*b9df5ad1SAndroid Build Coastguard Worker                       __func__,
88*b9df5ad1SAndroid Build Coastguard Worker                       timestamp,
89*b9df5ad1SAndroid Build Coastguard Worker                       duration,
90*b9df5ad1SAndroid Build Coastguard Worker                       csdRecord,
91*b9df5ad1SAndroid Build Coastguard Worker                       averageMel);
92*b9df5ad1SAndroid Build Coastguard Worker 
93*b9df5ad1SAndroid Build Coastguard Worker     mCurrentCsd += csdRecord;
94*b9df5ad1SAndroid Build Coastguard Worker     return mCsdRecords.emplace_hint(mCsdRecords.end(),
95*b9df5ad1SAndroid Build Coastguard Worker                                     timestamp,
96*b9df5ad1SAndroid Build Coastguard Worker                                     CsdRecord(timestamp,
97*b9df5ad1SAndroid Build Coastguard Worker                                               duration,
98*b9df5ad1SAndroid Build Coastguard Worker                                               csdRecord,
99*b9df5ad1SAndroid Build Coastguard Worker                                               averageMel));
100*b9df5ad1SAndroid Build Coastguard Worker }
101*b9df5ad1SAndroid Build Coastguard Worker 
removeOldCsdRecords_l(std::vector<CsdRecord> & removeRecords)102*b9df5ad1SAndroid Build Coastguard Worker void MelAggregator::removeOldCsdRecords_l(std::vector<CsdRecord>& removeRecords) {
103*b9df5ad1SAndroid Build Coastguard Worker     // Remove older CSD values
104*b9df5ad1SAndroid Build Coastguard Worker     while (!mCsdRecords.empty() && csdTimeIntervalStored_l() > mCsdWindowSeconds) {
105*b9df5ad1SAndroid Build Coastguard Worker         mCurrentCsd -= mCsdRecords.begin()->second.value;
106*b9df5ad1SAndroid Build Coastguard Worker         removeRecords.emplace_back(createRevertedRecord(mCsdRecords.begin()->second));
107*b9df5ad1SAndroid Build Coastguard Worker         mCsdRecords.erase(mCsdRecords.begin());
108*b9df5ad1SAndroid Build Coastguard Worker     }
109*b9df5ad1SAndroid Build Coastguard Worker }
110*b9df5ad1SAndroid Build Coastguard Worker 
updateCsdRecords_l()111*b9df5ad1SAndroid Build Coastguard Worker std::vector<CsdRecord> MelAggregator::updateCsdRecords_l()
112*b9df5ad1SAndroid Build Coastguard Worker {
113*b9df5ad1SAndroid Build Coastguard Worker     std::vector<CsdRecord> newRecords;
114*b9df5ad1SAndroid Build Coastguard Worker 
115*b9df5ad1SAndroid Build Coastguard Worker     // only update if we are above threshold
116*b9df5ad1SAndroid Build Coastguard Worker     if (mCurrentMelRecordsCsd < kMinCsdRecordToStore) {
117*b9df5ad1SAndroid Build Coastguard Worker         removeOldCsdRecords_l(newRecords);
118*b9df5ad1SAndroid Build Coastguard Worker         return newRecords;
119*b9df5ad1SAndroid Build Coastguard Worker     }
120*b9df5ad1SAndroid Build Coastguard Worker 
121*b9df5ad1SAndroid Build Coastguard Worker     float converted = 0.f;
122*b9df5ad1SAndroid Build Coastguard Worker     float averageMel = 0.f;
123*b9df5ad1SAndroid Build Coastguard Worker     float csdValue = 0.f;
124*b9df5ad1SAndroid Build Coastguard Worker     int64_t duration = 0;
125*b9df5ad1SAndroid Build Coastguard Worker     int64_t timestamp = mMelRecords.begin()->first;
126*b9df5ad1SAndroid Build Coastguard Worker     for (const auto& storedMel: mMelRecords) {
127*b9df5ad1SAndroid Build Coastguard Worker         int melsIdx = 0;
128*b9df5ad1SAndroid Build Coastguard Worker         for (const auto& mel: storedMel.second.mels) {
129*b9df5ad1SAndroid Build Coastguard Worker             averageMel = averageMelEnergy(averageMel, duration, mel, 1.f);
130*b9df5ad1SAndroid Build Coastguard Worker             csdValue += melToCsd(mel);
131*b9df5ad1SAndroid Build Coastguard Worker             ++duration;
132*b9df5ad1SAndroid Build Coastguard Worker             if (csdValue >= kMinCsdRecordToStore
133*b9df5ad1SAndroid Build Coastguard Worker                 && mCurrentMelRecordsCsd - converted - csdValue >= kMinCsdRecordToStore) {
134*b9df5ad1SAndroid Build Coastguard Worker                 auto it = addNewestCsdRecord_l(timestamp,
135*b9df5ad1SAndroid Build Coastguard Worker                                                duration,
136*b9df5ad1SAndroid Build Coastguard Worker                                                csdValue,
137*b9df5ad1SAndroid Build Coastguard Worker                                                averageMel);
138*b9df5ad1SAndroid Build Coastguard Worker                 newRecords.emplace_back(it->second);
139*b9df5ad1SAndroid Build Coastguard Worker 
140*b9df5ad1SAndroid Build Coastguard Worker                 duration = 0;
141*b9df5ad1SAndroid Build Coastguard Worker                 averageMel = 0.f;
142*b9df5ad1SAndroid Build Coastguard Worker                 converted += csdValue;
143*b9df5ad1SAndroid Build Coastguard Worker                 csdValue = 0.f;
144*b9df5ad1SAndroid Build Coastguard Worker                 timestamp = storedMel.first + melsIdx;
145*b9df5ad1SAndroid Build Coastguard Worker             }
146*b9df5ad1SAndroid Build Coastguard Worker             ++ melsIdx;
147*b9df5ad1SAndroid Build Coastguard Worker         }
148*b9df5ad1SAndroid Build Coastguard Worker     }
149*b9df5ad1SAndroid Build Coastguard Worker 
150*b9df5ad1SAndroid Build Coastguard Worker     if(csdValue > 0) {
151*b9df5ad1SAndroid Build Coastguard Worker         auto it = addNewestCsdRecord_l(timestamp,
152*b9df5ad1SAndroid Build Coastguard Worker                                        duration,
153*b9df5ad1SAndroid Build Coastguard Worker                                        csdValue,
154*b9df5ad1SAndroid Build Coastguard Worker                                        averageMel);
155*b9df5ad1SAndroid Build Coastguard Worker         newRecords.emplace_back(it->second);
156*b9df5ad1SAndroid Build Coastguard Worker     }
157*b9df5ad1SAndroid Build Coastguard Worker 
158*b9df5ad1SAndroid Build Coastguard Worker     removeOldCsdRecords_l(newRecords);
159*b9df5ad1SAndroid Build Coastguard Worker 
160*b9df5ad1SAndroid Build Coastguard Worker     // reset mel values
161*b9df5ad1SAndroid Build Coastguard Worker     mCurrentMelRecordsCsd = 0.0f;
162*b9df5ad1SAndroid Build Coastguard Worker     mMelRecords.clear();
163*b9df5ad1SAndroid Build Coastguard Worker 
164*b9df5ad1SAndroid Build Coastguard Worker     return newRecords;
165*b9df5ad1SAndroid Build Coastguard Worker }
166*b9df5ad1SAndroid Build Coastguard Worker 
aggregateAndAddNewMelRecord(const MelRecord & mel)167*b9df5ad1SAndroid Build Coastguard Worker std::vector<CsdRecord> MelAggregator::aggregateAndAddNewMelRecord(const MelRecord& mel)
168*b9df5ad1SAndroid Build Coastguard Worker {
169*b9df5ad1SAndroid Build Coastguard Worker     std::lock_guard _l(mLock);
170*b9df5ad1SAndroid Build Coastguard Worker     return aggregateAndAddNewMelRecord_l(mel);
171*b9df5ad1SAndroid Build Coastguard Worker }
172*b9df5ad1SAndroid Build Coastguard Worker 
aggregateAndAddNewMelRecord_l(const MelRecord & mel)173*b9df5ad1SAndroid Build Coastguard Worker std::vector<CsdRecord> MelAggregator::aggregateAndAddNewMelRecord_l(const MelRecord& mel)
174*b9df5ad1SAndroid Build Coastguard Worker {
175*b9df5ad1SAndroid Build Coastguard Worker     for (const auto& m : mel.mels) {
176*b9df5ad1SAndroid Build Coastguard Worker         mCurrentMelRecordsCsd += melToCsd(m);
177*b9df5ad1SAndroid Build Coastguard Worker     }
178*b9df5ad1SAndroid Build Coastguard Worker     ALOGV("%s: current mel values CSD %f", __func__, mCurrentMelRecordsCsd);
179*b9df5ad1SAndroid Build Coastguard Worker 
180*b9df5ad1SAndroid Build Coastguard Worker     auto mergeIt = mMelRecords.lower_bound(mel.timestamp);
181*b9df5ad1SAndroid Build Coastguard Worker 
182*b9df5ad1SAndroid Build Coastguard Worker     if (mergeIt != mMelRecords.begin()) {
183*b9df5ad1SAndroid Build Coastguard Worker         auto prevMergeIt = std::prev(mergeIt);
184*b9df5ad1SAndroid Build Coastguard Worker         if (prevMergeIt->second.overlapsEnd(mel)) {
185*b9df5ad1SAndroid Build Coastguard Worker             mergeIt = prevMergeIt;
186*b9df5ad1SAndroid Build Coastguard Worker         }
187*b9df5ad1SAndroid Build Coastguard Worker     }
188*b9df5ad1SAndroid Build Coastguard Worker 
189*b9df5ad1SAndroid Build Coastguard Worker     int64_t newTimestamp = mel.timestamp;
190*b9df5ad1SAndroid Build Coastguard Worker     std::vector<float> newMels = mel.mels;
191*b9df5ad1SAndroid Build Coastguard Worker     auto mergeStart = mergeIt;
192*b9df5ad1SAndroid Build Coastguard Worker     int overlapStart = 0;
193*b9df5ad1SAndroid Build Coastguard Worker     while(mergeIt != mMelRecords.end()) {
194*b9df5ad1SAndroid Build Coastguard Worker         const auto& [melRecordStart, melRecord] = *mergeIt;
195*b9df5ad1SAndroid Build Coastguard Worker         const auto [regionStart, regionEnd] = intersectRegion(melRecord, mel);
196*b9df5ad1SAndroid Build Coastguard Worker         if (regionStart >= regionEnd) {
197*b9df5ad1SAndroid Build Coastguard Worker             // no intersection
198*b9df5ad1SAndroid Build Coastguard Worker             break;
199*b9df5ad1SAndroid Build Coastguard Worker         }
200*b9df5ad1SAndroid Build Coastguard Worker 
201*b9df5ad1SAndroid Build Coastguard Worker         if (melRecordStart < regionStart) {
202*b9df5ad1SAndroid Build Coastguard Worker             newTimestamp = melRecordStart;
203*b9df5ad1SAndroid Build Coastguard Worker             overlapStart = regionStart - melRecordStart;
204*b9df5ad1SAndroid Build Coastguard Worker             newMels.insert(newMels.begin(), melRecord.mels.begin(),
205*b9df5ad1SAndroid Build Coastguard Worker                            melRecord.mels.begin() + overlapStart);
206*b9df5ad1SAndroid Build Coastguard Worker         }
207*b9df5ad1SAndroid Build Coastguard Worker 
208*b9df5ad1SAndroid Build Coastguard Worker         for (int64_t aggregateTime = regionStart; aggregateTime < regionEnd; ++aggregateTime) {
209*b9df5ad1SAndroid Build Coastguard Worker             const int offsetStored = aggregateTime - melRecordStart;
210*b9df5ad1SAndroid Build Coastguard Worker             const int offsetNew = aggregateTime - mel.timestamp;
211*b9df5ad1SAndroid Build Coastguard Worker             newMels[overlapStart + offsetNew] =
212*b9df5ad1SAndroid Build Coastguard Worker                 aggregateMels(melRecord.mels[offsetStored], mel.mels[offsetNew]);
213*b9df5ad1SAndroid Build Coastguard Worker         }
214*b9df5ad1SAndroid Build Coastguard Worker 
215*b9df5ad1SAndroid Build Coastguard Worker         const int64_t mergeEndTime = melRecordStart + melRecord.mels.size();
216*b9df5ad1SAndroid Build Coastguard Worker         if (mergeEndTime > regionEnd) {
217*b9df5ad1SAndroid Build Coastguard Worker             newMels.insert(newMels.end(),
218*b9df5ad1SAndroid Build Coastguard Worker                            melRecord.mels.end() - mergeEndTime + regionEnd,
219*b9df5ad1SAndroid Build Coastguard Worker                            melRecord.mels.end());
220*b9df5ad1SAndroid Build Coastguard Worker         }
221*b9df5ad1SAndroid Build Coastguard Worker 
222*b9df5ad1SAndroid Build Coastguard Worker         ++mergeIt;
223*b9df5ad1SAndroid Build Coastguard Worker     }
224*b9df5ad1SAndroid Build Coastguard Worker 
225*b9df5ad1SAndroid Build Coastguard Worker     auto hint = mergeIt;
226*b9df5ad1SAndroid Build Coastguard Worker     if (mergeStart != mergeIt) {
227*b9df5ad1SAndroid Build Coastguard Worker         hint = mMelRecords.erase(mergeStart, mergeIt);
228*b9df5ad1SAndroid Build Coastguard Worker     }
229*b9df5ad1SAndroid Build Coastguard Worker 
230*b9df5ad1SAndroid Build Coastguard Worker     mMelRecords.emplace_hint(hint,
231*b9df5ad1SAndroid Build Coastguard Worker                              newTimestamp,
232*b9df5ad1SAndroid Build Coastguard Worker                              MelRecord(mel.portId, newMels, newTimestamp));
233*b9df5ad1SAndroid Build Coastguard Worker 
234*b9df5ad1SAndroid Build Coastguard Worker     return updateCsdRecords_l();
235*b9df5ad1SAndroid Build Coastguard Worker }
236*b9df5ad1SAndroid Build Coastguard Worker 
reset(float newCsd,const std::vector<CsdRecord> & newRecords)237*b9df5ad1SAndroid Build Coastguard Worker void MelAggregator::reset(float newCsd, const std::vector<CsdRecord>& newRecords)
238*b9df5ad1SAndroid Build Coastguard Worker {
239*b9df5ad1SAndroid Build Coastguard Worker     std::lock_guard _l(mLock);
240*b9df5ad1SAndroid Build Coastguard Worker     mCsdRecords.clear();
241*b9df5ad1SAndroid Build Coastguard Worker     mMelRecords.clear();
242*b9df5ad1SAndroid Build Coastguard Worker 
243*b9df5ad1SAndroid Build Coastguard Worker     mCurrentCsd = newCsd;
244*b9df5ad1SAndroid Build Coastguard Worker     for (const auto& record : newRecords) {
245*b9df5ad1SAndroid Build Coastguard Worker         mCsdRecords.emplace_hint(mCsdRecords.end(), record.timestamp, record);
246*b9df5ad1SAndroid Build Coastguard Worker     }
247*b9df5ad1SAndroid Build Coastguard Worker }
248*b9df5ad1SAndroid Build Coastguard Worker 
getCachedMelRecordsSize() const249*b9df5ad1SAndroid Build Coastguard Worker size_t MelAggregator::getCachedMelRecordsSize() const
250*b9df5ad1SAndroid Build Coastguard Worker {
251*b9df5ad1SAndroid Build Coastguard Worker     std::lock_guard _l(mLock);
252*b9df5ad1SAndroid Build Coastguard Worker     return mMelRecords.size();
253*b9df5ad1SAndroid Build Coastguard Worker }
254*b9df5ad1SAndroid Build Coastguard Worker 
foreachCachedMel(const std::function<void (const MelRecord &)> & f) const255*b9df5ad1SAndroid Build Coastguard Worker void MelAggregator::foreachCachedMel(const std::function<void(const MelRecord&)>& f) const
256*b9df5ad1SAndroid Build Coastguard Worker {
257*b9df5ad1SAndroid Build Coastguard Worker      std::lock_guard _l(mLock);
258*b9df5ad1SAndroid Build Coastguard Worker      for (const auto &melRecord : mMelRecords) {
259*b9df5ad1SAndroid Build Coastguard Worker          f(melRecord.second);
260*b9df5ad1SAndroid Build Coastguard Worker      }
261*b9df5ad1SAndroid Build Coastguard Worker }
262*b9df5ad1SAndroid Build Coastguard Worker 
getCsd()263*b9df5ad1SAndroid Build Coastguard Worker float MelAggregator::getCsd() {
264*b9df5ad1SAndroid Build Coastguard Worker     std::lock_guard _l(mLock);
265*b9df5ad1SAndroid Build Coastguard Worker     return mCurrentCsd;
266*b9df5ad1SAndroid Build Coastguard Worker }
267*b9df5ad1SAndroid Build Coastguard Worker 
getCsdRecordsSize() const268*b9df5ad1SAndroid Build Coastguard Worker size_t MelAggregator::getCsdRecordsSize() const {
269*b9df5ad1SAndroid Build Coastguard Worker     std::lock_guard _l(mLock);
270*b9df5ad1SAndroid Build Coastguard Worker     return mCsdRecords.size();
271*b9df5ad1SAndroid Build Coastguard Worker }
272*b9df5ad1SAndroid Build Coastguard Worker 
foreachCsd(const std::function<void (const CsdRecord &)> & f) const273*b9df5ad1SAndroid Build Coastguard Worker void MelAggregator::foreachCsd(const std::function<void(const CsdRecord&)>& f) const
274*b9df5ad1SAndroid Build Coastguard Worker {
275*b9df5ad1SAndroid Build Coastguard Worker      std::lock_guard _l(mLock);
276*b9df5ad1SAndroid Build Coastguard Worker      for (const auto &csdRecord : mCsdRecords) {
277*b9df5ad1SAndroid Build Coastguard Worker          f(csdRecord.second);
278*b9df5ad1SAndroid Build Coastguard Worker      }
279*b9df5ad1SAndroid Build Coastguard Worker }
280*b9df5ad1SAndroid Build Coastguard Worker 
281*b9df5ad1SAndroid Build Coastguard Worker }  // namespace android::audio_utils
282