blob: b10874fe6e0c486c98000e932b20ec5ea2fc703a [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 Popa3d6d39d2022-12-21 18:59:16 +0100107 // used for testing only
Vlad Popa2900c0a2022-10-24 13:38:00 +0200108 size_t getCachedMelRecordsSize() const;
Vlad Popa3d6d39d2022-12-21 18:59:16 +0100109 bool forceUseFrameworkMel() const;
110 bool forceComputeCsdOnAllDevices() const;
Vlad Popaf09e93f2022-10-31 16:27:12 +0100111
Vlad Popa4defd0b2022-11-06 14:22:31 +0100112 /** Method for converting from audio_utils::CsdRecord to media::SoundDoseRecord. */
113 static media::SoundDoseRecord csdRecordToSoundDoseRecord(const audio_utils::CsdRecord& legacy);
114
Vlad Popaf09e93f2022-10-31 16:27:12 +0100115 // ------ Override audio_utils::MelProcessor::MelCallback ------
Vlad Popa4defd0b2022-11-06 14:22:31 +0100116 void onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length,
Vlad Popaf09e93f2022-10-31 16:27:12 +0100117 audio_port_handle_t deviceId) const override;
118
119 void onMomentaryExposure(float currentMel, audio_port_handle_t deviceId) const override;
Vlad Popa4defd0b2022-11-06 14:22:31 +0100120
Vlad Popae3fd1c22022-11-07 21:03:18 +0100121private:
122 class SoundDose : public media::BnSoundDose,
123 public IBinder::DeathRecipient {
124 public:
125 SoundDose(SoundDoseManager* manager, const sp<media::ISoundDoseCallback>& callback)
126 : mSoundDoseManager(manager),
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100127 mSoundDoseCallback(callback) {}
Vlad Popa4defd0b2022-11-06 14:22:31 +0100128
Vlad Popae3fd1c22022-11-07 21:03:18 +0100129 /** IBinder::DeathRecipient. Listen to the death of ISoundDoseCallback. */
130 virtual void binderDied(const wp<IBinder>& who);
131
132 /** BnSoundDose override */
133 binder::Status setOutputRs2(float value) override;
134 binder::Status resetCsd(float currentCsd,
135 const std::vector<media::SoundDoseRecord>& records) override;
Vlad Popa91930462022-12-20 22:42:48 +0100136 binder::Status getOutputRs2(float* value);
137 binder::Status getCsd(float* value);
138 binder::Status forceUseFrameworkMel(bool useFrameworkMel);
139 binder::Status forceComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
Vlad Popae3fd1c22022-11-07 21:03:18 +0100140
141 wp<SoundDoseManager> mSoundDoseManager;
142 const sp<media::ISoundDoseCallback> mSoundDoseCallback;
143 };
144
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100145 class HalSoundDoseCallback : public ISoundDose::BnHalSoundDoseCallback {
146 public:
147 explicit HalSoundDoseCallback(SoundDoseManager* manager)
148 : mSoundDoseManager(manager) {}
149
150 ndk::ScopedAStatus onMomentaryExposureWarning(
151 float in_currentDbA,
152 const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
153 ndk::ScopedAStatus onNewMelValues(
154 const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
155 const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
156
157 wp<SoundDoseManager> mSoundDoseManager;
158 };
159
Vlad Popae3fd1c22022-11-07 21:03:18 +0100160 void resetSoundDose();
161
162 void resetCsd(float currentCsd, const std::vector<media::SoundDoseRecord>& records);
163
164 sp<media::ISoundDoseCallback> getSoundDoseCallback() const;
Vlad Popa91930462022-12-20 22:42:48 +0100165
166 void setUseFrameworkMel(bool useFrameworkMel);
167 void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
Vlad Popa3d6d39d2022-12-21 18:59:16 +0100168 /** Returns the HAL sound dose interface or null if internal MEL computation is used. */
169 void getHalSoundDose(std::shared_ptr<ISoundDose>* halSoundDose) const;
Vlad Popa91930462022-12-20 22:42:48 +0100170
Vlad Popaf09e93f2022-10-31 16:27:12 +0100171 mutable std::mutex mLock;
Vlad Popa2900c0a2022-10-24 13:38:00 +0200172
173 // no need for lock since MelAggregator is thread-safe
Vlad Popaf09e93f2022-10-31 16:27:12 +0100174 const sp<audio_utils::MelAggregator> mMelAggregator;
Vlad Popa2900c0a2022-10-24 13:38:00 +0200175
Vlad Popa4defd0b2022-11-06 14:22:31 +0100176 std::unordered_map<audio_io_handle_t, wp<audio_utils::MelProcessor>> mActiveProcessors
177 GUARDED_BY(mLock);
Vlad Popaf09e93f2022-10-31 16:27:12 +0100178
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100179 // map active device address and type to device id
180 std::map<AudioDeviceTypeAddr, audio_port_handle_t> mActiveDevices GUARDED_BY(mLock);
181
Vlad Popaf09e93f2022-10-31 16:27:12 +0100182 float mRs2Value GUARDED_BY(mLock);
Vlad Popa63f047e2022-11-05 14:09:19 +0100183
Vlad Popae3fd1c22022-11-07 21:03:18 +0100184 sp<SoundDose> mSoundDose GUARDED_BY(mLock);
Vlad Popa91930462022-12-20 22:42:48 +0100185
Vlad Popa1d5f0d52022-12-18 12:21:26 +0100186 std::shared_ptr<ISoundDose> mHalSoundDose GUARDED_BY(mLock);
187 std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock);
188
Vlad Popa3d6d39d2022-12-21 18:59:16 +0100189 bool mUseFrameworkMel GUARDED_BY(mLock) = false;
190 bool mComputeCsdOnAllDevices GUARDED_BY(mLock) = false;
Vlad Popa2900c0a2022-10-24 13:38:00 +0200191};
192
193} // namespace android