xref: /aosp_15_r20/frameworks/av/media/libeffects/preprocessing/PreProcessing.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #include <stdlib.h>
18*ec779b8eSAndroid Build Coastguard Worker #include <string.h>
19*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "PreProcessing"
20*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
21*ec779b8eSAndroid Build Coastguard Worker #include <audio_effects/effect_aec.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <audio_effects/effect_agc.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <hardware/audio_effect.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <utils/Timers.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <audio_effects/effect_agc2.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <audio_effects/effect_ns.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <audio_processing.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <module_common_types.h>
30*ec779b8eSAndroid Build Coastguard Worker 
31*ec779b8eSAndroid Build Coastguard Worker // undefine to perform multi channels API functional tests
32*ec779b8eSAndroid Build Coastguard Worker //#define DUAL_MIC_TEST
33*ec779b8eSAndroid Build Coastguard Worker 
34*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
35*ec779b8eSAndroid Build Coastguard Worker // local definitions
36*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
37*ec779b8eSAndroid Build Coastguard Worker 
38*ec779b8eSAndroid Build Coastguard Worker // maximum number of sessions
39*ec779b8eSAndroid Build Coastguard Worker #define PREPROC_NUM_SESSIONS 8
40*ec779b8eSAndroid Build Coastguard Worker 
41*ec779b8eSAndroid Build Coastguard Worker // types of pre processing modules
42*ec779b8eSAndroid Build Coastguard Worker enum preproc_id {
43*ec779b8eSAndroid Build Coastguard Worker     PREPROC_AGC,  // Automatic Gain Control
44*ec779b8eSAndroid Build Coastguard Worker     PREPROC_AGC2,  // Automatic Gain Control 2
45*ec779b8eSAndroid Build Coastguard Worker     PREPROC_AEC,  // Acoustic Echo Canceler
46*ec779b8eSAndroid Build Coastguard Worker     PREPROC_NS,   // Noise Suppressor
47*ec779b8eSAndroid Build Coastguard Worker     PREPROC_NUM_EFFECTS
48*ec779b8eSAndroid Build Coastguard Worker };
49*ec779b8eSAndroid Build Coastguard Worker 
50*ec779b8eSAndroid Build Coastguard Worker // Session state
51*ec779b8eSAndroid Build Coastguard Worker enum preproc_session_state {
52*ec779b8eSAndroid Build Coastguard Worker     PREPROC_SESSION_STATE_INIT,   // initialized
53*ec779b8eSAndroid Build Coastguard Worker     PREPROC_SESSION_STATE_CONFIG  // configuration received
54*ec779b8eSAndroid Build Coastguard Worker };
55*ec779b8eSAndroid Build Coastguard Worker 
56*ec779b8eSAndroid Build Coastguard Worker // Effect/Preprocessor state
57*ec779b8eSAndroid Build Coastguard Worker enum preproc_effect_state {
58*ec779b8eSAndroid Build Coastguard Worker     PREPROC_EFFECT_STATE_INIT,     // initialized
59*ec779b8eSAndroid Build Coastguard Worker     PREPROC_EFFECT_STATE_CREATED,  // webRTC engine created
60*ec779b8eSAndroid Build Coastguard Worker     PREPROC_EFFECT_STATE_CONFIG,   // configuration received/disabled
61*ec779b8eSAndroid Build Coastguard Worker     PREPROC_EFFECT_STATE_ACTIVE    // active/enabled
62*ec779b8eSAndroid Build Coastguard Worker };
63*ec779b8eSAndroid Build Coastguard Worker 
64*ec779b8eSAndroid Build Coastguard Worker // handle on webRTC engine
65*ec779b8eSAndroid Build Coastguard Worker typedef void* preproc_fx_handle_t;
66*ec779b8eSAndroid Build Coastguard Worker 
67*ec779b8eSAndroid Build Coastguard Worker typedef struct preproc_session_s preproc_session_t;
68*ec779b8eSAndroid Build Coastguard Worker typedef struct preproc_effect_s preproc_effect_t;
69*ec779b8eSAndroid Build Coastguard Worker typedef struct preproc_ops_s preproc_ops_t;
70*ec779b8eSAndroid Build Coastguard Worker 
71*ec779b8eSAndroid Build Coastguard Worker // Effect operation table. Functions for all pre processors are declared in sPreProcOps[] table.
72*ec779b8eSAndroid Build Coastguard Worker // Function pointer can be null if no action required.
73*ec779b8eSAndroid Build Coastguard Worker struct preproc_ops_s {
74*ec779b8eSAndroid Build Coastguard Worker     int (*create)(preproc_effect_t* fx);
75*ec779b8eSAndroid Build Coastguard Worker     int (*init)(preproc_effect_t* fx);
76*ec779b8eSAndroid Build Coastguard Worker     int (*reset)(preproc_effect_t* fx);
77*ec779b8eSAndroid Build Coastguard Worker     void (*enable)(preproc_effect_t* fx);
78*ec779b8eSAndroid Build Coastguard Worker     void (*disable)(preproc_effect_t* fx);
79*ec779b8eSAndroid Build Coastguard Worker     int (*set_parameter)(preproc_effect_t* fx, void* param, void* value);
80*ec779b8eSAndroid Build Coastguard Worker     int (*get_parameter)(preproc_effect_t* fx, void* param, uint32_t* size, void* value);
81*ec779b8eSAndroid Build Coastguard Worker     int (*set_device)(preproc_effect_t* fx, uint32_t device);
82*ec779b8eSAndroid Build Coastguard Worker };
83*ec779b8eSAndroid Build Coastguard Worker 
84*ec779b8eSAndroid Build Coastguard Worker // Effect context
85*ec779b8eSAndroid Build Coastguard Worker struct preproc_effect_s {
86*ec779b8eSAndroid Build Coastguard Worker     const struct effect_interface_s* itfe;
87*ec779b8eSAndroid Build Coastguard Worker     uint32_t procId;             // type of pre processor (enum preproc_id)
88*ec779b8eSAndroid Build Coastguard Worker     uint32_t state;              // current state (enum preproc_effect_state)
89*ec779b8eSAndroid Build Coastguard Worker     preproc_session_t* session;  // session the effect is on
90*ec779b8eSAndroid Build Coastguard Worker     const preproc_ops_t* ops;    // effect ops table
91*ec779b8eSAndroid Build Coastguard Worker     preproc_fx_handle_t engine;  // handle on webRTC engine
92*ec779b8eSAndroid Build Coastguard Worker     uint32_t type;               // subtype of effect
93*ec779b8eSAndroid Build Coastguard Worker #ifdef DUAL_MIC_TEST
94*ec779b8eSAndroid Build Coastguard Worker     bool aux_channels_on;       // support auxiliary channels
95*ec779b8eSAndroid Build Coastguard Worker     size_t cur_channel_config;  // current auciliary channel configuration
96*ec779b8eSAndroid Build Coastguard Worker #endif
97*ec779b8eSAndroid Build Coastguard Worker };
98*ec779b8eSAndroid Build Coastguard Worker 
99*ec779b8eSAndroid Build Coastguard Worker // Session context
100*ec779b8eSAndroid Build Coastguard Worker struct preproc_session_s {
101*ec779b8eSAndroid Build Coastguard Worker     struct preproc_effect_s effects[PREPROC_NUM_EFFECTS];  // effects in this session
102*ec779b8eSAndroid Build Coastguard Worker     uint32_t state;                // current state (enum preproc_session_state)
103*ec779b8eSAndroid Build Coastguard Worker     int id;                        // audio session ID
104*ec779b8eSAndroid Build Coastguard Worker     int io;                        // handle of input stream this session is on
105*ec779b8eSAndroid Build Coastguard Worker     rtc::scoped_refptr<webrtc::AudioProcessing>
106*ec779b8eSAndroid Build Coastguard Worker             apm;  // handle on webRTC audio processing module (APM)
107*ec779b8eSAndroid Build Coastguard Worker     // Audio Processing module builder
108*ec779b8eSAndroid Build Coastguard Worker     webrtc::AudioProcessingBuilder ap_builder;
109*ec779b8eSAndroid Build Coastguard Worker     // frameCount represents the size of the buffers used for processing, and must represent 10ms.
110*ec779b8eSAndroid Build Coastguard Worker     size_t frameCount;
111*ec779b8eSAndroid Build Coastguard Worker     uint32_t samplingRate;     // sampling rate at effect process interface
112*ec779b8eSAndroid Build Coastguard Worker     uint32_t inChannelCount;   // input channel count
113*ec779b8eSAndroid Build Coastguard Worker     uint32_t outChannelCount;  // output channel count
114*ec779b8eSAndroid Build Coastguard Worker     uint32_t createdMsk;       // bit field containing IDs of crested pre processors
115*ec779b8eSAndroid Build Coastguard Worker     uint32_t enabledMsk;       // bit field containing IDs of enabled pre processors
116*ec779b8eSAndroid Build Coastguard Worker     uint32_t processedMsk;     // bit field containing IDs of pre processors already
117*ec779b8eSAndroid Build Coastguard Worker                                // processed in current round
118*ec779b8eSAndroid Build Coastguard Worker     // audio config strucutre
119*ec779b8eSAndroid Build Coastguard Worker     webrtc::AudioProcessing::Config config;
120*ec779b8eSAndroid Build Coastguard Worker     webrtc::StreamConfig inputConfig;   // input stream configuration
121*ec779b8eSAndroid Build Coastguard Worker     webrtc::StreamConfig outputConfig;  // output stream configuration
122*ec779b8eSAndroid Build Coastguard Worker     uint32_t revChannelCount;  // number of channels on reverse stream
123*ec779b8eSAndroid Build Coastguard Worker     uint32_t revEnabledMsk;    // bit field containing IDs of enabled pre processors
124*ec779b8eSAndroid Build Coastguard Worker                                // with reverse channel
125*ec779b8eSAndroid Build Coastguard Worker     uint32_t revProcessedMsk;  // bit field containing IDs of pre processors with reverse
126*ec779b8eSAndroid Build Coastguard Worker                                // channel already processed in current round
127*ec779b8eSAndroid Build Coastguard Worker     webrtc::StreamConfig revConfig;     // reverse stream configuration.
128*ec779b8eSAndroid Build Coastguard Worker };
129*ec779b8eSAndroid Build Coastguard Worker 
130*ec779b8eSAndroid Build Coastguard Worker #ifdef DUAL_MIC_TEST
131*ec779b8eSAndroid Build Coastguard Worker enum {
132*ec779b8eSAndroid Build Coastguard Worker     PREPROC_CMD_DUAL_MIC_ENABLE = EFFECT_CMD_FIRST_PROPRIETARY,  // enable dual mic mode
133*ec779b8eSAndroid Build Coastguard Worker     PREPROC_CMD_DUAL_MIC_PCM_DUMP_START,                         // start pcm capture
134*ec779b8eSAndroid Build Coastguard Worker     PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP                           // stop pcm capture
135*ec779b8eSAndroid Build Coastguard Worker };
136*ec779b8eSAndroid Build Coastguard Worker 
137*ec779b8eSAndroid Build Coastguard Worker enum {
138*ec779b8eSAndroid Build Coastguard Worker     CHANNEL_CFG_MONO,
139*ec779b8eSAndroid Build Coastguard Worker     CHANNEL_CFG_STEREO,
140*ec779b8eSAndroid Build Coastguard Worker     CHANNEL_CFG_MONO_AUX,
141*ec779b8eSAndroid Build Coastguard Worker     CHANNEL_CFG_STEREO_AUX,
142*ec779b8eSAndroid Build Coastguard Worker     CHANNEL_CFG_CNT,
143*ec779b8eSAndroid Build Coastguard Worker     CHANNEL_CFG_FIRST_AUX = CHANNEL_CFG_MONO_AUX,
144*ec779b8eSAndroid Build Coastguard Worker };
145*ec779b8eSAndroid Build Coastguard Worker 
146*ec779b8eSAndroid Build Coastguard Worker const channel_config_t sDualMicConfigs[CHANNEL_CFG_CNT] = {
147*ec779b8eSAndroid Build Coastguard Worker         {AUDIO_CHANNEL_IN_MONO, 0},
148*ec779b8eSAndroid Build Coastguard Worker         {AUDIO_CHANNEL_IN_STEREO, 0},
149*ec779b8eSAndroid Build Coastguard Worker         {AUDIO_CHANNEL_IN_FRONT, AUDIO_CHANNEL_IN_BACK},
150*ec779b8eSAndroid Build Coastguard Worker         {AUDIO_CHANNEL_IN_STEREO, AUDIO_CHANNEL_IN_RIGHT}};
151*ec779b8eSAndroid Build Coastguard Worker 
152*ec779b8eSAndroid Build Coastguard Worker bool sHasAuxChannels[PREPROC_NUM_EFFECTS] = {
153*ec779b8eSAndroid Build Coastguard Worker         false,  // PREPROC_AGC
154*ec779b8eSAndroid Build Coastguard Worker         false,  // PREPROC_AGC2
155*ec779b8eSAndroid Build Coastguard Worker         true,   // PREPROC_AEC
156*ec779b8eSAndroid Build Coastguard Worker         true,   // PREPROC_NS
157*ec779b8eSAndroid Build Coastguard Worker };
158*ec779b8eSAndroid Build Coastguard Worker 
159*ec779b8eSAndroid Build Coastguard Worker bool gDualMicEnabled;
160*ec779b8eSAndroid Build Coastguard Worker FILE* gPcmDumpFh;
161*ec779b8eSAndroid Build Coastguard Worker static pthread_mutex_t gPcmDumpLock = PTHREAD_MUTEX_INITIALIZER;
162*ec779b8eSAndroid Build Coastguard Worker #endif
163*ec779b8eSAndroid Build Coastguard Worker 
164*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
165*ec779b8eSAndroid Build Coastguard Worker // Effect descriptors
166*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
167*ec779b8eSAndroid Build Coastguard Worker 
168*ec779b8eSAndroid Build Coastguard Worker // UUIDs for effect types have been generated from http://www.itu.int/ITU-T/asn1/uuid.html
169*ec779b8eSAndroid Build Coastguard Worker // as the pre processing effects are not defined by OpenSL ES
170*ec779b8eSAndroid Build Coastguard Worker 
171*ec779b8eSAndroid Build Coastguard Worker // Automatic Gain Control
172*ec779b8eSAndroid Build Coastguard Worker static const effect_descriptor_t sAgcDescriptor = {
173*ec779b8eSAndroid Build Coastguard Worker         {0x0a8abfe0, 0x654c, 0x11e0, 0xba26, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // type
174*ec779b8eSAndroid Build Coastguard Worker         {0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid
175*ec779b8eSAndroid Build Coastguard Worker         EFFECT_CONTROL_API_VERSION,
176*ec779b8eSAndroid Build Coastguard Worker         (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
177*ec779b8eSAndroid Build Coastguard Worker         0,  // FIXME indicate CPU load
178*ec779b8eSAndroid Build Coastguard Worker         0,  // FIXME indicate memory usage
179*ec779b8eSAndroid Build Coastguard Worker         "Automatic Gain Control",
180*ec779b8eSAndroid Build Coastguard Worker         "The Android Open Source Project"};
181*ec779b8eSAndroid Build Coastguard Worker 
182*ec779b8eSAndroid Build Coastguard Worker // Automatic Gain Control 2
183*ec779b8eSAndroid Build Coastguard Worker static const effect_descriptor_t sAgc2Descriptor = {
184*ec779b8eSAndroid Build Coastguard Worker         {0xae3c653b, 0xbe18, 0x4ab8, 0x8938, {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}},  // type
185*ec779b8eSAndroid Build Coastguard Worker         {0x89f38e65, 0xd4d2, 0x4d64, 0xad0e, {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}},  // uuid
186*ec779b8eSAndroid Build Coastguard Worker         EFFECT_CONTROL_API_VERSION,
187*ec779b8eSAndroid Build Coastguard Worker         (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
188*ec779b8eSAndroid Build Coastguard Worker         0,  // FIXME indicate CPU load
189*ec779b8eSAndroid Build Coastguard Worker         0,  // FIXME indicate memory usage
190*ec779b8eSAndroid Build Coastguard Worker         "Automatic Gain Control 2",
191*ec779b8eSAndroid Build Coastguard Worker         "The Android Open Source Project"};
192*ec779b8eSAndroid Build Coastguard Worker 
193*ec779b8eSAndroid Build Coastguard Worker // Acoustic Echo Cancellation
194*ec779b8eSAndroid Build Coastguard Worker static const effect_descriptor_t sAecDescriptor = {
195*ec779b8eSAndroid Build Coastguard Worker         {0x7b491460, 0x8d4d, 0x11e0, 0xbd61, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // type
196*ec779b8eSAndroid Build Coastguard Worker         {0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid
197*ec779b8eSAndroid Build Coastguard Worker         EFFECT_CONTROL_API_VERSION,
198*ec779b8eSAndroid Build Coastguard Worker         (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
199*ec779b8eSAndroid Build Coastguard Worker         0,  // FIXME indicate CPU load
200*ec779b8eSAndroid Build Coastguard Worker         0,  // FIXME indicate memory usage
201*ec779b8eSAndroid Build Coastguard Worker         "Acoustic Echo Canceler",
202*ec779b8eSAndroid Build Coastguard Worker         "The Android Open Source Project"};
203*ec779b8eSAndroid Build Coastguard Worker 
204*ec779b8eSAndroid Build Coastguard Worker // Noise suppression
205*ec779b8eSAndroid Build Coastguard Worker static const effect_descriptor_t sNsDescriptor = {
206*ec779b8eSAndroid Build Coastguard Worker         {0x58b4b260, 0x8e06, 0x11e0, 0xaa8e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // type
207*ec779b8eSAndroid Build Coastguard Worker         {0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid
208*ec779b8eSAndroid Build Coastguard Worker         EFFECT_CONTROL_API_VERSION,
209*ec779b8eSAndroid Build Coastguard Worker         (EFFECT_FLAG_TYPE_PRE_PROC | EFFECT_FLAG_DEVICE_IND),
210*ec779b8eSAndroid Build Coastguard Worker         0,  // FIXME indicate CPU load
211*ec779b8eSAndroid Build Coastguard Worker         0,  // FIXME indicate memory usage
212*ec779b8eSAndroid Build Coastguard Worker         "Noise Suppression",
213*ec779b8eSAndroid Build Coastguard Worker         "The Android Open Source Project"};
214*ec779b8eSAndroid Build Coastguard Worker 
215*ec779b8eSAndroid Build Coastguard Worker static const effect_descriptor_t* sDescriptors[PREPROC_NUM_EFFECTS] = {&sAgcDescriptor,
216*ec779b8eSAndroid Build Coastguard Worker                                                                        &sAgc2Descriptor,
217*ec779b8eSAndroid Build Coastguard Worker                                                                        &sAecDescriptor,
218*ec779b8eSAndroid Build Coastguard Worker                                                                        &sNsDescriptor};
219*ec779b8eSAndroid Build Coastguard Worker 
220*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
221*ec779b8eSAndroid Build Coastguard Worker // Helper functions
222*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
223*ec779b8eSAndroid Build Coastguard Worker 
224*ec779b8eSAndroid Build Coastguard Worker const effect_uuid_t* const sUuidToPreProcTable[PREPROC_NUM_EFFECTS] = {FX_IID_AGC,
225*ec779b8eSAndroid Build Coastguard Worker                                                                        FX_IID_AGC2,
226*ec779b8eSAndroid Build Coastguard Worker                                                                        FX_IID_AEC, FX_IID_NS};
227*ec779b8eSAndroid Build Coastguard Worker 
ProcIdToUuid(int procId)228*ec779b8eSAndroid Build Coastguard Worker const effect_uuid_t* ProcIdToUuid(int procId) {
229*ec779b8eSAndroid Build Coastguard Worker     if (procId >= PREPROC_NUM_EFFECTS) {
230*ec779b8eSAndroid Build Coastguard Worker         return EFFECT_UUID_NULL;
231*ec779b8eSAndroid Build Coastguard Worker     }
232*ec779b8eSAndroid Build Coastguard Worker     return sUuidToPreProcTable[procId];
233*ec779b8eSAndroid Build Coastguard Worker }
234*ec779b8eSAndroid Build Coastguard Worker 
UuidToProcId(const effect_uuid_t * uuid)235*ec779b8eSAndroid Build Coastguard Worker uint32_t UuidToProcId(const effect_uuid_t* uuid) {
236*ec779b8eSAndroid Build Coastguard Worker     size_t i;
237*ec779b8eSAndroid Build Coastguard Worker     for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
238*ec779b8eSAndroid Build Coastguard Worker         if (memcmp(uuid, sUuidToPreProcTable[i], sizeof(*uuid)) == 0) {
239*ec779b8eSAndroid Build Coastguard Worker             break;
240*ec779b8eSAndroid Build Coastguard Worker         }
241*ec779b8eSAndroid Build Coastguard Worker     }
242*ec779b8eSAndroid Build Coastguard Worker     return i;
243*ec779b8eSAndroid Build Coastguard Worker }
244*ec779b8eSAndroid Build Coastguard Worker 
HasReverseStream(uint32_t procId)245*ec779b8eSAndroid Build Coastguard Worker bool HasReverseStream(uint32_t procId) {
246*ec779b8eSAndroid Build Coastguard Worker     if (procId == PREPROC_AEC) {
247*ec779b8eSAndroid Build Coastguard Worker         return true;
248*ec779b8eSAndroid Build Coastguard Worker     }
249*ec779b8eSAndroid Build Coastguard Worker     return false;
250*ec779b8eSAndroid Build Coastguard Worker }
251*ec779b8eSAndroid Build Coastguard Worker 
252*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
253*ec779b8eSAndroid Build Coastguard Worker // Automatic Gain Control (AGC)
254*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
255*ec779b8eSAndroid Build Coastguard Worker 
256*ec779b8eSAndroid Build Coastguard Worker static const int kAgcDefaultTargetLevel = 3;
257*ec779b8eSAndroid Build Coastguard Worker static const int kAgcDefaultCompGain = 9;
258*ec779b8eSAndroid Build Coastguard Worker static const bool kAgcDefaultLimiter = true;
259*ec779b8eSAndroid Build Coastguard Worker 
Agc2Init(preproc_effect_t * effect)260*ec779b8eSAndroid Build Coastguard Worker int Agc2Init(preproc_effect_t* effect) {
261*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Agc2Init");
262*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
263*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.gain_controller2.fixed_digital.gain_db = 0.f;
264*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
265*ec779b8eSAndroid Build Coastguard Worker     return 0;
266*ec779b8eSAndroid Build Coastguard Worker }
267*ec779b8eSAndroid Build Coastguard Worker 
AgcInit(preproc_effect_t * effect)268*ec779b8eSAndroid Build Coastguard Worker int AgcInit(preproc_effect_t* effect) {
269*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AgcInit");
270*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
271*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.gain_controller1.target_level_dbfs = kAgcDefaultTargetLevel;
272*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.gain_controller1.compression_gain_db = kAgcDefaultCompGain;
273*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.gain_controller1.enable_limiter = kAgcDefaultLimiter;
274*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
275*ec779b8eSAndroid Build Coastguard Worker     return 0;
276*ec779b8eSAndroid Build Coastguard Worker }
277*ec779b8eSAndroid Build Coastguard Worker 
Agc2Create(preproc_effect_t * effect)278*ec779b8eSAndroid Build Coastguard Worker int Agc2Create(preproc_effect_t* effect) {
279*ec779b8eSAndroid Build Coastguard Worker     Agc2Init(effect);
280*ec779b8eSAndroid Build Coastguard Worker     return 0;
281*ec779b8eSAndroid Build Coastguard Worker }
282*ec779b8eSAndroid Build Coastguard Worker 
AgcCreate(preproc_effect_t * effect)283*ec779b8eSAndroid Build Coastguard Worker int AgcCreate(preproc_effect_t* effect) {
284*ec779b8eSAndroid Build Coastguard Worker     AgcInit(effect);
285*ec779b8eSAndroid Build Coastguard Worker     return 0;
286*ec779b8eSAndroid Build Coastguard Worker }
287*ec779b8eSAndroid Build Coastguard Worker 
Agc2GetParameter(preproc_effect_t * effect,void * pParam,uint32_t * pValueSize,void * pValue)288*ec779b8eSAndroid Build Coastguard Worker int Agc2GetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
289*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
290*ec779b8eSAndroid Build Coastguard Worker     uint32_t param = *(uint32_t*)pParam;
291*ec779b8eSAndroid Build Coastguard Worker     agc2_settings_t* pProperties = (agc2_settings_t*)pValue;
292*ec779b8eSAndroid Build Coastguard Worker 
293*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
294*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_FIXED_DIGITAL_GAIN:
295*ec779b8eSAndroid Build Coastguard Worker             if (*pValueSize < sizeof(float)) {
296*ec779b8eSAndroid Build Coastguard Worker                 *pValueSize = 0.f;
297*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
298*ec779b8eSAndroid Build Coastguard Worker             }
299*ec779b8eSAndroid Build Coastguard Worker             break;
300*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
301*ec779b8eSAndroid Build Coastguard Worker             if (*pValueSize < sizeof(int32_t)) {
302*ec779b8eSAndroid Build Coastguard Worker                 *pValueSize = 0;
303*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
304*ec779b8eSAndroid Build Coastguard Worker             }
305*ec779b8eSAndroid Build Coastguard Worker             break;
306*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
307*ec779b8eSAndroid Build Coastguard Worker             if (*pValueSize < sizeof(float)) {
308*ec779b8eSAndroid Build Coastguard Worker                 *pValueSize = 0.f;
309*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
310*ec779b8eSAndroid Build Coastguard Worker             }
311*ec779b8eSAndroid Build Coastguard Worker             break;
312*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_PROPERTIES:
313*ec779b8eSAndroid Build Coastguard Worker             if (*pValueSize < sizeof(agc2_settings_t)) {
314*ec779b8eSAndroid Build Coastguard Worker                 *pValueSize = 0;
315*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
316*ec779b8eSAndroid Build Coastguard Worker             }
317*ec779b8eSAndroid Build Coastguard Worker             break;
318*ec779b8eSAndroid Build Coastguard Worker 
319*ec779b8eSAndroid Build Coastguard Worker         default:
320*ec779b8eSAndroid Build Coastguard Worker             ALOGW("Agc2GetParameter() unknown param %08x", param);
321*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
322*ec779b8eSAndroid Build Coastguard Worker             break;
323*ec779b8eSAndroid Build Coastguard Worker     }
324*ec779b8eSAndroid Build Coastguard Worker 
325*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
326*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
327*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_FIXED_DIGITAL_GAIN:
328*ec779b8eSAndroid Build Coastguard Worker             *(float*)pValue =
329*ec779b8eSAndroid Build Coastguard Worker                     (float)(effect->session->config.gain_controller2.fixed_digital.gain_db);
330*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Agc2GetParameter() target level %f dB", *(float*)pValue);
331*ec779b8eSAndroid Build Coastguard Worker             break;
332*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
333*ec779b8eSAndroid Build Coastguard Worker             // WebRTC only supports RMS level estimator now
334*ec779b8eSAndroid Build Coastguard Worker             *(uint32_t*)pValue = (uint32_t)(0);
335*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Agc2GetParameter() level estimator RMS");
336*ec779b8eSAndroid Build Coastguard Worker             break;
337*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
338*ec779b8eSAndroid Build Coastguard Worker             *(float*)pValue = (float)(2.0);
339*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Agc2GetParameter() extra saturation margin %f dB", *(float*)pValue);
340*ec779b8eSAndroid Build Coastguard Worker             break;
341*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_PROPERTIES:
342*ec779b8eSAndroid Build Coastguard Worker             pProperties->fixedDigitalGain =
343*ec779b8eSAndroid Build Coastguard Worker                     (float)(effect->session->config.gain_controller2.fixed_digital.gain_db);
344*ec779b8eSAndroid Build Coastguard Worker             pProperties->level_estimator = 0;
345*ec779b8eSAndroid Build Coastguard Worker             pProperties->extraSaturationMargin = 2.0;
346*ec779b8eSAndroid Build Coastguard Worker             break;
347*ec779b8eSAndroid Build Coastguard Worker         default:
348*ec779b8eSAndroid Build Coastguard Worker             ALOGW("Agc2GetParameter() unknown param %d", param);
349*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
350*ec779b8eSAndroid Build Coastguard Worker             break;
351*ec779b8eSAndroid Build Coastguard Worker     }
352*ec779b8eSAndroid Build Coastguard Worker 
353*ec779b8eSAndroid Build Coastguard Worker     return status;
354*ec779b8eSAndroid Build Coastguard Worker }
355*ec779b8eSAndroid Build Coastguard Worker 
AgcGetParameter(preproc_effect_t * effect,void * pParam,uint32_t * pValueSize,void * pValue)356*ec779b8eSAndroid Build Coastguard Worker int AgcGetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
357*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
358*ec779b8eSAndroid Build Coastguard Worker     uint32_t param = *(uint32_t*)pParam;
359*ec779b8eSAndroid Build Coastguard Worker     t_agc_settings* pProperties = (t_agc_settings*)pValue;
360*ec779b8eSAndroid Build Coastguard Worker 
361*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
362*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_TARGET_LEVEL:
363*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_COMP_GAIN:
364*ec779b8eSAndroid Build Coastguard Worker             if (*pValueSize < sizeof(int16_t)) {
365*ec779b8eSAndroid Build Coastguard Worker                 *pValueSize = 0;
366*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
367*ec779b8eSAndroid Build Coastguard Worker             }
368*ec779b8eSAndroid Build Coastguard Worker             break;
369*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_LIMITER_ENA:
370*ec779b8eSAndroid Build Coastguard Worker             if (*pValueSize < sizeof(bool)) {
371*ec779b8eSAndroid Build Coastguard Worker                 *pValueSize = 0;
372*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
373*ec779b8eSAndroid Build Coastguard Worker             }
374*ec779b8eSAndroid Build Coastguard Worker             break;
375*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_PROPERTIES:
376*ec779b8eSAndroid Build Coastguard Worker             if (*pValueSize < sizeof(t_agc_settings)) {
377*ec779b8eSAndroid Build Coastguard Worker                 *pValueSize = 0;
378*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
379*ec779b8eSAndroid Build Coastguard Worker             }
380*ec779b8eSAndroid Build Coastguard Worker             break;
381*ec779b8eSAndroid Build Coastguard Worker 
382*ec779b8eSAndroid Build Coastguard Worker         default:
383*ec779b8eSAndroid Build Coastguard Worker             ALOGW("AgcGetParameter() unknown param %08x", param);
384*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
385*ec779b8eSAndroid Build Coastguard Worker             break;
386*ec779b8eSAndroid Build Coastguard Worker     }
387*ec779b8eSAndroid Build Coastguard Worker 
388*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
389*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
390*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_TARGET_LEVEL:
391*ec779b8eSAndroid Build Coastguard Worker             *(int16_t*)pValue =
392*ec779b8eSAndroid Build Coastguard Worker                     (int16_t)(effect->session->config.gain_controller1.target_level_dbfs * -100);
393*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AgcGetParameter() target level %d milliBels", *(int16_t*)pValue);
394*ec779b8eSAndroid Build Coastguard Worker             break;
395*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_COMP_GAIN:
396*ec779b8eSAndroid Build Coastguard Worker             *(int16_t*)pValue =
397*ec779b8eSAndroid Build Coastguard Worker                     (int16_t)(effect->session->config.gain_controller1.compression_gain_db * -100);
398*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t*)pValue);
399*ec779b8eSAndroid Build Coastguard Worker             break;
400*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_LIMITER_ENA:
401*ec779b8eSAndroid Build Coastguard Worker             *(bool*)pValue = (bool)(effect->session->config.gain_controller1.enable_limiter);
402*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AgcGetParameter() limiter enabled %s",
403*ec779b8eSAndroid Build Coastguard Worker                   (*(int16_t*)pValue != 0) ? "true" : "false");
404*ec779b8eSAndroid Build Coastguard Worker             break;
405*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_PROPERTIES:
406*ec779b8eSAndroid Build Coastguard Worker             pProperties->targetLevel =
407*ec779b8eSAndroid Build Coastguard Worker                     (int16_t)(effect->session->config.gain_controller1.target_level_dbfs * -100);
408*ec779b8eSAndroid Build Coastguard Worker             pProperties->compGain =
409*ec779b8eSAndroid Build Coastguard Worker                     (int16_t)(effect->session->config.gain_controller1.compression_gain_db * -100);
410*ec779b8eSAndroid Build Coastguard Worker             pProperties->limiterEnabled =
411*ec779b8eSAndroid Build Coastguard Worker                     (bool)(effect->session->config.gain_controller1.enable_limiter);
412*ec779b8eSAndroid Build Coastguard Worker             break;
413*ec779b8eSAndroid Build Coastguard Worker         default:
414*ec779b8eSAndroid Build Coastguard Worker             ALOGW("AgcGetParameter() unknown param %d", param);
415*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
416*ec779b8eSAndroid Build Coastguard Worker             break;
417*ec779b8eSAndroid Build Coastguard Worker     }
418*ec779b8eSAndroid Build Coastguard Worker     return status;
419*ec779b8eSAndroid Build Coastguard Worker }
420*ec779b8eSAndroid Build Coastguard Worker 
Agc2SetParameter(preproc_effect_t * effect,void * pParam,void * pValue)421*ec779b8eSAndroid Build Coastguard Worker int Agc2SetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
422*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
423*ec779b8eSAndroid Build Coastguard Worker     uint32_t param = *(uint32_t*)pParam;
424*ec779b8eSAndroid Build Coastguard Worker     float valueFloat = 0.f;
425*ec779b8eSAndroid Build Coastguard Worker     agc2_settings_t* pProperties = (agc2_settings_t*)pValue;
426*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
427*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
428*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_FIXED_DIGITAL_GAIN:
429*ec779b8eSAndroid Build Coastguard Worker             valueFloat = (float)(*(int32_t*)pValue);
430*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Agc2SetParameter() fixed digital gain %f dB", valueFloat);
431*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.gain_controller2.fixed_digital.gain_db = valueFloat;
432*ec779b8eSAndroid Build Coastguard Worker             break;
433*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_ADAPT_DIGI_LEVEL_ESTIMATOR:
434*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Agc2SetParameter() level estimator %d", *(uint32_t*)pValue);
435*ec779b8eSAndroid Build Coastguard Worker             if (*(uint32_t*)pValue != 0) {
436*ec779b8eSAndroid Build Coastguard Worker               // only RMS is supported
437*ec779b8eSAndroid Build Coastguard Worker               status = -EINVAL;
438*ec779b8eSAndroid Build Coastguard Worker             }
439*ec779b8eSAndroid Build Coastguard Worker             break;
440*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_ADAPT_DIGI_EXTRA_SATURATION_MARGIN:
441*ec779b8eSAndroid Build Coastguard Worker             valueFloat = (float)(*(int32_t*)pValue);
442*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Agc2SetParameter() extra saturation margin %f dB", valueFloat);
443*ec779b8eSAndroid Build Coastguard Worker             if (valueFloat != 2.0) {
444*ec779b8eSAndroid Build Coastguard Worker               // extra_staturation_margin_db is no longer configurable in webrtc
445*ec779b8eSAndroid Build Coastguard Worker               status = -EINVAL;
446*ec779b8eSAndroid Build Coastguard Worker             }
447*ec779b8eSAndroid Build Coastguard Worker             break;
448*ec779b8eSAndroid Build Coastguard Worker         case AGC2_PARAM_PROPERTIES:
449*ec779b8eSAndroid Build Coastguard Worker             ALOGV("Agc2SetParameter() properties gain %f, level %d margin %f",
450*ec779b8eSAndroid Build Coastguard Worker                   pProperties->fixedDigitalGain, pProperties->level_estimator,
451*ec779b8eSAndroid Build Coastguard Worker                   pProperties->extraSaturationMargin);
452*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.gain_controller2.fixed_digital.gain_db =
453*ec779b8eSAndroid Build Coastguard Worker                     pProperties->fixedDigitalGain;
454*ec779b8eSAndroid Build Coastguard Worker             if (pProperties->level_estimator != 0 || pProperties->extraSaturationMargin != 2.0) {
455*ec779b8eSAndroid Build Coastguard Worker               status = -EINVAL;
456*ec779b8eSAndroid Build Coastguard Worker             }
457*ec779b8eSAndroid Build Coastguard Worker             break;
458*ec779b8eSAndroid Build Coastguard Worker         default:
459*ec779b8eSAndroid Build Coastguard Worker             ALOGW("Agc2SetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
460*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
461*ec779b8eSAndroid Build Coastguard Worker             break;
462*ec779b8eSAndroid Build Coastguard Worker     }
463*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
464*ec779b8eSAndroid Build Coastguard Worker 
465*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Agc2SetParameter() done status %d", status);
466*ec779b8eSAndroid Build Coastguard Worker 
467*ec779b8eSAndroid Build Coastguard Worker     return status;
468*ec779b8eSAndroid Build Coastguard Worker }
469*ec779b8eSAndroid Build Coastguard Worker 
AgcSetParameter(preproc_effect_t * effect,void * pParam,void * pValue)470*ec779b8eSAndroid Build Coastguard Worker int AgcSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
471*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
472*ec779b8eSAndroid Build Coastguard Worker     uint32_t param = *(uint32_t*)pParam;
473*ec779b8eSAndroid Build Coastguard Worker     t_agc_settings* pProperties = (t_agc_settings*)pValue;
474*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
475*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
476*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_TARGET_LEVEL:
477*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AgcSetParameter() target level %d milliBels", *(int16_t*)pValue);
478*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.gain_controller1.target_level_dbfs =
479*ec779b8eSAndroid Build Coastguard Worker                     (-(*(int16_t*)pValue / 100));
480*ec779b8eSAndroid Build Coastguard Worker             break;
481*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_COMP_GAIN:
482*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t*)pValue);
483*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.gain_controller1.compression_gain_db =
484*ec779b8eSAndroid Build Coastguard Worker                     (*(int16_t*)pValue / 100);
485*ec779b8eSAndroid Build Coastguard Worker             break;
486*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_LIMITER_ENA:
487*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AgcSetParameter() limiter enabled %s", *(bool*)pValue ? "true" : "false");
488*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.gain_controller1.enable_limiter = (*(bool*)pValue);
489*ec779b8eSAndroid Build Coastguard Worker             break;
490*ec779b8eSAndroid Build Coastguard Worker         case AGC_PARAM_PROPERTIES:
491*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AgcSetParameter() properties level %d, gain %d limiter %d",
492*ec779b8eSAndroid Build Coastguard Worker                   pProperties->targetLevel, pProperties->compGain, pProperties->limiterEnabled);
493*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.gain_controller1.target_level_dbfs =
494*ec779b8eSAndroid Build Coastguard Worker                     -(pProperties->targetLevel / 100);
495*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.gain_controller1.compression_gain_db =
496*ec779b8eSAndroid Build Coastguard Worker                     pProperties->compGain / 100;
497*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.gain_controller1.enable_limiter = pProperties->limiterEnabled;
498*ec779b8eSAndroid Build Coastguard Worker             break;
499*ec779b8eSAndroid Build Coastguard Worker         default:
500*ec779b8eSAndroid Build Coastguard Worker             ALOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
501*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
502*ec779b8eSAndroid Build Coastguard Worker             break;
503*ec779b8eSAndroid Build Coastguard Worker     }
504*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
505*ec779b8eSAndroid Build Coastguard Worker 
506*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AgcSetParameter() done status %d", status);
507*ec779b8eSAndroid Build Coastguard Worker 
508*ec779b8eSAndroid Build Coastguard Worker     return status;
509*ec779b8eSAndroid Build Coastguard Worker }
510*ec779b8eSAndroid Build Coastguard Worker 
Agc2Enable(preproc_effect_t * effect)511*ec779b8eSAndroid Build Coastguard Worker void Agc2Enable(preproc_effect_t* effect) {
512*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
513*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.gain_controller2.enabled = true;
514*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
515*ec779b8eSAndroid Build Coastguard Worker }
516*ec779b8eSAndroid Build Coastguard Worker 
AgcEnable(preproc_effect_t * effect)517*ec779b8eSAndroid Build Coastguard Worker void AgcEnable(preproc_effect_t* effect) {
518*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
519*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.gain_controller1.enabled = true;
520*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
521*ec779b8eSAndroid Build Coastguard Worker }
522*ec779b8eSAndroid Build Coastguard Worker 
Agc2Disable(preproc_effect_t * effect)523*ec779b8eSAndroid Build Coastguard Worker void Agc2Disable(preproc_effect_t* effect) {
524*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
525*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.gain_controller2.enabled = false;
526*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
527*ec779b8eSAndroid Build Coastguard Worker }
528*ec779b8eSAndroid Build Coastguard Worker 
AgcDisable(preproc_effect_t * effect)529*ec779b8eSAndroid Build Coastguard Worker void AgcDisable(preproc_effect_t* effect) {
530*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
531*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.gain_controller1.enabled = false;
532*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
533*ec779b8eSAndroid Build Coastguard Worker }
534*ec779b8eSAndroid Build Coastguard Worker 
535*ec779b8eSAndroid Build Coastguard Worker static const preproc_ops_t sAgcOps = {AgcCreate,       AgcInit,         NULL, AgcEnable, AgcDisable,
536*ec779b8eSAndroid Build Coastguard Worker                                       AgcSetParameter, AgcGetParameter, NULL};
537*ec779b8eSAndroid Build Coastguard Worker 
538*ec779b8eSAndroid Build Coastguard Worker static const preproc_ops_t sAgc2Ops = {Agc2Create,       Agc2Init,    NULL,
539*ec779b8eSAndroid Build Coastguard Worker                                        Agc2Enable,       Agc2Disable, Agc2SetParameter,
540*ec779b8eSAndroid Build Coastguard Worker                                        Agc2GetParameter, NULL};
541*ec779b8eSAndroid Build Coastguard Worker 
542*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
543*ec779b8eSAndroid Build Coastguard Worker // Acoustic Echo Canceler (AEC)
544*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
545*ec779b8eSAndroid Build Coastguard Worker 
546*ec779b8eSAndroid Build Coastguard Worker 
AecInit(preproc_effect_t * effect)547*ec779b8eSAndroid Build Coastguard Worker int AecInit(preproc_effect_t* effect) {
548*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AecInit");
549*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
550*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.echo_canceller.mobile_mode = true;
551*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
552*ec779b8eSAndroid Build Coastguard Worker     return 0;
553*ec779b8eSAndroid Build Coastguard Worker }
554*ec779b8eSAndroid Build Coastguard Worker 
AecCreate(preproc_effect_t * effect)555*ec779b8eSAndroid Build Coastguard Worker int AecCreate(preproc_effect_t* effect) {
556*ec779b8eSAndroid Build Coastguard Worker     AecInit(effect);
557*ec779b8eSAndroid Build Coastguard Worker     return 0;
558*ec779b8eSAndroid Build Coastguard Worker }
559*ec779b8eSAndroid Build Coastguard Worker 
AecGetParameter(preproc_effect_t * effect,void * pParam,uint32_t * pValueSize,void * pValue)560*ec779b8eSAndroid Build Coastguard Worker int AecGetParameter(preproc_effect_t* effect, void* pParam, uint32_t* pValueSize, void* pValue) {
561*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
562*ec779b8eSAndroid Build Coastguard Worker     uint32_t param = *(uint32_t*)pParam;
563*ec779b8eSAndroid Build Coastguard Worker 
564*ec779b8eSAndroid Build Coastguard Worker     if (*pValueSize < sizeof(uint32_t)) {
565*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
566*ec779b8eSAndroid Build Coastguard Worker     }
567*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
568*ec779b8eSAndroid Build Coastguard Worker         case AEC_PARAM_ECHO_DELAY:
569*ec779b8eSAndroid Build Coastguard Worker         case AEC_PARAM_PROPERTIES:
570*ec779b8eSAndroid Build Coastguard Worker             *(uint32_t*)pValue = 1000 * effect->session->apm->stream_delay_ms();
571*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AecGetParameter() echo delay %d us", *(uint32_t*)pValue);
572*ec779b8eSAndroid Build Coastguard Worker             break;
573*ec779b8eSAndroid Build Coastguard Worker         case AEC_PARAM_MOBILE_MODE:
574*ec779b8eSAndroid Build Coastguard Worker             effect->session->config = effect->session->apm->GetConfig();
575*ec779b8eSAndroid Build Coastguard Worker             *(uint32_t*)pValue = effect->session->config.echo_canceller.mobile_mode;
576*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AecGetParameter() mobile mode %d us", *(uint32_t*)pValue);
577*ec779b8eSAndroid Build Coastguard Worker             break;
578*ec779b8eSAndroid Build Coastguard Worker         default:
579*ec779b8eSAndroid Build Coastguard Worker             ALOGW("AecGetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
580*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
581*ec779b8eSAndroid Build Coastguard Worker             break;
582*ec779b8eSAndroid Build Coastguard Worker     }
583*ec779b8eSAndroid Build Coastguard Worker     return status;
584*ec779b8eSAndroid Build Coastguard Worker }
585*ec779b8eSAndroid Build Coastguard Worker 
AecSetParameter(preproc_effect_t * effect,void * pParam,void * pValue)586*ec779b8eSAndroid Build Coastguard Worker int AecSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
587*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
588*ec779b8eSAndroid Build Coastguard Worker     uint32_t param = *(uint32_t*)pParam;
589*ec779b8eSAndroid Build Coastguard Worker     uint32_t value = *(uint32_t*)pValue;
590*ec779b8eSAndroid Build Coastguard Worker 
591*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
592*ec779b8eSAndroid Build Coastguard Worker         case AEC_PARAM_ECHO_DELAY:
593*ec779b8eSAndroid Build Coastguard Worker         case AEC_PARAM_PROPERTIES:
594*ec779b8eSAndroid Build Coastguard Worker             status = effect->session->apm->set_stream_delay_ms(value / 1000);
595*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AecSetParameter() echo delay %d us, status %d", value, status);
596*ec779b8eSAndroid Build Coastguard Worker             break;
597*ec779b8eSAndroid Build Coastguard Worker         case AEC_PARAM_MOBILE_MODE:
598*ec779b8eSAndroid Build Coastguard Worker             effect->session->config = effect->session->apm->GetConfig();
599*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.echo_canceller.mobile_mode = value;
600*ec779b8eSAndroid Build Coastguard Worker             ALOGV("AecSetParameter() mobile mode %d us", value);
601*ec779b8eSAndroid Build Coastguard Worker             effect->session->apm->ApplyConfig(effect->session->config);
602*ec779b8eSAndroid Build Coastguard Worker             break;
603*ec779b8eSAndroid Build Coastguard Worker         default:
604*ec779b8eSAndroid Build Coastguard Worker             ALOGW("AecSetParameter() unknown param %08x value %08x", param, *(uint32_t*)pValue);
605*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
606*ec779b8eSAndroid Build Coastguard Worker             break;
607*ec779b8eSAndroid Build Coastguard Worker     }
608*ec779b8eSAndroid Build Coastguard Worker     return status;
609*ec779b8eSAndroid Build Coastguard Worker }
610*ec779b8eSAndroid Build Coastguard Worker 
AecEnable(preproc_effect_t * effect)611*ec779b8eSAndroid Build Coastguard Worker void AecEnable(preproc_effect_t* effect) {
612*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
613*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.echo_canceller.enabled = true;
614*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
615*ec779b8eSAndroid Build Coastguard Worker }
616*ec779b8eSAndroid Build Coastguard Worker 
AecDisable(preproc_effect_t * effect)617*ec779b8eSAndroid Build Coastguard Worker void AecDisable(preproc_effect_t* effect) {
618*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
619*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.echo_canceller.enabled = false;
620*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
621*ec779b8eSAndroid Build Coastguard Worker }
622*ec779b8eSAndroid Build Coastguard Worker 
AecSetDevice(preproc_effect_t * effect,uint32_t device)623*ec779b8eSAndroid Build Coastguard Worker int AecSetDevice(preproc_effect_t* effect, uint32_t device) {
624*ec779b8eSAndroid Build Coastguard Worker     ALOGV("AecSetDevice %08x", device);
625*ec779b8eSAndroid Build Coastguard Worker 
626*ec779b8eSAndroid Build Coastguard Worker     if (audio_is_input_device(device)) {
627*ec779b8eSAndroid Build Coastguard Worker         return 0;
628*ec779b8eSAndroid Build Coastguard Worker     }
629*ec779b8eSAndroid Build Coastguard Worker 
630*ec779b8eSAndroid Build Coastguard Worker     return 0;
631*ec779b8eSAndroid Build Coastguard Worker }
632*ec779b8eSAndroid Build Coastguard Worker 
633*ec779b8eSAndroid Build Coastguard Worker static const preproc_ops_t sAecOps = {AecCreate,       AecInit,     NULL,
634*ec779b8eSAndroid Build Coastguard Worker                                       AecEnable,       AecDisable,  AecSetParameter,
635*ec779b8eSAndroid Build Coastguard Worker                                       AecGetParameter, AecSetDevice};
636*ec779b8eSAndroid Build Coastguard Worker 
637*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
638*ec779b8eSAndroid Build Coastguard Worker // Noise Suppression (NS)
639*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
640*ec779b8eSAndroid Build Coastguard Worker 
641*ec779b8eSAndroid Build Coastguard Worker static const webrtc::AudioProcessing::Config::NoiseSuppression::Level kNsDefaultLevel =
642*ec779b8eSAndroid Build Coastguard Worker         webrtc::AudioProcessing::Config::NoiseSuppression::kModerate;
643*ec779b8eSAndroid Build Coastguard Worker 
NsInit(preproc_effect_t * effect)644*ec779b8eSAndroid Build Coastguard Worker int NsInit(preproc_effect_t* effect) {
645*ec779b8eSAndroid Build Coastguard Worker     ALOGV("NsInit");
646*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
647*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.noise_suppression.level = kNsDefaultLevel;
648*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
649*ec779b8eSAndroid Build Coastguard Worker     effect->type = NS_TYPE_SINGLE_CHANNEL;
650*ec779b8eSAndroid Build Coastguard Worker     return 0;
651*ec779b8eSAndroid Build Coastguard Worker }
652*ec779b8eSAndroid Build Coastguard Worker 
NsCreate(preproc_effect_t * effect)653*ec779b8eSAndroid Build Coastguard Worker int NsCreate(preproc_effect_t* effect) {
654*ec779b8eSAndroid Build Coastguard Worker     NsInit(effect);
655*ec779b8eSAndroid Build Coastguard Worker     return 0;
656*ec779b8eSAndroid Build Coastguard Worker }
657*ec779b8eSAndroid Build Coastguard Worker 
NsGetParameter(preproc_effect_t *,void *,uint32_t *,void *)658*ec779b8eSAndroid Build Coastguard Worker int NsGetParameter(preproc_effect_t* /*effect __unused*/, void* /*pParam __unused*/,
659*ec779b8eSAndroid Build Coastguard Worker                    uint32_t* /*pValueSize __unused*/, void* /*pValue __unused*/) {
660*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
661*ec779b8eSAndroid Build Coastguard Worker     return status;
662*ec779b8eSAndroid Build Coastguard Worker }
663*ec779b8eSAndroid Build Coastguard Worker 
NsSetParameter(preproc_effect_t * effect,void * pParam,void * pValue)664*ec779b8eSAndroid Build Coastguard Worker int NsSetParameter(preproc_effect_t* effect, void* pParam, void* pValue) {
665*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
666*ec779b8eSAndroid Build Coastguard Worker     uint32_t param = *(uint32_t*)pParam;
667*ec779b8eSAndroid Build Coastguard Worker     uint32_t value = *(uint32_t*)pValue;
668*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
669*ec779b8eSAndroid Build Coastguard Worker     switch (param) {
670*ec779b8eSAndroid Build Coastguard Worker         case NS_PARAM_LEVEL:
671*ec779b8eSAndroid Build Coastguard Worker             effect->session->config.noise_suppression.level =
672*ec779b8eSAndroid Build Coastguard Worker                     (webrtc::AudioProcessing::Config::NoiseSuppression::Level)value;
673*ec779b8eSAndroid Build Coastguard Worker             ALOGV("NsSetParameter() level %d", value);
674*ec779b8eSAndroid Build Coastguard Worker             break;
675*ec779b8eSAndroid Build Coastguard Worker         default:
676*ec779b8eSAndroid Build Coastguard Worker             ALOGW("NsSetParameter() unknown param %08x value %08x", param, value);
677*ec779b8eSAndroid Build Coastguard Worker             status = -EINVAL;
678*ec779b8eSAndroid Build Coastguard Worker     }
679*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
680*ec779b8eSAndroid Build Coastguard Worker 
681*ec779b8eSAndroid Build Coastguard Worker     return status;
682*ec779b8eSAndroid Build Coastguard Worker }
683*ec779b8eSAndroid Build Coastguard Worker 
NsEnable(preproc_effect_t * effect)684*ec779b8eSAndroid Build Coastguard Worker void NsEnable(preproc_effect_t* effect) {
685*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
686*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.noise_suppression.enabled = true;
687*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
688*ec779b8eSAndroid Build Coastguard Worker }
689*ec779b8eSAndroid Build Coastguard Worker 
NsDisable(preproc_effect_t * effect)690*ec779b8eSAndroid Build Coastguard Worker void NsDisable(preproc_effect_t* effect) {
691*ec779b8eSAndroid Build Coastguard Worker     ALOGV("NsDisable");
692*ec779b8eSAndroid Build Coastguard Worker     effect->session->config = effect->session->apm->GetConfig();
693*ec779b8eSAndroid Build Coastguard Worker     effect->session->config.noise_suppression.enabled = false;
694*ec779b8eSAndroid Build Coastguard Worker     effect->session->apm->ApplyConfig(effect->session->config);
695*ec779b8eSAndroid Build Coastguard Worker }
696*ec779b8eSAndroid Build Coastguard Worker 
697*ec779b8eSAndroid Build Coastguard Worker static const preproc_ops_t sNsOps = {NsCreate,  NsInit,         NULL,           NsEnable,
698*ec779b8eSAndroid Build Coastguard Worker                                      NsDisable, NsSetParameter, NsGetParameter, NULL};
699*ec779b8eSAndroid Build Coastguard Worker 
700*ec779b8eSAndroid Build Coastguard Worker static const preproc_ops_t* sPreProcOps[PREPROC_NUM_EFFECTS] = {&sAgcOps,
701*ec779b8eSAndroid Build Coastguard Worker                                                                 &sAgc2Ops,
702*ec779b8eSAndroid Build Coastguard Worker                                                                 &sAecOps, &sNsOps};
703*ec779b8eSAndroid Build Coastguard Worker 
704*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
705*ec779b8eSAndroid Build Coastguard Worker // Effect functions
706*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
707*ec779b8eSAndroid Build Coastguard Worker 
708*ec779b8eSAndroid Build Coastguard Worker void Session_SetProcEnabled(preproc_session_t* session, uint32_t procId, bool enabled);
709*ec779b8eSAndroid Build Coastguard Worker 
710*ec779b8eSAndroid Build Coastguard Worker extern "C" const struct effect_interface_s sEffectInterface;
711*ec779b8eSAndroid Build Coastguard Worker extern "C" const struct effect_interface_s sEffectInterfaceReverse;
712*ec779b8eSAndroid Build Coastguard Worker 
713*ec779b8eSAndroid Build Coastguard Worker #define BAD_STATE_ABORT(from, to) LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to);
714*ec779b8eSAndroid Build Coastguard Worker 
Effect_SetState(preproc_effect_t * effect,uint32_t state)715*ec779b8eSAndroid Build Coastguard Worker int Effect_SetState(preproc_effect_t* effect, uint32_t state) {
716*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
717*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Effect_SetState proc %d, new %d old %d", effect->procId, state, effect->state);
718*ec779b8eSAndroid Build Coastguard Worker     switch (state) {
719*ec779b8eSAndroid Build Coastguard Worker         case PREPROC_EFFECT_STATE_INIT:
720*ec779b8eSAndroid Build Coastguard Worker             switch (effect->state) {
721*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_ACTIVE:
722*ec779b8eSAndroid Build Coastguard Worker                     effect->ops->disable(effect);
723*ec779b8eSAndroid Build Coastguard Worker                     Session_SetProcEnabled(effect->session, effect->procId, false);
724*ec779b8eSAndroid Build Coastguard Worker                     break;
725*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_CONFIG:
726*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_CREATED:
727*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_INIT:
728*ec779b8eSAndroid Build Coastguard Worker                     break;
729*ec779b8eSAndroid Build Coastguard Worker                 default:
730*ec779b8eSAndroid Build Coastguard Worker                     BAD_STATE_ABORT(effect->state, state);
731*ec779b8eSAndroid Build Coastguard Worker             }
732*ec779b8eSAndroid Build Coastguard Worker             break;
733*ec779b8eSAndroid Build Coastguard Worker         case PREPROC_EFFECT_STATE_CREATED:
734*ec779b8eSAndroid Build Coastguard Worker             switch (effect->state) {
735*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_INIT:
736*ec779b8eSAndroid Build Coastguard Worker                     status = effect->ops->create(effect);
737*ec779b8eSAndroid Build Coastguard Worker                     break;
738*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_CREATED:
739*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_ACTIVE:
740*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_CONFIG:
741*ec779b8eSAndroid Build Coastguard Worker                     ALOGE("Effect_SetState invalid transition");
742*ec779b8eSAndroid Build Coastguard Worker                     status = -ENOSYS;
743*ec779b8eSAndroid Build Coastguard Worker                     break;
744*ec779b8eSAndroid Build Coastguard Worker                 default:
745*ec779b8eSAndroid Build Coastguard Worker                     BAD_STATE_ABORT(effect->state, state);
746*ec779b8eSAndroid Build Coastguard Worker             }
747*ec779b8eSAndroid Build Coastguard Worker             break;
748*ec779b8eSAndroid Build Coastguard Worker         case PREPROC_EFFECT_STATE_CONFIG:
749*ec779b8eSAndroid Build Coastguard Worker             switch (effect->state) {
750*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_INIT:
751*ec779b8eSAndroid Build Coastguard Worker                     ALOGE("Effect_SetState invalid transition");
752*ec779b8eSAndroid Build Coastguard Worker                     status = -ENOSYS;
753*ec779b8eSAndroid Build Coastguard Worker                     break;
754*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_ACTIVE:
755*ec779b8eSAndroid Build Coastguard Worker                     effect->ops->disable(effect);
756*ec779b8eSAndroid Build Coastguard Worker                     Session_SetProcEnabled(effect->session, effect->procId, false);
757*ec779b8eSAndroid Build Coastguard Worker                     break;
758*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_CREATED:
759*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_CONFIG:
760*ec779b8eSAndroid Build Coastguard Worker                     break;
761*ec779b8eSAndroid Build Coastguard Worker                 default:
762*ec779b8eSAndroid Build Coastguard Worker                     BAD_STATE_ABORT(effect->state, state);
763*ec779b8eSAndroid Build Coastguard Worker             }
764*ec779b8eSAndroid Build Coastguard Worker             break;
765*ec779b8eSAndroid Build Coastguard Worker         case PREPROC_EFFECT_STATE_ACTIVE:
766*ec779b8eSAndroid Build Coastguard Worker             switch (effect->state) {
767*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_INIT:
768*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_CREATED:
769*ec779b8eSAndroid Build Coastguard Worker                     ALOGE("Effect_SetState invalid transition");
770*ec779b8eSAndroid Build Coastguard Worker                     status = -ENOSYS;
771*ec779b8eSAndroid Build Coastguard Worker                     break;
772*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_ACTIVE:
773*ec779b8eSAndroid Build Coastguard Worker                     // enabling an already enabled effect is just ignored
774*ec779b8eSAndroid Build Coastguard Worker                     break;
775*ec779b8eSAndroid Build Coastguard Worker                 case PREPROC_EFFECT_STATE_CONFIG:
776*ec779b8eSAndroid Build Coastguard Worker                     effect->ops->enable(effect);
777*ec779b8eSAndroid Build Coastguard Worker                     Session_SetProcEnabled(effect->session, effect->procId, true);
778*ec779b8eSAndroid Build Coastguard Worker                     break;
779*ec779b8eSAndroid Build Coastguard Worker                 default:
780*ec779b8eSAndroid Build Coastguard Worker                     BAD_STATE_ABORT(effect->state, state);
781*ec779b8eSAndroid Build Coastguard Worker             }
782*ec779b8eSAndroid Build Coastguard Worker             break;
783*ec779b8eSAndroid Build Coastguard Worker         default:
784*ec779b8eSAndroid Build Coastguard Worker             BAD_STATE_ABORT(effect->state, state);
785*ec779b8eSAndroid Build Coastguard Worker     }
786*ec779b8eSAndroid Build Coastguard Worker     if (status == 0) {
787*ec779b8eSAndroid Build Coastguard Worker         effect->state = state;
788*ec779b8eSAndroid Build Coastguard Worker     }
789*ec779b8eSAndroid Build Coastguard Worker     return status;
790*ec779b8eSAndroid Build Coastguard Worker }
791*ec779b8eSAndroid Build Coastguard Worker 
Effect_Init(preproc_effect_t * effect,uint32_t procId)792*ec779b8eSAndroid Build Coastguard Worker int Effect_Init(preproc_effect_t* effect, uint32_t procId) {
793*ec779b8eSAndroid Build Coastguard Worker     if (HasReverseStream(procId)) {
794*ec779b8eSAndroid Build Coastguard Worker         effect->itfe = &sEffectInterfaceReverse;
795*ec779b8eSAndroid Build Coastguard Worker     } else {
796*ec779b8eSAndroid Build Coastguard Worker         effect->itfe = &sEffectInterface;
797*ec779b8eSAndroid Build Coastguard Worker     }
798*ec779b8eSAndroid Build Coastguard Worker     effect->ops = sPreProcOps[procId];
799*ec779b8eSAndroid Build Coastguard Worker     effect->procId = procId;
800*ec779b8eSAndroid Build Coastguard Worker     effect->state = PREPROC_EFFECT_STATE_INIT;
801*ec779b8eSAndroid Build Coastguard Worker     return 0;
802*ec779b8eSAndroid Build Coastguard Worker }
803*ec779b8eSAndroid Build Coastguard Worker 
Effect_Create(preproc_effect_t * effect,preproc_session_t * session,effect_handle_t * interface)804*ec779b8eSAndroid Build Coastguard Worker int Effect_Create(preproc_effect_t* effect, preproc_session_t* session,
805*ec779b8eSAndroid Build Coastguard Worker                   effect_handle_t* interface) {
806*ec779b8eSAndroid Build Coastguard Worker     effect->session = session;
807*ec779b8eSAndroid Build Coastguard Worker     *interface = (effect_handle_t)&effect->itfe;
808*ec779b8eSAndroid Build Coastguard Worker     return Effect_SetState(effect, PREPROC_EFFECT_STATE_CREATED);
809*ec779b8eSAndroid Build Coastguard Worker }
810*ec779b8eSAndroid Build Coastguard Worker 
Effect_Release(preproc_effect_t * effect)811*ec779b8eSAndroid Build Coastguard Worker int Effect_Release(preproc_effect_t* effect) {
812*ec779b8eSAndroid Build Coastguard Worker     return Effect_SetState(effect, PREPROC_EFFECT_STATE_INIT);
813*ec779b8eSAndroid Build Coastguard Worker }
814*ec779b8eSAndroid Build Coastguard Worker 
815*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
816*ec779b8eSAndroid Build Coastguard Worker // Session functions
817*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
818*ec779b8eSAndroid Build Coastguard Worker 
819*ec779b8eSAndroid Build Coastguard Worker #define RESAMPLER_QUALITY SPEEX_RESAMPLER_QUALITY_VOIP
820*ec779b8eSAndroid Build Coastguard Worker 
821*ec779b8eSAndroid Build Coastguard Worker static const int kPreprocDefaultSr = 16000;
822*ec779b8eSAndroid Build Coastguard Worker static const int kPreProcDefaultCnl = 1;
823*ec779b8eSAndroid Build Coastguard Worker 
Session_Init(preproc_session_t * session)824*ec779b8eSAndroid Build Coastguard Worker int Session_Init(preproc_session_t* session) {
825*ec779b8eSAndroid Build Coastguard Worker     size_t i;
826*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
827*ec779b8eSAndroid Build Coastguard Worker 
828*ec779b8eSAndroid Build Coastguard Worker     session->state = PREPROC_SESSION_STATE_INIT;
829*ec779b8eSAndroid Build Coastguard Worker     session->id = 0;
830*ec779b8eSAndroid Build Coastguard Worker     session->io = 0;
831*ec779b8eSAndroid Build Coastguard Worker     session->createdMsk = 0;
832*ec779b8eSAndroid Build Coastguard Worker     for (i = 0; i < PREPROC_NUM_EFFECTS && status == 0; i++) {
833*ec779b8eSAndroid Build Coastguard Worker         status = Effect_Init(&session->effects[i], i);
834*ec779b8eSAndroid Build Coastguard Worker     }
835*ec779b8eSAndroid Build Coastguard Worker     return status;
836*ec779b8eSAndroid Build Coastguard Worker }
837*ec779b8eSAndroid Build Coastguard Worker 
Session_CreateEffect(preproc_session_t * session,int32_t procId,effect_handle_t * interface)838*ec779b8eSAndroid Build Coastguard Worker extern "C" int Session_CreateEffect(preproc_session_t* session, int32_t procId,
839*ec779b8eSAndroid Build Coastguard Worker                                     effect_handle_t* interface) {
840*ec779b8eSAndroid Build Coastguard Worker     int status = -ENOMEM;
841*ec779b8eSAndroid Build Coastguard Worker 
842*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Session_CreateEffect procId %d, createdMsk %08x", procId, session->createdMsk);
843*ec779b8eSAndroid Build Coastguard Worker 
844*ec779b8eSAndroid Build Coastguard Worker     if (session->createdMsk == 0) {
845*ec779b8eSAndroid Build Coastguard Worker         session->apm = session->ap_builder.Create();
846*ec779b8eSAndroid Build Coastguard Worker         if (session->apm == NULL) {
847*ec779b8eSAndroid Build Coastguard Worker             ALOGW("Session_CreateEffect could not get apm engine");
848*ec779b8eSAndroid Build Coastguard Worker             goto error;
849*ec779b8eSAndroid Build Coastguard Worker         }
850*ec779b8eSAndroid Build Coastguard Worker         session->frameCount = kPreprocDefaultSr / 100;
851*ec779b8eSAndroid Build Coastguard Worker         session->samplingRate = kPreprocDefaultSr;
852*ec779b8eSAndroid Build Coastguard Worker         session->inChannelCount = kPreProcDefaultCnl;
853*ec779b8eSAndroid Build Coastguard Worker         session->outChannelCount = kPreProcDefaultCnl;
854*ec779b8eSAndroid Build Coastguard Worker         session->inputConfig.set_sample_rate_hz(kPreprocDefaultSr);
855*ec779b8eSAndroid Build Coastguard Worker         session->inputConfig.set_num_channels(kPreProcDefaultCnl);
856*ec779b8eSAndroid Build Coastguard Worker         session->outputConfig.set_sample_rate_hz(kPreprocDefaultSr);
857*ec779b8eSAndroid Build Coastguard Worker         session->outputConfig.set_num_channels(kPreProcDefaultCnl);
858*ec779b8eSAndroid Build Coastguard Worker         session->revChannelCount = kPreProcDefaultCnl;
859*ec779b8eSAndroid Build Coastguard Worker         session->revConfig.set_sample_rate_hz(kPreprocDefaultSr);
860*ec779b8eSAndroid Build Coastguard Worker         session->revConfig.set_num_channels(kPreProcDefaultCnl);
861*ec779b8eSAndroid Build Coastguard Worker         session->enabledMsk = 0;
862*ec779b8eSAndroid Build Coastguard Worker         session->processedMsk = 0;
863*ec779b8eSAndroid Build Coastguard Worker         session->revEnabledMsk = 0;
864*ec779b8eSAndroid Build Coastguard Worker         session->revProcessedMsk = 0;
865*ec779b8eSAndroid Build Coastguard Worker     }
866*ec779b8eSAndroid Build Coastguard Worker     status = Effect_Create(&session->effects[procId], session, interface);
867*ec779b8eSAndroid Build Coastguard Worker     if (status < 0) {
868*ec779b8eSAndroid Build Coastguard Worker         goto error;
869*ec779b8eSAndroid Build Coastguard Worker     }
870*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Session_CreateEffect OK");
871*ec779b8eSAndroid Build Coastguard Worker     session->createdMsk |= (1 << procId);
872*ec779b8eSAndroid Build Coastguard Worker     return status;
873*ec779b8eSAndroid Build Coastguard Worker 
874*ec779b8eSAndroid Build Coastguard Worker error:
875*ec779b8eSAndroid Build Coastguard Worker     if (session->createdMsk == 0) {
876*ec779b8eSAndroid Build Coastguard Worker         // Scoped_refptr will handle reference counting here
877*ec779b8eSAndroid Build Coastguard Worker         session->apm = nullptr;
878*ec779b8eSAndroid Build Coastguard Worker     }
879*ec779b8eSAndroid Build Coastguard Worker     return status;
880*ec779b8eSAndroid Build Coastguard Worker }
881*ec779b8eSAndroid Build Coastguard Worker 
Session_ReleaseEffect(preproc_session_t * session,preproc_effect_t * fx)882*ec779b8eSAndroid Build Coastguard Worker int Session_ReleaseEffect(preproc_session_t* session, preproc_effect_t* fx) {
883*ec779b8eSAndroid Build Coastguard Worker     ALOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId);
884*ec779b8eSAndroid Build Coastguard Worker     session->createdMsk &= ~(1 << fx->procId);
885*ec779b8eSAndroid Build Coastguard Worker     if (session->createdMsk == 0) {
886*ec779b8eSAndroid Build Coastguard Worker         // Scoped_refptr will handle reference counting here
887*ec779b8eSAndroid Build Coastguard Worker         session->apm = nullptr;
888*ec779b8eSAndroid Build Coastguard Worker         session->id = 0;
889*ec779b8eSAndroid Build Coastguard Worker     }
890*ec779b8eSAndroid Build Coastguard Worker 
891*ec779b8eSAndroid Build Coastguard Worker     return 0;
892*ec779b8eSAndroid Build Coastguard Worker }
893*ec779b8eSAndroid Build Coastguard Worker 
Session_SetConfig(preproc_session_t * session,effect_config_t * config)894*ec779b8eSAndroid Build Coastguard Worker int Session_SetConfig(preproc_session_t* session, effect_config_t* config) {
895*ec779b8eSAndroid Build Coastguard Worker     uint32_t inCnl = audio_channel_count_from_in_mask(config->inputCfg.channels);
896*ec779b8eSAndroid Build Coastguard Worker     uint32_t outCnl = audio_channel_count_from_in_mask(config->outputCfg.channels);
897*ec779b8eSAndroid Build Coastguard Worker 
898*ec779b8eSAndroid Build Coastguard Worker     if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
899*ec779b8eSAndroid Build Coastguard Worker         config->inputCfg.format != config->outputCfg.format ||
900*ec779b8eSAndroid Build Coastguard Worker         config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
901*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
902*ec779b8eSAndroid Build Coastguard Worker     }
903*ec779b8eSAndroid Build Coastguard Worker 
904*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Session_SetConfig sr %d cnl %08x", config->inputCfg.samplingRate,
905*ec779b8eSAndroid Build Coastguard Worker           config->inputCfg.channels);
906*ec779b8eSAndroid Build Coastguard Worker 
907*ec779b8eSAndroid Build Coastguard Worker     session->samplingRate = config->inputCfg.samplingRate;
908*ec779b8eSAndroid Build Coastguard Worker     session->frameCount = session->samplingRate / 100;
909*ec779b8eSAndroid Build Coastguard Worker     session->inChannelCount = inCnl;
910*ec779b8eSAndroid Build Coastguard Worker     session->outChannelCount = outCnl;
911*ec779b8eSAndroid Build Coastguard Worker     session->inputConfig.set_sample_rate_hz(session->samplingRate);
912*ec779b8eSAndroid Build Coastguard Worker     session->inputConfig.set_num_channels(inCnl);
913*ec779b8eSAndroid Build Coastguard Worker     session->outputConfig.set_sample_rate_hz(session->samplingRate);
914*ec779b8eSAndroid Build Coastguard Worker     session->outputConfig.set_num_channels(inCnl);
915*ec779b8eSAndroid Build Coastguard Worker 
916*ec779b8eSAndroid Build Coastguard Worker     session->revChannelCount = inCnl;
917*ec779b8eSAndroid Build Coastguard Worker     session->revConfig.set_sample_rate_hz(session->samplingRate);
918*ec779b8eSAndroid Build Coastguard Worker     session->revConfig.set_num_channels(inCnl);
919*ec779b8eSAndroid Build Coastguard Worker 
920*ec779b8eSAndroid Build Coastguard Worker     session->state = PREPROC_SESSION_STATE_CONFIG;
921*ec779b8eSAndroid Build Coastguard Worker     return 0;
922*ec779b8eSAndroid Build Coastguard Worker }
923*ec779b8eSAndroid Build Coastguard Worker 
Session_GetConfig(preproc_session_t * session,effect_config_t * config)924*ec779b8eSAndroid Build Coastguard Worker void Session_GetConfig(preproc_session_t* session, effect_config_t* config) {
925*ec779b8eSAndroid Build Coastguard Worker     memset(config, 0, sizeof(effect_config_t));
926*ec779b8eSAndroid Build Coastguard Worker     config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
927*ec779b8eSAndroid Build Coastguard Worker     config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
928*ec779b8eSAndroid Build Coastguard Worker     config->inputCfg.channels = audio_channel_in_mask_from_count(session->inChannelCount);
929*ec779b8eSAndroid Build Coastguard Worker     // "out" doesn't mean output device, so this is the correct API to convert channel count to mask
930*ec779b8eSAndroid Build Coastguard Worker     config->outputCfg.channels = audio_channel_in_mask_from_count(session->outChannelCount);
931*ec779b8eSAndroid Build Coastguard Worker     config->inputCfg.mask = config->outputCfg.mask =
932*ec779b8eSAndroid Build Coastguard Worker             (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
933*ec779b8eSAndroid Build Coastguard Worker }
934*ec779b8eSAndroid Build Coastguard Worker 
Session_SetReverseConfig(preproc_session_t * session,effect_config_t * config)935*ec779b8eSAndroid Build Coastguard Worker int Session_SetReverseConfig(preproc_session_t* session, effect_config_t* config) {
936*ec779b8eSAndroid Build Coastguard Worker     if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
937*ec779b8eSAndroid Build Coastguard Worker         config->inputCfg.format != config->outputCfg.format ||
938*ec779b8eSAndroid Build Coastguard Worker         config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
939*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
940*ec779b8eSAndroid Build Coastguard Worker     }
941*ec779b8eSAndroid Build Coastguard Worker 
942*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Session_SetReverseConfig sr %d cnl %08x", config->inputCfg.samplingRate,
943*ec779b8eSAndroid Build Coastguard Worker           config->inputCfg.channels);
944*ec779b8eSAndroid Build Coastguard Worker 
945*ec779b8eSAndroid Build Coastguard Worker     if (session->state < PREPROC_SESSION_STATE_CONFIG) {
946*ec779b8eSAndroid Build Coastguard Worker         return -ENOSYS;
947*ec779b8eSAndroid Build Coastguard Worker     }
948*ec779b8eSAndroid Build Coastguard Worker     if (config->inputCfg.samplingRate != session->samplingRate ||
949*ec779b8eSAndroid Build Coastguard Worker         config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
950*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
951*ec779b8eSAndroid Build Coastguard Worker     }
952*ec779b8eSAndroid Build Coastguard Worker     uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels);
953*ec779b8eSAndroid Build Coastguard Worker     session->revChannelCount = inCnl;
954*ec779b8eSAndroid Build Coastguard Worker 
955*ec779b8eSAndroid Build Coastguard Worker     return 0;
956*ec779b8eSAndroid Build Coastguard Worker }
957*ec779b8eSAndroid Build Coastguard Worker 
Session_GetReverseConfig(preproc_session_t * session,effect_config_t * config)958*ec779b8eSAndroid Build Coastguard Worker void Session_GetReverseConfig(preproc_session_t* session, effect_config_t* config) {
959*ec779b8eSAndroid Build Coastguard Worker     memset(config, 0, sizeof(effect_config_t));
960*ec779b8eSAndroid Build Coastguard Worker     config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate;
961*ec779b8eSAndroid Build Coastguard Worker     config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
962*ec779b8eSAndroid Build Coastguard Worker     config->inputCfg.channels = config->outputCfg.channels =
963*ec779b8eSAndroid Build Coastguard Worker             audio_channel_in_mask_from_count(session->revChannelCount);
964*ec779b8eSAndroid Build Coastguard Worker     config->inputCfg.mask = config->outputCfg.mask =
965*ec779b8eSAndroid Build Coastguard Worker             (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT);
966*ec779b8eSAndroid Build Coastguard Worker }
967*ec779b8eSAndroid Build Coastguard Worker 
Session_SetProcEnabled(preproc_session_t * session,uint32_t procId,bool enabled)968*ec779b8eSAndroid Build Coastguard Worker void Session_SetProcEnabled(preproc_session_t* session, uint32_t procId, bool enabled) {
969*ec779b8eSAndroid Build Coastguard Worker     if (enabled) {
970*ec779b8eSAndroid Build Coastguard Worker         session->enabledMsk |= (1 << procId);
971*ec779b8eSAndroid Build Coastguard Worker         if (HasReverseStream(procId)) {
972*ec779b8eSAndroid Build Coastguard Worker             session->revEnabledMsk |= (1 << procId);
973*ec779b8eSAndroid Build Coastguard Worker         }
974*ec779b8eSAndroid Build Coastguard Worker     } else {
975*ec779b8eSAndroid Build Coastguard Worker         session->enabledMsk &= ~(1 << procId);
976*ec779b8eSAndroid Build Coastguard Worker         if (HasReverseStream(procId)) {
977*ec779b8eSAndroid Build Coastguard Worker             session->revEnabledMsk &= ~(1 << procId);
978*ec779b8eSAndroid Build Coastguard Worker         }
979*ec779b8eSAndroid Build Coastguard Worker     }
980*ec779b8eSAndroid Build Coastguard Worker     ALOGV("Session_SetProcEnabled proc %d, enabled %d enabledMsk %08x revEnabledMsk %08x", procId,
981*ec779b8eSAndroid Build Coastguard Worker           enabled, session->enabledMsk, session->revEnabledMsk);
982*ec779b8eSAndroid Build Coastguard Worker     session->processedMsk = 0;
983*ec779b8eSAndroid Build Coastguard Worker     if (HasReverseStream(procId)) {
984*ec779b8eSAndroid Build Coastguard Worker         session->revProcessedMsk = 0;
985*ec779b8eSAndroid Build Coastguard Worker     }
986*ec779b8eSAndroid Build Coastguard Worker }
987*ec779b8eSAndroid Build Coastguard Worker 
988*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
989*ec779b8eSAndroid Build Coastguard Worker // Bundle functions
990*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
991*ec779b8eSAndroid Build Coastguard Worker 
992*ec779b8eSAndroid Build Coastguard Worker static int sInitStatus = 1;
993*ec779b8eSAndroid Build Coastguard Worker static preproc_session_t sSessions[PREPROC_NUM_SESSIONS];
994*ec779b8eSAndroid Build Coastguard Worker 
PreProc_GetSession(int32_t procId,int32_t sessionId,int32_t ioId)995*ec779b8eSAndroid Build Coastguard Worker preproc_session_t* PreProc_GetSession(int32_t procId, int32_t sessionId, int32_t ioId) {
996*ec779b8eSAndroid Build Coastguard Worker     size_t i;
997*ec779b8eSAndroid Build Coastguard Worker     for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
998*ec779b8eSAndroid Build Coastguard Worker         if (sSessions[i].id == sessionId) {
999*ec779b8eSAndroid Build Coastguard Worker             if (sSessions[i].createdMsk & (1 << procId)) {
1000*ec779b8eSAndroid Build Coastguard Worker                 return NULL;
1001*ec779b8eSAndroid Build Coastguard Worker             }
1002*ec779b8eSAndroid Build Coastguard Worker             return &sSessions[i];
1003*ec779b8eSAndroid Build Coastguard Worker         }
1004*ec779b8eSAndroid Build Coastguard Worker     }
1005*ec779b8eSAndroid Build Coastguard Worker     for (i = 0; i < PREPROC_NUM_SESSIONS; i++) {
1006*ec779b8eSAndroid Build Coastguard Worker         if (sSessions[i].id == 0) {
1007*ec779b8eSAndroid Build Coastguard Worker             sSessions[i].id = sessionId;
1008*ec779b8eSAndroid Build Coastguard Worker             sSessions[i].io = ioId;
1009*ec779b8eSAndroid Build Coastguard Worker             return &sSessions[i];
1010*ec779b8eSAndroid Build Coastguard Worker         }
1011*ec779b8eSAndroid Build Coastguard Worker     }
1012*ec779b8eSAndroid Build Coastguard Worker     return NULL;
1013*ec779b8eSAndroid Build Coastguard Worker }
1014*ec779b8eSAndroid Build Coastguard Worker 
PreProc_Init()1015*ec779b8eSAndroid Build Coastguard Worker int PreProc_Init() {
1016*ec779b8eSAndroid Build Coastguard Worker     size_t i;
1017*ec779b8eSAndroid Build Coastguard Worker     int status = 0;
1018*ec779b8eSAndroid Build Coastguard Worker 
1019*ec779b8eSAndroid Build Coastguard Worker     if (sInitStatus <= 0) {
1020*ec779b8eSAndroid Build Coastguard Worker         return sInitStatus;
1021*ec779b8eSAndroid Build Coastguard Worker     }
1022*ec779b8eSAndroid Build Coastguard Worker     for (i = 0; i < PREPROC_NUM_SESSIONS && status == 0; i++) {
1023*ec779b8eSAndroid Build Coastguard Worker         status = Session_Init(&sSessions[i]);
1024*ec779b8eSAndroid Build Coastguard Worker     }
1025*ec779b8eSAndroid Build Coastguard Worker     sInitStatus = status;
1026*ec779b8eSAndroid Build Coastguard Worker     return sInitStatus;
1027*ec779b8eSAndroid Build Coastguard Worker }
1028*ec779b8eSAndroid Build Coastguard Worker 
PreProc_GetDescriptor(const effect_uuid_t * uuid)1029*ec779b8eSAndroid Build Coastguard Worker const effect_descriptor_t* PreProc_GetDescriptor(const effect_uuid_t* uuid) {
1030*ec779b8eSAndroid Build Coastguard Worker     size_t i;
1031*ec779b8eSAndroid Build Coastguard Worker     for (i = 0; i < PREPROC_NUM_EFFECTS; i++) {
1032*ec779b8eSAndroid Build Coastguard Worker         if (memcmp(&sDescriptors[i]->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
1033*ec779b8eSAndroid Build Coastguard Worker             return sDescriptors[i];
1034*ec779b8eSAndroid Build Coastguard Worker         }
1035*ec779b8eSAndroid Build Coastguard Worker     }
1036*ec779b8eSAndroid Build Coastguard Worker     return NULL;
1037*ec779b8eSAndroid Build Coastguard Worker }
1038*ec779b8eSAndroid Build Coastguard Worker 
1039*ec779b8eSAndroid Build Coastguard Worker extern "C" {
1040*ec779b8eSAndroid Build Coastguard Worker 
1041*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1042*ec779b8eSAndroid Build Coastguard Worker // Effect Control Interface Implementation
1043*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1044*ec779b8eSAndroid Build Coastguard Worker 
PreProcessingFx_Process(effect_handle_t self,audio_buffer_t * inBuffer,audio_buffer_t * outBuffer)1045*ec779b8eSAndroid Build Coastguard Worker int PreProcessingFx_Process(effect_handle_t self, audio_buffer_t* inBuffer,
1046*ec779b8eSAndroid Build Coastguard Worker                             audio_buffer_t* outBuffer) {
1047*ec779b8eSAndroid Build Coastguard Worker     preproc_effect_t* effect = (preproc_effect_t*)self;
1048*ec779b8eSAndroid Build Coastguard Worker 
1049*ec779b8eSAndroid Build Coastguard Worker     if (effect == NULL) {
1050*ec779b8eSAndroid Build Coastguard Worker         ALOGV("PreProcessingFx_Process() ERROR effect == NULL");
1051*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1052*ec779b8eSAndroid Build Coastguard Worker     }
1053*ec779b8eSAndroid Build Coastguard Worker     preproc_session_t* session = (preproc_session_t*)effect->session;
1054*ec779b8eSAndroid Build Coastguard Worker 
1055*ec779b8eSAndroid Build Coastguard Worker     if (inBuffer == NULL || inBuffer->raw == NULL || outBuffer == NULL || outBuffer->raw == NULL) {
1056*ec779b8eSAndroid Build Coastguard Worker         ALOGW("PreProcessingFx_Process() ERROR bad pointer");
1057*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1058*ec779b8eSAndroid Build Coastguard Worker     }
1059*ec779b8eSAndroid Build Coastguard Worker 
1060*ec779b8eSAndroid Build Coastguard Worker     if (inBuffer->frameCount != outBuffer->frameCount) {
1061*ec779b8eSAndroid Build Coastguard Worker         ALOGW("inBuffer->frameCount %zu is not equal to outBuffer->frameCount %zu",
1062*ec779b8eSAndroid Build Coastguard Worker               inBuffer->frameCount, outBuffer->frameCount);
1063*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1064*ec779b8eSAndroid Build Coastguard Worker     }
1065*ec779b8eSAndroid Build Coastguard Worker 
1066*ec779b8eSAndroid Build Coastguard Worker     if (inBuffer->frameCount != session->frameCount) {
1067*ec779b8eSAndroid Build Coastguard Worker         ALOGW("inBuffer->frameCount %zu != %zu representing 10ms at sampling rate %d",
1068*ec779b8eSAndroid Build Coastguard Worker               inBuffer->frameCount, session->frameCount, session->samplingRate);
1069*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1070*ec779b8eSAndroid Build Coastguard Worker     }
1071*ec779b8eSAndroid Build Coastguard Worker 
1072*ec779b8eSAndroid Build Coastguard Worker     session->processedMsk |= (1 << effect->procId);
1073*ec779b8eSAndroid Build Coastguard Worker 
1074*ec779b8eSAndroid Build Coastguard Worker     //    ALOGV("PreProcessingFx_Process In %d frames enabledMsk %08x processedMsk %08x",
1075*ec779b8eSAndroid Build Coastguard Worker     //         inBuffer->frameCount, session->enabledMsk, session->processedMsk);
1076*ec779b8eSAndroid Build Coastguard Worker     if ((session->processedMsk & session->enabledMsk) == session->enabledMsk) {
1077*ec779b8eSAndroid Build Coastguard Worker         effect->session->processedMsk = 0;
1078*ec779b8eSAndroid Build Coastguard Worker         if (int status = effect->session->apm->ProcessStream(
1079*ec779b8eSAndroid Build Coastguard Worker                     (const int16_t* const)inBuffer->s16,
1080*ec779b8eSAndroid Build Coastguard Worker                     (const webrtc::StreamConfig)effect->session->inputConfig,
1081*ec779b8eSAndroid Build Coastguard Worker                     (const webrtc::StreamConfig)effect->session->outputConfig,
1082*ec779b8eSAndroid Build Coastguard Worker                     (int16_t* const)outBuffer->s16);
1083*ec779b8eSAndroid Build Coastguard Worker             status != 0) {
1084*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Process Stream failed with error %d\n", status);
1085*ec779b8eSAndroid Build Coastguard Worker             return status;
1086*ec779b8eSAndroid Build Coastguard Worker         }
1087*ec779b8eSAndroid Build Coastguard Worker         return 0;
1088*ec779b8eSAndroid Build Coastguard Worker     } else {
1089*ec779b8eSAndroid Build Coastguard Worker         return -ENODATA;
1090*ec779b8eSAndroid Build Coastguard Worker     }
1091*ec779b8eSAndroid Build Coastguard Worker }
1092*ec779b8eSAndroid Build Coastguard Worker 
PreProcessingFx_Command(effect_handle_t self,uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t * replySize,void * pReplyData)1093*ec779b8eSAndroid Build Coastguard Worker int PreProcessingFx_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
1094*ec779b8eSAndroid Build Coastguard Worker                             void* pCmdData, uint32_t* replySize, void* pReplyData) {
1095*ec779b8eSAndroid Build Coastguard Worker     preproc_effect_t* effect = (preproc_effect_t*)self;
1096*ec779b8eSAndroid Build Coastguard Worker 
1097*ec779b8eSAndroid Build Coastguard Worker     if (effect == NULL) {
1098*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1099*ec779b8eSAndroid Build Coastguard Worker     }
1100*ec779b8eSAndroid Build Coastguard Worker 
1101*ec779b8eSAndroid Build Coastguard Worker     // ALOGV("PreProcessingFx_Command: command %d cmdSize %d",cmdCode, cmdSize);
1102*ec779b8eSAndroid Build Coastguard Worker 
1103*ec779b8eSAndroid Build Coastguard Worker     switch (cmdCode) {
1104*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_INIT:
1105*ec779b8eSAndroid Build Coastguard Worker             if (pReplyData == NULL || *replySize != sizeof(int)) {
1106*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1107*ec779b8eSAndroid Build Coastguard Worker             }
1108*ec779b8eSAndroid Build Coastguard Worker             if (effect->ops->init) {
1109*ec779b8eSAndroid Build Coastguard Worker                 effect->ops->init(effect);
1110*ec779b8eSAndroid Build Coastguard Worker             }
1111*ec779b8eSAndroid Build Coastguard Worker             *(int*)pReplyData = 0;
1112*ec779b8eSAndroid Build Coastguard Worker             break;
1113*ec779b8eSAndroid Build Coastguard Worker 
1114*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_SET_CONFIG: {
1115*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || pReplyData == NULL ||
1116*ec779b8eSAndroid Build Coastguard Worker                 *replySize != sizeof(int)) {
1117*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: "
1118*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_SET_CONFIG: ERROR");
1119*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1120*ec779b8eSAndroid Build Coastguard Worker             }
1121*ec779b8eSAndroid Build Coastguard Worker #ifdef DUAL_MIC_TEST
1122*ec779b8eSAndroid Build Coastguard Worker             // make sure that the config command is accepted by making as if all effects were
1123*ec779b8eSAndroid Build Coastguard Worker             // disabled: this is OK for functional tests
1124*ec779b8eSAndroid Build Coastguard Worker             uint32_t enabledMsk = effect->session->enabledMsk;
1125*ec779b8eSAndroid Build Coastguard Worker             if (gDualMicEnabled) {
1126*ec779b8eSAndroid Build Coastguard Worker                 effect->session->enabledMsk = 0;
1127*ec779b8eSAndroid Build Coastguard Worker             }
1128*ec779b8eSAndroid Build Coastguard Worker #endif
1129*ec779b8eSAndroid Build Coastguard Worker             *(int*)pReplyData = Session_SetConfig(effect->session, (effect_config_t*)pCmdData);
1130*ec779b8eSAndroid Build Coastguard Worker #ifdef DUAL_MIC_TEST
1131*ec779b8eSAndroid Build Coastguard Worker             if (gDualMicEnabled) {
1132*ec779b8eSAndroid Build Coastguard Worker                 effect->session->enabledMsk = enabledMsk;
1133*ec779b8eSAndroid Build Coastguard Worker             }
1134*ec779b8eSAndroid Build Coastguard Worker #endif
1135*ec779b8eSAndroid Build Coastguard Worker             if (*(int*)pReplyData != 0) {
1136*ec779b8eSAndroid Build Coastguard Worker                 break;
1137*ec779b8eSAndroid Build Coastguard Worker             }
1138*ec779b8eSAndroid Build Coastguard Worker             if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) {
1139*ec779b8eSAndroid Build Coastguard Worker                 *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
1140*ec779b8eSAndroid Build Coastguard Worker             }
1141*ec779b8eSAndroid Build Coastguard Worker         } break;
1142*ec779b8eSAndroid Build Coastguard Worker 
1143*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_GET_CONFIG:
1144*ec779b8eSAndroid Build Coastguard Worker             if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
1145*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("\tLVM_ERROR : PreProcessingFx_Command cmdCode Case: "
1146*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_GET_CONFIG: ERROR");
1147*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1148*ec779b8eSAndroid Build Coastguard Worker             }
1149*ec779b8eSAndroid Build Coastguard Worker 
1150*ec779b8eSAndroid Build Coastguard Worker             Session_GetConfig(effect->session, (effect_config_t*)pReplyData);
1151*ec779b8eSAndroid Build Coastguard Worker             break;
1152*ec779b8eSAndroid Build Coastguard Worker 
1153*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_SET_CONFIG_REVERSE:
1154*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || pReplyData == NULL ||
1155*ec779b8eSAndroid Build Coastguard Worker                 *replySize != sizeof(int)) {
1156*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: "
1157*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_SET_CONFIG_REVERSE: ERROR");
1158*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1159*ec779b8eSAndroid Build Coastguard Worker             }
1160*ec779b8eSAndroid Build Coastguard Worker             *(int*)pReplyData =
1161*ec779b8eSAndroid Build Coastguard Worker                     Session_SetReverseConfig(effect->session, (effect_config_t*)pCmdData);
1162*ec779b8eSAndroid Build Coastguard Worker             if (*(int*)pReplyData != 0) {
1163*ec779b8eSAndroid Build Coastguard Worker                 break;
1164*ec779b8eSAndroid Build Coastguard Worker             }
1165*ec779b8eSAndroid Build Coastguard Worker             break;
1166*ec779b8eSAndroid Build Coastguard Worker 
1167*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_GET_CONFIG_REVERSE:
1168*ec779b8eSAndroid Build Coastguard Worker             if (pReplyData == NULL || *replySize != sizeof(effect_config_t)) {
1169*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: "
1170*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_GET_CONFIG_REVERSE: ERROR");
1171*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1172*ec779b8eSAndroid Build Coastguard Worker             }
1173*ec779b8eSAndroid Build Coastguard Worker             Session_GetReverseConfig(effect->session, (effect_config_t*)pCmdData);
1174*ec779b8eSAndroid Build Coastguard Worker             break;
1175*ec779b8eSAndroid Build Coastguard Worker 
1176*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_RESET:
1177*ec779b8eSAndroid Build Coastguard Worker             if (effect->ops->reset) {
1178*ec779b8eSAndroid Build Coastguard Worker                 effect->ops->reset(effect);
1179*ec779b8eSAndroid Build Coastguard Worker             }
1180*ec779b8eSAndroid Build Coastguard Worker             break;
1181*ec779b8eSAndroid Build Coastguard Worker 
1182*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_GET_PARAM: {
1183*ec779b8eSAndroid Build Coastguard Worker             effect_param_t* p = (effect_param_t*)pCmdData;
1184*ec779b8eSAndroid Build Coastguard Worker 
1185*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) ||
1186*ec779b8eSAndroid Build Coastguard Worker                 cmdSize < (sizeof(effect_param_t) + p->psize) || pReplyData == NULL ||
1187*ec779b8eSAndroid Build Coastguard Worker                 replySize == NULL || *replySize < (sizeof(effect_param_t) + p->psize)) {
1188*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: "
1189*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_GET_PARAM: ERROR");
1190*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1191*ec779b8eSAndroid Build Coastguard Worker             }
1192*ec779b8eSAndroid Build Coastguard Worker 
1193*ec779b8eSAndroid Build Coastguard Worker             memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
1194*ec779b8eSAndroid Build Coastguard Worker 
1195*ec779b8eSAndroid Build Coastguard Worker             p = (effect_param_t*)pReplyData;
1196*ec779b8eSAndroid Build Coastguard Worker 
1197*ec779b8eSAndroid Build Coastguard Worker             int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
1198*ec779b8eSAndroid Build Coastguard Worker 
1199*ec779b8eSAndroid Build Coastguard Worker             if (effect->ops->get_parameter) {
1200*ec779b8eSAndroid Build Coastguard Worker                 p->status =
1201*ec779b8eSAndroid Build Coastguard Worker                         effect->ops->get_parameter(effect, p->data, &p->vsize, p->data + voffset);
1202*ec779b8eSAndroid Build Coastguard Worker                 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
1203*ec779b8eSAndroid Build Coastguard Worker             }
1204*ec779b8eSAndroid Build Coastguard Worker         } break;
1205*ec779b8eSAndroid Build Coastguard Worker 
1206*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_SET_PARAM: {
1207*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) || pReplyData == NULL ||
1208*ec779b8eSAndroid Build Coastguard Worker                 replySize == NULL || *replySize != sizeof(int32_t)) {
1209*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: "
1210*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_SET_PARAM: ERROR");
1211*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1212*ec779b8eSAndroid Build Coastguard Worker             }
1213*ec779b8eSAndroid Build Coastguard Worker             effect_param_t* p = (effect_param_t*)pCmdData;
1214*ec779b8eSAndroid Build Coastguard Worker 
1215*ec779b8eSAndroid Build Coastguard Worker             if (p->psize != sizeof(int32_t)) {
1216*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: "
1217*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
1218*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1219*ec779b8eSAndroid Build Coastguard Worker             }
1220*ec779b8eSAndroid Build Coastguard Worker             if (effect->ops->set_parameter) {
1221*ec779b8eSAndroid Build Coastguard Worker                 *(int*)pReplyData =
1222*ec779b8eSAndroid Build Coastguard Worker                         effect->ops->set_parameter(effect, (void*)p->data, p->data + p->psize);
1223*ec779b8eSAndroid Build Coastguard Worker             }
1224*ec779b8eSAndroid Build Coastguard Worker         } break;
1225*ec779b8eSAndroid Build Coastguard Worker 
1226*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_ENABLE:
1227*ec779b8eSAndroid Build Coastguard Worker             if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
1228*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_ENABLE: ERROR");
1229*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1230*ec779b8eSAndroid Build Coastguard Worker             }
1231*ec779b8eSAndroid Build Coastguard Worker             *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_ACTIVE);
1232*ec779b8eSAndroid Build Coastguard Worker             break;
1233*ec779b8eSAndroid Build Coastguard Worker 
1234*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_DISABLE:
1235*ec779b8eSAndroid Build Coastguard Worker             if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
1236*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_DISABLE: ERROR");
1237*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1238*ec779b8eSAndroid Build Coastguard Worker             }
1239*ec779b8eSAndroid Build Coastguard Worker             *(int*)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
1240*ec779b8eSAndroid Build Coastguard Worker             break;
1241*ec779b8eSAndroid Build Coastguard Worker 
1242*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_SET_DEVICE:
1243*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_SET_INPUT_DEVICE:
1244*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize != sizeof(uint32_t)) {
1245*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_DEVICE: ERROR");
1246*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1247*ec779b8eSAndroid Build Coastguard Worker             }
1248*ec779b8eSAndroid Build Coastguard Worker 
1249*ec779b8eSAndroid Build Coastguard Worker             if (effect->ops->set_device) {
1250*ec779b8eSAndroid Build Coastguard Worker                 effect->ops->set_device(effect, *(uint32_t*)pCmdData);
1251*ec779b8eSAndroid Build Coastguard Worker             }
1252*ec779b8eSAndroid Build Coastguard Worker             break;
1253*ec779b8eSAndroid Build Coastguard Worker 
1254*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_SET_VOLUME:
1255*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_SET_AUDIO_MODE:
1256*ec779b8eSAndroid Build Coastguard Worker             break;
1257*ec779b8eSAndroid Build Coastguard Worker 
1258*ec779b8eSAndroid Build Coastguard Worker #ifdef DUAL_MIC_TEST
1259*ec779b8eSAndroid Build Coastguard Worker         ///// test commands start
1260*ec779b8eSAndroid Build Coastguard Worker         case PREPROC_CMD_DUAL_MIC_ENABLE: {
1261*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize != sizeof(uint32_t) || pReplyData == NULL ||
1262*ec779b8eSAndroid Build Coastguard Worker                 replySize == NULL) {
1263*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("PreProcessingFx_Command cmdCode Case: "
1264*ec779b8eSAndroid Build Coastguard Worker                       "PREPROC_CMD_DUAL_MIC_ENABLE: ERROR");
1265*ec779b8eSAndroid Build Coastguard Worker                 *replySize = 0;
1266*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1267*ec779b8eSAndroid Build Coastguard Worker             }
1268*ec779b8eSAndroid Build Coastguard Worker             gDualMicEnabled = *(bool*)pCmdData;
1269*ec779b8eSAndroid Build Coastguard Worker             if (gDualMicEnabled) {
1270*ec779b8eSAndroid Build Coastguard Worker                 effect->aux_channels_on = sHasAuxChannels[effect->procId];
1271*ec779b8eSAndroid Build Coastguard Worker             } else {
1272*ec779b8eSAndroid Build Coastguard Worker                 effect->aux_channels_on = false;
1273*ec779b8eSAndroid Build Coastguard Worker             }
1274*ec779b8eSAndroid Build Coastguard Worker             effect->cur_channel_config =
1275*ec779b8eSAndroid Build Coastguard Worker                     (effect->session->inChannelCount == 1) ? CHANNEL_CFG_MONO : CHANNEL_CFG_STEREO;
1276*ec779b8eSAndroid Build Coastguard Worker 
1277*ec779b8eSAndroid Build Coastguard Worker             ALOGV("PREPROC_CMD_DUAL_MIC_ENABLE: %s", gDualMicEnabled ? "enabled" : "disabled");
1278*ec779b8eSAndroid Build Coastguard Worker             *replySize = sizeof(int);
1279*ec779b8eSAndroid Build Coastguard Worker             *(int*)pReplyData = 0;
1280*ec779b8eSAndroid Build Coastguard Worker         } break;
1281*ec779b8eSAndroid Build Coastguard Worker         case PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: {
1282*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || pReplyData == NULL || replySize == NULL) {
1283*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("PreProcessingFx_Command cmdCode Case: "
1284*ec779b8eSAndroid Build Coastguard Worker                       "PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: ERROR");
1285*ec779b8eSAndroid Build Coastguard Worker                 *replySize = 0;
1286*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1287*ec779b8eSAndroid Build Coastguard Worker             }
1288*ec779b8eSAndroid Build Coastguard Worker             pthread_mutex_lock(&gPcmDumpLock);
1289*ec779b8eSAndroid Build Coastguard Worker             if (gPcmDumpFh != NULL) {
1290*ec779b8eSAndroid Build Coastguard Worker                 fclose(gPcmDumpFh);
1291*ec779b8eSAndroid Build Coastguard Worker                 gPcmDumpFh = NULL;
1292*ec779b8eSAndroid Build Coastguard Worker             }
1293*ec779b8eSAndroid Build Coastguard Worker             char* path = strndup((char*)pCmdData, cmdSize);
1294*ec779b8eSAndroid Build Coastguard Worker             gPcmDumpFh = fopen((char*)path, "wb");
1295*ec779b8eSAndroid Build Coastguard Worker             pthread_mutex_unlock(&gPcmDumpLock);
1296*ec779b8eSAndroid Build Coastguard Worker             ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: path %s gPcmDumpFh %p", path, gPcmDumpFh);
1297*ec779b8eSAndroid Build Coastguard Worker             ALOGE_IF(gPcmDumpFh <= 0, "gPcmDumpFh open error %d %s", errno, strerror(errno));
1298*ec779b8eSAndroid Build Coastguard Worker             free(path);
1299*ec779b8eSAndroid Build Coastguard Worker             *replySize = sizeof(int);
1300*ec779b8eSAndroid Build Coastguard Worker             *(int*)pReplyData = 0;
1301*ec779b8eSAndroid Build Coastguard Worker         } break;
1302*ec779b8eSAndroid Build Coastguard Worker         case PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: {
1303*ec779b8eSAndroid Build Coastguard Worker             if (pReplyData == NULL || replySize == NULL) {
1304*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("PreProcessingFx_Command cmdCode Case: "
1305*ec779b8eSAndroid Build Coastguard Worker                       "PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: ERROR");
1306*ec779b8eSAndroid Build Coastguard Worker                 *replySize = 0;
1307*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1308*ec779b8eSAndroid Build Coastguard Worker             }
1309*ec779b8eSAndroid Build Coastguard Worker             pthread_mutex_lock(&gPcmDumpLock);
1310*ec779b8eSAndroid Build Coastguard Worker             if (gPcmDumpFh != NULL) {
1311*ec779b8eSAndroid Build Coastguard Worker                 fclose(gPcmDumpFh);
1312*ec779b8eSAndroid Build Coastguard Worker                 gPcmDumpFh = NULL;
1313*ec779b8eSAndroid Build Coastguard Worker             }
1314*ec779b8eSAndroid Build Coastguard Worker             pthread_mutex_unlock(&gPcmDumpLock);
1315*ec779b8eSAndroid Build Coastguard Worker             ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP");
1316*ec779b8eSAndroid Build Coastguard Worker             *replySize = sizeof(int);
1317*ec779b8eSAndroid Build Coastguard Worker             *(int*)pReplyData = 0;
1318*ec779b8eSAndroid Build Coastguard Worker         } break;
1319*ec779b8eSAndroid Build Coastguard Worker             ///// test commands end
1320*ec779b8eSAndroid Build Coastguard Worker 
1321*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: {
1322*ec779b8eSAndroid Build Coastguard Worker             if (!gDualMicEnabled) {
1323*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1324*ec779b8eSAndroid Build Coastguard Worker             }
1325*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize != 2 * sizeof(uint32_t) || pReplyData == NULL ||
1326*ec779b8eSAndroid Build Coastguard Worker                 replySize == NULL) {
1327*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("PreProcessingFx_Command cmdCode Case: "
1328*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: ERROR");
1329*ec779b8eSAndroid Build Coastguard Worker                 *replySize = 0;
1330*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1331*ec779b8eSAndroid Build Coastguard Worker             }
1332*ec779b8eSAndroid Build Coastguard Worker             if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
1333*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command feature EFFECT_FEATURE_AUX_CHANNELS not supported by"
1334*ec779b8eSAndroid Build Coastguard Worker                       " fx %d",
1335*ec779b8eSAndroid Build Coastguard Worker                       effect->procId);
1336*ec779b8eSAndroid Build Coastguard Worker                 *(uint32_t*)pReplyData = -ENOSYS;
1337*ec779b8eSAndroid Build Coastguard Worker                 *replySize = sizeof(uint32_t);
1338*ec779b8eSAndroid Build Coastguard Worker                 break;
1339*ec779b8eSAndroid Build Coastguard Worker             }
1340*ec779b8eSAndroid Build Coastguard Worker             size_t num_configs = *((uint32_t*)pCmdData + 1);
1341*ec779b8eSAndroid Build Coastguard Worker             if (*replySize < (2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t))) {
1342*ec779b8eSAndroid Build Coastguard Worker                 *replySize = 0;
1343*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1344*ec779b8eSAndroid Build Coastguard Worker             }
1345*ec779b8eSAndroid Build Coastguard Worker 
1346*ec779b8eSAndroid Build Coastguard Worker             *((uint32_t*)pReplyData + 1) = CHANNEL_CFG_CNT;
1347*ec779b8eSAndroid Build Coastguard Worker             if (num_configs < CHANNEL_CFG_CNT ||
1348*ec779b8eSAndroid Build Coastguard Worker                 *replySize < (2 * sizeof(uint32_t) + CHANNEL_CFG_CNT * sizeof(channel_config_t))) {
1349*ec779b8eSAndroid Build Coastguard Worker                 *(uint32_t*)pReplyData = -ENOMEM;
1350*ec779b8eSAndroid Build Coastguard Worker             } else {
1351*ec779b8eSAndroid Build Coastguard Worker                 num_configs = CHANNEL_CFG_CNT;
1352*ec779b8eSAndroid Build Coastguard Worker                 *(uint32_t*)pReplyData = 0;
1353*ec779b8eSAndroid Build Coastguard Worker             }
1354*ec779b8eSAndroid Build Coastguard Worker             ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS num config %d",
1355*ec779b8eSAndroid Build Coastguard Worker                   num_configs);
1356*ec779b8eSAndroid Build Coastguard Worker 
1357*ec779b8eSAndroid Build Coastguard Worker             *replySize = 2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t);
1358*ec779b8eSAndroid Build Coastguard Worker             *((uint32_t*)pReplyData + 1) = num_configs;
1359*ec779b8eSAndroid Build Coastguard Worker             memcpy((uint32_t*)pReplyData + 2, &sDualMicConfigs,
1360*ec779b8eSAndroid Build Coastguard Worker                    num_configs * sizeof(channel_config_t));
1361*ec779b8eSAndroid Build Coastguard Worker         } break;
1362*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_GET_FEATURE_CONFIG:
1363*ec779b8eSAndroid Build Coastguard Worker             if (!gDualMicEnabled) {
1364*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1365*ec779b8eSAndroid Build Coastguard Worker             }
1366*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize != sizeof(uint32_t) || pReplyData == NULL ||
1367*ec779b8eSAndroid Build Coastguard Worker                 replySize == NULL || *replySize < sizeof(uint32_t) + sizeof(channel_config_t)) {
1368*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("PreProcessingFx_Command cmdCode Case: "
1369*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_GET_FEATURE_CONFIG: ERROR");
1370*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1371*ec779b8eSAndroid Build Coastguard Worker             }
1372*ec779b8eSAndroid Build Coastguard Worker             if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
1373*ec779b8eSAndroid Build Coastguard Worker                 *(uint32_t*)pReplyData = -ENOSYS;
1374*ec779b8eSAndroid Build Coastguard Worker                 *replySize = sizeof(uint32_t);
1375*ec779b8eSAndroid Build Coastguard Worker                 break;
1376*ec779b8eSAndroid Build Coastguard Worker             }
1377*ec779b8eSAndroid Build Coastguard Worker             ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_CONFIG");
1378*ec779b8eSAndroid Build Coastguard Worker             *(uint32_t*)pReplyData = 0;
1379*ec779b8eSAndroid Build Coastguard Worker             *replySize = sizeof(uint32_t) + sizeof(channel_config_t);
1380*ec779b8eSAndroid Build Coastguard Worker             memcpy((uint32_t*)pReplyData + 1, &sDualMicConfigs[effect->cur_channel_config],
1381*ec779b8eSAndroid Build Coastguard Worker                    sizeof(channel_config_t));
1382*ec779b8eSAndroid Build Coastguard Worker             break;
1383*ec779b8eSAndroid Build Coastguard Worker         case EFFECT_CMD_SET_FEATURE_CONFIG: {
1384*ec779b8eSAndroid Build Coastguard Worker             ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG: "
1385*ec779b8eSAndroid Build Coastguard Worker                   "gDualMicEnabled %d effect->aux_channels_on %d",
1386*ec779b8eSAndroid Build Coastguard Worker                   gDualMicEnabled, effect->aux_channels_on);
1387*ec779b8eSAndroid Build Coastguard Worker             if (!gDualMicEnabled) {
1388*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1389*ec779b8eSAndroid Build Coastguard Worker             }
1390*ec779b8eSAndroid Build Coastguard Worker             if (pCmdData == NULL || cmdSize != (sizeof(uint32_t) + sizeof(channel_config_t)) ||
1391*ec779b8eSAndroid Build Coastguard Worker                 pReplyData == NULL || replySize == NULL || *replySize < sizeof(uint32_t)) {
1392*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("PreProcessingFx_Command cmdCode Case: "
1393*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
1394*ec779b8eSAndroid Build Coastguard Worker                       "pCmdData %p cmdSize %d pReplyData %p replySize %p *replySize %d",
1395*ec779b8eSAndroid Build Coastguard Worker                       pCmdData, cmdSize, pReplyData, replySize, replySize ? *replySize : -1);
1396*ec779b8eSAndroid Build Coastguard Worker                 return -EINVAL;
1397*ec779b8eSAndroid Build Coastguard Worker             }
1398*ec779b8eSAndroid Build Coastguard Worker             *replySize = sizeof(uint32_t);
1399*ec779b8eSAndroid Build Coastguard Worker             if (*(uint32_t*)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) {
1400*ec779b8eSAndroid Build Coastguard Worker                 *(uint32_t*)pReplyData = -ENOSYS;
1401*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command cmdCode Case: "
1402*ec779b8eSAndroid Build Coastguard Worker                       "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n"
1403*ec779b8eSAndroid Build Coastguard Worker                       "CmdData %d effect->aux_channels_on %d",
1404*ec779b8eSAndroid Build Coastguard Worker                       *(uint32_t*)pCmdData, effect->aux_channels_on);
1405*ec779b8eSAndroid Build Coastguard Worker                 break;
1406*ec779b8eSAndroid Build Coastguard Worker             }
1407*ec779b8eSAndroid Build Coastguard Worker             size_t i;
1408*ec779b8eSAndroid Build Coastguard Worker             for (i = 0; i < CHANNEL_CFG_CNT; i++) {
1409*ec779b8eSAndroid Build Coastguard Worker                 if (memcmp((uint32_t*)pCmdData + 1, &sDualMicConfigs[i],
1410*ec779b8eSAndroid Build Coastguard Worker                            sizeof(channel_config_t)) == 0) {
1411*ec779b8eSAndroid Build Coastguard Worker                     break;
1412*ec779b8eSAndroid Build Coastguard Worker                 }
1413*ec779b8eSAndroid Build Coastguard Worker             }
1414*ec779b8eSAndroid Build Coastguard Worker             if (i == CHANNEL_CFG_CNT) {
1415*ec779b8eSAndroid Build Coastguard Worker                 *(uint32_t*)pReplyData = -EINVAL;
1416*ec779b8eSAndroid Build Coastguard Worker                 ALOGW("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG invalid config"
1417*ec779b8eSAndroid Build Coastguard Worker                       "[%08x].[%08x]",
1418*ec779b8eSAndroid Build Coastguard Worker                       *((uint32_t*)pCmdData + 1), *((uint32_t*)pCmdData + 2));
1419*ec779b8eSAndroid Build Coastguard Worker             } else {
1420*ec779b8eSAndroid Build Coastguard Worker                 effect->cur_channel_config = i;
1421*ec779b8eSAndroid Build Coastguard Worker                 *(uint32_t*)pReplyData = 0;
1422*ec779b8eSAndroid Build Coastguard Worker                 ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG New config"
1423*ec779b8eSAndroid Build Coastguard Worker                       "[%08x].[%08x]",
1424*ec779b8eSAndroid Build Coastguard Worker                       sDualMicConfigs[i].main_channels, sDualMicConfigs[i].aux_channels);
1425*ec779b8eSAndroid Build Coastguard Worker             }
1426*ec779b8eSAndroid Build Coastguard Worker         } break;
1427*ec779b8eSAndroid Build Coastguard Worker #endif
1428*ec779b8eSAndroid Build Coastguard Worker         default:
1429*ec779b8eSAndroid Build Coastguard Worker             return -EINVAL;
1430*ec779b8eSAndroid Build Coastguard Worker     }
1431*ec779b8eSAndroid Build Coastguard Worker     return 0;
1432*ec779b8eSAndroid Build Coastguard Worker }
1433*ec779b8eSAndroid Build Coastguard Worker 
PreProcessingFx_GetDescriptor(effect_handle_t self,effect_descriptor_t * pDescriptor)1434*ec779b8eSAndroid Build Coastguard Worker int PreProcessingFx_GetDescriptor(effect_handle_t self, effect_descriptor_t* pDescriptor) {
1435*ec779b8eSAndroid Build Coastguard Worker     preproc_effect_t* effect = (preproc_effect_t*)self;
1436*ec779b8eSAndroid Build Coastguard Worker 
1437*ec779b8eSAndroid Build Coastguard Worker     if (effect == NULL || pDescriptor == NULL) {
1438*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1439*ec779b8eSAndroid Build Coastguard Worker     }
1440*ec779b8eSAndroid Build Coastguard Worker 
1441*ec779b8eSAndroid Build Coastguard Worker     *pDescriptor = *sDescriptors[effect->procId];
1442*ec779b8eSAndroid Build Coastguard Worker 
1443*ec779b8eSAndroid Build Coastguard Worker     return 0;
1444*ec779b8eSAndroid Build Coastguard Worker }
1445*ec779b8eSAndroid Build Coastguard Worker 
PreProcessingFx_ProcessReverse(effect_handle_t self,audio_buffer_t * inBuffer,audio_buffer_t * outBuffer)1446*ec779b8eSAndroid Build Coastguard Worker int PreProcessingFx_ProcessReverse(effect_handle_t self, audio_buffer_t* inBuffer,
1447*ec779b8eSAndroid Build Coastguard Worker                                    audio_buffer_t* outBuffer) {
1448*ec779b8eSAndroid Build Coastguard Worker     preproc_effect_t* effect = (preproc_effect_t*)self;
1449*ec779b8eSAndroid Build Coastguard Worker 
1450*ec779b8eSAndroid Build Coastguard Worker     if (effect == NULL) {
1451*ec779b8eSAndroid Build Coastguard Worker         ALOGW("PreProcessingFx_ProcessReverse() ERROR effect == NULL");
1452*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1453*ec779b8eSAndroid Build Coastguard Worker     }
1454*ec779b8eSAndroid Build Coastguard Worker     preproc_session_t* session = (preproc_session_t*)effect->session;
1455*ec779b8eSAndroid Build Coastguard Worker 
1456*ec779b8eSAndroid Build Coastguard Worker     if (inBuffer == NULL || inBuffer->raw == NULL) {
1457*ec779b8eSAndroid Build Coastguard Worker         ALOGW("PreProcessingFx_ProcessReverse() ERROR bad pointer");
1458*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1459*ec779b8eSAndroid Build Coastguard Worker     }
1460*ec779b8eSAndroid Build Coastguard Worker 
1461*ec779b8eSAndroid Build Coastguard Worker     if (inBuffer->frameCount != outBuffer->frameCount) {
1462*ec779b8eSAndroid Build Coastguard Worker         ALOGW("inBuffer->frameCount %zu is not equal to outBuffer->frameCount %zu",
1463*ec779b8eSAndroid Build Coastguard Worker               inBuffer->frameCount, outBuffer->frameCount);
1464*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1465*ec779b8eSAndroid Build Coastguard Worker     }
1466*ec779b8eSAndroid Build Coastguard Worker 
1467*ec779b8eSAndroid Build Coastguard Worker     if (inBuffer->frameCount != session->frameCount) {
1468*ec779b8eSAndroid Build Coastguard Worker         ALOGW("inBuffer->frameCount %zu != %zu representing 10ms at sampling rate %d",
1469*ec779b8eSAndroid Build Coastguard Worker               inBuffer->frameCount, session->frameCount, session->samplingRate);
1470*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1471*ec779b8eSAndroid Build Coastguard Worker     }
1472*ec779b8eSAndroid Build Coastguard Worker 
1473*ec779b8eSAndroid Build Coastguard Worker     session->revProcessedMsk |= (1 << effect->procId);
1474*ec779b8eSAndroid Build Coastguard Worker 
1475*ec779b8eSAndroid Build Coastguard Worker     //    ALOGV("PreProcessingFx_ProcessReverse In %d frames revEnabledMsk %08x revProcessedMsk
1476*ec779b8eSAndroid Build Coastguard Worker     //    %08x",
1477*ec779b8eSAndroid Build Coastguard Worker     //         inBuffer->frameCount, session->revEnabledMsk, session->revProcessedMsk);
1478*ec779b8eSAndroid Build Coastguard Worker 
1479*ec779b8eSAndroid Build Coastguard Worker     if ((session->revProcessedMsk & session->revEnabledMsk) == session->revEnabledMsk) {
1480*ec779b8eSAndroid Build Coastguard Worker         effect->session->revProcessedMsk = 0;
1481*ec779b8eSAndroid Build Coastguard Worker         if (int status = effect->session->apm->ProcessReverseStream(
1482*ec779b8eSAndroid Build Coastguard Worker                     (const int16_t* const)inBuffer->s16,
1483*ec779b8eSAndroid Build Coastguard Worker                     (const webrtc::StreamConfig)effect->session->revConfig,
1484*ec779b8eSAndroid Build Coastguard Worker                     (const webrtc::StreamConfig)effect->session->revConfig,
1485*ec779b8eSAndroid Build Coastguard Worker                     (int16_t* const)outBuffer->s16);
1486*ec779b8eSAndroid Build Coastguard Worker             status != 0) {
1487*ec779b8eSAndroid Build Coastguard Worker             ALOGE("Process Reverse Stream failed with error %d\n", status);
1488*ec779b8eSAndroid Build Coastguard Worker             return status;
1489*ec779b8eSAndroid Build Coastguard Worker         }
1490*ec779b8eSAndroid Build Coastguard Worker         return 0;
1491*ec779b8eSAndroid Build Coastguard Worker     } else {
1492*ec779b8eSAndroid Build Coastguard Worker         return -ENODATA;
1493*ec779b8eSAndroid Build Coastguard Worker     }
1494*ec779b8eSAndroid Build Coastguard Worker }
1495*ec779b8eSAndroid Build Coastguard Worker 
1496*ec779b8eSAndroid Build Coastguard Worker // effect_handle_t interface implementation for effect
1497*ec779b8eSAndroid Build Coastguard Worker const struct effect_interface_s sEffectInterface = {
1498*ec779b8eSAndroid Build Coastguard Worker         PreProcessingFx_Process, PreProcessingFx_Command, PreProcessingFx_GetDescriptor, NULL};
1499*ec779b8eSAndroid Build Coastguard Worker 
1500*ec779b8eSAndroid Build Coastguard Worker const struct effect_interface_s sEffectInterfaceReverse = {
1501*ec779b8eSAndroid Build Coastguard Worker         PreProcessingFx_Process, PreProcessingFx_Command, PreProcessingFx_GetDescriptor,
1502*ec779b8eSAndroid Build Coastguard Worker         PreProcessingFx_ProcessReverse};
1503*ec779b8eSAndroid Build Coastguard Worker 
1504*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1505*ec779b8eSAndroid Build Coastguard Worker // Effect Library Interface Implementation
1506*ec779b8eSAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1507*ec779b8eSAndroid Build Coastguard Worker 
PreProcessingLib_Create(const effect_uuid_t * uuid,int32_t sessionId,int32_t ioId,effect_handle_t * pInterface)1508*ec779b8eSAndroid Build Coastguard Worker int PreProcessingLib_Create(const effect_uuid_t* uuid, int32_t sessionId, int32_t ioId,
1509*ec779b8eSAndroid Build Coastguard Worker                             effect_handle_t* pInterface) {
1510*ec779b8eSAndroid Build Coastguard Worker     ALOGV("EffectCreate: uuid: %08x session %d IO: %d", uuid->timeLow, sessionId, ioId);
1511*ec779b8eSAndroid Build Coastguard Worker 
1512*ec779b8eSAndroid Build Coastguard Worker     int status;
1513*ec779b8eSAndroid Build Coastguard Worker     const effect_descriptor_t* desc;
1514*ec779b8eSAndroid Build Coastguard Worker     preproc_session_t* session;
1515*ec779b8eSAndroid Build Coastguard Worker     uint32_t procId;
1516*ec779b8eSAndroid Build Coastguard Worker 
1517*ec779b8eSAndroid Build Coastguard Worker     if (PreProc_Init() != 0) {
1518*ec779b8eSAndroid Build Coastguard Worker         return sInitStatus;
1519*ec779b8eSAndroid Build Coastguard Worker     }
1520*ec779b8eSAndroid Build Coastguard Worker     desc = PreProc_GetDescriptor(uuid);
1521*ec779b8eSAndroid Build Coastguard Worker     if (desc == NULL) {
1522*ec779b8eSAndroid Build Coastguard Worker         ALOGW("EffectCreate: fx not found uuid: %08x", uuid->timeLow);
1523*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1524*ec779b8eSAndroid Build Coastguard Worker     }
1525*ec779b8eSAndroid Build Coastguard Worker     procId = UuidToProcId(&desc->type);
1526*ec779b8eSAndroid Build Coastguard Worker 
1527*ec779b8eSAndroid Build Coastguard Worker     session = PreProc_GetSession(procId, sessionId, ioId);
1528*ec779b8eSAndroid Build Coastguard Worker     if (session == NULL) {
1529*ec779b8eSAndroid Build Coastguard Worker         ALOGW("EffectCreate: no more session available");
1530*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1531*ec779b8eSAndroid Build Coastguard Worker     }
1532*ec779b8eSAndroid Build Coastguard Worker 
1533*ec779b8eSAndroid Build Coastguard Worker     status = Session_CreateEffect(session, procId, pInterface);
1534*ec779b8eSAndroid Build Coastguard Worker 
1535*ec779b8eSAndroid Build Coastguard Worker     if (status < 0 && session->createdMsk == 0) {
1536*ec779b8eSAndroid Build Coastguard Worker         session->id = 0;
1537*ec779b8eSAndroid Build Coastguard Worker     }
1538*ec779b8eSAndroid Build Coastguard Worker     return status;
1539*ec779b8eSAndroid Build Coastguard Worker }
1540*ec779b8eSAndroid Build Coastguard Worker 
PreProcessingLib_Release(effect_handle_t interface)1541*ec779b8eSAndroid Build Coastguard Worker int PreProcessingLib_Release(effect_handle_t interface) {
1542*ec779b8eSAndroid Build Coastguard Worker     ALOGV("EffectRelease start %p", interface);
1543*ec779b8eSAndroid Build Coastguard Worker     if (PreProc_Init() != 0) {
1544*ec779b8eSAndroid Build Coastguard Worker         return sInitStatus;
1545*ec779b8eSAndroid Build Coastguard Worker     }
1546*ec779b8eSAndroid Build Coastguard Worker 
1547*ec779b8eSAndroid Build Coastguard Worker     preproc_effect_t* fx = (preproc_effect_t*)interface;
1548*ec779b8eSAndroid Build Coastguard Worker 
1549*ec779b8eSAndroid Build Coastguard Worker     if (fx->session->id == 0) {
1550*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1551*ec779b8eSAndroid Build Coastguard Worker     }
1552*ec779b8eSAndroid Build Coastguard Worker     return Session_ReleaseEffect(fx->session, fx);
1553*ec779b8eSAndroid Build Coastguard Worker }
1554*ec779b8eSAndroid Build Coastguard Worker 
PreProcessingLib_GetDescriptor(const effect_uuid_t * uuid,effect_descriptor_t * pDescriptor)1555*ec779b8eSAndroid Build Coastguard Worker int PreProcessingLib_GetDescriptor(const effect_uuid_t* uuid, effect_descriptor_t* pDescriptor) {
1556*ec779b8eSAndroid Build Coastguard Worker     if (pDescriptor == NULL || uuid == NULL) {
1557*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1558*ec779b8eSAndroid Build Coastguard Worker     }
1559*ec779b8eSAndroid Build Coastguard Worker 
1560*ec779b8eSAndroid Build Coastguard Worker     const effect_descriptor_t* desc = PreProc_GetDescriptor(uuid);
1561*ec779b8eSAndroid Build Coastguard Worker     if (desc == NULL) {
1562*ec779b8eSAndroid Build Coastguard Worker         ALOGV("PreProcessingLib_GetDescriptor() not found");
1563*ec779b8eSAndroid Build Coastguard Worker         return -EINVAL;
1564*ec779b8eSAndroid Build Coastguard Worker     }
1565*ec779b8eSAndroid Build Coastguard Worker 
1566*ec779b8eSAndroid Build Coastguard Worker     ALOGV("PreProcessingLib_GetDescriptor() got fx %s", desc->name);
1567*ec779b8eSAndroid Build Coastguard Worker 
1568*ec779b8eSAndroid Build Coastguard Worker     *pDescriptor = *desc;
1569*ec779b8eSAndroid Build Coastguard Worker     return 0;
1570*ec779b8eSAndroid Build Coastguard Worker }
1571*ec779b8eSAndroid Build Coastguard Worker 
1572*ec779b8eSAndroid Build Coastguard Worker // This is the only symbol that needs to be exported
1573*ec779b8eSAndroid Build Coastguard Worker __attribute__((visibility("default"))) audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
1574*ec779b8eSAndroid Build Coastguard Worker         .tag = AUDIO_EFFECT_LIBRARY_TAG,
1575*ec779b8eSAndroid Build Coastguard Worker         .version = EFFECT_LIBRARY_API_VERSION,
1576*ec779b8eSAndroid Build Coastguard Worker         .name = "Audio Preprocessing Library",
1577*ec779b8eSAndroid Build Coastguard Worker         .implementor = "The Android Open Source Project",
1578*ec779b8eSAndroid Build Coastguard Worker         .create_effect = PreProcessingLib_Create,
1579*ec779b8eSAndroid Build Coastguard Worker         .release_effect = PreProcessingLib_Release,
1580*ec779b8eSAndroid Build Coastguard Worker         .get_descriptor = PreProcessingLib_GetDescriptor};
1581*ec779b8eSAndroid Build Coastguard Worker 
1582*ec779b8eSAndroid Build Coastguard Worker };  // extern "C"
1583