blob: 37eb30bc485f73332f55ecdea8215cbc9bb1162d [file] [log] [blame]
Shunkai Yao6afc8552022-10-26 22:47:20 +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 Yao6afc8552022-10-26 22:47:20 +000017#define LOG_TAG "AHAL_VisualizerSw"
Shunkai Yao6afc8552022-10-26 22:47:20 +000018
19#include <android-base/logging.h>
Shunkai Yao6afc8552022-10-26 22:47:20 +000020
21#include "VisualizerSw.h"
22
Shunkai Yaoc12e0822022-12-12 07:13:58 +000023using aidl::android::hardware::audio::effect::Descriptor;
Shunkai Yao6afc8552022-10-26 22:47:20 +000024using aidl::android::hardware::audio::effect::IEffect;
Shunkai Yao812d5b42022-11-16 18:08:50 +000025using aidl::android::hardware::audio::effect::kVisualizerSwImplUUID;
Shunkai Yao6afc8552022-10-26 22:47:20 +000026using aidl::android::hardware::audio::effect::State;
27using aidl::android::hardware::audio::effect::VisualizerSw;
Shunkai Yao6afc8552022-10-26 22:47:20 +000028using aidl::android::media::audio::common::AudioUuid;
29
30extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
31 std::shared_ptr<IEffect>* instanceSpp) {
Shunkai Yao812d5b42022-11-16 18:08:50 +000032 if (!in_impl_uuid || *in_impl_uuid != kVisualizerSwImplUUID) {
Shunkai Yao6afc8552022-10-26 22:47:20 +000033 LOG(ERROR) << __func__ << "uuid not supported";
34 return EX_ILLEGAL_ARGUMENT;
35 }
36 if (instanceSpp) {
37 *instanceSpp = ndk::SharedRefBase::make<VisualizerSw>();
38 LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
39 return EX_NONE;
40 } else {
41 LOG(ERROR) << __func__ << " invalid input parameter!";
42 return EX_ILLEGAL_ARGUMENT;
43 }
44}
45
Shunkai Yaoc12e0822022-12-12 07:13:58 +000046extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
47 if (!in_impl_uuid || *in_impl_uuid != kVisualizerSwImplUUID) {
48 LOG(ERROR) << __func__ << "uuid not supported";
49 return EX_ILLEGAL_ARGUMENT;
Shunkai Yao6afc8552022-10-26 22:47:20 +000050 }
Shunkai Yaoc12e0822022-12-12 07:13:58 +000051 *_aidl_return = VisualizerSw::kDescriptor;
Shunkai Yao6afc8552022-10-26 22:47:20 +000052 return EX_NONE;
53}
54
55namespace aidl::android::hardware::audio::effect {
56
Shunkai Yaoc12e0822022-12-12 07:13:58 +000057const std::string VisualizerSw::kEffectName = "VisualizerSw";
Sham Rathod94aae5e2022-11-23 12:22:32 +053058/* capabilities */
59const Visualizer::CaptureSizeRange mCaptureSizeRange = {MIN_CAPTURE_SIZE, MAX_CAPTURE_SIZE};
60const Visualizer::Capability VisualizerSw::kCapability = {.maxLatencyMs = MAX_LATENCY,
61 .captureSizeRange = mCaptureSizeRange};
Shunkai Yaoc12e0822022-12-12 07:13:58 +000062const Descriptor VisualizerSw::kDescriptor = {
63 .common = {.id = {.type = kVisualizerTypeUUID,
64 .uuid = kVisualizerSwImplUUID,
65 .proxy = std::nullopt},
66 .flags = {.type = Flags::Type::INSERT,
67 .insert = Flags::Insert::FIRST,
68 .volume = Flags::Volume::CTRL},
69 .name = VisualizerSw::kEffectName,
70 .implementor = "The Android Open Source Project"},
71 .capability = Capability::make<Capability::visualizer>(VisualizerSw::kCapability)};
72
Shunkai Yao6afc8552022-10-26 22:47:20 +000073ndk::ScopedAStatus VisualizerSw::getDescriptor(Descriptor* _aidl_return) {
74 LOG(DEBUG) << __func__ << kDescriptor.toString();
75 *_aidl_return = kDescriptor;
76 return ndk::ScopedAStatus::ok();
77}
78
79ndk::ScopedAStatus VisualizerSw::setParameterSpecific(const Parameter::Specific& specific) {
80 RETURN_IF(Parameter::Specific::visualizer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
81 "EffectNotSupported");
Shunkai Yao6afc8552022-10-26 22:47:20 +000082
Sham Rathod94aae5e2022-11-23 12:22:32 +053083 auto& vsParam = specific.get<Parameter::Specific::visualizer>();
84 auto tag = vsParam.getTag();
85
86 switch (tag) {
87 case Visualizer::captureSizeBytes: {
88 RETURN_IF(mContext->setVsCaptureSize(vsParam.get<Visualizer::captureSizeBytes>()) !=
89 RetCode::SUCCESS,
90 EX_ILLEGAL_ARGUMENT, "captureSizeNotSupported");
91 return ndk::ScopedAStatus::ok();
92 }
93 case Visualizer::scalingMode: {
94 RETURN_IF(mContext->setVsScalingMode(vsParam.get<Visualizer::scalingMode>()) !=
95 RetCode::SUCCESS,
96 EX_ILLEGAL_ARGUMENT, "scalingModeNotSupported");
97 return ndk::ScopedAStatus::ok();
98 }
99 case Visualizer::measurementMode: {
100 RETURN_IF(mContext->setVsMeasurementMode(vsParam.get<Visualizer::measurementMode>()) !=
101 RetCode::SUCCESS,
102 EX_ILLEGAL_ARGUMENT, "measurementModeNotSupported");
103 return ndk::ScopedAStatus::ok();
104 }
105 case Visualizer::setOnlyParameters: {
106 return setSetOnlyParameterVisualizer(vsParam.get<Visualizer::setOnlyParameters>());
107 }
108 case Visualizer::getOnlyParameters: {
109 LOG(ERROR) << __func__ << " unsupported settable getOnlyParam";
110 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
111 EX_ILLEGAL_ARGUMENT, "SetofGetOnlyParamsNotSupported");
112 }
113 default: {
114 LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
115 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
116 "VisualizerTagNotSupported");
117 }
118 }
119}
120
121ndk::ScopedAStatus VisualizerSw::setSetOnlyParameterVisualizer(
122 Visualizer::SetOnlyParameters setOnlyParam) {
123 auto tag = setOnlyParam.getTag();
124 RETURN_IF(Visualizer::SetOnlyParameters::latencyMs != tag, EX_ILLEGAL_ARGUMENT,
125 "SetOnlyParametersTagNotSupported");
126 RETURN_IF(
127 mContext->setVsLatency(setOnlyParam.get<Visualizer::SetOnlyParameters::latencyMs>()) !=
128 RetCode::SUCCESS,
129 EX_ILLEGAL_ARGUMENT, "latencyNotSupported");
Shunkai Yao6afc8552022-10-26 22:47:20 +0000130 return ndk::ScopedAStatus::ok();
131}
132
133ndk::ScopedAStatus VisualizerSw::getParameterSpecific(const Parameter::Id& id,
134 Parameter::Specific* specific) {
135 auto tag = id.getTag();
136 RETURN_IF(Parameter::Id::visualizerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
Sham Rathod94aae5e2022-11-23 12:22:32 +0530137 auto vsId = id.get<Parameter::Id::visualizerTag>();
138 auto vsIdTag = vsId.getTag();
139 switch (vsIdTag) {
140 case Visualizer::Id::commonTag:
141 return getParameterVisualizer(vsId.get<Visualizer::Id::commonTag>(), specific);
142 case Visualizer::Id::getOnlyParamTag:
143 return getGetOnlyParameterVisualizer(vsId.get<Visualizer::Id::getOnlyParamTag>(),
144 specific);
145 case Visualizer::Id::setOnlyParamTag: {
146 LOG(ERROR) << __func__ << " unsupported gettable setOnlyParam";
147 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
148 EX_ILLEGAL_ARGUMENT, "GetofSetOnlyParamsNotSupported");
149 }
150 default:
151 LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
152 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
153 "VisualizerTagNotSupported");
154 }
155}
156ndk::ScopedAStatus VisualizerSw::getParameterVisualizer(const Visualizer::Tag& tag,
157 Parameter::Specific* specific) {
158 RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
159
160 Visualizer vsParam;
161 switch (tag) {
162 case Visualizer::captureSizeBytes: {
163 vsParam.set<Visualizer::captureSizeBytes>(mContext->getVsCaptureSize());
164 break;
165 }
166 case Visualizer::scalingMode: {
167 vsParam.set<Visualizer::scalingMode>(mContext->getVsScalingMode());
168 break;
169 }
170 case Visualizer::measurementMode: {
171 vsParam.set<Visualizer::measurementMode>(mContext->getVsMeasurementMode());
172 break;
173 }
174 default: {
175 LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
176 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
177 "VisualizerTagNotSupported");
178 }
179 }
180 specific->set<Parameter::Specific::visualizer>(vsParam);
181 return ndk::ScopedAStatus::ok();
182}
183
184ndk::ScopedAStatus VisualizerSw::getGetOnlyParameterVisualizer(
185 const Visualizer::GetOnlyParameters::Tag& tag, Parameter::Specific* specific) {
186 Visualizer::GetOnlyParameters getOnlyParam;
187 switch (tag) {
188 case Visualizer::GetOnlyParameters::measurement: {
189 getOnlyParam.set<Visualizer::GetOnlyParameters::measurement>(
190 mContext->getVsMeasurement());
191 break;
192 }
193 case Visualizer::GetOnlyParameters::captureBytes: {
194 getOnlyParam.set<Visualizer::GetOnlyParameters::captureBytes>(
195 mContext->getVsCaptureBytes());
196 break;
197 }
198 default: {
199 LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
200 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
201 EX_ILLEGAL_ARGUMENT, "GetOnlyParameterTagNotSupported");
202 }
203 }
204 Visualizer vsParam;
205 vsParam.set<Visualizer::getOnlyParameters>(getOnlyParam);
206 specific->set<Parameter::Specific::visualizer>(vsParam);
Shunkai Yao6afc8552022-10-26 22:47:20 +0000207 return ndk::ScopedAStatus::ok();
208}
209
210std::shared_ptr<EffectContext> VisualizerSw::createContext(const Parameter::Common& common) {
211 if (mContext) {
212 LOG(DEBUG) << __func__ << " context already exist";
Shraddha Basantwanif627d802022-11-08 14:45:07 +0530213 } else {
214 mContext = std::make_shared<VisualizerSwContext>(1 /* statusFmqDepth */, common);
Shunkai Yao6afc8552022-10-26 22:47:20 +0000215 }
Shraddha Basantwanif627d802022-11-08 14:45:07 +0530216
217 return mContext;
218}
219
220std::shared_ptr<EffectContext> VisualizerSw::getContext() {
Shunkai Yao6afc8552022-10-26 22:47:20 +0000221 return mContext;
222}
223
224RetCode VisualizerSw::releaseContext() {
225 if (mContext) {
226 mContext.reset();
227 }
228 return RetCode::SUCCESS;
229}
230
231// Processing method running in EffectWorker thread.
Shraddha Basantwanif627d802022-11-08 14:45:07 +0530232IEffect::Status VisualizerSw::effectProcessImpl(float* in, float* out, int samples) {
Shunkai Yao6afc8552022-10-26 22:47:20 +0000233 // TODO: get data buffer and process.
Shraddha Basantwanif627d802022-11-08 14:45:07 +0530234 LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
235 for (int i = 0; i < samples; i++) {
Shunkai Yao6afc8552022-10-26 22:47:20 +0000236 *out++ = *in++;
237 }
Shraddha Basantwanif627d802022-11-08 14:45:07 +0530238 return {STATUS_OK, samples, samples};
Shunkai Yao6afc8552022-10-26 22:47:20 +0000239}
240
241} // namespace aidl::android::hardware::audio::effect