blob: d6135afbae761fe3e8e2b913aa3a448fbe4622b7 [file] [log] [blame]
Shunkai Yao51202502022-12-12 06:11:46 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Shunkai Yaoc6308712023-02-22 17:53:04 +000017#include <cstddef>
Shunkai Yao51202502022-12-12 06:11:46 +000018#define LOG_TAG "EffectHalAidl"
19//#define LOG_NDEBUG 0
20
Shunkai Yao242521c2023-01-29 18:08:09 +000021#include <memory>
22
Mikhail Naganov5e406ba2023-01-13 00:27:22 +000023#include <error/expected_utils.h>
Shunkai Yao51202502022-12-12 06:11:46 +000024#include <media/AidlConversionCppNdk.h>
Shunkai Yaoa03533e2023-01-25 06:38:10 +000025#include <media/AidlConversionEffect.h>
Mikhail Naganov5e406ba2023-01-13 00:27:22 +000026#include <media/AidlConversionUtil.h>
Shunkai Yao51202502022-12-12 06:11:46 +000027#include <media/EffectsFactoryApi.h>
28#include <mediautils/TimeCheck.h>
Shunkai Yao242521c2023-01-29 18:08:09 +000029#include <system/audio.h>
Shunkai Yao399be682023-03-06 18:54:18 +000030#include <system/audio_effects/effect_uuid.h>
Shunkai Yao51202502022-12-12 06:11:46 +000031#include <utils/Log.h>
32
33#include "EffectHalAidl.h"
Shunkai Yao5c718342023-02-23 23:49:51 +000034#include "EffectProxy.h"
Shunkai Yao51202502022-12-12 06:11:46 +000035
Shunkai Yao51202502022-12-12 06:11:46 +000036#include <aidl/android/hardware/audio/effect/IEffect.h>
37
Shunkai Yaodba8ba32023-01-27 17:02:21 +000038#include "effectsAidlConversion/AidlConversionAec.h"
Shunkai Yao61ce9572023-02-28 23:55:33 +000039#include "effectsAidlConversion/AidlConversionAgc1.h"
Shunkai Yaodba8ba32023-01-27 17:02:21 +000040#include "effectsAidlConversion/AidlConversionAgc2.h"
41#include "effectsAidlConversion/AidlConversionBassBoost.h"
42#include "effectsAidlConversion/AidlConversionDownmix.h"
43#include "effectsAidlConversion/AidlConversionDynamicsProcessing.h"
Shunkai Yao242521c2023-01-29 18:08:09 +000044#include "effectsAidlConversion/AidlConversionEnvReverb.h"
45#include "effectsAidlConversion/AidlConversionEq.h"
46#include "effectsAidlConversion/AidlConversionHapticGenerator.h"
47#include "effectsAidlConversion/AidlConversionLoudnessEnhancer.h"
48#include "effectsAidlConversion/AidlConversionNoiseSuppression.h"
49#include "effectsAidlConversion/AidlConversionPresetReverb.h"
50#include "effectsAidlConversion/AidlConversionSpatializer.h"
51#include "effectsAidlConversion/AidlConversionVendorExtension.h"
52#include "effectsAidlConversion/AidlConversionVirtualizer.h"
53#include "effectsAidlConversion/AidlConversionVisualizer.h"
Shunkai Yaodba8ba32023-01-27 17:02:21 +000054
Mikhail Naganov5e406ba2023-01-13 00:27:22 +000055using ::aidl::android::aidl_utils::statusTFromBinderStatus;
Shunkai Yao51202502022-12-12 06:11:46 +000056using ::aidl::android::hardware::audio::effect::Descriptor;
57using ::aidl::android::hardware::audio::effect::IEffect;
Shunkai Yao44bdbad2023-01-14 05:11:58 +000058using ::aidl::android::hardware::audio::effect::IFactory;
Shunkai Yao51202502022-12-12 06:11:46 +000059
60namespace android {
61namespace effect {
62
Shunkai Yao399be682023-03-06 18:54:18 +000063EffectHalAidl::EffectHalAidl(const std::shared_ptr<IFactory>& factory,
64 const std::shared_ptr<IEffect>& effect, uint64_t effectId,
Shunkai Yao5c718342023-02-23 23:49:51 +000065 int32_t sessionId, int32_t ioId, const Descriptor& desc,
66 bool isProxyEffect)
Shunkai Yaodba8ba32023-01-27 17:02:21 +000067 : mFactory(factory),
Shunkai Yao44bdbad2023-01-14 05:11:58 +000068 mEffect(effect),
Shunkai Yao284bb0d2023-01-10 00:42:36 +000069 mEffectId(effectId),
70 mSessionId(sessionId),
71 mIoId(ioId),
Shunkai Yao5c718342023-02-23 23:49:51 +000072 mDesc(desc),
73 mIsProxyEffect(isProxyEffect) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +000074 createAidlConversion(effect, sessionId, ioId, desc);
75}
Shunkai Yao51202502022-12-12 06:11:46 +000076
Shunkai Yao44bdbad2023-01-14 05:11:58 +000077EffectHalAidl::~EffectHalAidl() {
Shunkai Yao5c718342023-02-23 23:49:51 +000078 if (mEffect) {
79 mIsProxyEffect ? std::static_pointer_cast<EffectProxy>(mEffect)->destroy()
80 : mFactory->destroyEffect(mEffect);
Shunkai Yao44bdbad2023-01-14 05:11:58 +000081 }
82}
Shunkai Yao51202502022-12-12 06:11:46 +000083
Shunkai Yaodba8ba32023-01-27 17:02:21 +000084status_t EffectHalAidl::createAidlConversion(
Shunkai Yao399be682023-03-06 18:54:18 +000085 std::shared_ptr<IEffect> effect,
Shunkai Yaodba8ba32023-01-27 17:02:21 +000086 int32_t sessionId, int32_t ioId,
Shunkai Yao399be682023-03-06 18:54:18 +000087 const Descriptor& desc) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +000088 const auto& typeUuid = desc.common.id.type;
Shunkai Yao242521c2023-01-29 18:08:09 +000089 ALOGI("%s create UUID %s", __func__, typeUuid.toString().c_str());
Shunkai Yao399be682023-03-06 18:54:18 +000090 if (typeUuid ==
91 ::aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler()) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +000092 mConversion =
93 std::make_unique<android::effect::AidlConversionAec>(effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +000094 } else if (typeUuid == ::aidl::android::hardware::audio::effect::
95 getEffectTypeUuidAutomaticGainControlV1()) {
Shunkai Yao61ce9572023-02-28 23:55:33 +000096 mConversion = std::make_unique<android::effect::AidlConversionAgc1>(effect, sessionId, ioId,
97 desc);
Shunkai Yao399be682023-03-06 18:54:18 +000098 } else if (typeUuid == ::aidl::android::hardware::audio::effect::
99 getEffectTypeUuidAutomaticGainControlV2()) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000100 mConversion = std::make_unique<android::effect::AidlConversionAgc2>(effect, sessionId, ioId,
101 desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000102 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost()) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000103 mConversion = std::make_unique<android::effect::AidlConversionBassBoost>(effect, sessionId,
104 ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000105 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix()) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000106 mConversion = std::make_unique<android::effect::AidlConversionDownmix>(effect, sessionId,
107 ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000108 } else if (typeUuid ==
109 ::aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing()) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000110 mConversion =
111 std::make_unique<android::effect::AidlConversionDp>(effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000112 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000113 mConversion = std::make_unique<android::effect::AidlConversionEnvReverb>(effect, sessionId,
114 ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000115 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000116 mConversion =
117 std::make_unique<android::effect::AidlConversionEq>(effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000118 } else if (typeUuid ==
119 ::aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000120 mConversion = std::make_unique<android::effect::AidlConversionHapticGenerator>(
121 effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000122 } else if (typeUuid ==
123 ::aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000124 mConversion = std::make_unique<android::effect::AidlConversionLoudnessEnhancer>(
125 effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000126 } else if (typeUuid ==
127 ::aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000128 mConversion = std::make_unique<android::effect::AidlConversionNoiseSuppression>(
129 effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000130 } else if (typeUuid ==
131 ::aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000132 mConversion = std::make_unique<android::effect::AidlConversionPresetReverb>(
133 effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000134 } else if (typeUuid ==
135 ::aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000136 mConversion = std::make_unique<android::effect::AidlConversionSpatializer>(
137 effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000138 } else if (typeUuid ==
139 ::aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000140 mConversion = std::make_unique<android::effect::AidlConversionVirtualizer>(
141 effect, sessionId, ioId, desc);
Shunkai Yao399be682023-03-06 18:54:18 +0000142 } else if (typeUuid ==
143 ::aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000144 mConversion = std::make_unique<android::effect::AidlConversionVisualizer>(effect, sessionId,
145 ioId, desc);
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000146 } else {
Shunkai Yao242521c2023-01-29 18:08:09 +0000147 // For unknown UUID, use vendor extension implementation
148 mConversion = std::make_unique<android::effect::AidlConversionVendorExtension>(
149 effect, sessionId, ioId, desc);
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000150 }
151 return OK;
152}
153
Shunkai Yao51202502022-12-12 06:11:46 +0000154status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000155 mInBuffer = buffer;
Shunkai Yao51202502022-12-12 06:11:46 +0000156 return OK;
157}
158
159status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000160 mOutBuffer = buffer;
Shunkai Yao51202502022-12-12 06:11:46 +0000161 return OK;
162}
163
Shunkai Yaoc6308712023-02-22 17:53:04 +0000164
165// write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
Shunkai Yao51202502022-12-12 06:11:46 +0000166status_t EffectHalAidl::process() {
Shunkai Yao5c718342023-02-23 23:49:51 +0000167 auto statusQ = mConversion->getStatusMQ();
168 auto inputQ = mConversion->getInputMQ();
169 auto outputQ = mConversion->getOutputMQ();
170 if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
171 !outputQ->isValid()) {
172 ALOGE("%s invalid FMQ [Status %d I %d O %d]", __func__, statusQ ? statusQ->isValid() : 0,
173 inputQ ? inputQ->isValid() : 0, outputQ ? outputQ->isValid() : 0);
174 return INVALID_OPERATION;
175 }
176
177 size_t available = inputQ->availableToWrite();
Shunkai Yaoc6308712023-02-22 17:53:04 +0000178 size_t floatsToWrite = std::min(available, mInBuffer->getSize() / sizeof(float));
179 if (floatsToWrite == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000180 ALOGE("%s not able to write, floats in buffer %zu, space in FMQ %zu", __func__,
Shunkai Yaoc6308712023-02-22 17:53:04 +0000181 mInBuffer->getSize() / sizeof(float), available);
182 return INVALID_OPERATION;
183 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000184 if (!mInBuffer->audioBuffer() ||
185 !inputQ->write((float*)mInBuffer->audioBuffer()->f32, floatsToWrite)) {
186 ALOGE("%s failed to write %zu floats from audiobuffer %p to inputQ [avail %zu]", __func__,
187 floatsToWrite, mInBuffer->audioBuffer(), inputQ->availableToWrite());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000188 return INVALID_OPERATION;
189 }
190
191 IEffect::Status retStatus{};
Shunkai Yao5c718342023-02-23 23:49:51 +0000192 if (!statusQ->readBlocking(&retStatus, 1) || retStatus.status != OK ||
Shunkai Yaoc6308712023-02-22 17:53:04 +0000193 (size_t)retStatus.fmqConsumed != floatsToWrite || retStatus.fmqProduced == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000194 ALOGE("%s read status failed: %s", __func__, retStatus.toString().c_str());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000195 return INVALID_OPERATION;
196 }
197
Shunkai Yao5c718342023-02-23 23:49:51 +0000198 available = outputQ->availableToRead();
Shunkai Yaoc6308712023-02-22 17:53:04 +0000199 size_t floatsToRead = std::min(available, mOutBuffer->getSize() / sizeof(float));
200 if (floatsToRead == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000201 ALOGE("%s not able to read, buffer space %zu, floats in FMQ %zu", __func__,
Shunkai Yaoc6308712023-02-22 17:53:04 +0000202 mOutBuffer->getSize() / sizeof(float), available);
203 return INVALID_OPERATION;
204 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000205 // always read floating point data for AIDL
206 if (!mOutBuffer->audioBuffer() ||
207 !outputQ->read(mOutBuffer->audioBuffer()->f32, floatsToRead)) {
208 ALOGE("%s failed to read %zu from outputQ to audioBuffer %p", __func__, floatsToRead,
209 mOutBuffer->audioBuffer());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000210 return INVALID_OPERATION;
211 }
212
213 ALOGD("%s %s consumed %zu produced %zu", __func__, mDesc.common.name.c_str(), floatsToWrite,
214 floatsToRead);
Shunkai Yao51202502022-12-12 06:11:46 +0000215 return OK;
216}
217
218// TODO: no one using, maybe deprecate this interface
219status_t EffectHalAidl::processReverse() {
220 ALOGW("%s not implemented yet", __func__);
221 return OK;
222}
223
Shunkai Yao51202502022-12-12 06:11:46 +0000224status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
225 uint32_t* replySize, void* pReplyData) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000226 TIME_CHECK();
227 if (!mConversion) {
228 ALOGE("%s can not handle command %d when conversion not exist", __func__, cmdCode);
229 return INVALID_OPERATION;
230 }
231
Shunkai Yao5c718342023-02-23 23:49:51 +0000232 return mConversion->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
Shunkai Yao51202502022-12-12 06:11:46 +0000233}
234
235status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000236 TIME_CHECK();
Shunkai Yao51202502022-12-12 06:11:46 +0000237 if (pDescriptor == nullptr) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000238 ALOGE("%s null descriptor pointer", __func__);
Shunkai Yao51202502022-12-12 06:11:46 +0000239 return BAD_VALUE;
240 }
241 Descriptor aidlDesc;
Mikhail Naganov5e406ba2023-01-13 00:27:22 +0000242 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getDescriptor(&aidlDesc)));
Shunkai Yao51202502022-12-12 06:11:46 +0000243
244 *pDescriptor = VALUE_OR_RETURN_STATUS(
245 ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(aidlDesc));
246 return OK;
247}
248
249status_t EffectHalAidl::close() {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000250 TIME_CHECK();
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000251 return statusTFromBinderStatus(mEffect->close());
Shunkai Yao51202502022-12-12 06:11:46 +0000252}
253
254status_t EffectHalAidl::dump(int fd) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000255 TIME_CHECK();
256 return mEffect->dump(fd, nullptr, 0);
Shunkai Yao51202502022-12-12 06:11:46 +0000257}
258
259} // namespace effect
260} // namespace android