blob: 61a2bf571b79622e0a57d89c69d7de6207f5e3f6 [file] [log] [blame]
Eric Laurenta9390d42011-06-17 20:17:17 -07001/*
2 * Copyright (C) 2011 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
17#include <stdlib.h>
18#include <string.h>
19#define LOG_TAG "PreProcessing"
20//#define LOG_NDEBUG 0
Eric Laurenta9390d42011-06-17 20:17:17 -070021#include <audio_effects/effect_aec.h>
22#include <audio_effects/effect_agc.h>
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080023#include <hardware/audio_effect.h>
24#include <utils/Log.h>
25#include <utils/Timers.h>
Saketh Sathuvalli08337032020-09-22 21:13:45 +053026#include <audio_effects/effect_agc2.h>
Eric Laurenta9390d42011-06-17 20:17:17 -070027#include <audio_effects/effect_ns.h>
Eric Laurent53876962012-01-31 12:35:20 -080028#include <audio_processing.h>
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080029#include <module_common_types.h>
Eric Laurenta9390d42011-06-17 20:17:17 -070030
Eric Laurent3f9c84c2012-04-03 15:36:53 -070031// undefine to perform multi channels API functional tests
32//#define DUAL_MIC_TEST
Eric Laurenta9390d42011-06-17 20:17:17 -070033
34//------------------------------------------------------------------------------
35// local definitions
36//------------------------------------------------------------------------------
37
38// maximum number of sessions
39#define PREPROC_NUM_SESSIONS 8
40
41// types of pre processing modules
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080042enum preproc_id {
43 PREPROC_AGC, // Automatic Gain Control
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080044 PREPROC_AGC2, // Automatic Gain Control 2
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080045 PREPROC_AEC, // Acoustic Echo Canceler
46 PREPROC_NS, // Noise Suppressor
Eric Laurenta9390d42011-06-17 20:17:17 -070047 PREPROC_NUM_EFFECTS
48};
49
50// Session state
51enum preproc_session_state {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080052 PREPROC_SESSION_STATE_INIT, // initialized
53 PREPROC_SESSION_STATE_CONFIG // configuration received
Eric Laurenta9390d42011-06-17 20:17:17 -070054};
55
56// Effect/Preprocessor state
57enum preproc_effect_state {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080058 PREPROC_EFFECT_STATE_INIT, // initialized
59 PREPROC_EFFECT_STATE_CREATED, // webRTC engine created
60 PREPROC_EFFECT_STATE_CONFIG, // configuration received/disabled
61 PREPROC_EFFECT_STATE_ACTIVE // active/enabled
Eric Laurenta9390d42011-06-17 20:17:17 -070062};
63
64// handle on webRTC engine
65typedef void* preproc_fx_handle_t;
66
67typedef struct preproc_session_s preproc_session_t;
68typedef struct preproc_effect_s preproc_effect_t;
69typedef struct preproc_ops_s preproc_ops_t;
70
71// Effect operation table. Functions for all pre processors are declared in sPreProcOps[] table.
72// Function pointer can be null if no action required.
73struct preproc_ops_s {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080074 int (*create)(preproc_effect_t* fx);
75 int (*init)(preproc_effect_t* fx);
76 int (*reset)(preproc_effect_t* fx);
77 void (*enable)(preproc_effect_t* fx);
78 void (*disable)(preproc_effect_t* fx);
79 int (*set_parameter)(preproc_effect_t* fx, void* param, void* value);
80 int (*get_parameter)(preproc_effect_t* fx, void* param, uint32_t* size, void* value);
81 int (*set_device)(preproc_effect_t* fx, uint32_t device);
Eric Laurenta9390d42011-06-17 20:17:17 -070082};
83
84// Effect context
85struct preproc_effect_s {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080086 const struct effect_interface_s* itfe;
87 uint32_t procId; // type of pre processor (enum preproc_id)
88 uint32_t state; // current state (enum preproc_effect_state)
89 preproc_session_t* session; // session the effect is on
90 const preproc_ops_t* ops; // effect ops table
91 preproc_fx_handle_t engine; // handle on webRTC engine
92 uint32_t type; // subtype of effect
Eric Laurent3f9c84c2012-04-03 15:36:53 -070093#ifdef DUAL_MIC_TEST
Harish Mahendrakarb6926c72020-11-27 15:22:44 -080094 bool aux_channels_on; // support auxiliary channels
95 size_t cur_channel_config; // current auciliary channel configuration
Eric Laurent3f9c84c2012-04-03 15:36:53 -070096#endif
Eric Laurenta9390d42011-06-17 20:17:17 -070097};
98
99// Session context
100struct preproc_session_s {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800101 struct preproc_effect_s effects[PREPROC_NUM_EFFECTS]; // effects in this session
102 uint32_t state; // current state (enum preproc_session_state)
103 int id; // audio session ID
104 int io; // handle of input stream this session is on
105 webrtc::AudioProcessing* apm; // handle on webRTC audio processing module (APM)
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530106 // Audio Processing module builder
107 webrtc::AudioProcessingBuilder ap_builder;
Harish Mahendrakard510fdd2021-03-16 13:26:31 -0700108 // frameCount represents the size of the buffers used for processing, and must represent 10ms.
109 size_t frameCount;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800110 uint32_t samplingRate; // sampling rate at effect process interface
111 uint32_t inChannelCount; // input channel count
112 uint32_t outChannelCount; // output channel count
113 uint32_t createdMsk; // bit field containing IDs of crested pre processors
114 uint32_t enabledMsk; // bit field containing IDs of enabled pre processors
115 uint32_t processedMsk; // bit field containing IDs of pre processors already
116 // processed in current round
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530117 // audio config strucutre
118 webrtc::AudioProcessing::Config config;
119 webrtc::StreamConfig inputConfig; // input stream configuration
120 webrtc::StreamConfig outputConfig; // output stream configuration
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800121 uint32_t revChannelCount; // number of channels on reverse stream
122 uint32_t revEnabledMsk; // bit field containing IDs of enabled pre processors
123 // with reverse channel
124 uint32_t revProcessedMsk; // bit field containing IDs of pre processors with reverse
125 // channel already processed in current round
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530126 webrtc::StreamConfig revConfig; // reverse stream configuration.
Eric Laurenta9390d42011-06-17 20:17:17 -0700127};
128
Eric Laurent3f9c84c2012-04-03 15:36:53 -0700129#ifdef DUAL_MIC_TEST
130enum {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800131 PREPROC_CMD_DUAL_MIC_ENABLE = EFFECT_CMD_FIRST_PROPRIETARY, // enable dual mic mode
132 PREPROC_CMD_DUAL_MIC_PCM_DUMP_START, // start pcm capture
133 PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP // stop pcm capture
Eric Laurent3f9c84c2012-04-03 15:36:53 -0700134};
135
136enum {
137 CHANNEL_CFG_MONO,
138 CHANNEL_CFG_STEREO,
139 CHANNEL_CFG_MONO_AUX,
140 CHANNEL_CFG_STEREO_AUX,
141 CHANNEL_CFG_CNT,
142 CHANNEL_CFG_FIRST_AUX = CHANNEL_CFG_MONO_AUX,
143};
144
145const channel_config_t sDualMicConfigs[CHANNEL_CFG_CNT] = {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800146 {AUDIO_CHANNEL_IN_MONO, 0},
147 {AUDIO_CHANNEL_IN_STEREO, 0},
148 {AUDIO_CHANNEL_IN_FRONT, AUDIO_CHANNEL_IN_BACK},
149 {AUDIO_CHANNEL_IN_STEREO, AUDIO_CHANNEL_IN_RIGHT}};
Eric Laurent3f9c84c2012-04-03 15:36:53 -0700150
151bool sHasAuxChannels[PREPROC_NUM_EFFECTS] = {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800152 false, // PREPROC_AGC
Atneya Nair2a77e832021-12-08 19:31:45 -0500153 false, // PREPROC_AGC2
Eric Laurent3f9c84c2012-04-03 15:36:53 -0700154 true, // PREPROC_AEC
155 true, // PREPROC_NS
156};
157
158bool gDualMicEnabled;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800159FILE* gPcmDumpFh;
Eric Laurent3f9c84c2012-04-03 15:36:53 -0700160static pthread_mutex_t gPcmDumpLock = PTHREAD_MUTEX_INITIALIZER;
161#endif
162
Eric Laurenta9390d42011-06-17 20:17:17 -0700163//------------------------------------------------------------------------------
164// Effect descriptors
165//------------------------------------------------------------------------------
166
167// UUIDs for effect types have been generated from http://www.itu.int/ITU-T/asn1/uuid.html
168// as the pre processing effects are not defined by OpenSL ES
169
170// Automatic Gain Control
171static const effect_descriptor_t sAgcDescriptor = {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800172 {0x0a8abfe0, 0x654c, 0x11e0, 0xba26, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
173 {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
Eric Laurenta9390d42011-06-17 20:17:17 -0700174 EFFECT_CONTROL_API_VERSION,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800175 (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
176 0, // FIXME indicate CPU load
177 0, // FIXME indicate memory usage
Eric Laurenta9390d42011-06-17 20:17:17 -0700178 "Automatic Gain Control",
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800179 "The Android Open Source Project"};
Eric Laurenta9390d42011-06-17 20:17:17 -0700180
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530181// Automatic Gain Control 2
182static const effect_descriptor_t sAgc2Descriptor = {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800183 {0xae3c653b, 0xbe18, 0x4ab8, 0x8938, {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}}, // type
184 {0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}}, // uuid
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530185 EFFECT_CONTROL_API_VERSION,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800186 (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
187 0, // FIXME indicate CPU load
188 0, // FIXME indicate memory usage
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530189 "Automatic Gain Control 2",
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800190 "The Android Open Source Project"};
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530191
Eric Laurenta9390d42011-06-17 20:17:17 -0700192// Acoustic Echo Cancellation
193static const effect_descriptor_t sAecDescriptor = {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800194 {0x7b491460, 0x8d4d, 0x11e0, 0xbd61, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
195 {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
Eric Laurenta9390d42011-06-17 20:17:17 -0700196 EFFECT_CONTROL_API_VERSION,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800197 (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
198 0, // FIXME indicate CPU load
199 0, // FIXME indicate memory usage
Eric Laurenta9390d42011-06-17 20:17:17 -0700200 "Acoustic Echo Canceler",
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800201 "The Android Open Source Project"};
Eric Laurenta9390d42011-06-17 20:17:17 -0700202
203// Noise suppression
204static const effect_descriptor_t sNsDescriptor = {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800205 {0x58b4b260, 0x8e06, 0x11e0, 0xaa8e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
206 {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
Eric Laurenta9390d42011-06-17 20:17:17 -0700207 EFFECT_CONTROL_API_VERSION,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800208 (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
209 0, // FIXME indicate CPU load
210 0, // FIXME indicate memory usage
Eric Laurenta9390d42011-06-17 20:17:17 -0700211 "Noise Suppression",
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800212 "The Android Open Source Project"};
Eric Laurenta9390d42011-06-17 20:17:17 -0700213
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800214static const effect_descriptor_t* sDescriptors[PREPROC_NUM_EFFECTS] = {&sAgcDescriptor,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800215 &sAgc2Descriptor,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800216 &sAecDescriptor,
217 &sNsDescriptor};
Eric Laurenta9390d42011-06-17 20:17:17 -0700218
219//------------------------------------------------------------------------------
220// Helper functions
221//------------------------------------------------------------------------------
222
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800223const effect_uuid_t* const sUuidToPreProcTable[PREPROC_NUM_EFFECTS] = {FX_IID_AGC,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800224 FX_IID_AGC2,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800225 FX_IID_AEC, FX_IID_NS};
Eric Laurenta9390d42011-06-17 20:17:17 -0700226
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800227const effect_uuid_t* ProcIdToUuid(int procId) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700228 if (procId >= PREPROC_NUM_EFFECTS) {
229 return EFFECT_UUID_NULL;
230 }
231 return sUuidToPreProcTable[procId];
232}
233
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800234uint32_t UuidToProcId(const effect_uuid_t* uuid) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700235 size_t i;
236 for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
237 if (memcmp(uuid, sUuidToPreProcTable[i], sizeof(*uuid)) == 0) {
238 break;
239 }
240 }
241 return i;
242}
243
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800244bool HasReverseStream(uint32_t procId) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700245 if (procId == PREPROC_AEC) {
246 return true;
247 }
248 return false;
249}
250
Eric Laurenta9390d42011-06-17 20:17:17 -0700251//------------------------------------------------------------------------------
252// Automatic Gain Control (AGC)
253//------------------------------------------------------------------------------
254
Eric Laurent53876962012-01-31 12:35:20 -0800255static const int kAgcDefaultTargetLevel = 3;
256static const int kAgcDefaultCompGain = 9;
Eric Laurenta9390d42011-06-17 20:17:17 -0700257static const bool kAgcDefaultLimiter = true;
258
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800259int Agc2Init(preproc_effect_t* effect) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530260 ALOGV("Agc2Init");
261 effect->session->config = effect->session->apm->GetConfig();
262 effect->session->config.gain_controller2.fixed_digital.gain_db = 0.f;
263 effect->session->config.gain_controller2.adaptive_digital.level_estimator =
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800264 effect->session->config.gain_controller2.kRms;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530265 effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db = 2.f;
266 effect->session->apm->ApplyConfig(effect->session->config);
267 return 0;
268}
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530269
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800270int AgcInit(preproc_effect_t* effect) {
Steve Block3856b092011-10-20 11:56:00 +0100271 ALOGV("AgcInit");
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530272 effect->session->config = effect->session->apm->GetConfig();
273 effect->session->config.gain_controller1.target_level_dbfs = kAgcDefaultTargetLevel;
274 effect->session->config.gain_controller1.compression_gain_db = kAgcDefaultCompGain;
275 effect->session->config.gain_controller1.enable_limiter = kAgcDefaultLimiter;
276 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700277 return 0;
278}
279
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800280int Agc2Create(preproc_effect_t* effect) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530281 Agc2Init(effect);
282 return 0;
283}
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530284
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800285int AgcCreate(preproc_effect_t* effect) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700286 AgcInit(effect);
287 return 0;
288}
289
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800290int Agc2GetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530291 int status = 0;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800292 uint32_t param = *(uint32_t*)pParam;
293 agc2_settings_t* pProperties = (agc2_settings_t*)pValue;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530294
295 switch (param) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800296 case AGC2_PARAM_FIXED_DIGITAL_GAIN:
297 if (*pValueSize < sizeof(float)) {
298 *pValueSize = 0.f;
299 return -EINVAL;
300 }
301 break;
302 case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
303 if (*pValueSize < sizeof(int32_t)) {
304 *pValueSize = 0;
305 return -EINVAL;
306 }
307 break;
308 case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
309 if (*pValueSize < sizeof(float)) {
310 *pValueSize = 0.f;
311 return -EINVAL;
312 }
313 break;
314 case AGC2_PARAM_PROPERTIES:
315 if (*pValueSize < sizeof(agc2_settings_t)) {
316 *pValueSize = 0;
317 return -EINVAL;
318 }
319 break;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530320
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800321 default:
322 ALOGW("Agc2GetParameter() unknown param %08x", param);
323 status = -EINVAL;
324 break;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530325 }
326
327 effect->session->config = effect->session->apm->GetConfig();
328 switch (param) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800329 case AGC2_PARAM_FIXED_DIGITAL_GAIN:
330 *(float*)pValue =
331 (float)(effect->session->config.gain_controller2.fixed_digital.gain_db);
332 ALOGV("Agc2GetParameter() target level %f dB", *(float*)pValue);
333 break;
334 case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
335 *(uint32_t*)pValue = (uint32_t)(
336 effect->session->config.gain_controller2.adaptive_digital.level_estimator);
337 ALOGV("Agc2GetParameter() level estimator %d",
338 *(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
339 break;
340 case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
341 *(float*)pValue = (float)(effect->session->config.gain_controller2.adaptive_digital
342 .extra_saturation_margin_db);
343 ALOGV("Agc2GetParameter() extra saturation margin %f dB", *(float*)pValue);
344 break;
345 case AGC2_PARAM_PROPERTIES:
346 pProperties->fixedDigitalGain =
347 (float)(effect->session->config.gain_controller2.fixed_digital.gain_db);
348 pProperties->level_estimator = (uint32_t)(
349 effect->session->config.gain_controller2.adaptive_digital.level_estimator);
350 pProperties->extraSaturationMargin =
351 (float)(effect->session->config.gain_controller2.adaptive_digital
352 .extra_saturation_margin_db);
353 break;
354 default:
355 ALOGW("Agc2GetParameter() unknown param %d", param);
356 status = -EINVAL;
357 break;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530358 }
359
360 return status;
361}
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530362
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800363int AgcGetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700364 int status = 0;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800365 uint32_t param = *(uint32_t*)pParam;
366 t_agc_settings* pProperties = (t_agc_settings*)pValue;
Eric Laurenta9390d42011-06-17 20:17:17 -0700367
368 switch (param) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800369 case AGC_PARAM_TARGET_LEVEL:
370 case AGC_PARAM_COMP_GAIN:
371 if (*pValueSize < sizeof(int16_t)) {
372 *pValueSize = 0;
373 return -EINVAL;
374 }
375 break;
376 case AGC_PARAM_LIMITER_ENA:
377 if (*pValueSize < sizeof(bool)) {
378 *pValueSize = 0;
379 return -EINVAL;
380 }
381 break;
382 case AGC_PARAM_PROPERTIES:
383 if (*pValueSize < sizeof(t_agc_settings)) {
384 *pValueSize = 0;
385 return -EINVAL;
386 }
387 break;
Eric Laurenta9390d42011-06-17 20:17:17 -0700388
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800389 default:
390 ALOGW("AgcGetParameter() unknown param %08x", param);
391 status = -EINVAL;
392 break;
Eric Laurenta9390d42011-06-17 20:17:17 -0700393 }
394
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530395 effect->session->config = effect->session->apm->GetConfig();
396 switch (param) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800397 case AGC_PARAM_TARGET_LEVEL:
398 *(int16_t*)pValue =
399 (int16_t)(effect->session->config.gain_controller1.target_level_dbfs * -100);
400 ALOGV("AgcGetParameter() target level %d milliBels", *(int16_t*)pValue);
401 break;
402 case AGC_PARAM_COMP_GAIN:
403 *(int16_t*)pValue =
404 (int16_t)(effect->session->config.gain_controller1.compression_gain_db * -100);
405 ALOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t*)pValue);
406 break;
407 case AGC_PARAM_LIMITER_ENA:
408 *(bool*)pValue = (bool)(effect->session->config.gain_controller1.enable_limiter);
409 ALOGV("AgcGetParameter() limiter enabled %s",
410 (*(int16_t*)pValue != 0) ? "true" : "false");
411 break;
412 case AGC_PARAM_PROPERTIES:
413 pProperties->targetLevel =
414 (int16_t)(effect->session->config.gain_controller1.target_level_dbfs * -100);
415 pProperties->compGain =
416 (int16_t)(effect->session->config.gain_controller1.compression_gain_db * -100);
417 pProperties->limiterEnabled =
418 (bool)(effect->session->config.gain_controller1.enable_limiter);
419 break;
420 default:
421 ALOGW("AgcGetParameter() unknown param %d", param);
422 status = -EINVAL;
423 break;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530424 }
Eric Laurenta9390d42011-06-17 20:17:17 -0700425 return status;
426}
427
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800428int Agc2SetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530429 int status = 0;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800430 uint32_t param = *(uint32_t*)pParam;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530431 float valueFloat = 0.f;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800432 agc2_settings_t* pProperties = (agc2_settings_t*)pValue;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530433 effect->session->config = effect->session->apm->GetConfig();
434 switch (param) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800435 case AGC2_PARAM_FIXED_DIGITAL_GAIN:
436 valueFloat = (float)(*(int32_t*)pValue);
437 ALOGV("Agc2SetParameter() fixed digital gain %f dB", valueFloat);
438 effect->session->config.gain_controller2.fixed_digital.gain_db = valueFloat;
439 break;
440 case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
441 ALOGV("Agc2SetParameter() level estimator %d",
442 *(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
443 effect->session->config.gain_controller2.adaptive_digital.level_estimator =
444 (*(webrtc::AudioProcessing::Config::GainController2::LevelEstimator*)pValue);
445 break;
446 case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
447 valueFloat = (float)(*(int32_t*)pValue);
448 ALOGV("Agc2SetParameter() extra saturation margin %f dB", valueFloat);
449 effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db =
450 valueFloat;
451 break;
452 case AGC2_PARAM_PROPERTIES:
453 ALOGV("Agc2SetParameter() properties gain %f, level %d margin %f",
454 pProperties->fixedDigitalGain, pProperties->level_estimator,
455 pProperties->extraSaturationMargin);
456 effect->session->config.gain_controller2.fixed_digital.gain_db =
457 pProperties->fixedDigitalGain;
458 effect->session->config.gain_controller2.adaptive_digital.level_estimator =
459 (webrtc::AudioProcessing::Config::GainController2::LevelEstimator)
460 pProperties->level_estimator;
461 effect->session->config.gain_controller2.adaptive_digital.extra_saturation_margin_db =
462 pProperties->extraSaturationMargin;
463 break;
464 default:
465 ALOGW("Agc2SetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
466 status = -EINVAL;
467 break;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530468 }
469 effect->session->apm->ApplyConfig(effect->session->config);
470
471 ALOGV("Agc2SetParameter() done status %d", status);
472
473 return status;
474}
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530475
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800476int AgcSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700477 int status = 0;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800478 uint32_t param = *(uint32_t*)pParam;
479 t_agc_settings* pProperties = (t_agc_settings*)pValue;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530480 effect->session->config = effect->session->apm->GetConfig();
481 switch (param) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800482 case AGC_PARAM_TARGET_LEVEL:
483 ALOGV("AgcSetParameter() target level %d milliBels", *(int16_t*)pValue);
484 effect->session->config.gain_controller1.target_level_dbfs =
485 (-(*(int16_t*)pValue / 100));
486 break;
487 case AGC_PARAM_COMP_GAIN:
488 ALOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t*)pValue);
489 effect->session->config.gain_controller1.compression_gain_db =
490 (*(int16_t*)pValue / 100);
491 break;
492 case AGC_PARAM_LIMITER_ENA:
493 ALOGV("AgcSetParameter() limiter enabled %s", *(bool*)pValue ? "true" : "false");
494 effect->session->config.gain_controller1.enable_limiter = (*(bool*)pValue);
495 break;
496 case AGC_PARAM_PROPERTIES:
497 ALOGV("AgcSetParameter() properties level %d, gain %d limiter %d",
498 pProperties->targetLevel, pProperties->compGain, pProperties->limiterEnabled);
499 effect->session->config.gain_controller1.target_level_dbfs =
500 -(pProperties->targetLevel / 100);
501 effect->session->config.gain_controller1.compression_gain_db =
502 pProperties->compGain / 100;
503 effect->session->config.gain_controller1.enable_limiter = pProperties->limiterEnabled;
504 break;
505 default:
506 ALOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
507 status = -EINVAL;
508 break;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530509 }
510 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700511
Steve Block3856b092011-10-20 11:56:00 +0100512 ALOGV("AgcSetParameter() done status %d", status);
Eric Laurenta9390d42011-06-17 20:17:17 -0700513
514 return status;
515}
516
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800517void Agc2Enable(preproc_effect_t* effect) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530518 effect->session->config = effect->session->apm->GetConfig();
519 effect->session->config.gain_controller2.enabled = true;
520 effect->session->apm->ApplyConfig(effect->session->config);
521}
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530522
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800523void AgcEnable(preproc_effect_t* effect) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530524 effect->session->config = effect->session->apm->GetConfig();
525 effect->session->config.gain_controller1.enabled = true;
526 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700527}
528
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800529void Agc2Disable(preproc_effect_t* effect) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530530 effect->session->config = effect->session->apm->GetConfig();
531 effect->session->config.gain_controller2.enabled = false;
532 effect->session->apm->ApplyConfig(effect->session->config);
533}
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530534
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800535void AgcDisable(preproc_effect_t* effect) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530536 effect->session->config = effect->session->apm->GetConfig();
537 effect->session->config.gain_controller1.enabled = false;
538 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700539}
540
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800541static const preproc_ops_t sAgcOps = {AgcCreate, AgcInit, NULL, AgcEnable, AgcDisable,
542 AgcSetParameter, AgcGetParameter, NULL};
Eric Laurenta9390d42011-06-17 20:17:17 -0700543
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800544static const preproc_ops_t sAgc2Ops = {Agc2Create, Agc2Init, NULL,
545 Agc2Enable, Agc2Disable, Agc2SetParameter,
546 Agc2GetParameter, NULL};
Eric Laurenta9390d42011-06-17 20:17:17 -0700547
548//------------------------------------------------------------------------------
549// Acoustic Echo Canceler (AEC)
550//------------------------------------------------------------------------------
551
Eric Laurenta9390d42011-06-17 20:17:17 -0700552
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800553int AecInit(preproc_effect_t* effect) {
Steve Block3856b092011-10-20 11:56:00 +0100554 ALOGV("AecInit");
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800555 effect->session->config = effect->session->apm->GetConfig();
Rivukanta Bhattacharyac4c54172020-11-25 23:55:44 +0530556 effect->session->config.echo_canceller.mobile_mode = true;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530557 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700558 return 0;
559}
560
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800561int AecCreate(preproc_effect_t* effect) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800562 AecInit(effect);
Eric Laurenta9390d42011-06-17 20:17:17 -0700563 return 0;
564}
565
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800566int AecGetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700567 int status = 0;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800568 uint32_t param = *(uint32_t*)pParam;
Eric Laurenta9390d42011-06-17 20:17:17 -0700569
570 if (*pValueSize < sizeof(uint32_t)) {
571 return -EINVAL;
572 }
573 switch (param) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800574 case AEC_PARAM_ECHO_DELAY:
575 case AEC_PARAM_PROPERTIES:
576 *(uint32_t*)pValue = 1000 * effect->session->apm->stream_delay_ms();
577 ALOGV("AecGetParameter() echo delay %d us", *(uint32_t*)pValue);
578 break;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800579 case AEC_PARAM_MOBILE_MODE:
580 effect->session->config = effect->session->apm->GetConfig();
581 *(uint32_t*)pValue = effect->session->config.echo_canceller.mobile_mode;
582 ALOGV("AecGetParameter() mobile mode %d us", *(uint32_t*)pValue);
583 break;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800584 default:
585 ALOGW("AecGetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
586 status = -EINVAL;
587 break;
Eric Laurenta9390d42011-06-17 20:17:17 -0700588 }
589 return status;
590}
591
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800592int AecSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700593 int status = 0;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800594 uint32_t param = *(uint32_t*)pParam;
595 uint32_t value = *(uint32_t*)pValue;
Eric Laurenta9390d42011-06-17 20:17:17 -0700596
597 switch (param) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800598 case AEC_PARAM_ECHO_DELAY:
599 case AEC_PARAM_PROPERTIES:
600 status = effect->session->apm->set_stream_delay_ms(value / 1000);
601 ALOGV("AecSetParameter() echo delay %d us, status %d", value, status);
602 break;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800603 case AEC_PARAM_MOBILE_MODE:
604 effect->session->config = effect->session->apm->GetConfig();
605 effect->session->config.echo_canceller.mobile_mode = value;
606 ALOGV("AecSetParameter() mobile mode %d us", value);
607 effect->session->apm->ApplyConfig(effect->session->config);
608 break;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800609 default:
610 ALOGW("AecSetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
611 status = -EINVAL;
612 break;
Eric Laurenta9390d42011-06-17 20:17:17 -0700613 }
614 return status;
615}
616
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800617void AecEnable(preproc_effect_t* effect) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530618 effect->session->config = effect->session->apm->GetConfig();
619 effect->session->config.echo_canceller.enabled = true;
620 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700621}
622
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800623void AecDisable(preproc_effect_t* effect) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530624 effect->session->config = effect->session->apm->GetConfig();
625 effect->session->config.echo_canceller.enabled = false;
626 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700627}
628
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800629int AecSetDevice(preproc_effect_t* effect, uint32_t device) {
Steve Block3856b092011-10-20 11:56:00 +0100630 ALOGV("AecSetDevice %08x", device);
Eric Laurenta9390d42011-06-17 20:17:17 -0700631
Eric Laurent88959252012-08-28 14:26:53 -0700632 if (audio_is_input_device(device)) {
633 return 0;
634 }
635
Eric Laurenta9390d42011-06-17 20:17:17 -0700636 return 0;
637}
638
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800639static const preproc_ops_t sAecOps = {AecCreate, AecInit, NULL,
640 AecEnable, AecDisable, AecSetParameter,
641 AecGetParameter, AecSetDevice};
Eric Laurenta9390d42011-06-17 20:17:17 -0700642
643//------------------------------------------------------------------------------
644// Noise Suppression (NS)
645//------------------------------------------------------------------------------
646
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530647static const webrtc::AudioProcessing::Config::NoiseSuppression::Level kNsDefaultLevel =
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800648 webrtc::AudioProcessing::Config::NoiseSuppression::kModerate;
Eric Laurenta9390d42011-06-17 20:17:17 -0700649
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800650int NsInit(preproc_effect_t* effect) {
Steve Block3856b092011-10-20 11:56:00 +0100651 ALOGV("NsInit");
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800652 effect->session->config = effect->session->apm->GetConfig();
653 effect->session->config.noise_suppression.level = kNsDefaultLevel;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530654 effect->session->apm->ApplyConfig(effect->session->config);
Alex Luebs766bf732015-12-14 21:32:13 -0800655 effect->type = NS_TYPE_SINGLE_CHANNEL;
Eric Laurenta9390d42011-06-17 20:17:17 -0700656 return 0;
657}
658
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800659int NsCreate(preproc_effect_t* effect) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800660 NsInit(effect);
Eric Laurenta9390d42011-06-17 20:17:17 -0700661 return 0;
662}
663
Rivukanta Bhattacharya013e02e2021-03-12 05:50:55 +0530664int NsGetParameter(preproc_effect_t* /*effect __unused*/, void* /*pParam __unused*/,
665 uint32_t* /*pValueSize __unused*/, void* /*pValue __unused*/) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700666 int status = 0;
667 return status;
668}
669
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800670int NsSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700671 int status = 0;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800672 uint32_t param = *(uint32_t*)pParam;
673 uint32_t value = *(uint32_t*)pValue;
674 effect->session->config = effect->session->apm->GetConfig();
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530675 switch (param) {
676 case NS_PARAM_LEVEL:
677 effect->session->config.noise_suppression.level =
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800678 (webrtc::AudioProcessing::Config::NoiseSuppression::Level)value;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530679 ALOGV("NsSetParameter() level %d", value);
680 break;
681 default:
682 ALOGW("NsSetParameter() unknown param %08x value %08x", param, value);
683 status = -EINVAL;
684 }
685 effect->session->apm->ApplyConfig(effect->session->config);
Alex Luebs766bf732015-12-14 21:32:13 -0800686
Eric Laurenta9390d42011-06-17 20:17:17 -0700687 return status;
688}
689
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800690void NsEnable(preproc_effect_t* effect) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800691 effect->session->config = effect->session->apm->GetConfig();
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530692 effect->session->config.noise_suppression.enabled = true;
693 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700694}
695
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800696void NsDisable(preproc_effect_t* effect) {
Steve Block3856b092011-10-20 11:56:00 +0100697 ALOGV("NsDisable");
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800698 effect->session->config = effect->session->apm->GetConfig();
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530699 effect->session->config.noise_suppression.enabled = false;
700 effect->session->apm->ApplyConfig(effect->session->config);
Eric Laurenta9390d42011-06-17 20:17:17 -0700701}
702
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800703static const preproc_ops_t sNsOps = {NsCreate, NsInit, NULL, NsEnable,
704 NsDisable, NsSetParameter, NsGetParameter, NULL};
Eric Laurenta9390d42011-06-17 20:17:17 -0700705
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800706static const preproc_ops_t* sPreProcOps[PREPROC_NUM_EFFECTS] = {&sAgcOps,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800707 &sAgc2Ops,
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800708 &sAecOps, &sNsOps};
Eric Laurenta9390d42011-06-17 20:17:17 -0700709
710//------------------------------------------------------------------------------
711// Effect functions
712//------------------------------------------------------------------------------
713
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800714void Session_SetProcEnabled(preproc_session_t* session, uint32_t procId, bool enabled);
Eric Laurenta9390d42011-06-17 20:17:17 -0700715
716extern "C" const struct effect_interface_s sEffectInterface;
717extern "C" const struct effect_interface_s sEffectInterfaceReverse;
718
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800719#define BAD_STATE_ABORT(from, to) LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to);
Eric Laurenta9390d42011-06-17 20:17:17 -0700720
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800721int Effect_SetState(preproc_effect_t* effect, uint32_t state) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700722 int status = 0;
Steve Block3856b092011-10-20 11:56:00 +0100723 ALOGV("Effect_SetState proc %d, new %d old %d", effect->procId, state, effect->state);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800724 switch (state) {
725 case PREPROC_EFFECT_STATE_INIT:
726 switch (effect->state) {
727 case PREPROC_EFFECT_STATE_ACTIVE:
728 effect->ops->disable(effect);
729 Session_SetProcEnabled(effect->session, effect->procId, false);
730 break;
731 case PREPROC_EFFECT_STATE_CONFIG:
732 case PREPROC_EFFECT_STATE_CREATED:
733 case PREPROC_EFFECT_STATE_INIT:
734 break;
735 default:
736 BAD_STATE_ABORT(effect->state, state);
737 }
738 break;
739 case PREPROC_EFFECT_STATE_CREATED:
740 switch (effect->state) {
741 case PREPROC_EFFECT_STATE_INIT:
742 status = effect->ops->create(effect);
743 break;
744 case PREPROC_EFFECT_STATE_CREATED:
745 case PREPROC_EFFECT_STATE_ACTIVE:
746 case PREPROC_EFFECT_STATE_CONFIG:
747 ALOGE("Effect_SetState invalid transition");
748 status = -ENOSYS;
749 break;
750 default:
751 BAD_STATE_ABORT(effect->state, state);
752 }
Andy Hung320fd852018-10-09 14:06:37 -0700753 break;
Eric Laurenta9390d42011-06-17 20:17:17 -0700754 case PREPROC_EFFECT_STATE_CONFIG:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800755 switch (effect->state) {
756 case PREPROC_EFFECT_STATE_INIT:
757 ALOGE("Effect_SetState invalid transition");
758 status = -ENOSYS;
759 break;
760 case PREPROC_EFFECT_STATE_ACTIVE:
761 effect->ops->disable(effect);
762 Session_SetProcEnabled(effect->session, effect->procId, false);
763 break;
764 case PREPROC_EFFECT_STATE_CREATED:
765 case PREPROC_EFFECT_STATE_CONFIG:
766 break;
767 default:
768 BAD_STATE_ABORT(effect->state, state);
769 }
770 break;
771 case PREPROC_EFFECT_STATE_ACTIVE:
772 switch (effect->state) {
773 case PREPROC_EFFECT_STATE_INIT:
774 case PREPROC_EFFECT_STATE_CREATED:
775 ALOGE("Effect_SetState invalid transition");
776 status = -ENOSYS;
777 break;
778 case PREPROC_EFFECT_STATE_ACTIVE:
779 // enabling an already enabled effect is just ignored
780 break;
781 case PREPROC_EFFECT_STATE_CONFIG:
782 effect->ops->enable(effect);
783 Session_SetProcEnabled(effect->session, effect->procId, true);
784 break;
785 default:
786 BAD_STATE_ABORT(effect->state, state);
787 }
Eric Laurenta9390d42011-06-17 20:17:17 -0700788 break;
789 default:
790 BAD_STATE_ABORT(effect->state, state);
Eric Laurenta9390d42011-06-17 20:17:17 -0700791 }
792 if (status == 0) {
793 effect->state = state;
794 }
795 return status;
796}
797
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800798int Effect_Init(preproc_effect_t* effect, uint32_t procId) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700799 if (HasReverseStream(procId)) {
800 effect->itfe = &sEffectInterfaceReverse;
801 } else {
802 effect->itfe = &sEffectInterface;
803 }
804 effect->ops = sPreProcOps[procId];
805 effect->procId = procId;
806 effect->state = PREPROC_EFFECT_STATE_INIT;
807 return 0;
808}
809
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800810int Effect_Create(preproc_effect_t* effect, preproc_session_t* session,
811 effect_handle_t* interface) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700812 effect->session = session;
813 *interface = (effect_handle_t)&effect->itfe;
814 return Effect_SetState(effect, PREPROC_EFFECT_STATE_CREATED);
815}
816
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800817int Effect_Release(preproc_effect_t* effect) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700818 return Effect_SetState(effect, PREPROC_EFFECT_STATE_INIT);
819}
820
Eric Laurenta9390d42011-06-17 20:17:17 -0700821//------------------------------------------------------------------------------
822// Session functions
823//------------------------------------------------------------------------------
824
825#define RESAMPLER_QUALITY SPEEX_RESAMPLER_QUALITY_VOIP
826
827static const int kPreprocDefaultSr = 16000;
828static const int kPreProcDefaultCnl = 1;
829
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800830int Session_Init(preproc_session_t* session) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700831 size_t i;
832 int status = 0;
833
834 session->state = PREPROC_SESSION_STATE_INIT;
835 session->id = 0;
836 session->io = 0;
837 session->createdMsk = 0;
Eric Laurenta9390d42011-06-17 20:17:17 -0700838 for (i = 0; i < PREPROC_NUM_EFFECTS && status == 0; i++) {
839 status = Effect_Init(&session->effects[i], i);
840 }
841 return status;
842}
843
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800844extern "C" int Session_CreateEffect(preproc_session_t* session, int32_t procId,
845 effect_handle_t* interface) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700846 int status = -ENOMEM;
847
Steve Block3856b092011-10-20 11:56:00 +0100848 ALOGV("Session_CreateEffect procId %d, createdMsk %08x", procId, session->createdMsk);
Eric Laurenta9390d42011-06-17 20:17:17 -0700849
850 if (session->createdMsk == 0) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530851 session->apm = session->ap_builder.Create();
852 if (session->apm == NULL) {
853 ALOGW("Session_CreateEffect could not get apm engine");
854 goto error;
855 }
Harish Mahendrakard510fdd2021-03-16 13:26:31 -0700856 session->frameCount = kPreprocDefaultSr / 100;
Eric Laurenta9390d42011-06-17 20:17:17 -0700857 session->samplingRate = kPreprocDefaultSr;
858 session->inChannelCount = kPreProcDefaultCnl;
859 session->outChannelCount = kPreProcDefaultCnl;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530860 session->inputConfig.set_sample_rate_hz(kPreprocDefaultSr);
861 session->inputConfig.set_num_channels(kPreProcDefaultCnl);
862 session->outputConfig.set_sample_rate_hz(kPreprocDefaultSr);
863 session->outputConfig.set_num_channels(kPreProcDefaultCnl);
Eric Laurenta9390d42011-06-17 20:17:17 -0700864 session->revChannelCount = kPreProcDefaultCnl;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530865 session->revConfig.set_sample_rate_hz(kPreprocDefaultSr);
866 session->revConfig.set_num_channels(kPreProcDefaultCnl);
Eric Laurenta9390d42011-06-17 20:17:17 -0700867 session->enabledMsk = 0;
868 session->processedMsk = 0;
869 session->revEnabledMsk = 0;
870 session->revProcessedMsk = 0;
Eric Laurenta9390d42011-06-17 20:17:17 -0700871 }
872 status = Effect_Create(&session->effects[procId], session, interface);
873 if (status < 0) {
874 goto error;
875 }
Steve Block3856b092011-10-20 11:56:00 +0100876 ALOGV("Session_CreateEffect OK");
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800877 session->createdMsk |= (1 << procId);
Eric Laurenta9390d42011-06-17 20:17:17 -0700878 return status;
879
880error:
881 if (session->createdMsk == 0) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530882 delete session->apm;
883 session->apm = NULL;
Eric Laurenta9390d42011-06-17 20:17:17 -0700884 }
885 return status;
886}
887
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800888int Session_ReleaseEffect(preproc_session_t* session, preproc_effect_t* fx) {
Steve Block5ff1dd52012-01-05 23:22:43 +0000889 ALOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800890 session->createdMsk &= ~(1 << fx->procId);
Eric Laurenta9390d42011-06-17 20:17:17 -0700891 if (session->createdMsk == 0) {
Alex Luebs9718b7d2015-11-24 14:33:14 -0800892 delete session->apm;
Eric Laurenta9390d42011-06-17 20:17:17 -0700893 session->apm = NULL;
Eric Laurentb20cf7d2019-04-05 19:37:34 -0700894 session->id = 0;
Eric Laurenta9390d42011-06-17 20:17:17 -0700895 }
896
897 return 0;
898}
899
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800900int Session_SetConfig(preproc_session_t* session, effect_config_t* config) {
Alex Luebs3f11ef02016-01-15 15:51:58 -0800901 uint32_t inCnl = audio_channel_count_from_in_mask(config->inputCfg.channels);
902 uint32_t outCnl = audio_channel_count_from_in_mask(config->outputCfg.channels);
Eric Laurenta9390d42011-06-17 20:17:17 -0700903
904 if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
905 config->inputCfg.format != config->outputCfg.format ||
906 config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
907 return -EINVAL;
908 }
909
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800910 ALOGV("Session_SetConfig sr %d cnl %08x", config->inputCfg.samplingRate,
911 config->inputCfg.channels);
Eric Laurenta9390d42011-06-17 20:17:17 -0700912
Eric Laurenta9390d42011-06-17 20:17:17 -0700913 session->samplingRate = config->inputCfg.samplingRate;
Harish Mahendrakard510fdd2021-03-16 13:26:31 -0700914 session->frameCount = session->samplingRate / 100;
Eric Laurenta9390d42011-06-17 20:17:17 -0700915 session->inChannelCount = inCnl;
916 session->outChannelCount = outCnl;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530917 session->inputConfig.set_sample_rate_hz(session->samplingRate);
918 session->inputConfig.set_num_channels(inCnl);
919 session->outputConfig.set_sample_rate_hz(session->samplingRate);
920 session->outputConfig.set_num_channels(inCnl);
Eric Laurenta9390d42011-06-17 20:17:17 -0700921
922 session->revChannelCount = inCnl;
Saketh Sathuvalli08337032020-09-22 21:13:45 +0530923 session->revConfig.set_sample_rate_hz(session->samplingRate);
924 session->revConfig.set_num_channels(inCnl);
Eric Laurenta9390d42011-06-17 20:17:17 -0700925
Eric Laurenta9390d42011-06-17 20:17:17 -0700926 session->state = PREPROC_SESSION_STATE_CONFIG;
927 return 0;
928}
929
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800930void Session_GetConfig(preproc_session_t* session, effect_config_t* config) {
Eric Laurent3d5188b2011-12-16 15:30:36 -0800931 memset(config, 0, sizeof(effect_config_t));
932 config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
933 config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Glenn Kastenab334fd2012-03-14 12:56:06 -0700934 config->inputCfg.channels = audio_channel_in_mask_from_count(session->inChannelCount);
935 // "out" doesn't mean output device, so this is the correct API to convert channel count to mask
936 config->outputCfg.channels = audio_channel_in_mask_from_count(session->outChannelCount);
Eric Laurent3d5188b2011-12-16 15:30:36 -0800937 config->inputCfg.mask = config->outputCfg.mask =
938 (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
939}
940
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800941int Session_SetReverseConfig(preproc_session_t* session, effect_config_t* config) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700942 if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800943 config->inputCfg.format != config->outputCfg.format ||
944 config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700945 return -EINVAL;
946 }
947
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800948 ALOGV("Session_SetReverseConfig sr %d cnl %08x", config->inputCfg.samplingRate,
949 config->inputCfg.channels);
Eric Laurenta9390d42011-06-17 20:17:17 -0700950
951 if (session->state < PREPROC_SESSION_STATE_CONFIG) {
952 return -ENOSYS;
953 }
954 if (config->inputCfg.samplingRate != session->samplingRate ||
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800955 config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700956 return -EINVAL;
957 }
Andy Hunge5412692014-05-16 11:25:07 -0700958 uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels);
Eric Laurenta9390d42011-06-17 20:17:17 -0700959 session->revChannelCount = inCnl;
Eric Laurent3f9c84c2012-04-03 15:36:53 -0700960
Eric Laurenta9390d42011-06-17 20:17:17 -0700961 return 0;
962}
963
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800964void Session_GetReverseConfig(preproc_session_t* session, effect_config_t* config) {
Eric Laurent3d5188b2011-12-16 15:30:36 -0800965 memset(config, 0, sizeof(effect_config_t));
966 config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
967 config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
968 config->inputCfg.channels = config->outputCfg.channels =
Glenn Kastenab334fd2012-03-14 12:56:06 -0700969 audio_channel_in_mask_from_count(session->revChannelCount);
Eric Laurent3d5188b2011-12-16 15:30:36 -0800970 config->inputCfg.mask = config->outputCfg.mask =
971 (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
972}
973
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800974void Session_SetProcEnabled(preproc_session_t* session, uint32_t procId, bool enabled) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700975 if (enabled) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700976 session->enabledMsk |= (1 << procId);
977 if (HasReverseStream(procId)) {
Eric Laurenta9390d42011-06-17 20:17:17 -0700978 session->revEnabledMsk |= (1 << procId);
979 }
980 } else {
981 session->enabledMsk &= ~(1 << procId);
982 if (HasReverseStream(procId)) {
983 session->revEnabledMsk &= ~(1 << procId);
984 }
985 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -0800986 ALOGV("Session_SetProcEnabled proc %d, enabled %d enabledMsk %08x revEnabledMsk %08x", procId,
987 enabled, session->enabledMsk, session->revEnabledMsk);
Eric Laurenta9390d42011-06-17 20:17:17 -0700988 session->processedMsk = 0;
989 if (HasReverseStream(procId)) {
990 session->revProcessedMsk = 0;
991 }
992}
993
994//------------------------------------------------------------------------------
995// Bundle functions
996//------------------------------------------------------------------------------
997
998static int sInitStatus = 1;
999static preproc_session_t sSessions[PREPROC_NUM_SESSIONS];
1000
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001001preproc_session_t* PreProc_GetSession(int32_t procId, int32_t sessionId, int32_t ioId) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001002 size_t i;
Eric Laurenta9390d42011-06-17 20:17:17 -07001003 for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
Eric Laurentb20cf7d2019-04-05 19:37:34 -07001004 if (sSessions[i].id == sessionId) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001005 if (sSessions[i].createdMsk & (1 << procId)) {
1006 return NULL;
1007 }
1008 return &sSessions[i];
1009 }
1010 }
1011 for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
Eric Laurentb20cf7d2019-04-05 19:37:34 -07001012 if (sSessions[i].id == 0) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001013 sSessions[i].id = sessionId;
1014 sSessions[i].io = ioId;
1015 return &sSessions[i];
1016 }
1017 }
1018 return NULL;
1019}
1020
Eric Laurenta9390d42011-06-17 20:17:17 -07001021int PreProc_Init() {
1022 size_t i;
1023 int status = 0;
1024
1025 if (sInitStatus <= 0) {
1026 return sInitStatus;
1027 }
1028 for (i = 0; i < PREPROC_NUM_SESSIONS && status == 0; i++) {
1029 status = Session_Init(&sSessions[i]);
1030 }
1031 sInitStatus = status;
1032 return sInitStatus;
1033}
1034
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001035const effect_descriptor_t* PreProc_GetDescriptor(const effect_uuid_t* uuid) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001036 size_t i;
1037 for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
1038 if (memcmp(&sDescriptors[i]->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
1039 return sDescriptors[i];
1040 }
1041 }
1042 return NULL;
1043}
1044
Eric Laurenta9390d42011-06-17 20:17:17 -07001045extern "C" {
1046
1047//------------------------------------------------------------------------------
1048// Effect Control Interface Implementation
1049//------------------------------------------------------------------------------
1050
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001051int PreProcessingFx_Process(effect_handle_t self, audio_buffer_t* inBuffer,
1052 audio_buffer_t* outBuffer) {
1053 preproc_effect_t* effect = (preproc_effect_t*)self;
Eric Laurenta9390d42011-06-17 20:17:17 -07001054
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001055 if (effect == NULL) {
Steve Block3856b092011-10-20 11:56:00 +01001056 ALOGV("PreProcessingFx_Process() ERROR effect == NULL");
Eric Laurenta9390d42011-06-17 20:17:17 -07001057 return -EINVAL;
1058 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001059 preproc_session_t* session = (preproc_session_t*)effect->session;
Eric Laurenta9390d42011-06-17 20:17:17 -07001060
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001061 if (inBuffer == NULL || inBuffer->raw == NULL || outBuffer == NULL || outBuffer->raw == NULL) {
Steve Block5ff1dd52012-01-05 23:22:43 +00001062 ALOGW("PreProcessingFx_Process() ERROR bad pointer");
Eric Laurenta9390d42011-06-17 20:17:17 -07001063 return -EINVAL;
1064 }
1065
Harish Mahendrakard510fdd2021-03-16 13:26:31 -07001066 if (inBuffer->frameCount != outBuffer->frameCount) {
1067 ALOGW("inBuffer->frameCount %zu is not equal to outBuffer->frameCount %zu",
1068 inBuffer->frameCount, outBuffer->frameCount);
1069 return -EINVAL;
1070 }
1071
1072 if (inBuffer->frameCount != session->frameCount) {
1073 ALOGW("inBuffer->frameCount %zu != %zu representing 10ms at sampling rate %d",
1074 inBuffer->frameCount, session->frameCount, session->samplingRate);
1075 return -EINVAL;
1076 }
1077
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001078 session->processedMsk |= (1 << effect->procId);
Eric Laurenta9390d42011-06-17 20:17:17 -07001079
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001080 // ALOGV("PreProcessingFx_Process In %d frames enabledMsk %08x processedMsk %08x",
1081 // inBuffer->frameCount, session->enabledMsk, session->processedMsk);
Eric Laurenta9390d42011-06-17 20:17:17 -07001082 if ((session->processedMsk & session->enabledMsk) == session->enabledMsk) {
1083 effect->session->processedMsk = 0;
Saketh Sathuvalli08337032020-09-22 21:13:45 +05301084 if (int status = effect->session->apm->ProcessStream(
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001085 (const int16_t* const)inBuffer->s16,
1086 (const webrtc::StreamConfig)effect->session->inputConfig,
1087 (const webrtc::StreamConfig)effect->session->outputConfig,
1088 (int16_t* const)outBuffer->s16);
1089 status != 0) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +05301090 ALOGE("Process Stream failed with error %d\n", status);
1091 return status;
1092 }
Eric Laurenta9390d42011-06-17 20:17:17 -07001093 return 0;
1094 } else {
1095 return -ENODATA;
1096 }
1097}
1098
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001099int PreProcessingFx_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
1100 void* pCmdData, uint32_t* replySize, void* pReplyData) {
1101 preproc_effect_t* effect = (preproc_effect_t*)self;
Eric Laurenta9390d42011-06-17 20:17:17 -07001102
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001103 if (effect == NULL) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001104 return -EINVAL;
1105 }
1106
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001107 // ALOGV("PreProcessingFx_Command: command %d cmdSize %d",cmdCode, cmdSize);
Eric Laurenta9390d42011-06-17 20:17:17 -07001108
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001109 switch (cmdCode) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001110 case EFFECT_CMD_INIT:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001111 if (pReplyData == NULL || *replySize != sizeof(int)) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001112 return -EINVAL;
1113 }
1114 if (effect->ops->init) {
1115 effect->ops->init(effect);
1116 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001117 *(int*)pReplyData = 0;
Eric Laurenta9390d42011-06-17 20:17:17 -07001118 break;
1119
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001120 case EFFECT_CMD_SET_CONFIG: {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001121 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || pReplyData == NULL ||
1122 *replySize != sizeof(int)) {
Steve Block3856b092011-10-20 11:56:00 +01001123 ALOGV("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001124 "EFFECT_CMD_SET_CONFIG: ERROR");
Eric Laurenta9390d42011-06-17 20:17:17 -07001125 return -EINVAL;
1126 }
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001127#ifdef DUAL_MIC_TEST
1128 // make sure that the config command is accepted by making as if all effects were
1129 // disabled: this is OK for functional tests
1130 uint32_t enabledMsk = effect->session->enabledMsk;
1131 if (gDualMicEnabled) {
1132 effect->session->enabledMsk = 0;
1133 }
1134#endif
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001135 *(int*)pReplyData = Session_SetConfig(effect->session, (effect_config_t*)pCmdData);
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001136#ifdef DUAL_MIC_TEST
1137 if (gDualMicEnabled) {
1138 effect->session->enabledMsk = enabledMsk;
1139 }
1140#endif
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001141 if (*(int*)pReplyData != 0) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001142 break;
1143 }
Eric Laurent76533e92012-02-17 17:52:04 -08001144 if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001145 *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
Eric Laurent76533e92012-02-17 17:52:04 -08001146 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001147 } break;
Eric Laurenta9390d42011-06-17 20:17:17 -07001148
Eric Laurent3d5188b2011-12-16 15:30:36 -08001149 case EFFECT_CMD_GET_CONFIG:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001150 if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
Eric Laurent3d5188b2011-12-16 15:30:36 -08001151 ALOGV("\tLVM_ERROR : PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001152 "EFFECT_CMD_GET_CONFIG: ERROR");
Eric Laurent3d5188b2011-12-16 15:30:36 -08001153 return -EINVAL;
1154 }
1155
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001156 Session_GetConfig(effect->session, (effect_config_t*)pReplyData);
Eric Laurent3d5188b2011-12-16 15:30:36 -08001157 break;
1158
1159 case EFFECT_CMD_SET_CONFIG_REVERSE:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001160 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || pReplyData == NULL ||
Eric Laurent3d5188b2011-12-16 15:30:36 -08001161 *replySize != sizeof(int)) {
Steve Block3856b092011-10-20 11:56:00 +01001162 ALOGV("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001163 "EFFECT_CMD_SET_CONFIG_REVERSE: ERROR");
Eric Laurenta9390d42011-06-17 20:17:17 -07001164 return -EINVAL;
1165 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001166 *(int*)pReplyData =
1167 Session_SetReverseConfig(effect->session, (effect_config_t*)pCmdData);
1168 if (*(int*)pReplyData != 0) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001169 break;
1170 }
1171 break;
1172
Eric Laurent3d5188b2011-12-16 15:30:36 -08001173 case EFFECT_CMD_GET_CONFIG_REVERSE:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001174 if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
Eric Laurent3d5188b2011-12-16 15:30:36 -08001175 ALOGV("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001176 "EFFECT_CMD_GET_CONFIG_REVERSE: ERROR");
Eric Laurent3d5188b2011-12-16 15:30:36 -08001177 return -EINVAL;
1178 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001179 Session_GetReverseConfig(effect->session, (effect_config_t*)pCmdData);
Eric Laurent3d5188b2011-12-16 15:30:36 -08001180 break;
1181
Eric Laurenta9390d42011-06-17 20:17:17 -07001182 case EFFECT_CMD_RESET:
1183 if (effect->ops->reset) {
1184 effect->ops->reset(effect);
1185 }
1186 break;
1187
Eric Laurent0f714a42015-06-19 15:33:57 -07001188 case EFFECT_CMD_GET_PARAM: {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001189 effect_param_t* p = (effect_param_t*)pCmdData;
Eric Laurent0f714a42015-06-19 15:33:57 -07001190
1191 if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) ||
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001192 cmdSize < (sizeof(effect_param_t) + p->psize) || pReplyData == NULL ||
1193 replySize == NULL || *replySize < (sizeof(effect_param_t) + p->psize)) {
Steve Block3856b092011-10-20 11:56:00 +01001194 ALOGV("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001195 "EFFECT_CMD_GET_PARAM: ERROR");
Eric Laurenta9390d42011-06-17 20:17:17 -07001196 return -EINVAL;
1197 }
Eric Laurenta9390d42011-06-17 20:17:17 -07001198
1199 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
1200
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001201 p = (effect_param_t*)pReplyData;
Eric Laurenta9390d42011-06-17 20:17:17 -07001202
1203 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
1204
1205 if (effect->ops->get_parameter) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001206 p->status =
1207 effect->ops->get_parameter(effect, p->data, &p->vsize, p->data + voffset);
Eric Laurenta9390d42011-06-17 20:17:17 -07001208 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
1209 }
1210 } break;
1211
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001212 case EFFECT_CMD_SET_PARAM: {
1213 if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) || pReplyData == NULL ||
1214 replySize == NULL || *replySize != sizeof(int32_t)) {
Steve Block3856b092011-10-20 11:56:00 +01001215 ALOGV("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001216 "EFFECT_CMD_SET_PARAM: ERROR");
Eric Laurenta9390d42011-06-17 20:17:17 -07001217 return -EINVAL;
1218 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001219 effect_param_t* p = (effect_param_t*)pCmdData;
Eric Laurenta9390d42011-06-17 20:17:17 -07001220
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001221 if (p->psize != sizeof(int32_t)) {
Steve Block3856b092011-10-20 11:56:00 +01001222 ALOGV("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001223 "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
Eric Laurenta9390d42011-06-17 20:17:17 -07001224 return -EINVAL;
1225 }
1226 if (effect->ops->set_parameter) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001227 *(int*)pReplyData =
1228 effect->ops->set_parameter(effect, (void*)p->data, p->data + p->psize);
Eric Laurenta9390d42011-06-17 20:17:17 -07001229 }
1230 } break;
1231
1232 case EFFECT_CMD_ENABLE:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001233 if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
Steve Block3856b092011-10-20 11:56:00 +01001234 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_ENABLE: ERROR");
Eric Laurenta9390d42011-06-17 20:17:17 -07001235 return -EINVAL;
1236 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001237 *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_ACTIVE);
Eric Laurenta9390d42011-06-17 20:17:17 -07001238 break;
1239
1240 case EFFECT_CMD_DISABLE:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001241 if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
Steve Block3856b092011-10-20 11:56:00 +01001242 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_DISABLE: ERROR");
Eric Laurenta9390d42011-06-17 20:17:17 -07001243 return -EINVAL;
1244 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001245 *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
Eric Laurenta9390d42011-06-17 20:17:17 -07001246 break;
1247
1248 case EFFECT_CMD_SET_DEVICE:
1249 case EFFECT_CMD_SET_INPUT_DEVICE:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001250 if (pCmdData == NULL || cmdSize != sizeof(uint32_t)) {
Steve Block3856b092011-10-20 11:56:00 +01001251 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_DEVICE: ERROR");
Eric Laurenta9390d42011-06-17 20:17:17 -07001252 return -EINVAL;
1253 }
1254
1255 if (effect->ops->set_device) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001256 effect->ops->set_device(effect, *(uint32_t*)pCmdData);
Eric Laurenta9390d42011-06-17 20:17:17 -07001257 }
1258 break;
1259
1260 case EFFECT_CMD_SET_VOLUME:
1261 case EFFECT_CMD_SET_AUDIO_MODE:
1262 break;
1263
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001264#ifdef DUAL_MIC_TEST
1265 ///// test commands start
1266 case PREPROC_CMD_DUAL_MIC_ENABLE: {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001267 if (pCmdData == NULL || cmdSize != sizeof(uint32_t) || pReplyData == NULL ||
1268 replySize == NULL) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001269 ALOGE("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001270 "PREPROC_CMD_DUAL_MIC_ENABLE: ERROR");
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001271 *replySize = 0;
1272 return -EINVAL;
1273 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001274 gDualMicEnabled = *(bool*)pCmdData;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001275 if (gDualMicEnabled) {
1276 effect->aux_channels_on = sHasAuxChannels[effect->procId];
1277 } else {
1278 effect->aux_channels_on = false;
1279 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001280 effect->cur_channel_config =
1281 (effect->session->inChannelCount == 1) ? CHANNEL_CFG_MONO : CHANNEL_CFG_STEREO;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001282
1283 ALOGV("PREPROC_CMD_DUAL_MIC_ENABLE: %s", gDualMicEnabled ? "enabled" : "disabled");
1284 *replySize = sizeof(int);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001285 *(int*)pReplyData = 0;
1286 } break;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001287 case PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001288 if (pCmdData == NULL || pReplyData == NULL || replySize == NULL) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001289 ALOGE("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001290 "PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: ERROR");
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001291 *replySize = 0;
1292 return -EINVAL;
1293 }
1294 pthread_mutex_lock(&gPcmDumpLock);
1295 if (gPcmDumpFh != NULL) {
1296 fclose(gPcmDumpFh);
1297 gPcmDumpFh = NULL;
1298 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001299 char* path = strndup((char*)pCmdData, cmdSize);
1300 gPcmDumpFh = fopen((char*)path, "wb");
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001301 pthread_mutex_unlock(&gPcmDumpLock);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001302 ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: path %s gPcmDumpFh %p", path, gPcmDumpFh);
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001303 ALOGE_IF(gPcmDumpFh <= 0, "gPcmDumpFh open error %d %s", errno, strerror(errno));
1304 free(path);
1305 *replySize = sizeof(int);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001306 *(int*)pReplyData = 0;
1307 } break;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001308 case PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: {
1309 if (pReplyData == NULL || replySize == NULL) {
1310 ALOGE("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001311 "PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: ERROR");
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001312 *replySize = 0;
1313 return -EINVAL;
1314 }
1315 pthread_mutex_lock(&gPcmDumpLock);
1316 if (gPcmDumpFh != NULL) {
1317 fclose(gPcmDumpFh);
1318 gPcmDumpFh = NULL;
1319 }
1320 pthread_mutex_unlock(&gPcmDumpLock);
1321 ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP");
1322 *replySize = sizeof(int);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001323 *(int*)pReplyData = 0;
1324 } break;
1325 ///// test commands end
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001326
1327 case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001328 if (!gDualMicEnabled) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001329 return -EINVAL;
1330 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001331 if (pCmdData == NULL || cmdSize != 2 * sizeof(uint32_t) || pReplyData == NULL ||
1332 replySize == NULL) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001333 ALOGE("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001334 "EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: ERROR");
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001335 *replySize = 0;
1336 return -EINVAL;
1337 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001338 if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001339 ALOGV("PreProcessingFx_Command feature EFFECT_FEATURE_AUX_CHANNELS not supported by"
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001340 " fx %d",
1341 effect->procId);
1342 *(uint32_t*)pReplyData = -ENOSYS;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001343 *replySize = sizeof(uint32_t);
1344 break;
1345 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001346 size_t num_configs = *((uint32_t*)pCmdData + 1);
1347 if (*replySize < (2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t))) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001348 *replySize = 0;
1349 return -EINVAL;
1350 }
1351
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001352 *((uint32_t*)pReplyData + 1) = CHANNEL_CFG_CNT;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001353 if (num_configs < CHANNEL_CFG_CNT ||
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001354 *replySize < (2 * sizeof(uint32_t) + CHANNEL_CFG_CNT * sizeof(channel_config_t))) {
1355 *(uint32_t*)pReplyData = -ENOMEM;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001356 } else {
1357 num_configs = CHANNEL_CFG_CNT;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001358 *(uint32_t*)pReplyData = 0;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001359 }
1360 ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS num config %d",
1361 num_configs);
1362
1363 *replySize = 2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001364 *((uint32_t*)pReplyData + 1) = num_configs;
1365 memcpy((uint32_t*)pReplyData + 2, &sDualMicConfigs,
1366 num_configs * sizeof(channel_config_t));
1367 } break;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001368 case EFFECT_CMD_GET_FEATURE_CONFIG:
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001369 if (!gDualMicEnabled) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001370 return -EINVAL;
1371 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001372 if (pCmdData == NULL || cmdSize != sizeof(uint32_t) || pReplyData == NULL ||
1373 replySize == NULL || *replySize < sizeof(uint32_t) + sizeof(channel_config_t)) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001374 ALOGE("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001375 "EFFECT_CMD_GET_FEATURE_CONFIG: ERROR");
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001376 return -EINVAL;
1377 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001378 if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
1379 *(uint32_t*)pReplyData = -ENOSYS;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001380 *replySize = sizeof(uint32_t);
1381 break;
1382 }
1383 ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_CONFIG");
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001384 *(uint32_t*)pReplyData = 0;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001385 *replySize = sizeof(uint32_t) + sizeof(channel_config_t);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001386 memcpy((uint32_t*)pReplyData + 1, &sDualMicConfigs[effect->cur_channel_config],
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001387 sizeof(channel_config_t));
1388 break;
1389 case EFFECT_CMD_SET_FEATURE_CONFIG: {
1390 ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001391 "gDualMicEnabled %d effect->aux_channels_on %d",
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001392 gDualMicEnabled, effect->aux_channels_on);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001393 if (!gDualMicEnabled) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001394 return -EINVAL;
1395 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001396 if (pCmdData == NULL || cmdSize != (sizeof(uint32_t) + sizeof(channel_config_t)) ||
1397 pReplyData == NULL || replySize == NULL || *replySize < sizeof(uint32_t)) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001398 ALOGE("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001399 "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
1400 "pCmdData %p cmdSize %d pReplyData %p replySize %p *replySize %d",
1401 pCmdData, cmdSize, pReplyData, replySize, replySize ? *replySize : -1);
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001402 return -EINVAL;
1403 }
1404 *replySize = sizeof(uint32_t);
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001405 if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
1406 *(uint32_t*)pReplyData = -ENOSYS;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001407 ALOGV("PreProcessingFx_Command cmdCode Case: "
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001408 "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
1409 "CmdData %d effect->aux_channels_on %d",
1410 *(uint32_t*)pCmdData, effect->aux_channels_on);
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001411 break;
1412 }
1413 size_t i;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001414 for (i = 0; i < CHANNEL_CFG_CNT; i++) {
1415 if (memcmp((uint32_t*)pCmdData + 1, &sDualMicConfigs[i],
1416 sizeof(channel_config_t)) == 0) {
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001417 break;
1418 }
1419 }
1420 if (i == CHANNEL_CFG_CNT) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001421 *(uint32_t*)pReplyData = -EINVAL;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001422 ALOGW("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG invalid config"
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001423 "[%08x].[%08x]",
1424 *((uint32_t*)pCmdData + 1), *((uint32_t*)pCmdData + 2));
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001425 } else {
1426 effect->cur_channel_config = i;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001427 *(uint32_t*)pReplyData = 0;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001428 ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG New config"
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001429 "[%08x].[%08x]",
1430 sDualMicConfigs[i].main_channels, sDualMicConfigs[i].aux_channels);
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001431 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001432 } break;
Eric Laurent3f9c84c2012-04-03 15:36:53 -07001433#endif
Eric Laurenta9390d42011-06-17 20:17:17 -07001434 default:
1435 return -EINVAL;
1436 }
1437 return 0;
1438}
1439
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001440int PreProcessingFx_GetDescriptor(effect_handle_t self, effect_descriptor_t* pDescriptor) {
1441 preproc_effect_t* effect = (preproc_effect_t*)self;
Eric Laurenta9390d42011-06-17 20:17:17 -07001442
1443 if (effect == NULL || pDescriptor == NULL) {
1444 return -EINVAL;
1445 }
1446
Glenn Kastena189a682012-02-20 12:16:30 -08001447 *pDescriptor = *sDescriptors[effect->procId];
Eric Laurenta9390d42011-06-17 20:17:17 -07001448
1449 return 0;
1450}
1451
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001452int PreProcessingFx_ProcessReverse(effect_handle_t self, audio_buffer_t* inBuffer,
Rivukanta Bhattacharya013e02e2021-03-12 05:50:55 +05301453 audio_buffer_t* outBuffer) {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001454 preproc_effect_t* effect = (preproc_effect_t*)self;
Eric Laurenta9390d42011-06-17 20:17:17 -07001455
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001456 if (effect == NULL) {
Steve Block5ff1dd52012-01-05 23:22:43 +00001457 ALOGW("PreProcessingFx_ProcessReverse() ERROR effect == NULL");
Eric Laurenta9390d42011-06-17 20:17:17 -07001458 return -EINVAL;
1459 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001460 preproc_session_t* session = (preproc_session_t*)effect->session;
Eric Laurenta9390d42011-06-17 20:17:17 -07001461
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001462 if (inBuffer == NULL || inBuffer->raw == NULL) {
Steve Block5ff1dd52012-01-05 23:22:43 +00001463 ALOGW("PreProcessingFx_ProcessReverse() ERROR bad pointer");
Eric Laurenta9390d42011-06-17 20:17:17 -07001464 return -EINVAL;
1465 }
1466
Harish Mahendrakard510fdd2021-03-16 13:26:31 -07001467 if (inBuffer->frameCount != outBuffer->frameCount) {
1468 ALOGW("inBuffer->frameCount %zu is not equal to outBuffer->frameCount %zu",
1469 inBuffer->frameCount, outBuffer->frameCount);
1470 return -EINVAL;
1471 }
1472
1473 if (inBuffer->frameCount != session->frameCount) {
1474 ALOGW("inBuffer->frameCount %zu != %zu representing 10ms at sampling rate %d",
1475 inBuffer->frameCount, session->frameCount, session->samplingRate);
1476 return -EINVAL;
1477 }
1478
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001479 session->revProcessedMsk |= (1 << effect->procId);
Eric Laurenta9390d42011-06-17 20:17:17 -07001480
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001481 // ALOGV("PreProcessingFx_ProcessReverse In %d frames revEnabledMsk %08x revProcessedMsk
1482 // %08x",
1483 // inBuffer->frameCount, session->revEnabledMsk, session->revProcessedMsk);
Eric Laurenta9390d42011-06-17 20:17:17 -07001484
1485 if ((session->revProcessedMsk & session->revEnabledMsk) == session->revEnabledMsk) {
1486 effect->session->revProcessedMsk = 0;
Saketh Sathuvalli08337032020-09-22 21:13:45 +05301487 if (int status = effect->session->apm->ProcessReverseStream(
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001488 (const int16_t* const)inBuffer->s16,
1489 (const webrtc::StreamConfig)effect->session->revConfig,
1490 (const webrtc::StreamConfig)effect->session->revConfig,
1491 (int16_t* const)outBuffer->s16);
1492 status != 0) {
Saketh Sathuvalli08337032020-09-22 21:13:45 +05301493 ALOGE("Process Reverse Stream failed with error %d\n", status);
1494 return status;
1495 }
Eric Laurenta9390d42011-06-17 20:17:17 -07001496 return 0;
1497 } else {
1498 return -ENODATA;
1499 }
1500}
1501
Eric Laurenta9390d42011-06-17 20:17:17 -07001502// effect_handle_t interface implementation for effect
1503const struct effect_interface_s sEffectInterface = {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001504 PreProcessingFx_Process, PreProcessingFx_Command, PreProcessingFx_GetDescriptor, NULL};
Eric Laurenta9390d42011-06-17 20:17:17 -07001505
1506const struct effect_interface_s sEffectInterfaceReverse = {
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001507 PreProcessingFx_Process, PreProcessingFx_Command, PreProcessingFx_GetDescriptor,
1508 PreProcessingFx_ProcessReverse};
Eric Laurenta9390d42011-06-17 20:17:17 -07001509
1510//------------------------------------------------------------------------------
1511// Effect Library Interface Implementation
1512//------------------------------------------------------------------------------
1513
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001514int PreProcessingLib_Create(const effect_uuid_t* uuid, int32_t sessionId, int32_t ioId,
1515 effect_handle_t* pInterface) {
Steve Block3856b092011-10-20 11:56:00 +01001516 ALOGV("EffectCreate: uuid: %08x session %d IO: %d", uuid->timeLow, sessionId, ioId);
Eric Laurenta9390d42011-06-17 20:17:17 -07001517
1518 int status;
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001519 const effect_descriptor_t* desc;
1520 preproc_session_t* session;
Eric Laurenta9390d42011-06-17 20:17:17 -07001521 uint32_t procId;
1522
1523 if (PreProc_Init() != 0) {
1524 return sInitStatus;
1525 }
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001526 desc = PreProc_GetDescriptor(uuid);
Eric Laurenta9390d42011-06-17 20:17:17 -07001527 if (desc == NULL) {
Steve Block5ff1dd52012-01-05 23:22:43 +00001528 ALOGW("EffectCreate: fx not found uuid: %08x", uuid->timeLow);
Eric Laurenta9390d42011-06-17 20:17:17 -07001529 return -EINVAL;
1530 }
1531 procId = UuidToProcId(&desc->type);
1532
1533 session = PreProc_GetSession(procId, sessionId, ioId);
1534 if (session == NULL) {
Steve Block5ff1dd52012-01-05 23:22:43 +00001535 ALOGW("EffectCreate: no more session available");
Eric Laurenta9390d42011-06-17 20:17:17 -07001536 return -EINVAL;
1537 }
1538
1539 status = Session_CreateEffect(session, procId, pInterface);
1540
1541 if (status < 0 && session->createdMsk == 0) {
Eric Laurentb20cf7d2019-04-05 19:37:34 -07001542 session->id = 0;
Eric Laurenta9390d42011-06-17 20:17:17 -07001543 }
1544 return status;
1545}
1546
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001547int PreProcessingLib_Release(effect_handle_t interface) {
Steve Block3856b092011-10-20 11:56:00 +01001548 ALOGV("EffectRelease start %p", interface);
Eric Laurenta9390d42011-06-17 20:17:17 -07001549 if (PreProc_Init() != 0) {
1550 return sInitStatus;
1551 }
1552
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001553 preproc_effect_t* fx = (preproc_effect_t*)interface;
Eric Laurenta9390d42011-06-17 20:17:17 -07001554
Eric Laurentb20cf7d2019-04-05 19:37:34 -07001555 if (fx->session->id == 0) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001556 return -EINVAL;
1557 }
1558 return Session_ReleaseEffect(fx->session, fx);
1559}
1560
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001561int PreProcessingLib_GetDescriptor(const effect_uuid_t* uuid, effect_descriptor_t* pDescriptor) {
1562 if (pDescriptor == NULL || uuid == NULL) {
Eric Laurenta9390d42011-06-17 20:17:17 -07001563 return -EINVAL;
1564 }
1565
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001566 const effect_descriptor_t* desc = PreProc_GetDescriptor(uuid);
Eric Laurenta9390d42011-06-17 20:17:17 -07001567 if (desc == NULL) {
Steve Block3856b092011-10-20 11:56:00 +01001568 ALOGV("PreProcessingLib_GetDescriptor() not found");
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001569 return -EINVAL;
Eric Laurenta9390d42011-06-17 20:17:17 -07001570 }
1571
Steve Block3856b092011-10-20 11:56:00 +01001572 ALOGV("PreProcessingLib_GetDescriptor() got fx %s", desc->name);
Eric Laurenta9390d42011-06-17 20:17:17 -07001573
Glenn Kastena189a682012-02-20 12:16:30 -08001574 *pDescriptor = *desc;
Eric Laurenta9390d42011-06-17 20:17:17 -07001575 return 0;
1576}
1577
Marco Nelissen7f16b192012-10-25 16:05:57 -07001578// This is the only symbol that needs to be exported
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001579__attribute__((visibility("default"))) audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
1580 .tag = AUDIO_EFFECT_LIBRARY_TAG,
1581 .version = EFFECT_LIBRARY_API_VERSION,
1582 .name = "Audio Preprocessing Library",
1583 .implementor = "The Android Open Source Project",
1584 .create_effect = PreProcessingLib_Create,
1585 .release_effect = PreProcessingLib_Release,
1586 .get_descriptor = PreProcessingLib_GetDescriptor};
Eric Laurenta9390d42011-06-17 20:17:17 -07001587
Harish Mahendrakarb6926c72020-11-27 15:22:44 -08001588}; // extern "C"