blob: 642d352eed6d7188c8b314704870694d4772541b [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 Yao26689d92023-08-01 23:06:13 +000059using ::aidl::android::hardware::audio::effect::State;
Shunkai Yao51202502022-12-12 06:11:46 +000060
61namespace android {
62namespace effect {
63
Shunkai Yao399be682023-03-06 18:54:18 +000064EffectHalAidl::EffectHalAidl(const std::shared_ptr<IFactory>& factory,
Mikhail Naganov89c22e42023-06-14 15:49:59 -070065 const std::shared_ptr<IEffect>& effect,
Shunkai Yao5c718342023-02-23 23:49:51 +000066 int32_t sessionId, int32_t ioId, const Descriptor& desc,
67 bool isProxyEffect)
Shunkai Yaodba8ba32023-01-27 17:02:21 +000068 : mFactory(factory),
Shunkai Yao44bdbad2023-01-14 05:11:58 +000069 mEffect(effect),
Shunkai Yao284bb0d2023-01-10 00:42:36 +000070 mSessionId(sessionId),
71 mIoId(ioId),
Shunkai Yao5c718342023-02-23 23:49:51 +000072 mIsProxyEffect(isProxyEffect) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +000073 createAidlConversion(effect, sessionId, ioId, desc);
74}
Shunkai Yao51202502022-12-12 06:11:46 +000075
Shunkai Yao44bdbad2023-01-14 05:11:58 +000076EffectHalAidl::~EffectHalAidl() {
Shunkai Yao5c718342023-02-23 23:49:51 +000077 if (mEffect) {
Shunkai Yao79f98742023-05-03 23:54:43 +000078 if (mIsProxyEffect) {
79 std::static_pointer_cast<EffectProxy>(mEffect)->destroy();
80 } else if (mFactory) {
81 mFactory->destroyEffect(mEffect);
82 }
Shunkai Yao44bdbad2023-01-14 05:11:58 +000083 }
84}
Shunkai Yao51202502022-12-12 06:11:46 +000085
Shunkai Yaodba8ba32023-01-27 17:02:21 +000086status_t EffectHalAidl::createAidlConversion(
Shunkai Yao399be682023-03-06 18:54:18 +000087 std::shared_ptr<IEffect> effect,
Shunkai Yaodba8ba32023-01-27 17:02:21 +000088 int32_t sessionId, int32_t ioId,
Shunkai Yao399be682023-03-06 18:54:18 +000089 const Descriptor& desc) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +000090 const auto& typeUuid = desc.common.id.type;
Shunkai Yao242521c2023-01-29 18:08:09 +000091 ALOGI("%s create UUID %s", __func__, typeUuid.toString().c_str());
Shunkai Yao399be682023-03-06 18:54:18 +000092 if (typeUuid ==
93 ::aidl::android::hardware::audio::effect::getEffectTypeUuidAcousticEchoCanceler()) {
Shunkai Yao323273d2023-05-24 00:45:43 +000094 mConversion = std::make_unique<android::effect::AidlConversionAec>(effect, sessionId, ioId,
95 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +000096 } else if (typeUuid == ::aidl::android::hardware::audio::effect::
97 getEffectTypeUuidAutomaticGainControlV1()) {
Shunkai Yao61ce9572023-02-28 23:55:33 +000098 mConversion = std::make_unique<android::effect::AidlConversionAgc1>(effect, sessionId, ioId,
Shunkai Yao323273d2023-05-24 00:45:43 +000099 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000100 } else if (typeUuid == ::aidl::android::hardware::audio::effect::
101 getEffectTypeUuidAutomaticGainControlV2()) {
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000102 mConversion = std::make_unique<android::effect::AidlConversionAgc2>(effect, sessionId, ioId,
Shunkai Yao323273d2023-05-24 00:45:43 +0000103 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000104 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidBassBoost()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000105 mConversion = std::make_unique<android::effect::AidlConversionBassBoost>(
106 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000107 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000108 mConversion = std::make_unique<android::effect::AidlConversionDownmix>(
109 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000110 } else if (typeUuid ==
111 ::aidl::android::hardware::audio::effect::getEffectTypeUuidDynamicsProcessing()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000112 mConversion = std::make_unique<android::effect::AidlConversionDp>(effect, sessionId, ioId,
113 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000114 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000115 mConversion = std::make_unique<android::effect::AidlConversionEnvReverb>(
116 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000117 } else if (typeUuid == ::aidl::android::hardware::audio::effect::getEffectTypeUuidEqualizer()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000118 mConversion = std::make_unique<android::effect::AidlConversionEq>(effect, sessionId, ioId,
119 desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000120 } else if (typeUuid ==
121 ::aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000122 mConversion = std::make_unique<android::effect::AidlConversionHapticGenerator>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000123 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000124 } else if (typeUuid ==
125 ::aidl::android::hardware::audio::effect::getEffectTypeUuidLoudnessEnhancer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000126 mConversion = std::make_unique<android::effect::AidlConversionLoudnessEnhancer>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000127 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000128 } else if (typeUuid ==
129 ::aidl::android::hardware::audio::effect::getEffectTypeUuidNoiseSuppression()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000130 mConversion = std::make_unique<android::effect::AidlConversionNoiseSuppression>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000131 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000132 } else if (typeUuid ==
133 ::aidl::android::hardware::audio::effect::getEffectTypeUuidPresetReverb()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000134 mConversion = std::make_unique<android::effect::AidlConversionPresetReverb>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000135 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000136 } else if (typeUuid ==
137 ::aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000138 mConversion = std::make_unique<android::effect::AidlConversionSpatializer>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000139 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000140 } else if (typeUuid ==
141 ::aidl::android::hardware::audio::effect::getEffectTypeUuidVirtualizer()) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000142 mConversion = std::make_unique<android::effect::AidlConversionVirtualizer>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000143 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yao399be682023-03-06 18:54:18 +0000144 } else if (typeUuid ==
145 ::aidl::android::hardware::audio::effect::getEffectTypeUuidVisualizer()) {
Shunkai Yao323273d2023-05-24 00:45:43 +0000146 mConversion = std::make_unique<android::effect::AidlConversionVisualizer>(
147 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000148 } else {
Shunkai Yao242521c2023-01-29 18:08:09 +0000149 // For unknown UUID, use vendor extension implementation
150 mConversion = std::make_unique<android::effect::AidlConversionVendorExtension>(
Shunkai Yao323273d2023-05-24 00:45:43 +0000151 effect, sessionId, ioId, desc, mIsProxyEffect);
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000152 }
153 return OK;
154}
155
Shunkai Yao51202502022-12-12 06:11:46 +0000156status_t EffectHalAidl::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000157 mInBuffer = buffer;
Shunkai Yao51202502022-12-12 06:11:46 +0000158 return OK;
159}
160
161status_t EffectHalAidl::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000162 mOutBuffer = buffer;
Shunkai Yao51202502022-12-12 06:11:46 +0000163 return OK;
164}
165
Shunkai Yaoc6308712023-02-22 17:53:04 +0000166// write to input FMQ here, wait for statusMQ STATUS_OK, and read from output FMQ
Shunkai Yao51202502022-12-12 06:11:46 +0000167status_t EffectHalAidl::process() {
Shunkai Yao26689d92023-08-01 23:06:13 +0000168 State state = State::INIT;
169 if (mConversion->isBypassing() || !mEffect->getState(&state).isOk() ||
170 state != State::PROCESSING) {
Shunkai Yao29f327a2023-08-14 20:48:37 +0000171 ALOGI("%s skipping %s process because it's %s", __func__,
172 mConversion->getDescriptor().common.name.c_str(),
Shunkai Yao26689d92023-08-01 23:06:13 +0000173 mConversion->isBypassing()
174 ? "bypassing"
175 : aidl::android::hardware::audio::effect::toString(state).c_str());
176 return OK;
177 }
178
Shunkai Yao5c718342023-02-23 23:49:51 +0000179 auto statusQ = mConversion->getStatusMQ();
180 auto inputQ = mConversion->getInputMQ();
181 auto outputQ = mConversion->getOutputMQ();
Shunkai Yaofb79da92023-04-10 17:09:57 +0000182 auto efGroup = mConversion->getEventFlagGroup();
Shunkai Yao5c718342023-02-23 23:49:51 +0000183 if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
Shunkai Yaofb79da92023-04-10 17:09:57 +0000184 !outputQ->isValid() || !efGroup) {
185 ALOGE("%s invalid FMQ [Status %d I %d O %d] efGroup %p", __func__,
186 statusQ ? statusQ->isValid() : 0, inputQ ? inputQ->isValid() : 0,
187 outputQ ? outputQ->isValid() : 0, efGroup.get());
Shunkai Yao5c718342023-02-23 23:49:51 +0000188 return INVALID_OPERATION;
189 }
190
191 size_t available = inputQ->availableToWrite();
Shunkai Yaoc6308712023-02-22 17:53:04 +0000192 size_t floatsToWrite = std::min(available, mInBuffer->getSize() / sizeof(float));
193 if (floatsToWrite == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000194 ALOGE("%s not able to write, floats in buffer %zu, space in FMQ %zu", __func__,
Shunkai Yaoc6308712023-02-22 17:53:04 +0000195 mInBuffer->getSize() / sizeof(float), available);
196 return INVALID_OPERATION;
197 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000198 if (!mInBuffer->audioBuffer() ||
199 !inputQ->write((float*)mInBuffer->audioBuffer()->f32, floatsToWrite)) {
200 ALOGE("%s failed to write %zu floats from audiobuffer %p to inputQ [avail %zu]", __func__,
201 floatsToWrite, mInBuffer->audioBuffer(), inputQ->availableToWrite());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000202 return INVALID_OPERATION;
203 }
Shunkai Yaofb79da92023-04-10 17:09:57 +0000204 efGroup->wake(aidl::android::hardware::audio::effect::kEventFlagNotEmpty);
Shunkai Yaoc6308712023-02-22 17:53:04 +0000205
206 IEffect::Status retStatus{};
Shunkai Yao5c718342023-02-23 23:49:51 +0000207 if (!statusQ->readBlocking(&retStatus, 1) || retStatus.status != OK ||
Shunkai Yaoc6308712023-02-22 17:53:04 +0000208 (size_t)retStatus.fmqConsumed != floatsToWrite || retStatus.fmqProduced == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000209 ALOGE("%s read status failed: %s", __func__, retStatus.toString().c_str());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000210 return INVALID_OPERATION;
211 }
212
Shunkai Yao5c718342023-02-23 23:49:51 +0000213 available = outputQ->availableToRead();
Shunkai Yaoc6308712023-02-22 17:53:04 +0000214 size_t floatsToRead = std::min(available, mOutBuffer->getSize() / sizeof(float));
215 if (floatsToRead == 0) {
Shunkai Yao5c718342023-02-23 23:49:51 +0000216 ALOGE("%s not able to read, buffer space %zu, floats in FMQ %zu", __func__,
Shunkai Yaoc6308712023-02-22 17:53:04 +0000217 mOutBuffer->getSize() / sizeof(float), available);
218 return INVALID_OPERATION;
219 }
Shunkai Yao5c718342023-02-23 23:49:51 +0000220 // always read floating point data for AIDL
221 if (!mOutBuffer->audioBuffer() ||
222 !outputQ->read(mOutBuffer->audioBuffer()->f32, floatsToRead)) {
223 ALOGE("%s failed to read %zu from outputQ to audioBuffer %p", __func__, floatsToRead,
224 mOutBuffer->audioBuffer());
Shunkai Yaoc6308712023-02-22 17:53:04 +0000225 return INVALID_OPERATION;
226 }
227
Shunkai Yao29f327a2023-08-14 20:48:37 +0000228 ALOGD("%s %s consumed %zu produced %zu", __func__,
229 mConversion->getDescriptor().common.name.c_str(), floatsToWrite, floatsToRead);
Shunkai Yao51202502022-12-12 06:11:46 +0000230 return OK;
231}
232
233// TODO: no one using, maybe deprecate this interface
234status_t EffectHalAidl::processReverse() {
235 ALOGW("%s not implemented yet", __func__);
236 return OK;
237}
238
Shunkai Yao51202502022-12-12 06:11:46 +0000239status_t EffectHalAidl::command(uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
240 uint32_t* replySize, void* pReplyData) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000241 TIME_CHECK();
242 if (!mConversion) {
243 ALOGE("%s can not handle command %d when conversion not exist", __func__, cmdCode);
244 return INVALID_OPERATION;
245 }
246
Shunkai Yao5c718342023-02-23 23:49:51 +0000247 return mConversion->handleCommand(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
Shunkai Yao51202502022-12-12 06:11:46 +0000248}
249
250status_t EffectHalAidl::getDescriptor(effect_descriptor_t* pDescriptor) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000251 TIME_CHECK();
Shunkai Yao51202502022-12-12 06:11:46 +0000252 if (pDescriptor == nullptr) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000253 ALOGE("%s null descriptor pointer", __func__);
Shunkai Yao51202502022-12-12 06:11:46 +0000254 return BAD_VALUE;
255 }
256 Descriptor aidlDesc;
Mikhail Naganov5e406ba2023-01-13 00:27:22 +0000257 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getDescriptor(&aidlDesc)));
Shunkai Yao51202502022-12-12 06:11:46 +0000258
259 *pDescriptor = VALUE_OR_RETURN_STATUS(
260 ::aidl::android::aidl2legacy_Descriptor_effect_descriptor(aidlDesc));
261 return OK;
262}
263
264status_t EffectHalAidl::close() {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000265 TIME_CHECK();
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000266 return statusTFromBinderStatus(mEffect->close());
Shunkai Yao51202502022-12-12 06:11:46 +0000267}
268
269status_t EffectHalAidl::dump(int fd) {
Shunkai Yaoc6308712023-02-22 17:53:04 +0000270 TIME_CHECK();
271 return mEffect->dump(fd, nullptr, 0);
Shunkai Yao51202502022-12-12 06:11:46 +0000272}
273
274} // namespace effect
275} // namespace android