1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2022, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker ** http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker
18*ec779b8eSAndroid Build Coastguard Worker // #define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "MelReporter"
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include "MelReporter.h"
22*ec779b8eSAndroid Build Coastguard Worker
23*ec779b8eSAndroid Build Coastguard Worker #include <android/media/ISoundDoseCallback.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <audio_utils/power.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
26*ec779b8eSAndroid Build Coastguard Worker
27*ec779b8eSAndroid Build Coastguard Worker using aidl::android::hardware::audio::core::sounddose::ISoundDose;
28*ec779b8eSAndroid Build Coastguard Worker
29*ec779b8eSAndroid Build Coastguard Worker namespace android {
30*ec779b8eSAndroid Build Coastguard Worker
activateHalSoundDoseComputation(const std::string & module,const sp<DeviceHalInterface> & device)31*ec779b8eSAndroid Build Coastguard Worker bool MelReporter::activateHalSoundDoseComputation(const std::string& module,
32*ec779b8eSAndroid Build Coastguard Worker const sp<DeviceHalInterface>& device) {
33*ec779b8eSAndroid Build Coastguard Worker if (mSoundDoseManager->isFrameworkMelForced()) {
34*ec779b8eSAndroid Build Coastguard Worker ALOGD("%s: Forcing use of internal MEL computation.", __func__);
35*ec779b8eSAndroid Build Coastguard Worker activateInternalSoundDoseComputation();
36*ec779b8eSAndroid Build Coastguard Worker return false;
37*ec779b8eSAndroid Build Coastguard Worker }
38*ec779b8eSAndroid Build Coastguard Worker
39*ec779b8eSAndroid Build Coastguard Worker ndk::SpAIBinder soundDoseBinder;
40*ec779b8eSAndroid Build Coastguard Worker if (device->getSoundDoseInterface(module, &soundDoseBinder) != OK) {
41*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: HAL cannot provide sound dose interface for module %s",
42*ec779b8eSAndroid Build Coastguard Worker __func__, module.c_str());
43*ec779b8eSAndroid Build Coastguard Worker return false;
44*ec779b8eSAndroid Build Coastguard Worker }
45*ec779b8eSAndroid Build Coastguard Worker
46*ec779b8eSAndroid Build Coastguard Worker if (soundDoseBinder == nullptr) {
47*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: HAL doesn't implement a sound dose interface for module %s",
48*ec779b8eSAndroid Build Coastguard Worker __func__, module.c_str());
49*ec779b8eSAndroid Build Coastguard Worker return false;
50*ec779b8eSAndroid Build Coastguard Worker }
51*ec779b8eSAndroid Build Coastguard Worker
52*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<ISoundDose> soundDoseInterface = ISoundDose::fromBinder(soundDoseBinder);
53*ec779b8eSAndroid Build Coastguard Worker
54*ec779b8eSAndroid Build Coastguard Worker if (!mSoundDoseManager->setHalSoundDoseInterface(module, soundDoseInterface)) {
55*ec779b8eSAndroid Build Coastguard Worker ALOGW("%s: cannot activate HAL MEL reporting for module %s", __func__, module.c_str());
56*ec779b8eSAndroid Build Coastguard Worker return false;
57*ec779b8eSAndroid Build Coastguard Worker }
58*ec779b8eSAndroid Build Coastguard Worker
59*ec779b8eSAndroid Build Coastguard Worker stopInternalMelComputation();
60*ec779b8eSAndroid Build Coastguard Worker return true;
61*ec779b8eSAndroid Build Coastguard Worker }
62*ec779b8eSAndroid Build Coastguard Worker
activateInternalSoundDoseComputation()63*ec779b8eSAndroid Build Coastguard Worker void MelReporter::activateInternalSoundDoseComputation() {
64*ec779b8eSAndroid Build Coastguard Worker {
65*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
66*ec779b8eSAndroid Build Coastguard Worker if (!mUseHalSoundDoseInterface) {
67*ec779b8eSAndroid Build Coastguard Worker // no need to start internal MEL on active patches
68*ec779b8eSAndroid Build Coastguard Worker return;
69*ec779b8eSAndroid Build Coastguard Worker }
70*ec779b8eSAndroid Build Coastguard Worker mUseHalSoundDoseInterface = false;
71*ec779b8eSAndroid Build Coastguard Worker }
72*ec779b8eSAndroid Build Coastguard Worker
73*ec779b8eSAndroid Build Coastguard Worker // reset the HAL interfaces and use internal MELs
74*ec779b8eSAndroid Build Coastguard Worker mSoundDoseManager->resetHalSoundDoseInterfaces();
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker
onFirstRef()77*ec779b8eSAndroid Build Coastguard Worker void MelReporter::onFirstRef() {
78*ec779b8eSAndroid Build Coastguard Worker mAfMelReporterCallback->getPatchCommandThread()->addListener(this);
79*ec779b8eSAndroid Build Coastguard Worker
80*ec779b8eSAndroid Build Coastguard Worker mSoundDoseManager = sp<SoundDoseManager>::make(sp<IMelReporterCallback>::fromExisting(this));
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker
updateMetadataForCsd(audio_io_handle_t streamHandle,const std::vector<playback_track_metadata_v7_t> & metadataVec)83*ec779b8eSAndroid Build Coastguard Worker void MelReporter::updateMetadataForCsd(audio_io_handle_t streamHandle,
84*ec779b8eSAndroid Build Coastguard Worker const std::vector<playback_track_metadata_v7_t>& metadataVec) {
85*ec779b8eSAndroid Build Coastguard Worker if (!mSoundDoseManager->isCsdEnabled()) {
86*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s csd is disabled", __func__);
87*ec779b8eSAndroid Build Coastguard Worker return;
88*ec779b8eSAndroid Build Coastguard Worker }
89*ec779b8eSAndroid Build Coastguard Worker
90*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex()); // AudioFlinger_Mutex
91*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
92*ec779b8eSAndroid Build Coastguard Worker auto activeMelPatchId = activePatchStreamHandle_l(streamHandle);
93*ec779b8eSAndroid Build Coastguard Worker if (!activeMelPatchId) {
94*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s stream handle %d does not have an active patch", __func__, streamHandle);
95*ec779b8eSAndroid Build Coastguard Worker return;
96*ec779b8eSAndroid Build Coastguard Worker }
97*ec779b8eSAndroid Build Coastguard Worker
98*ec779b8eSAndroid Build Coastguard Worker bool shouldActivateCsd = false;
99*ec779b8eSAndroid Build Coastguard Worker for (const auto& metadata : metadataVec) {
100*ec779b8eSAndroid Build Coastguard Worker if (metadata.base.usage == AUDIO_USAGE_GAME || metadata.base.usage == AUDIO_USAGE_MEDIA) {
101*ec779b8eSAndroid Build Coastguard Worker shouldActivateCsd = true;
102*ec779b8eSAndroid Build Coastguard Worker }
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker
105*ec779b8eSAndroid Build Coastguard Worker auto activeMelPatchIt = mActiveMelPatches.find(activeMelPatchId.value());
106*ec779b8eSAndroid Build Coastguard Worker if (activeMelPatchIt != mActiveMelPatches.end()) {
107*ec779b8eSAndroid Build Coastguard Worker if (shouldActivateCsd != activeMelPatchIt->second.csdActive) {
108*ec779b8eSAndroid Build Coastguard Worker if (activeMelPatchIt->second.csdActive) {
109*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s should not compute CSD for stream handle %d", __func__, streamHandle);
110*ec779b8eSAndroid Build Coastguard Worker stopMelComputationForPatch_l(activeMelPatchIt->second);
111*ec779b8eSAndroid Build Coastguard Worker } else {
112*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s should compute CSD for stream handle %d", __func__, streamHandle);
113*ec779b8eSAndroid Build Coastguard Worker startMelComputationForActivePatch_l(activeMelPatchIt->second);
114*ec779b8eSAndroid Build Coastguard Worker }
115*ec779b8eSAndroid Build Coastguard Worker activeMelPatchIt->second.csdActive = shouldActivateCsd;
116*ec779b8eSAndroid Build Coastguard Worker }
117*ec779b8eSAndroid Build Coastguard Worker }
118*ec779b8eSAndroid Build Coastguard Worker }
119*ec779b8eSAndroid Build Coastguard Worker
resetReferencesForTest()120*ec779b8eSAndroid Build Coastguard Worker void MelReporter::resetReferencesForTest() {
121*ec779b8eSAndroid Build Coastguard Worker mAfMelReporterCallback.clear();
122*ec779b8eSAndroid Build Coastguard Worker mSoundDoseManager->resetReferencesForTest();
123*ec779b8eSAndroid Build Coastguard Worker }
124*ec779b8eSAndroid Build Coastguard Worker
onCreateAudioPatch(audio_patch_handle_t handle,const IAfPatchPanel::Patch & patch)125*ec779b8eSAndroid Build Coastguard Worker void MelReporter::onCreateAudioPatch(audio_patch_handle_t handle,
126*ec779b8eSAndroid Build Coastguard Worker const IAfPatchPanel::Patch& patch) {
127*ec779b8eSAndroid Build Coastguard Worker if (!mSoundDoseManager->isCsdEnabled()) {
128*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s csd is disabled", __func__);
129*ec779b8eSAndroid Build Coastguard Worker return;
130*ec779b8eSAndroid Build Coastguard Worker }
131*ec779b8eSAndroid Build Coastguard Worker
132*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: handle %d mHalHandle %d device sink %08x",
133*ec779b8eSAndroid Build Coastguard Worker __func__, handle, patch.mHalHandle,
134*ec779b8eSAndroid Build Coastguard Worker patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
135*ec779b8eSAndroid Build Coastguard Worker if (patch.mAudioPatch.num_sources == 0
136*ec779b8eSAndroid Build Coastguard Worker || patch.mAudioPatch.sources[0].type != AUDIO_PORT_TYPE_MIX) {
137*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: patch does not contain any mix sources", __func__);
138*ec779b8eSAndroid Build Coastguard Worker return;
139*ec779b8eSAndroid Build Coastguard Worker }
140*ec779b8eSAndroid Build Coastguard Worker
141*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t streamHandle = patch.mAudioPatch.sources[0].ext.mix.handle;
142*ec779b8eSAndroid Build Coastguard Worker ActiveMelPatch newPatch;
143*ec779b8eSAndroid Build Coastguard Worker newPatch.streamHandle = streamHandle;
144*ec779b8eSAndroid Build Coastguard Worker newPatch.csdActive = false;
145*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < patch.mAudioPatch.num_sinks; ++i) {
146*ec779b8eSAndroid Build Coastguard Worker if (patch.mAudioPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE &&
147*ec779b8eSAndroid Build Coastguard Worker mSoundDoseManager->shouldComputeCsdForDeviceType(
148*ec779b8eSAndroid Build Coastguard Worker patch.mAudioPatch.sinks[i].ext.device.type)) {
149*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t deviceId = patch.mAudioPatch.sinks[i].id;
150*ec779b8eSAndroid Build Coastguard Worker bool shouldComputeCsd = mSoundDoseManager->shouldComputeCsdForDeviceWithAddress(
151*ec779b8eSAndroid Build Coastguard Worker patch.mAudioPatch.sinks[i].ext.device.type,
152*ec779b8eSAndroid Build Coastguard Worker patch.mAudioPatch.sinks[i].ext.device.address);
153*ec779b8eSAndroid Build Coastguard Worker newPatch.deviceStates.push_back({deviceId, shouldComputeCsd});
154*ec779b8eSAndroid Build Coastguard Worker newPatch.csdActive |= shouldComputeCsd;
155*ec779b8eSAndroid Build Coastguard Worker AudioDeviceTypeAddr adt{patch.mAudioPatch.sinks[i].ext.device.type,
156*ec779b8eSAndroid Build Coastguard Worker patch.mAudioPatch.sinks[i].ext.device.address};
157*ec779b8eSAndroid Build Coastguard Worker mSoundDoseManager->mapAddressToDeviceId(adt, deviceId);
158*ec779b8eSAndroid Build Coastguard Worker }
159*ec779b8eSAndroid Build Coastguard Worker }
160*ec779b8eSAndroid Build Coastguard Worker
161*ec779b8eSAndroid Build Coastguard Worker if (!newPatch.deviceStates.empty() && newPatch.csdActive) {
162*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _afl(mAfMelReporterCallback->mutex()); // AudioFlinger_Mutex
163*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
164*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s add patch handle %d to active devices", __func__, handle);
165*ec779b8eSAndroid Build Coastguard Worker startMelComputationForActivePatch_l(newPatch);
166*ec779b8eSAndroid Build Coastguard Worker mActiveMelPatches[handle] = newPatch;
167*ec779b8eSAndroid Build Coastguard Worker }
168*ec779b8eSAndroid Build Coastguard Worker }
169*ec779b8eSAndroid Build Coastguard Worker
startMelComputationForActivePatch_l(const ActiveMelPatch & patch)170*ec779b8eSAndroid Build Coastguard Worker void MelReporter::startMelComputationForActivePatch_l(const ActiveMelPatch& patch)
171*ec779b8eSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS // access of AudioFlinger::checkOutputThread_l
172*ec779b8eSAndroid Build Coastguard Worker {
173*ec779b8eSAndroid Build Coastguard Worker auto outputThread = mAfMelReporterCallback->checkOutputThread_l(patch.streamHandle);
174*ec779b8eSAndroid Build Coastguard Worker if (outputThread == nullptr) {
175*ec779b8eSAndroid Build Coastguard Worker ALOGE("%s cannot find thread for stream handle %d", __func__, patch.streamHandle);
176*ec779b8eSAndroid Build Coastguard Worker return;
177*ec779b8eSAndroid Build Coastguard Worker }
178*ec779b8eSAndroid Build Coastguard Worker
179*ec779b8eSAndroid Build Coastguard Worker for (const auto& device : patch.deviceStates) {
180*ec779b8eSAndroid Build Coastguard Worker if (device.second) {
181*ec779b8eSAndroid Build Coastguard Worker ++mActiveDevices[device.first];
182*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s add stream %d that uses device %d for CSD, nr of streams: %d", __func__,
183*ec779b8eSAndroid Build Coastguard Worker patch.streamHandle, device.first, mActiveDevices[device.first]);
184*ec779b8eSAndroid Build Coastguard Worker
185*ec779b8eSAndroid Build Coastguard Worker if (outputThread != nullptr && !useHalSoundDoseInterface_l()) {
186*ec779b8eSAndroid Build Coastguard Worker outputThread->startMelComputation_l(
187*ec779b8eSAndroid Build Coastguard Worker mSoundDoseManager->getOrCreateProcessorForDevice(
188*ec779b8eSAndroid Build Coastguard Worker device.first,
189*ec779b8eSAndroid Build Coastguard Worker patch.streamHandle,
190*ec779b8eSAndroid Build Coastguard Worker outputThread->sampleRate(),
191*ec779b8eSAndroid Build Coastguard Worker outputThread->channelCount(),
192*ec779b8eSAndroid Build Coastguard Worker outputThread->format()));
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker }
195*ec779b8eSAndroid Build Coastguard Worker }
196*ec779b8eSAndroid Build Coastguard Worker }
197*ec779b8eSAndroid Build Coastguard Worker
startMelComputationForDeviceId(audio_port_handle_t deviceId)198*ec779b8eSAndroid Build Coastguard Worker void MelReporter::startMelComputationForDeviceId(audio_port_handle_t deviceId) {
199*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s(%d)", __func__, deviceId);
200*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex());
201*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
202*ec779b8eSAndroid Build Coastguard Worker
203*ec779b8eSAndroid Build Coastguard Worker for (auto& activeMelPatch : mActiveMelPatches) {
204*ec779b8eSAndroid Build Coastguard Worker bool csdActive = false;
205*ec779b8eSAndroid Build Coastguard Worker for (auto& device: activeMelPatch.second.deviceStates) {
206*ec779b8eSAndroid Build Coastguard Worker if (device.first == deviceId && !device.second) {
207*ec779b8eSAndroid Build Coastguard Worker device.second = true;
208*ec779b8eSAndroid Build Coastguard Worker }
209*ec779b8eSAndroid Build Coastguard Worker csdActive |= device.second;
210*ec779b8eSAndroid Build Coastguard Worker }
211*ec779b8eSAndroid Build Coastguard Worker if (csdActive && !activeMelPatch.second.csdActive) {
212*ec779b8eSAndroid Build Coastguard Worker activeMelPatch.second.csdActive = csdActive;
213*ec779b8eSAndroid Build Coastguard Worker startMelComputationForActivePatch_l(activeMelPatch.second);
214*ec779b8eSAndroid Build Coastguard Worker }
215*ec779b8eSAndroid Build Coastguard Worker }
216*ec779b8eSAndroid Build Coastguard Worker }
217*ec779b8eSAndroid Build Coastguard Worker
onReleaseAudioPatch(audio_patch_handle_t handle)218*ec779b8eSAndroid Build Coastguard Worker void MelReporter::onReleaseAudioPatch(audio_patch_handle_t handle) {
219*ec779b8eSAndroid Build Coastguard Worker if (!mSoundDoseManager->isCsdEnabled()) {
220*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s csd is disabled", __func__);
221*ec779b8eSAndroid Build Coastguard Worker return;
222*ec779b8eSAndroid Build Coastguard Worker }
223*ec779b8eSAndroid Build Coastguard Worker
224*ec779b8eSAndroid Build Coastguard Worker ActiveMelPatch melPatch;
225*ec779b8eSAndroid Build Coastguard Worker {
226*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
227*ec779b8eSAndroid Build Coastguard Worker
228*ec779b8eSAndroid Build Coastguard Worker auto patchIt = mActiveMelPatches.find(handle);
229*ec779b8eSAndroid Build Coastguard Worker if (patchIt == mActiveMelPatches.end()) {
230*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s patch handle %d does not contain any mix sources with active MEL calculation",
231*ec779b8eSAndroid Build Coastguard Worker __func__, handle);
232*ec779b8eSAndroid Build Coastguard Worker return;
233*ec779b8eSAndroid Build Coastguard Worker }
234*ec779b8eSAndroid Build Coastguard Worker
235*ec779b8eSAndroid Build Coastguard Worker melPatch = patchIt->second;
236*ec779b8eSAndroid Build Coastguard Worker mActiveMelPatches.erase(patchIt);
237*ec779b8eSAndroid Build Coastguard Worker }
238*ec779b8eSAndroid Build Coastguard Worker
239*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _afl(mAfMelReporterCallback->mutex()); // AudioFlinger_Mutex
240*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
241*ec779b8eSAndroid Build Coastguard Worker if (melPatch.csdActive) {
242*ec779b8eSAndroid Build Coastguard Worker // only need to stop if patch was active
243*ec779b8eSAndroid Build Coastguard Worker melPatch.csdActive = false;
244*ec779b8eSAndroid Build Coastguard Worker stopMelComputationForPatch_l(melPatch);
245*ec779b8eSAndroid Build Coastguard Worker }
246*ec779b8eSAndroid Build Coastguard Worker }
247*ec779b8eSAndroid Build Coastguard Worker
onUpdateAudioPatch(audio_patch_handle_t oldHandle,audio_patch_handle_t newHandle,const IAfPatchPanel::Patch & patch)248*ec779b8eSAndroid Build Coastguard Worker void MelReporter::onUpdateAudioPatch(audio_patch_handle_t oldHandle,
249*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t newHandle, const IAfPatchPanel::Patch& patch) {
250*ec779b8eSAndroid Build Coastguard Worker onReleaseAudioPatch(oldHandle);
251*ec779b8eSAndroid Build Coastguard Worker onCreateAudioPatch(newHandle, patch);
252*ec779b8eSAndroid Build Coastguard Worker }
253*ec779b8eSAndroid Build Coastguard Worker
getSoundDoseInterface(const sp<media::ISoundDoseCallback> & callback)254*ec779b8eSAndroid Build Coastguard Worker sp<media::ISoundDose> MelReporter::getSoundDoseInterface(
255*ec779b8eSAndroid Build Coastguard Worker const sp<media::ISoundDoseCallback>& callback) {
256*ec779b8eSAndroid Build Coastguard Worker // no need to lock since getSoundDoseInterface is synchronized
257*ec779b8eSAndroid Build Coastguard Worker return mSoundDoseManager->getSoundDoseInterface(callback);
258*ec779b8eSAndroid Build Coastguard Worker }
259*ec779b8eSAndroid Build Coastguard Worker
stopInternalMelComputation()260*ec779b8eSAndroid Build Coastguard Worker void MelReporter::stopInternalMelComputation() {
261*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s", __func__);
262*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
263*ec779b8eSAndroid Build Coastguard Worker if (mUseHalSoundDoseInterface) {
264*ec779b8eSAndroid Build Coastguard Worker return;
265*ec779b8eSAndroid Build Coastguard Worker }
266*ec779b8eSAndroid Build Coastguard Worker mActiveMelPatches.clear();
267*ec779b8eSAndroid Build Coastguard Worker mUseHalSoundDoseInterface = true;
268*ec779b8eSAndroid Build Coastguard Worker }
269*ec779b8eSAndroid Build Coastguard Worker
stopMelComputationForPatch_l(const ActiveMelPatch & patch)270*ec779b8eSAndroid Build Coastguard Worker void MelReporter::stopMelComputationForPatch_l(const ActiveMelPatch& patch)
271*ec779b8eSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS // access of AudioFlinger::checkOutputThread_l
272*ec779b8eSAndroid Build Coastguard Worker {
273*ec779b8eSAndroid Build Coastguard Worker auto outputThread = mAfMelReporterCallback->checkOutputThread_l(patch.streamHandle);
274*ec779b8eSAndroid Build Coastguard Worker
275*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s: stop MEL for stream id: %d", __func__, patch.streamHandle);
276*ec779b8eSAndroid Build Coastguard Worker for (const auto& device : patch.deviceStates) {
277*ec779b8eSAndroid Build Coastguard Worker if (mActiveDevices[device.first] > 0) {
278*ec779b8eSAndroid Build Coastguard Worker --mActiveDevices[device.first];
279*ec779b8eSAndroid Build Coastguard Worker if (mActiveDevices[device.first] == 0) {
280*ec779b8eSAndroid Build Coastguard Worker // no stream is using deviceId anymore
281*ec779b8eSAndroid Build Coastguard Worker ALOGI("%s removing device %d from active CSD devices", __func__, device.first);
282*ec779b8eSAndroid Build Coastguard Worker mSoundDoseManager->clearMapDeviceIdEntries(device.first);
283*ec779b8eSAndroid Build Coastguard Worker }
284*ec779b8eSAndroid Build Coastguard Worker }
285*ec779b8eSAndroid Build Coastguard Worker }
286*ec779b8eSAndroid Build Coastguard Worker
287*ec779b8eSAndroid Build Coastguard Worker mSoundDoseManager->removeStreamProcessor(patch.streamHandle);
288*ec779b8eSAndroid Build Coastguard Worker if (outputThread != nullptr && !useHalSoundDoseInterface_l()) {
289*ec779b8eSAndroid Build Coastguard Worker outputThread->stopMelComputation_l();
290*ec779b8eSAndroid Build Coastguard Worker }
291*ec779b8eSAndroid Build Coastguard Worker }
292*ec779b8eSAndroid Build Coastguard Worker
stopMelComputationForDeviceId(audio_port_handle_t deviceId)293*ec779b8eSAndroid Build Coastguard Worker void MelReporter::stopMelComputationForDeviceId(audio_port_handle_t deviceId) {
294*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s(%d)", __func__, deviceId);
295*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex());
296*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
297*ec779b8eSAndroid Build Coastguard Worker
298*ec779b8eSAndroid Build Coastguard Worker for (auto& activeMelPatch : mActiveMelPatches) {
299*ec779b8eSAndroid Build Coastguard Worker bool csdActive = false;
300*ec779b8eSAndroid Build Coastguard Worker for (auto& device: activeMelPatch.second.deviceStates) {
301*ec779b8eSAndroid Build Coastguard Worker if (device.first == deviceId && device.second) {
302*ec779b8eSAndroid Build Coastguard Worker device.second = false;
303*ec779b8eSAndroid Build Coastguard Worker }
304*ec779b8eSAndroid Build Coastguard Worker csdActive |= device.second;
305*ec779b8eSAndroid Build Coastguard Worker }
306*ec779b8eSAndroid Build Coastguard Worker
307*ec779b8eSAndroid Build Coastguard Worker if (!csdActive && activeMelPatch.second.csdActive) {
308*ec779b8eSAndroid Build Coastguard Worker activeMelPatch.second.csdActive = csdActive;
309*ec779b8eSAndroid Build Coastguard Worker stopMelComputationForPatch_l(activeMelPatch.second);
310*ec779b8eSAndroid Build Coastguard Worker }
311*ec779b8eSAndroid Build Coastguard Worker }
312*ec779b8eSAndroid Build Coastguard Worker
313*ec779b8eSAndroid Build Coastguard Worker }
314*ec779b8eSAndroid Build Coastguard Worker
applyAllAudioPatches()315*ec779b8eSAndroid Build Coastguard Worker void MelReporter::applyAllAudioPatches() {
316*ec779b8eSAndroid Build Coastguard Worker ALOGV("%s", __func__);
317*ec779b8eSAndroid Build Coastguard Worker
318*ec779b8eSAndroid Build Coastguard Worker std::vector<IAfPatchPanel::Patch> patchesCopy;
319*ec779b8eSAndroid Build Coastguard Worker {
320*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _laf(mAfMelReporterCallback->mutex());
321*ec779b8eSAndroid Build Coastguard Worker for (const auto& patch : mAfPatchPanel->patches_l()) {
322*ec779b8eSAndroid Build Coastguard Worker patchesCopy.emplace_back(patch.second);
323*ec779b8eSAndroid Build Coastguard Worker }
324*ec779b8eSAndroid Build Coastguard Worker }
325*ec779b8eSAndroid Build Coastguard Worker
326*ec779b8eSAndroid Build Coastguard Worker for (const auto& patch : patchesCopy) {
327*ec779b8eSAndroid Build Coastguard Worker onCreateAudioPatch(patch.mHalHandle, patch);
328*ec779b8eSAndroid Build Coastguard Worker }
329*ec779b8eSAndroid Build Coastguard Worker }
330*ec779b8eSAndroid Build Coastguard Worker
activePatchStreamHandle_l(audio_io_handle_t streamHandle)331*ec779b8eSAndroid Build Coastguard Worker std::optional<audio_patch_handle_t> MelReporter::activePatchStreamHandle_l(
332*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t streamHandle) {
333*ec779b8eSAndroid Build Coastguard Worker for(const auto& patchIt : mActiveMelPatches) {
334*ec779b8eSAndroid Build Coastguard Worker if (patchIt.second.streamHandle == streamHandle) {
335*ec779b8eSAndroid Build Coastguard Worker return patchIt.first;
336*ec779b8eSAndroid Build Coastguard Worker }
337*ec779b8eSAndroid Build Coastguard Worker }
338*ec779b8eSAndroid Build Coastguard Worker return std::nullopt;
339*ec779b8eSAndroid Build Coastguard Worker }
340*ec779b8eSAndroid Build Coastguard Worker
useHalSoundDoseInterface_l()341*ec779b8eSAndroid Build Coastguard Worker bool MelReporter::useHalSoundDoseInterface_l() {
342*ec779b8eSAndroid Build Coastguard Worker return !mSoundDoseManager->isFrameworkMelForced() & mUseHalSoundDoseInterface;
343*ec779b8eSAndroid Build Coastguard Worker }
344*ec779b8eSAndroid Build Coastguard Worker
dump()345*ec779b8eSAndroid Build Coastguard Worker std::string MelReporter::dump() {
346*ec779b8eSAndroid Build Coastguard Worker audio_utils::lock_guard _l(mutex());
347*ec779b8eSAndroid Build Coastguard Worker std::string output("\nSound Dose:\n");
348*ec779b8eSAndroid Build Coastguard Worker output.append(mSoundDoseManager->dump());
349*ec779b8eSAndroid Build Coastguard Worker return output;
350*ec779b8eSAndroid Build Coastguard Worker }
351*ec779b8eSAndroid Build Coastguard Worker
352*ec779b8eSAndroid Build Coastguard Worker } // namespace android
353