blob: 5081ce4f15a8cc1451665f03a9f6b998035d8a37 [file] [log] [blame]
Vlad Popa2900c0a2022-10-24 13:38:00 +02001/*
2**
3** Copyright 2022, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#pragma once
19
Vlad Popadebe0a72022-12-28 16:55:13 +010020#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
Vlad Popa1d5f0d52022-12-18 12:21:26 +010021#include <aidl/android/media/audio/common/AudioDevice.h>
Vlad Popae3fd1c22022-11-07 21:03:18 +010022#include <android/media/BnSoundDose.h>
Vlad Popa63f047e2022-11-05 14:09:19 +010023#include <android/media/ISoundDoseCallback.h>
Vlad Popa1d5f0d52022-12-18 12:21:26 +010024#include <media/AudioDeviceTypeAddr.h>
Vlad Popa2900c0a2022-10-24 13:38:00 +020025#include <audio_utils/MelAggregator.h>
Vlad Popa4defd0b2022-11-06 14:22:31 +010026#include <audio_utils/MelProcessor.h>
Vlad Popae3fd1c22022-11-07 21:03:18 +010027#include <binder/Status.h>
Vlad Popa2900c0a2022-10-24 13:38:00 +020028#include <mutex>
29#include <unordered_map>
30
31namespace android {
32
Vlad Popadebe0a72022-12-28 16:55:13 +010033using aidl::android::hardware::audio::core::sounddose::ISoundDose;
Vlad Popa1d5f0d52022-12-18 12:21:26 +010034
Vlad Popaf09e93f2022-10-31 16:27:12 +010035class SoundDoseManager : public audio_utils::MelProcessor::MelCallback {
Vlad Popa1d5f0d52022-12-18 12:21:26 +010036public:
Vlad Popaf09e93f2022-10-31 16:27:12 +010037 /** CSD is computed with a rolling window of 7 days. */
38 static constexpr int64_t kCsdWindowSeconds = 604800; // 60s * 60m * 24h * 7d
Vlad Popa4847de12023-03-16 18:30:08 +010039 /** Default RS2 upper bound in dBA as defined in IEC 62368-1 3rd edition. */
40 static constexpr float kDefaultRs2UpperBound = 100.f;
Vlad Popaf09e93f2022-10-31 16:27:12 +010041
42 SoundDoseManager()
43 : mMelAggregator(sp<audio_utils::MelAggregator>::make(kCsdWindowSeconds)),
Vlad Popa4847de12023-03-16 18:30:08 +010044 mRs2UpperBound(kDefaultRs2UpperBound) {};
Vlad Popa2900c0a2022-10-24 13:38:00 +020045
46 /**
Vlad Popaf09e93f2022-10-31 16:27:12 +010047 * \brief Creates or gets the MelProcessor assigned to the streamHandle
Vlad Popa2900c0a2022-10-24 13:38:00 +020048 *
49 * \param deviceId id for the devices where the stream is active.
Vlad Popa1d5f0d52022-12-18 12:21:26 +010050 * \param streamHandle handle to the stream
Vlad Popaf09e93f2022-10-31 16:27:12 +010051 * \param sampleRate sample rate for the processor
52 * \param channelCount number of channels to be processed.
53 * \param format format of the input samples.
54 *
55 * \return MelProcessor assigned to the stream and device id.
Vlad Popa2900c0a2022-10-24 13:38:00 +020056 */
Vlad Popa4defd0b2022-11-06 14:22:31 +010057 sp<audio_utils::MelProcessor> getOrCreateProcessorForDevice(audio_port_handle_t deviceId,
58 audio_io_handle_t streamHandle,
59 uint32_t sampleRate,
60 size_t channelCount,
61 audio_format_t format);
Vlad Popa2900c0a2022-10-24 13:38:00 +020062
63 /**
Vlad Popaf09e93f2022-10-31 16:27:12 +010064 * \brief Removes stream processor when MEL computation is not needed anymore
Vlad Popa2900c0a2022-10-24 13:38:00 +020065 *
Vlad Popa1d5f0d52022-12-18 12:21:26 +010066 * \param streamHandle handle to the stream
Vlad Popa2900c0a2022-10-24 13:38:00 +020067 */
Vlad Popaf09e93f2022-10-31 16:27:12 +010068 void removeStreamProcessor(audio_io_handle_t streamHandle);
69
70 /**
Vlad Popa4847de12023-03-16 18:30:08 +010071 * Sets the output RS2 upper bound for momentary exposure warnings. Must not be
Vlad Popaf09e93f2022-10-31 16:27:12 +010072 * higher than 100dBA and not lower than 80dBA.
73 *
74 * \param rs2Value value to use for momentary exposure
75 */
Vlad Popa4847de12023-03-16 18:30:08 +010076 void setOutputRs2UpperBound(float rs2Value);
Vlad Popa2900c0a2022-10-24 13:38:00 +020077
Vlad Popae3fd1c22022-11-07 21:03:18 +010078 /**
79 * \brief Registers the interface for passing callbacks to the AudioService and gets
80 * the ISoundDose interface.
81 *
82 * \returns the sound dose binder to send commands to the SoundDoseManager
83 **/
84 sp<media::ISoundDose> getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback);
Vlad Popa2900c0a2022-10-24 13:38:00 +020085
Vlad Popa1d5f0d52022-12-18 12:21:26 +010086 /**
87 * Sets the HAL sound dose interface to use for the MEL computation. Use nullptr
88 * for using the internal MEL computation.
89 *
90 * @return true if setting the HAL sound dose value was successful, false otherwise.
91 */
92 bool setHalSoundDoseInterface(const std::shared_ptr<ISoundDose>& halSoundDose);
93
94 /** Returns the cached audio port id from the active devices. */
95 audio_port_handle_t getIdForAudioDevice(
96 const aidl::android::media::audio::common::AudioDevice& audioDevice) const;
97
Vlad Popa58e72dc2023-02-01 13:18:40 +010098 /** Caches mapping between address, device port id and device type. */
99 void mapAddressToDeviceId(const AudioDeviceTypeAddr& adt, const audio_port_handle_t deviceId);
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100100
101 /** Clear all map entries with passed audio_port_handle_t. */
102 void clearMapDeviceIdEntries(audio_port_handle_t deviceId);
103
Vlad Popa2a06fca2023-02-06 16:45:45 +0100104 /** Returns true if CSD is disabled. */
105 bool isCsdDisabled();
106
Vlad Popae3fd1c22022-11-07 21:03:18 +0100107 std::string dump() const;
Vlad Popa63f047e2022-11-05 14:09:19 +0100108
Vlad Popa3d6d39d2022-12-21 18:59:16 +0100109 // used for testing only
Vlad Popa2900c0a2022-10-24 13:38:00 +0200110 size_t getCachedMelRecordsSize() const;
Vlad Popa3d6d39d2022-12-21 18:59:16 +0100111 bool forceUseFrameworkMel() const;
112 bool forceComputeCsdOnAllDevices() const;
Vlad Popaf09e93f2022-10-31 16:27:12 +0100113
Vlad Popa4defd0b2022-11-06 14:22:31 +0100114 /** Method for converting from audio_utils::CsdRecord to media::SoundDoseRecord. */
115 static media::SoundDoseRecord csdRecordToSoundDoseRecord(const audio_utils::CsdRecord& legacy);
116
Vlad Popaf09e93f2022-10-31 16:27:12 +0100117 // ------ Override audio_utils::MelProcessor::MelCallback ------
Vlad Popa4defd0b2022-11-06 14:22:31 +0100118 void onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length,
Vlad Popaf09e93f2022-10-31 16:27:12 +0100119 audio_port_handle_t deviceId) const override;
120
121 void onMomentaryExposure(float currentMel, audio_port_handle_t deviceId) const override;
Vlad Popa4defd0b2022-11-06 14:22:31 +0100122
Vlad Popae3fd1c22022-11-07 21:03:18 +0100123private:
124 class SoundDose : public media::BnSoundDose,
125 public IBinder::DeathRecipient {
126 public:
127 SoundDose(SoundDoseManager* manager, const sp<media::ISoundDoseCallback>& callback)
128 : mSoundDoseManager(manager),
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100129 mSoundDoseCallback(callback) {}
Vlad Popa4defd0b2022-11-06 14:22:31 +0100130
Vlad Popae3fd1c22022-11-07 21:03:18 +0100131 /** IBinder::DeathRecipient. Listen to the death of ISoundDoseCallback. */
132 virtual void binderDied(const wp<IBinder>& who);
133
134 /** BnSoundDose override */
Vlad Popa4847de12023-03-16 18:30:08 +0100135 binder::Status setOutputRs2UpperBound(float value) override;
Vlad Popae3fd1c22022-11-07 21:03:18 +0100136 binder::Status resetCsd(float currentCsd,
137 const std::vector<media::SoundDoseRecord>& records) override;
Vlad Popa58e72dc2023-02-01 13:18:40 +0100138 binder::Status updateAttenuation(float attenuationDB, int device) override;
Vlad Popa4847de12023-03-16 18:30:08 +0100139 binder::Status getOutputRs2UpperBound(float* value) override;
Vlad Popa2a06fca2023-02-06 16:45:45 +0100140 binder::Status disableCsd() override;
141
Vlad Popa58e72dc2023-02-01 13:18:40 +0100142 binder::Status getCsd(float* value) override;
143 binder::Status forceUseFrameworkMel(bool useFrameworkMel) override;
144 binder::Status forceComputeCsdOnAllDevices(bool computeCsdOnAllDevices) override;
Vlad Popa95ee3ca2023-03-20 19:29:38 +0000145 binder::Status isSoundDoseHalSupported(bool* value) override;
Vlad Popae3fd1c22022-11-07 21:03:18 +0100146
147 wp<SoundDoseManager> mSoundDoseManager;
148 const sp<media::ISoundDoseCallback> mSoundDoseCallback;
149 };
150
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100151 class HalSoundDoseCallback : public ISoundDose::BnHalSoundDoseCallback {
152 public:
153 explicit HalSoundDoseCallback(SoundDoseManager* manager)
154 : mSoundDoseManager(manager) {}
155
156 ndk::ScopedAStatus onMomentaryExposureWarning(
157 float in_currentDbA,
158 const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
159 ndk::ScopedAStatus onNewMelValues(
160 const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
161 const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
162
163 wp<SoundDoseManager> mSoundDoseManager;
164 };
165
Vlad Popae3fd1c22022-11-07 21:03:18 +0100166 void resetSoundDose();
167
168 void resetCsd(float currentCsd, const std::vector<media::SoundDoseRecord>& records);
169
170 sp<media::ISoundDoseCallback> getSoundDoseCallback() const;
Vlad Popa91930462022-12-20 22:42:48 +0100171
Vlad Popa58e72dc2023-02-01 13:18:40 +0100172 void updateAttenuation(float attenuationDB, audio_devices_t deviceType);
Vlad Popa2a06fca2023-02-06 16:45:45 +0100173 void disableCsd();
Vlad Popa91930462022-12-20 22:42:48 +0100174 void setUseFrameworkMel(bool useFrameworkMel);
175 void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
Vlad Popa95ee3ca2023-03-20 19:29:38 +0000176 bool isSoundDoseHalSupported() const;
Vlad Popa3d6d39d2022-12-21 18:59:16 +0100177 /** Returns the HAL sound dose interface or null if internal MEL computation is used. */
178 void getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const;
Vlad Popa91930462022-12-20 22:42:48 +0100179
Vlad Popaf09e93f2022-10-31 16:27:12 +0100180 mutable std::mutex mLock;
Vlad Popa2900c0a2022-10-24 13:38:00 +0200181
182 // no need for lock since MelAggregator is thread-safe
Vlad Popaf09e93f2022-10-31 16:27:12 +0100183 const sp<audio_utils::MelAggregator> mMelAggregator;
Vlad Popa2900c0a2022-10-24 13:38:00 +0200184
Vlad Popa4defd0b2022-11-06 14:22:31 +0100185 std::unordered_map<audio_io_handle_t, wp<audio_utils::MelProcessor>> mActiveProcessors
186 GUARDED_BY(mLock);
Vlad Popaf09e93f2022-10-31 16:27:12 +0100187
Vlad Popa7e81cea2023-01-19 16:34:16 +0100188 // map active device address and type to device id, used also for managing the pause/resume
189 // logic for deviceId's that should not report MEL values (e.g.: do not have an active MUSIC
190 // or GAME stream).
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100191 std::map<AudioDeviceTypeAddr, audio_port_handle_t> mActiveDevices GUARDED_BY(mLock);
Vlad Popa58e72dc2023-02-01 13:18:40 +0100192 std::unordered_map<audio_port_handle_t, audio_devices_t> mActiveDeviceTypes GUARDED_BY(mLock);
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100193
Vlad Popa4847de12023-03-16 18:30:08 +0100194 float mRs2UpperBound GUARDED_BY(mLock);
Vlad Popa58e72dc2023-02-01 13:18:40 +0100195 std::unordered_map<audio_devices_t, float> mMelAttenuationDB GUARDED_BY(mLock);
Vlad Popa63f047e2022-11-05 14:09:19 +0100196
Vlad Popae3fd1c22022-11-07 21:03:18 +0100197 sp<SoundDose> mSoundDose GUARDED_BY(mLock);
Vlad Popa91930462022-12-20 22:42:48 +0100198
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100199 std::shared_ptr<ISoundDose> mHalSoundDose GUARDED_BY(mLock);
200 std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock);
201
Vlad Popa2a06fca2023-02-06 16:45:45 +0100202 bool mUseFrameworkMel GUARDED_BY(mLock) = true;
Vlad Popa3d6d39d2022-12-21 18:59:16 +0100203 bool mComputeCsdOnAllDevices GUARDED_BY(mLock) = false;
Vlad Popa2a06fca2023-02-06 16:45:45 +0100204
205 bool mDisableCsd GUARDED_BY(mLock) = false;
Vlad Popa2900c0a2022-10-24 13:38:00 +0200206};
207
208} // namespace android