blob: 199e8c92115d0408a62008742dec13052688c1af [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 Popa1d5f0d52022-12-18 12:21:26 +010020#include <aidl/android/hardware/audio/core/ISoundDose.h>
21#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 Popa1d5f0d52022-12-18 12:21:26 +010033using aidl::android::hardware::audio::core::ISoundDose;
34
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
39 /** Default RS2 value in dBA as defined in IEC 62368-1 3rd edition. */
40 static constexpr float kDefaultRs2Value = 100.f;
41
42 SoundDoseManager()
43 : mMelAggregator(sp<audio_utils::MelAggregator>::make(kCsdWindowSeconds)),
Vlad Popa1d5f0d52022-12-18 12:21:26 +010044 mRs2Value(kDefaultRs2Value) {};
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 /**
71 * Sets the output RS2 value for momentary exposure warnings. Must not be
72 * higher than 100dBA and not lower than 80dBA.
73 *
74 * \param rs2Value value to use for momentary exposure
75 */
76 void setOutputRs2(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
98 /** Caches mapping between address and device port id. */
99 void mapAddressToDeviceId(const AudioDeviceTypeAddr& adt,
100 const audio_port_handle_t deviceId);
101
102 /** Clear all map entries with passed audio_port_handle_t. */
103 void clearMapDeviceIdEntries(audio_port_handle_t deviceId);
104
Vlad Popae3fd1c22022-11-07 21:03:18 +0100105 std::string dump() const;
Vlad Popa63f047e2022-11-05 14:09:19 +0100106
Vlad Popa2900c0a2022-10-24 13:38:00 +0200107 // used for testing
108 size_t getCachedMelRecordsSize() const;
Vlad Popa91930462022-12-20 22:42:48 +0100109 bool useFrameworkMel() const;
110 bool computeCsdOnAllDevices() const;
111
Vlad Popaf09e93f2022-10-31 16:27:12 +0100112
Vlad Popa4defd0b2022-11-06 14:22:31 +0100113 /** Method for converting from audio_utils::CsdRecord to media::SoundDoseRecord. */
114 static media::SoundDoseRecord csdRecordToSoundDoseRecord(const audio_utils::CsdRecord& legacy);
115
Vlad Popaf09e93f2022-10-31 16:27:12 +0100116 // ------ Override audio_utils::MelProcessor::MelCallback ------
Vlad Popa4defd0b2022-11-06 14:22:31 +0100117 void onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length,
Vlad Popaf09e93f2022-10-31 16:27:12 +0100118 audio_port_handle_t deviceId) const override;
119
120 void onMomentaryExposure(float currentMel, audio_port_handle_t deviceId) const override;
Vlad Popa4defd0b2022-11-06 14:22:31 +0100121
Vlad Popae3fd1c22022-11-07 21:03:18 +0100122private:
123 class SoundDose : public media::BnSoundDose,
124 public IBinder::DeathRecipient {
125 public:
126 SoundDose(SoundDoseManager* manager, const sp<media::ISoundDoseCallback>& callback)
127 : mSoundDoseManager(manager),
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100128 mSoundDoseCallback(callback) {}
Vlad Popa4defd0b2022-11-06 14:22:31 +0100129
Vlad Popae3fd1c22022-11-07 21:03:18 +0100130 /** IBinder::DeathRecipient. Listen to the death of ISoundDoseCallback. */
131 virtual void binderDied(const wp<IBinder>& who);
132
133 /** BnSoundDose override */
134 binder::Status setOutputRs2(float value) override;
135 binder::Status resetCsd(float currentCsd,
136 const std::vector<media::SoundDoseRecord>& records) override;
Vlad Popa91930462022-12-20 22:42:48 +0100137 binder::Status getOutputRs2(float* value);
138 binder::Status getCsd(float* value);
139 binder::Status forceUseFrameworkMel(bool useFrameworkMel);
140 binder::Status forceComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
Vlad Popae3fd1c22022-11-07 21:03:18 +0100141
142 wp<SoundDoseManager> mSoundDoseManager;
143 const sp<media::ISoundDoseCallback> mSoundDoseCallback;
144 };
145
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100146 class HalSoundDoseCallback : public ISoundDose::BnHalSoundDoseCallback {
147 public:
148 explicit HalSoundDoseCallback(SoundDoseManager* manager)
149 : mSoundDoseManager(manager) {}
150
151 ndk::ScopedAStatus onMomentaryExposureWarning(
152 float in_currentDbA,
153 const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
154 ndk::ScopedAStatus onNewMelValues(
155 const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
156 const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
157
158 wp<SoundDoseManager> mSoundDoseManager;
159 };
160
Vlad Popae3fd1c22022-11-07 21:03:18 +0100161 void resetSoundDose();
162
163 void resetCsd(float currentCsd, const std::vector<media::SoundDoseRecord>& records);
164
165 sp<media::ISoundDoseCallback> getSoundDoseCallback() const;
Vlad Popa91930462022-12-20 22:42:48 +0100166
167 void setUseFrameworkMel(bool useFrameworkMel);
168 void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
169
Vlad Popaf09e93f2022-10-31 16:27:12 +0100170 mutable std::mutex mLock;
Vlad Popa2900c0a2022-10-24 13:38:00 +0200171
172 // no need for lock since MelAggregator is thread-safe
Vlad Popaf09e93f2022-10-31 16:27:12 +0100173 const sp<audio_utils::MelAggregator> mMelAggregator;
Vlad Popa2900c0a2022-10-24 13:38:00 +0200174
Vlad Popa4defd0b2022-11-06 14:22:31 +0100175 std::unordered_map<audio_io_handle_t, wp<audio_utils::MelProcessor>> mActiveProcessors
176 GUARDED_BY(mLock);
Vlad Popaf09e93f2022-10-31 16:27:12 +0100177
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100178 // map active device address and type to device id
179 std::map<AudioDeviceTypeAddr, audio_port_handle_t> mActiveDevices GUARDED_BY(mLock);
180
Vlad Popaf09e93f2022-10-31 16:27:12 +0100181 float mRs2Value GUARDED_BY(mLock);
Vlad Popa63f047e2022-11-05 14:09:19 +0100182
Vlad Popae3fd1c22022-11-07 21:03:18 +0100183 sp<SoundDose> mSoundDose GUARDED_BY(mLock);
Vlad Popa91930462022-12-20 22:42:48 +0100184
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100185 std::shared_ptr<ISoundDose> mHalSoundDose GUARDED_BY(mLock);
186 std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock);
187
Vlad Popa91930462022-12-20 22:42:48 +0100188 bool mUseFrameworkMel GUARDED_BY(mLock);
189 bool mComputeCsdOnAllDevices GUARDED_BY(mLock);
Vlad Popa2900c0a2022-10-24 13:38:00 +0200190};
191
192} // namespace android