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