1a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent/* 2a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * Copyright (C) 2011 The Android Open Source Project 3a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * 4a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 5a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * you may not use this file except in compliance with the License. 6a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * You may obtain a copy of the License at 7a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * 8a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 9a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * 10a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * Unless required by applicable law or agreed to in writing, software 11a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 12a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * See the License for the specific language governing permissions and 14a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent * limitations under the License. 15a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent */ 16a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 17a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include <stdlib.h> 18a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include <string.h> 19a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#define LOG_TAG "PreProcessing" 20a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//#define LOG_NDEBUG 0 21a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include <utils/Log.h> 22a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include <utils/Timers.h> 23a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include <hardware/audio_effect.h> 24a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include <audio_effects/effect_aec.h> 25a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include <audio_effects/effect_agc.h> 26a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include <audio_effects/effect_ns.h> 275387696d25bc710f8cd0e6d08079e2aa8d6c1417Eric Laurent#include <module_common_types.h> 285387696d25bc710f8cd0e6d08079e2aa8d6c1417Eric Laurent#include <audio_processing.h> 29a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#include "speex/speex_resampler.h" 30a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 313f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent// undefine to perform multi channels API functional tests 323f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent//#define DUAL_MIC_TEST 33a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 34a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 35a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// local definitions 36a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 37a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 38a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// maximum number of sessions 39a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#define PREPROC_NUM_SESSIONS 8 40a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 41a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// types of pre processing modules 42a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentenum preproc_id 43a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 44a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_AGC, // Automatic Gain Control 45a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_AEC, // Acoustic Echo Canceler 46a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_NS, // Noise Suppressor 47a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_NUM_EFFECTS 48a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 49a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 50a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Session state 51a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentenum preproc_session_state { 52a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_SESSION_STATE_INIT, // initialized 53a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_SESSION_STATE_CONFIG // configuration received 54a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 55a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 56a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Effect/Preprocessor state 57a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentenum preproc_effect_state { 58a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_EFFECT_STATE_INIT, // initialized 59a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_EFFECT_STATE_CREATED, // webRTC engine created 60a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_EFFECT_STATE_CONFIG, // configuration received/disabled 61a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PREPROC_EFFECT_STATE_ACTIVE // active/enabled 62a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 63a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 64a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// handle on webRTC engine 65a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurenttypedef void* preproc_fx_handle_t; 66a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 67a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurenttypedef struct preproc_session_s preproc_session_t; 68a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurenttypedef struct preproc_effect_s preproc_effect_t; 69a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurenttypedef struct preproc_ops_s preproc_ops_t; 70a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 71a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Effect operation table. Functions for all pre processors are declared in sPreProcOps[] table. 72a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Function pointer can be null if no action required. 73a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstruct preproc_ops_s { 74a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int (* create)(preproc_effect_t *fx); 75a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int (* init)(preproc_effect_t *fx); 76a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int (* reset)(preproc_effect_t *fx); 77a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent void (* enable)(preproc_effect_t *fx); 78a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent void (* disable)(preproc_effect_t *fx); 79a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int (* set_parameter)(preproc_effect_t *fx, void *param, void *value); 80b302bd5d288be2d3363b80053ca2392560b00b25Ashok Bhat int (* get_parameter)(preproc_effect_t *fx, void *param, uint32_t *size, void *value); 81a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int (* set_device)(preproc_effect_t *fx, uint32_t device); 82a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 83a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 84a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Effect context 85a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstruct preproc_effect_s { 86a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent const struct effect_interface_s *itfe; 87a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t procId; // type of pre processor (enum preproc_id) 88a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t state; // current state (enum preproc_effect_state) 89a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_session_t *session; // session the effect is on 90a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent const preproc_ops_t *ops; // effect ops table 91a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_fx_handle_t engine; // handle on webRTC engine 92766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs uint32_t type; // subtype of effect 933f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#ifdef DUAL_MIC_TEST 943f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent bool aux_channels_on; // support auxiliary channels 953f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent size_t cur_channel_config; // current auciliary channel configuration 963f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#endif 97a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 98a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 99a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Session context 100a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstruct preproc_session_s { 101a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent struct preproc_effect_s effects[PREPROC_NUM_EFFECTS]; // effects in this session 102a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t state; // current state (enum preproc_session_state) 103a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int id; // audio session ID 104a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int io; // handle of input stream this session is on 105a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::AudioProcessing* apm; // handle on webRTC audio processing module (APM) 106a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t apmFrameCount; // buffer size for webRTC process (10 ms) 107a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t apmSamplingRate; // webRTC APM sampling rate (8/16 or 32 kHz) 108a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t frameCount; // buffer size before input resampler ( <=> apmFrameCount) 109a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t samplingRate; // sampling rate at effect process interface 110a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t inChannelCount; // input channel count 111a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t outChannelCount; // output channel count 112a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t createdMsk; // bit field containing IDs of crested pre processors 113a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t enabledMsk; // bit field containing IDs of enabled pre processors 114a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t processedMsk; // bit field containing IDs of pre processors already 115a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent // processed in current round 116a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::AudioFrame *procFrame; // audio frame passed to webRTC AMP ProcessStream() 117a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int16_t *inBuf; // input buffer used when resampling 118a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t inBufSize; // input buffer size in frames 119a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t framesIn; // number of frames in input buffer 120a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent SpeexResamplerState *inResampler; // handle on input speex resampler 121a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int16_t *outBuf; // output buffer used when resampling 122a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t outBufSize; // output buffer size in frames 123a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t framesOut; // number of frames in output buffer 124a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent SpeexResamplerState *outResampler; // handle on output speex resampler 125a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t revChannelCount; // number of channels on reverse stream 126a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t revEnabledMsk; // bit field containing IDs of enabled pre processors 127a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent // with reverse channel 128a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t revProcessedMsk; // bit field containing IDs of pre processors with reverse 129a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent // channel already processed in current round 130a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::AudioFrame *revFrame; // audio frame passed to webRTC AMP AnalyzeReverseStream() 131a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int16_t *revBuf; // reverse channel input buffer 132a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t revBufSize; // reverse channel input buffer size 133a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t framesRev; // number of frames in reverse channel input buffer 134a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent SpeexResamplerState *revResampler; // handle on reverse channel input speex resampler 135a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 136a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1373f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#ifdef DUAL_MIC_TEST 1383f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurentenum { 1393f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent PREPROC_CMD_DUAL_MIC_ENABLE = EFFECT_CMD_FIRST_PROPRIETARY, // enable dual mic mode 1403f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent PREPROC_CMD_DUAL_MIC_PCM_DUMP_START, // start pcm capture 1413f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP // stop pcm capture 1423f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent}; 1433f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 1443f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurentenum { 1453f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent CHANNEL_CFG_MONO, 1463f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent CHANNEL_CFG_STEREO, 1473f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent CHANNEL_CFG_MONO_AUX, 1483f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent CHANNEL_CFG_STEREO_AUX, 1493f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent CHANNEL_CFG_CNT, 1503f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent CHANNEL_CFG_FIRST_AUX = CHANNEL_CFG_MONO_AUX, 1513f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent}; 1523f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 1533f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurentconst channel_config_t sDualMicConfigs[CHANNEL_CFG_CNT] = { 1543f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent {AUDIO_CHANNEL_IN_MONO , 0}, 1553f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent {AUDIO_CHANNEL_IN_STEREO , 0}, 1563f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent {AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK}, 1573f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent {AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT} 1583f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent}; 1593f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 1603f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurentbool sHasAuxChannels[PREPROC_NUM_EFFECTS] = { 1613f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent false, // PREPROC_AGC 1623f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent true, // PREPROC_AEC 1633f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent true, // PREPROC_NS 1643f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent}; 1653f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 1663f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurentbool gDualMicEnabled; 1673f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric LaurentFILE *gPcmDumpFh; 1683f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurentstatic pthread_mutex_t gPcmDumpLock = PTHREAD_MUTEX_INITIALIZER; 1693f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#endif 1703f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 1713f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 172a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 173a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Effect descriptors 174a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 175a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 176a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// UUIDs for effect types have been generated from http://www.itu.int/ITU-T/asn1/uuid.html 177a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// as the pre processing effects are not defined by OpenSL ES 178a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 179a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Automatic Gain Control 180a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const effect_descriptor_t sAgcDescriptor = { 181a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent { 0x0a8abfe0, 0x654c, 0x11e0, 0xba26, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type 182a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent { 0xaa8130e0, 0x66fc, 0x11e0, 0xbad0, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid 183a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent EFFECT_CONTROL_API_VERSION, 184a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 185a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, //FIXME indicate CPU load 186a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, //FIXME indicate memory usage 187a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "Automatic Gain Control", 188a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "The Android Open Source Project" 189a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 190a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 191a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Acoustic Echo Cancellation 192a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const effect_descriptor_t sAecDescriptor = { 193a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent { 0x7b491460, 0x8d4d, 0x11e0, 0xbd61, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type 194a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent { 0xbb392ec0, 0x8d4d, 0x11e0, 0xa896, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid 195a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent EFFECT_CONTROL_API_VERSION, 196a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 197a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, //FIXME indicate CPU load 198a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, //FIXME indicate memory usage 199a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "Acoustic Echo Canceler", 200a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "The Android Open Source Project" 201a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 202a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 203a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Noise suppression 204a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const effect_descriptor_t sNsDescriptor = { 205a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent { 0x58b4b260, 0x8e06, 0x11e0, 0xaa8e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type 206a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent { 0xc06c8400, 0x8e06, 0x11e0, 0x9cb6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // uuid 207a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent EFFECT_CONTROL_API_VERSION, 208a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 209a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, //FIXME indicate CPU load 210a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, //FIXME indicate memory usage 211a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "Noise Suppression", 212a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "The Android Open Source Project" 213a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 214a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 215a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 216a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const effect_descriptor_t *sDescriptors[PREPROC_NUM_EFFECTS] = { 217a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &sAgcDescriptor, 218a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &sAecDescriptor, 219a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &sNsDescriptor 220a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 221a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 222a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 223a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Helper functions 224a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 225a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 226a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentconst effect_uuid_t * const sUuidToPreProcTable[PREPROC_NUM_EFFECTS] = { 227a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent FX_IID_AGC, 228a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent FX_IID_AEC, 229a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent FX_IID_NS 230a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 231a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 232a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 233a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentconst effect_uuid_t * ProcIdToUuid(int procId) 234a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 235a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (procId >= PREPROC_NUM_EFFECTS) { 236a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return EFFECT_UUID_NULL; 237a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 238a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return sUuidToPreProcTable[procId]; 239a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 240a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 241a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentuint32_t UuidToProcId(const effect_uuid_t * uuid) 242a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 243a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t i; 244a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent for (i = 0; i < PREPROC_NUM_EFFECTS; i++) { 245a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (memcmp(uuid, sUuidToPreProcTable[i], sizeof(*uuid)) == 0) { 246a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 247a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 248a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 249a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return i; 250a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 251a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 252a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentbool HasReverseStream(uint32_t procId) 253a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 254a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (procId == PREPROC_AEC) { 255a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return true; 256a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 257a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return false; 258a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 259a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 260a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 261a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 262a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Automatic Gain Control (AGC) 263a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 264a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 2655387696d25bc710f8cd0e6d08079e2aa8d6c1417Eric Laurentstatic const int kAgcDefaultTargetLevel = 3; 2665387696d25bc710f8cd0e6d08079e2aa8d6c1417Eric Laurentstatic const int kAgcDefaultCompGain = 9; 267a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const bool kAgcDefaultLimiter = true; 268a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 269a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint AgcInit (preproc_effect_t *effect) 270a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 2713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcInit"); 272a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine); 273a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent agc->set_mode(webrtc::GainControl::kFixedDigital); 274a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent agc->set_target_level_dbfs(kAgcDefaultTargetLevel); 275a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent agc->set_compression_gain_db(kAgcDefaultCompGain); 276a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent agc->enable_limiter(kAgcDefaultLimiter); 277a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 278a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 279a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 280a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint AgcCreate(preproc_effect_t *effect) 281a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 282a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::GainControl *agc = effect->session->apm->gain_control(); 2833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcCreate got agc %p", agc); 284a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (agc == NULL) { 2855ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AgcCreate Error"); 286a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -ENOMEM; 287a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 288a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->engine = static_cast<preproc_fx_handle_t>(agc); 289a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AgcInit(effect); 290a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 291a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 292a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 293a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint AgcGetParameter(preproc_effect_t *effect, 294a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent void *pParam, 295b302bd5d288be2d3363b80053ca2392560b00b25Ashok Bhat uint32_t *pValueSize, 296a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent void *pValue) 297a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 298a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 299a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t param = *(uint32_t *)pParam; 300a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent t_agc_settings *pProperties = (t_agc_settings *)pValue; 301a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine); 302a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 303a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch (param) { 304a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_TARGET_LEVEL: 305a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_COMP_GAIN: 306a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (*pValueSize < sizeof(int16_t)) { 307a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *pValueSize = 0; 308a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 309a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 310a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 311a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_LIMITER_ENA: 312a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (*pValueSize < sizeof(bool)) { 313a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *pValueSize = 0; 314a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 315a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 316a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 317a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_PROPERTIES: 318a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (*pValueSize < sizeof(t_agc_settings)) { 319a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *pValueSize = 0; 320a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 321a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 322a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 323a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 324a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 3255ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AgcGetParameter() unknown param %08x", param); 326a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = -EINVAL; 327a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 328a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 329a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 330a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch (param) { 331a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_TARGET_LEVEL: 332a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(int16_t *) pValue = (int16_t)(agc->target_level_dbfs() * -100); 3333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcGetParameter() target level %d milliBels", *(int16_t *) pValue); 334a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 335a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_COMP_GAIN: 336a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(int16_t *) pValue = (int16_t)(agc->compression_gain_db() * 100); 3373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcGetParameter() comp gain %d milliBels", *(int16_t *) pValue); 338a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 339a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_LIMITER_ENA: 340a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(bool *) pValue = (bool)agc->is_limiter_enabled(); 3413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcGetParameter() limiter enabled %s", 342a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (*(int16_t *) pValue != 0) ? "true" : "false"); 343a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 344a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_PROPERTIES: 345a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent pProperties->targetLevel = (int16_t)(agc->target_level_dbfs() * -100); 346a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent pProperties->compGain = (int16_t)(agc->compression_gain_db() * 100); 347a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent pProperties->limiterEnabled = (bool)agc->is_limiter_enabled(); 348a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 349a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 3505ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AgcGetParameter() unknown param %d", param); 351a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = -EINVAL; 352a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 353a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 354a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 355a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 356a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 357a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint AgcSetParameter (preproc_effect_t *effect, void *pParam, void *pValue) 358a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 359a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 360a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t param = *(uint32_t *)pParam; 361a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent t_agc_settings *pProperties = (t_agc_settings *)pValue; 362a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine); 363a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 364a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch (param) { 365a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_TARGET_LEVEL: 3663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcSetParameter() target level %d milliBels", *(int16_t *)pValue); 367a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = agc->set_target_level_dbfs(-(*(int16_t *)pValue / 100)); 368a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 369a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_COMP_GAIN: 3703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcSetParameter() comp gain %d milliBels", *(int16_t *)pValue); 371a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = agc->set_compression_gain_db(*(int16_t *)pValue / 100); 372a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 373a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_LIMITER_ENA: 3743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcSetParameter() limiter enabled %s", *(bool *)pValue ? "true" : "false"); 375a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = agc->enable_limiter(*(bool *)pValue); 376a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 377a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AGC_PARAM_PROPERTIES: 3783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcSetParameter() properties level %d, gain %d limiter %d", 379a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent pProperties->targetLevel, 380a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent pProperties->compGain, 381a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent pProperties->limiterEnabled); 382a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = agc->set_target_level_dbfs(-(pProperties->targetLevel / 100)); 383a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (status != 0) break; 384a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = agc->set_compression_gain_db(pProperties->compGain / 100); 385a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (status != 0) break; 386a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = agc->enable_limiter(pProperties->limiterEnabled); 387a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 388a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 3895ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AgcSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue); 390a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = -EINVAL; 391a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 392a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 393a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 3943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcSetParameter() done status %d", status); 395a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 396a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 397a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 398a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 399a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentvoid AgcEnable(preproc_effect_t *effect) 400a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 401a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine); 4023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcEnable agc %p", agc); 403a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent agc->Enable(true); 404a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 405a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 406a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentvoid AgcDisable(preproc_effect_t *effect) 407a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 4083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AgcDisable"); 409a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::GainControl *agc = static_cast<webrtc::GainControl *>(effect->engine); 410a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent agc->Enable(false); 411a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 412a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 413a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 414a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const preproc_ops_t sAgcOps = { 415a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AgcCreate, 416a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AgcInit, 417a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NULL, 418a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AgcEnable, 419a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AgcDisable, 420a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AgcSetParameter, 421a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AgcGetParameter, 422a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NULL 423a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 424a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 425a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 426a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 427a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Acoustic Echo Canceler (AEC) 428a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 429a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 430a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const webrtc::EchoControlMobile::RoutingMode kAecDefaultMode = 431a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::EchoControlMobile::kEarpiece; 432a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const bool kAecDefaultComfortNoise = true; 433a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 434a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint AecInit (preproc_effect_t *effect) 435a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 4363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AecInit"); 437a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine); 438a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent aec->set_routing_mode(kAecDefaultMode); 439a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent aec->enable_comfort_noise(kAecDefaultComfortNoise); 440a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 441a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 442a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 443a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint AecCreate(preproc_effect_t *effect) 444a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 445a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::EchoControlMobile *aec = effect->session->apm->echo_control_mobile(); 4463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AecCreate got aec %p", aec); 447a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (aec == NULL) { 4485ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AgcCreate Error"); 449a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -ENOMEM; 450a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 451a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->engine = static_cast<preproc_fx_handle_t>(aec); 452a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AecInit (effect); 453a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 454a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 455a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 456b302bd5d288be2d3363b80053ca2392560b00b25Ashok Bhatint AecGetParameter(preproc_effect_t *effect, 457a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent void *pParam, 458b302bd5d288be2d3363b80053ca2392560b00b25Ashok Bhat uint32_t *pValueSize, 459a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent void *pValue) 460a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 461a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 462a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t param = *(uint32_t *)pParam; 463a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 464a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (*pValueSize < sizeof(uint32_t)) { 465a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 466a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 467a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch (param) { 468a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AEC_PARAM_ECHO_DELAY: 469a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AEC_PARAM_PROPERTIES: 470a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(uint32_t *)pValue = 1000 * effect->session->apm->stream_delay_ms(); 4713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AecGetParameter() echo delay %d us", *(uint32_t *)pValue); 472a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 473a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 4745ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AecGetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue); 475a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = -EINVAL; 476a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 477a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 478a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 479a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 480a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 481a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint AecSetParameter (preproc_effect_t *effect, void *pParam, void *pValue) 482a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 483a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 484a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t param = *(uint32_t *)pParam; 485a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t value = *(uint32_t *)pValue; 486a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 487a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch (param) { 488a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AEC_PARAM_ECHO_DELAY: 489a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AEC_PARAM_PROPERTIES: 490a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = effect->session->apm->set_stream_delay_ms(value/1000); 4913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AecSetParameter() echo delay %d us, status %d", value, status); 492a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 493a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 4945ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AecSetParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue); 495a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = -EINVAL; 496a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 497a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 498a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 499a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 500a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 501a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentvoid AecEnable(preproc_effect_t *effect) 502a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 503a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine); 5043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AecEnable aec %p", aec); 505a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent aec->Enable(true); 506a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 507a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 508a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentvoid AecDisable(preproc_effect_t *effect) 509a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 5103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AecDisable"); 511a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine); 512a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent aec->Enable(false); 513a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 514a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 515a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint AecSetDevice(preproc_effect_t *effect, uint32_t device) 516a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 5173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("AecSetDevice %08x", device); 518a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::EchoControlMobile *aec = static_cast<webrtc::EchoControlMobile *>(effect->engine); 519a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::EchoControlMobile::RoutingMode mode = webrtc::EchoControlMobile::kQuietEarpieceOrHeadset; 520a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 5218895925e38d2521607fd2010f3f3b14ecd15962cEric Laurent if (audio_is_input_device(device)) { 5228895925e38d2521607fd2010f3f3b14ecd15962cEric Laurent return 0; 5238895925e38d2521607fd2010f3f3b14ecd15962cEric Laurent } 5248895925e38d2521607fd2010f3f3b14ecd15962cEric Laurent 525a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch(device) { 526a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AUDIO_DEVICE_OUT_EARPIECE: 527a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent mode = webrtc::EchoControlMobile::kEarpiece; 528a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 529a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AUDIO_DEVICE_OUT_SPEAKER: 530a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent mode = webrtc::EchoControlMobile::kSpeakerphone; 531a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 532a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADSET: 533a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 534a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 535a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 536a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 537a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent aec->set_routing_mode(mode); 538a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 539a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 540a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 541a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const preproc_ops_t sAecOps = { 542a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AecCreate, 543a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AecInit, 544a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NULL, 545a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AecEnable, 546a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AecDisable, 547a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AecSetParameter, 548a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AecGetParameter, 549a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent AecSetDevice 550a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 551a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 552a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 553a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Noise Suppression (NS) 554a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 555a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 556a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const webrtc::NoiseSuppression::Level kNsDefaultLevel = webrtc::NoiseSuppression::kModerate; 557a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 558a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint NsInit (preproc_effect_t *effect) 559a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 5603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("NsInit"); 561a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine); 562a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent ns->set_level(kNsDefaultLevel); 563766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs webrtc::Config config; 564766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs std::vector<webrtc::Point> geometry; 565766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs // TODO(aluebs): Make the geometry settable. 566766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs geometry.push_back(webrtc::Point(-0.03f, 0.f, 0.f)); 567766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs geometry.push_back(webrtc::Point(-0.01f, 0.f, 0.f)); 568766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs geometry.push_back(webrtc::Point(0.01f, 0.f, 0.f)); 569766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs geometry.push_back(webrtc::Point(0.03f, 0.f, 0.f)); 570766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs // The geometry needs to be set with Beamforming enabled. 571766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs config.Set<webrtc::Beamforming>( 572766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs new webrtc::Beamforming(true, geometry)); 573766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs effect->session->apm->SetExtraOptions(config); 574766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs config.Set<webrtc::Beamforming>( 575766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs new webrtc::Beamforming(false, geometry)); 576766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs effect->session->apm->SetExtraOptions(config); 577766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs effect->type = NS_TYPE_SINGLE_CHANNEL; 578a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 579a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 580a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 581a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint NsCreate(preproc_effect_t *effect) 582a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 583a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::NoiseSuppression *ns = effect->session->apm->noise_suppression(); 5843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("NsCreate got ns %p", ns); 585a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (ns == NULL) { 5865ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AgcCreate Error"); 587a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -ENOMEM; 588a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 589a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->engine = static_cast<preproc_fx_handle_t>(ns); 590a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NsInit (effect); 591a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 592a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 593a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 5940f714a464d2425afe00d6450535e763131b40844Eric Laurentint NsGetParameter(preproc_effect_t *effect __unused, 5950f714a464d2425afe00d6450535e763131b40844Eric Laurent void *pParam __unused, 5960f714a464d2425afe00d6450535e763131b40844Eric Laurent uint32_t *pValueSize __unused, 5970f714a464d2425afe00d6450535e763131b40844Eric Laurent void *pValue __unused) 598a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 599a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 600a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 601a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 602a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 603766bf734984a0d5765980f8bd154d111de08ec19Alex Luebsint NsSetParameter (preproc_effect_t *effect, void *pParam, void *pValue) 604a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 605a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 606766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine); 607766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs uint32_t param = *(uint32_t *)pParam; 608766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs uint32_t value = *(uint32_t *)pValue; 609766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs switch(param) { 610766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs case NS_PARAM_LEVEL: 611766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs ns->set_level((webrtc::NoiseSuppression::Level)value); 612766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs ALOGV("NsSetParameter() level %d", value); 613766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs break; 614766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs case NS_PARAM_TYPE: 615766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs { 616766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs webrtc::Config config; 617766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs std::vector<webrtc::Point> geometry; 618766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs bool is_beamforming_enabled = 619766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs value == NS_TYPE_MULTI_CHANNEL && ns->is_enabled(); 620766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs config.Set<webrtc::Beamforming>( 621766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs new webrtc::Beamforming(is_beamforming_enabled, geometry)); 622766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs effect->session->apm->SetExtraOptions(config); 623766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs effect->type = value; 624766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs ALOGV("NsSetParameter() type %d", value); 625766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs break; 626766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs } 627766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs default: 628766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs ALOGW("NsSetParameter() unknown param %08x value %08x", param, value); 629766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs status = -EINVAL; 630766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs } 631766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs 632a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 633a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 634a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 635a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentvoid NsEnable(preproc_effect_t *effect) 636a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 637a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine); 6383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("NsEnable ns %p", ns); 639a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent ns->Enable(true); 640766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs if (effect->type == NS_TYPE_MULTI_CHANNEL) { 641766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs webrtc::Config config; 642766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs std::vector<webrtc::Point> geometry; 643766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs config.Set<webrtc::Beamforming>(new webrtc::Beamforming(true, geometry)); 644766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs effect->session->apm->SetExtraOptions(config); 645766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs } 646a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 647a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 648a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentvoid NsDisable(preproc_effect_t *effect) 649a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 6503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("NsDisable"); 651a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent webrtc::NoiseSuppression *ns = static_cast<webrtc::NoiseSuppression *>(effect->engine); 652a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent ns->Enable(false); 653766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs webrtc::Config config; 654766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs std::vector<webrtc::Point> geometry; 655766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs config.Set<webrtc::Beamforming>(new webrtc::Beamforming(false, geometry)); 656766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs effect->session->apm->SetExtraOptions(config); 657a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 658a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 659a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const preproc_ops_t sNsOps = { 660a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NsCreate, 661a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NsInit, 662a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NULL, 663a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NsEnable, 664a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NsDisable, 665a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NsSetParameter, 666a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NsGetParameter, 667a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NULL 668a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 669a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 670a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 671a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const preproc_ops_t *sPreProcOps[PREPROC_NUM_EFFECTS] = { 672a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &sAgcOps, 673a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &sAecOps, 674a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &sNsOps 675a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 676a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 677a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 678a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 679a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Effect functions 680a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 681a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 682a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentvoid Session_SetProcEnabled(preproc_session_t *session, uint32_t procId, bool enabled); 683a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 684a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentextern "C" const struct effect_interface_s sEffectInterface; 685a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentextern "C" const struct effect_interface_s sEffectInterfaceReverse; 686a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 687a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#define BAD_STATE_ABORT(from, to) \ 688a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to); 689a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 690a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint Effect_SetState(preproc_effect_t *effect, uint32_t state) 691a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 692a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 6933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Effect_SetState proc %d, new %d old %d", effect->procId, state, effect->state); 694a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch(state) { 695a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_INIT: 696a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch(effect->state) { 697a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_ACTIVE: 698a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->ops->disable(effect); 699a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent Session_SetProcEnabled(effect->session, effect->procId, false); 700a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CONFIG: 701a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CREATED: 702a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_INIT: 703a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 704a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 705a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent BAD_STATE_ABORT(effect->state, state); 706a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 707a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 708a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CREATED: 709a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch(effect->state) { 710a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_INIT: 711a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = effect->ops->create(effect); 712a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 713a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CREATED: 714a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_ACTIVE: 715a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CONFIG: 71629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Effect_SetState invalid transition"); 717a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = -ENOSYS; 718a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 719a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 720a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent BAD_STATE_ABORT(effect->state, state); 721a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 722a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 723a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CONFIG: 724a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch(effect->state) { 725a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_INIT: 72629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Effect_SetState invalid transition"); 727a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = -ENOSYS; 728a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 729a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_ACTIVE: 730a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->ops->disable(effect); 731a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent Session_SetProcEnabled(effect->session, effect->procId, false); 732a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 733a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CREATED: 734a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CONFIG: 735a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 736a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 737a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent BAD_STATE_ABORT(effect->state, state); 738a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 739a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 740a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_ACTIVE: 741a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch(effect->state) { 742a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_INIT: 743a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CREATED: 74429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Effect_SetState invalid transition"); 745a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = -ENOSYS; 746a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 7473f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent case PREPROC_EFFECT_STATE_ACTIVE: 7483f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent // enabling an already enabled effect is just ignored 7493f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent break; 750a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case PREPROC_EFFECT_STATE_CONFIG: 751a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->ops->enable(effect); 752a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent Session_SetProcEnabled(effect->session, effect->procId, true); 753a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 754a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 755a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent BAD_STATE_ABORT(effect->state, state); 756a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 757a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 758a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 759a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent BAD_STATE_ABORT(effect->state, state); 760a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 761a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (status == 0) { 762a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->state = state; 763a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 764a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 765a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 766a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 767a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint Effect_Init(preproc_effect_t *effect, uint32_t procId) 768a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 769a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (HasReverseStream(procId)) { 770a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->itfe = &sEffectInterfaceReverse; 771a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 772a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->itfe = &sEffectInterface; 773a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 774a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->ops = sPreProcOps[procId]; 775a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->procId = procId; 776a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->state = PREPROC_EFFECT_STATE_INIT; 777a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 778a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 779a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 780a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint Effect_Create(preproc_effect_t *effect, 781a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_session_t *session, 782a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect_handle_t *interface) 783a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 784a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->session = session; 785a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *interface = (effect_handle_t)&effect->itfe; 786a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return Effect_SetState(effect, PREPROC_EFFECT_STATE_CREATED); 787a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 788a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 789a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint Effect_Release(preproc_effect_t *effect) 790a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 791a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return Effect_SetState(effect, PREPROC_EFFECT_STATE_INIT); 792a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 793a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 794a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 795a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 796a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Session functions 797a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 798a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 799a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent#define RESAMPLER_QUALITY SPEEX_RESAMPLER_QUALITY_VOIP 800a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 801a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const int kPreprocDefaultSr = 16000; 802a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic const int kPreProcDefaultCnl = 1; 803a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 804a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint Session_Init(preproc_session_t *session) 805a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 806a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t i; 807a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 808a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 809a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->state = PREPROC_SESSION_STATE_INIT; 810a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->id = 0; 811a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->io = 0; 812a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->createdMsk = 0; 813a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apm = NULL; 814a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent for (i = 0; i < PREPROC_NUM_EFFECTS && status == 0; i++) { 815a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = Effect_Init(&session->effects[i], i); 816a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 817a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 818a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 819a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 820a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 821a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentextern "C" int Session_CreateEffect(preproc_session_t *session, 822a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int32_t procId, 823a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect_handle_t *interface) 824a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 825a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = -ENOMEM; 826a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 8273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Session_CreateEffect procId %d, createdMsk %08x", procId, session->createdMsk); 828a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 829a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->createdMsk == 0) { 8309718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs session->apm = webrtc::AudioProcessing::Create(); 831a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->apm == NULL) { 8325ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Session_CreateEffect could not get apm engine"); 833a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent goto error; 834a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 8359718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs const webrtc::ProcessingConfig processing_config = { 8369718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs {{kPreprocDefaultSr, kPreProcDefaultCnl}, 8379718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs {kPreprocDefaultSr, kPreProcDefaultCnl}, 8389718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs {kPreprocDefaultSr, kPreProcDefaultCnl}, 8399718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs {kPreprocDefaultSr, kPreProcDefaultCnl}}}; 8409718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs session->apm->Initialize(processing_config); 841a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->procFrame = new webrtc::AudioFrame(); 842a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->procFrame == NULL) { 8435ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Session_CreateEffect could not allocate audio frame"); 844a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent goto error; 845a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 846a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revFrame = new webrtc::AudioFrame(); 847a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->revFrame == NULL) { 8485ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Session_CreateEffect could not allocate reverse audio frame"); 849a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent goto error; 850a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 851a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmSamplingRate = kPreprocDefaultSr; 852a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmFrameCount = (kPreprocDefaultSr) / 100; 853a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->frameCount = session->apmFrameCount; 854a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->samplingRate = kPreprocDefaultSr; 855a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inChannelCount = kPreProcDefaultCnl; 856a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outChannelCount = kPreProcDefaultCnl; 857de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->sample_rate_hz_ = kPreprocDefaultSr; 858de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->num_channels_ = kPreProcDefaultCnl; 859a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revChannelCount = kPreProcDefaultCnl; 860de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->revFrame->sample_rate_hz_ = kPreprocDefaultSr; 861de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->revFrame->num_channels_ = kPreProcDefaultCnl; 862a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->enabledMsk = 0; 863a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->processedMsk = 0; 864a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revEnabledMsk = 0; 865a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revProcessedMsk = 0; 866a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inResampler = NULL; 867a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inBuf = NULL; 868a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inBufSize = 0; 869a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outResampler = NULL; 870a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBuf = NULL; 871a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBufSize = 0; 872a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revResampler = NULL; 873a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revBuf = NULL; 874a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revBufSize = 0; 875a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 876a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = Effect_Create(&session->effects[procId], session, interface); 877a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (status < 0) { 878a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent goto error; 879a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 8803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Session_CreateEffect OK"); 881a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->createdMsk |= (1<<procId); 882a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 883a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 884a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurenterror: 885a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->createdMsk == 0) { 886a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent delete session->revFrame; 887a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revFrame = NULL; 888a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent delete session->procFrame; 889a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->procFrame = NULL; 8909718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs delete session->apm; 891a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apm = NULL; 892a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 893a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 894a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 895a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 896a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint Session_ReleaseEffect(preproc_session_t *session, 897a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_effect_t *fx) 898a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 8995ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW_IF(Effect_Release(fx) != 0, " Effect_Release() failed for proc ID %d", fx->procId); 900a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->createdMsk &= ~(1<<fx->procId); 901a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->createdMsk == 0) { 9029718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs delete session->apm; 903a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apm = NULL; 904a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent delete session->procFrame; 905a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->procFrame = NULL; 906a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent delete session->revFrame; 907a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revFrame = NULL; 908a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inResampler != NULL) { 909a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->inResampler); 910a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inResampler = NULL; 911a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 912a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->outResampler != NULL) { 913a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->outResampler); 914a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outResampler = NULL; 915a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 916a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->revResampler != NULL) { 917a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->revResampler); 918a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revResampler = NULL; 919a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 920a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent delete session->inBuf; 921a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inBuf = NULL; 922a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent delete session->outBuf; 923a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBuf = NULL; 924a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent delete session->revBuf; 925a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revBuf = NULL; 926a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 927a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->io = 0; 928a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 929a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 930a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 931a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 932a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 933a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 934a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint Session_SetConfig(preproc_session_t *session, effect_config_t *config) 935a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 936a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t sr; 9373f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs uint32_t inCnl = audio_channel_count_from_in_mask(config->inputCfg.channels); 9383f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs uint32_t outCnl = audio_channel_count_from_in_mask(config->outputCfg.channels); 939a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 940a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (config->inputCfg.samplingRate != config->outputCfg.samplingRate || 941a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent config->inputCfg.format != config->outputCfg.format || 942a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) { 943a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 944a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 945a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 9463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Session_SetConfig sr %d cnl %08x", 947a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent config->inputCfg.samplingRate, config->inputCfg.channels); 948a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status; 949a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 950a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent // AEC implementation is limited to 16kHz 951a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) { 952a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmSamplingRate = 32000; 953a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else 954a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (config->inputCfg.samplingRate >= 16000) { 955a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmSamplingRate = 16000; 956a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else if (config->inputCfg.samplingRate >= 8000) { 957a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmSamplingRate = 8000; 958a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 9599718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs 9609718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs const webrtc::ProcessingConfig processing_config = { 9613f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs {{static_cast<int>(session->apmSamplingRate), inCnl}, 9623f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs {static_cast<int>(session->apmSamplingRate), outCnl}, 9633f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs {static_cast<int>(session->apmSamplingRate), inCnl}, 9643f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs {static_cast<int>(session->apmSamplingRate), inCnl}}}; 9659718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs status = session->apm->Initialize(processing_config); 966a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (status < 0) { 967a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 968a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 969a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 970a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->samplingRate = config->inputCfg.samplingRate; 971a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmFrameCount = session->apmSamplingRate / 100; 972a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->samplingRate == session->apmSamplingRate) { 973a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->frameCount = session->apmFrameCount; 974a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 975a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->frameCount = (session->apmFrameCount * session->samplingRate) / 976a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmSamplingRate + 1; 977a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 978a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inChannelCount = inCnl; 979a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outChannelCount = outCnl; 980de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->num_channels_ = inCnl; 981de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->sample_rate_hz_ = session->apmSamplingRate; 982a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 983a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revChannelCount = inCnl; 984de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->revFrame->num_channels_ = inCnl; 985de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->revFrame->sample_rate_hz_ = session->apmSamplingRate; 986a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 9873f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent // force process buffer reallocation 9883f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent session->inBufSize = 0; 9893f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent session->outBufSize = 0; 9903f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent session->framesIn = 0; 9913f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent session->framesOut = 0; 9923f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 9933f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 994a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inResampler != NULL) { 995a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->inResampler); 996a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inResampler = NULL; 997a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 998a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->outResampler != NULL) { 999a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->outResampler); 1000a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outResampler = NULL; 1001a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1002a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->revResampler != NULL) { 1003a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->revResampler); 1004a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revResampler = NULL; 1005a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1006a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->samplingRate != session->apmSamplingRate) { 1007a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int error; 1008a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inResampler = speex_resampler_init(session->inChannelCount, 1009a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->samplingRate, 1010a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmSamplingRate, 1011a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent RESAMPLER_QUALITY, 1012a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &error); 1013a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inResampler == NULL) { 10145ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Session_SetConfig Cannot create speex resampler: %s", 1015a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_strerror(error)); 1016a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1017a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1018a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outResampler = speex_resampler_init(session->outChannelCount, 1019a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmSamplingRate, 1020a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->samplingRate, 1021a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent RESAMPLER_QUALITY, 1022a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &error); 1023a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->outResampler == NULL) { 10245ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Session_SetConfig Cannot create speex resampler: %s", 1025a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_strerror(error)); 1026a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->inResampler); 1027a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inResampler = NULL; 1028a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1029a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1030a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revResampler = speex_resampler_init(session->inChannelCount, 1031a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->samplingRate, 1032a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->apmSamplingRate, 1033a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent RESAMPLER_QUALITY, 1034a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &error); 1035a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->revResampler == NULL) { 10365ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Session_SetConfig Cannot create speex resampler: %s", 1037a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_strerror(error)); 1038a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->inResampler); 1039a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inResampler = NULL; 1040a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_destroy(session->outResampler); 1041a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outResampler = NULL; 1042a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1043a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1044a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1045a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1046a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->state = PREPROC_SESSION_STATE_CONFIG; 1047a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1048a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1049a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 10503d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurentvoid Session_GetConfig(preproc_session_t *session, effect_config_t *config) 10513d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent{ 10523d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent memset(config, 0, sizeof(effect_config_t)); 10533d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate; 10543d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 1055ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten config->inputCfg.channels = audio_channel_in_mask_from_count(session->inChannelCount); 1056ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten // "out" doesn't mean output device, so this is the correct API to convert channel count to mask 1057ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten config->outputCfg.channels = audio_channel_in_mask_from_count(session->outChannelCount); 10583d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent config->inputCfg.mask = config->outputCfg.mask = 10593d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT); 10603d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent} 10613d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent 1062a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint Session_SetReverseConfig(preproc_session_t *session, effect_config_t *config) 1063a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1064a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (config->inputCfg.samplingRate != config->outputCfg.samplingRate || 1065a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent config->inputCfg.format != config->outputCfg.format || 1066a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) { 1067a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1068a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1069a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 10703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Session_SetReverseConfig sr %d cnl %08x", 1071a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent config->inputCfg.samplingRate, config->inputCfg.channels); 1072a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1073a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->state < PREPROC_SESSION_STATE_CONFIG) { 1074a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -ENOSYS; 1075a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1076a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (config->inputCfg.samplingRate != session->samplingRate || 1077a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) { 1078a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1079a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1080e541269be94f3a1072932d51537905b120ef4733Andy Hung uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels); 10819718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs const webrtc::ProcessingConfig processing_config = { 10823f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs {{static_cast<int>(session->apmSamplingRate), session->inChannelCount}, 10833f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs {static_cast<int>(session->apmSamplingRate), session->outChannelCount}, 10843f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs {static_cast<int>(session->apmSamplingRate), inCnl}, 10853f11ef01574219f323a7f9ee4216d610733df50fAlex Luebs {static_cast<int>(session->apmSamplingRate), inCnl}}}; 10869718b7d9cba77c739269462ac57d43cc6ae69134Alex Luebs int status = session->apm->Initialize(processing_config); 1087a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (status < 0) { 1088a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1089a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1090a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revChannelCount = inCnl; 1091de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->revFrame->num_channels_ = inCnl; 1092de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->revFrame->sample_rate_hz_ = session->apmSamplingRate; 10933f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent // force process buffer reallocation 10943f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent session->revBufSize = 0; 10953f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent session->framesRev = 0; 10963f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 1097a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1098a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1099a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 11003d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurentvoid Session_GetReverseConfig(preproc_session_t *session, effect_config_t *config) 11013d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent{ 11023d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent memset(config, 0, sizeof(effect_config_t)); 11033d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent config->inputCfg.samplingRate = config->outputCfg.samplingRate = session->samplingRate; 11043d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent config->inputCfg.format = config->outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 11053d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent config->inputCfg.channels = config->outputCfg.channels = 1106ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten audio_channel_in_mask_from_count(session->revChannelCount); 11073d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent config->inputCfg.mask = config->outputCfg.mask = 11083d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT); 11093d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent} 11103d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent 1111a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentvoid Session_SetProcEnabled(preproc_session_t *session, uint32_t procId, bool enabled) 1112a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1113a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (enabled) { 1114a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if(session->enabledMsk == 0) { 1115a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesIn = 0; 1116a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inResampler != NULL) { 1117a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_reset_mem(session->inResampler); 1118a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1119a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesOut = 0; 1120a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->outResampler != NULL) { 1121a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_reset_mem(session->outResampler); 1122a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1123a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1124a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->enabledMsk |= (1 << procId); 1125a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (HasReverseStream(procId)) { 1126a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesRev = 0; 1127a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->revResampler != NULL) { 1128a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_reset_mem(session->revResampler); 1129a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1130a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revEnabledMsk |= (1 << procId); 1131a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1132a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1133a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->enabledMsk &= ~(1 << procId); 1134a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (HasReverseStream(procId)) { 1135a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revEnabledMsk &= ~(1 << procId); 1136a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1137a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 11383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Session_SetProcEnabled proc %d, enabled %d enabledMsk %08x revEnabledMsk %08x", 1139a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent procId, enabled, session->enabledMsk, session->revEnabledMsk); 1140a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->processedMsk = 0; 1141a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (HasReverseStream(procId)) { 1142a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revProcessedMsk = 0; 1143a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1144a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1145a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1146a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 1147a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Bundle functions 1148a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 1149a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1150a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic int sInitStatus = 1; 1151a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentstatic preproc_session_t sSessions[PREPROC_NUM_SESSIONS]; 1152a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1153a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentpreproc_session_t *PreProc_GetSession(int32_t procId, int32_t sessionId, int32_t ioId) 1154a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1155a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t i; 1156a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int free = -1; 1157a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent for (i = 0; i < PREPROC_NUM_SESSIONS; i++) { 1158a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (sSessions[i].io == ioId) { 1159a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (sSessions[i].createdMsk & (1 << procId)) { 1160a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return NULL; 1161a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1162a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return &sSessions[i]; 1163a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1164a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1165a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent for (i = 0; i < PREPROC_NUM_SESSIONS; i++) { 1166a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (sSessions[i].io == 0) { 1167a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent sSessions[i].id = sessionId; 1168a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent sSessions[i].io = ioId; 1169a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return &sSessions[i]; 1170a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1171a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1172a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return NULL; 1173a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1174a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1175a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1176a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint PreProc_Init() { 1177a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t i; 1178a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 1179a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1180a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (sInitStatus <= 0) { 1181a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return sInitStatus; 1182a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1183a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent for (i = 0; i < PREPROC_NUM_SESSIONS && status == 0; i++) { 1184a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = Session_Init(&sSessions[i]); 1185a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1186a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent sInitStatus = status; 1187a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return sInitStatus; 1188a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1189a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 11905e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenconst effect_descriptor_t *PreProc_GetDescriptor(const effect_uuid_t *uuid) 1191a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1192a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t i; 1193a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent for (i = 0; i < PREPROC_NUM_EFFECTS; i++) { 1194a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (memcmp(&sDescriptors[i]->uuid, uuid, sizeof(effect_uuid_t)) == 0) { 1195a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return sDescriptors[i]; 1196a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1197a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1198a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return NULL; 1199a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1200a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1201a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1202a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentextern "C" { 1203a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1204a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 1205a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Effect Control Interface Implementation 1206a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 1207a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1208a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint PreProcessingFx_Process(effect_handle_t self, 1209a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent audio_buffer_t *inBuffer, 1210a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent audio_buffer_t *outBuffer) 1211a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1212a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_effect_t * effect = (preproc_effect_t *)self; 1213a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 1214a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1215a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect == NULL){ 12163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Process() ERROR effect == NULL"); 1217a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1218a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1219a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_session_t * session = (preproc_session_t *)effect->session; 1220a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1221a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (inBuffer == NULL || inBuffer->raw == NULL || 1222a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent outBuffer == NULL || outBuffer->raw == NULL){ 12235ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("PreProcessingFx_Process() ERROR bad pointer"); 1224a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1225a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1226a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1227a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->processedMsk |= (1<<effect->procId); 1228a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 12293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block// ALOGV("PreProcessingFx_Process In %d frames enabledMsk %08x processedMsk %08x", 1230a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// inBuffer->frameCount, session->enabledMsk, session->processedMsk); 1231a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1232a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if ((session->processedMsk & session->enabledMsk) == session->enabledMsk) { 1233a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->session->processedMsk = 0; 1234a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t framesRq = outBuffer->frameCount; 1235a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t framesWr = 0; 1236a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->framesOut) { 1237a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t fr = session->framesOut; 1238a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (outBuffer->frameCount < fr) { 1239a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr = outBuffer->frameCount; 1240a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1241a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(outBuffer->s16, 1242a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBuf, 1243a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr * session->outChannelCount * sizeof(int16_t)); 1244a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(session->outBuf, 1245a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBuf + fr * session->outChannelCount, 1246a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t)); 1247a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesOut -= fr; 1248a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent framesWr += fr; 1249a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1250a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent outBuffer->frameCount = framesWr; 1251a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (framesWr == framesRq) { 1252a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->frameCount = 0; 1253a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1254a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1255a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1256a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inResampler != NULL) { 1257a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t fr = session->frameCount - session->framesIn; 1258a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (inBuffer->frameCount < fr) { 1259a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr = inBuffer->frameCount; 1260a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1261a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inBufSize < session->framesIn + fr) { 1262679650f008a6dee59d89238fab17edd208a1878eEric Laurent int16_t *buf; 1263a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inBufSize = session->framesIn + fr; 1264679650f008a6dee59d89238fab17edd208a1878eEric Laurent buf = (int16_t *)realloc(session->inBuf, 1265a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inBufSize * session->inChannelCount * sizeof(int16_t)); 1266679650f008a6dee59d89238fab17edd208a1878eEric Laurent if (buf == NULL) { 1267679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->framesIn = 0; 1268679650f008a6dee59d89238fab17edd208a1878eEric Laurent free(session->inBuf); 1269679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->inBuf = NULL; 1270679650f008a6dee59d89238fab17edd208a1878eEric Laurent return -ENOMEM; 1271679650f008a6dee59d89238fab17edd208a1878eEric Laurent } 1272679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->inBuf = buf; 1273a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1274a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(session->inBuf + session->framesIn * session->inChannelCount, 1275a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->s16, 1276a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr * session->inChannelCount * sizeof(int16_t)); 12773f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#ifdef DUAL_MIC_TEST 12783f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pthread_mutex_lock(&gPcmDumpLock); 12793f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (gPcmDumpFh != NULL) { 12803f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent fwrite(inBuffer->raw, 12813f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent fr * session->inChannelCount * sizeof(int16_t), 1, gPcmDumpFh); 12823f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 12833f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pthread_mutex_unlock(&gPcmDumpLock); 12843f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#endif 1285a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1286a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesIn += fr; 1287a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->frameCount = fr; 1288a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->framesIn < session->frameCount) { 1289a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1290a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1291377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT spx_uint32_t frIn = session->framesIn; 1292377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT spx_uint32_t frOut = session->apmFrameCount; 1293a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inChannelCount == 1) { 1294a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_process_int(session->inResampler, 1295a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, 1296a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inBuf, 1297a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frIn, 1298de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->data_, 1299a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frOut); 1300a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1301a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_process_interleaved_int(session->inResampler, 1302a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inBuf, 1303a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frIn, 1304de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->data_, 1305a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frOut); 1306a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1307a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(session->inBuf, 1308a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->inBuf + frIn * session->inChannelCount, 1309a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (session->framesIn - frIn) * session->inChannelCount * sizeof(int16_t)); 1310a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesIn -= frIn; 1311a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1312a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t fr = session->frameCount - session->framesIn; 1313a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (inBuffer->frameCount < fr) { 1314a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr = inBuffer->frameCount; 1315a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1316de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh memcpy(session->procFrame->data_ + session->framesIn * session->inChannelCount, 1317a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->s16, 1318a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr * session->inChannelCount * sizeof(int16_t)); 13193f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 13203f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#ifdef DUAL_MIC_TEST 13213f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pthread_mutex_lock(&gPcmDumpLock); 13223f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (gPcmDumpFh != NULL) { 13233f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent fwrite(inBuffer->raw, 13243f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent fr * session->inChannelCount * sizeof(int16_t), 1, gPcmDumpFh); 13253f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 13263f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pthread_mutex_unlock(&gPcmDumpLock); 13273f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#endif 13283f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 1329a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesIn += fr; 1330a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->frameCount = fr; 1331a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->framesIn < session->frameCount) { 1332a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1333a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1334a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesIn = 0; 1335a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1336766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs session->procFrame->samples_per_channel_ = session->apmFrameCount; 1337a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1338a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->session->apm->ProcessStream(session->procFrame); 1339a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1340a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->outBufSize < session->framesOut + session->frameCount) { 1341679650f008a6dee59d89238fab17edd208a1878eEric Laurent int16_t *buf; 1342a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBufSize = session->framesOut + session->frameCount; 1343679650f008a6dee59d89238fab17edd208a1878eEric Laurent buf = (int16_t *)realloc(session->outBuf, 1344679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->outBufSize * session->outChannelCount * sizeof(int16_t)); 1345679650f008a6dee59d89238fab17edd208a1878eEric Laurent if (buf == NULL) { 1346679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->framesOut = 0; 1347679650f008a6dee59d89238fab17edd208a1878eEric Laurent free(session->outBuf); 1348679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->outBuf = NULL; 1349679650f008a6dee59d89238fab17edd208a1878eEric Laurent return -ENOMEM; 1350679650f008a6dee59d89238fab17edd208a1878eEric Laurent } 1351679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->outBuf = buf; 1352a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1353a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1354a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->outResampler != NULL) { 1355377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT spx_uint32_t frIn = session->apmFrameCount; 1356377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT spx_uint32_t frOut = session->frameCount; 1357a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inChannelCount == 1) { 1358a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_process_int(session->outResampler, 1359a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, 1360de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->data_, 1361a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frIn, 1362a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBuf + session->framesOut * session->outChannelCount, 1363a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frOut); 1364a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1365a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_process_interleaved_int(session->outResampler, 1366de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->data_, 1367a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frIn, 1368a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBuf + session->framesOut * session->outChannelCount, 1369a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frOut); 1370a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1371a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesOut += frOut; 1372a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1373a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(session->outBuf + session->framesOut * session->outChannelCount, 1374de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->procFrame->data_, 1375a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->frameCount * session->outChannelCount * sizeof(int16_t)); 1376a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesOut += session->frameCount; 1377a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1378a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t fr = session->framesOut; 1379a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (framesRq - framesWr < fr) { 1380a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr = framesRq - framesWr; 1381a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1382a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(outBuffer->s16 + framesWr * session->outChannelCount, 1383a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBuf, 1384a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr * session->outChannelCount * sizeof(int16_t)); 1385a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(session->outBuf, 1386a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->outBuf + fr * session->outChannelCount, 1387a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (session->framesOut - fr) * session->outChannelCount * sizeof(int16_t)); 1388a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesOut -= fr; 1389a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent outBuffer->frameCount += fr; 1390a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1391a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1392a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1393a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -ENODATA; 1394a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1395a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1396a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1397a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint PreProcessingFx_Command(effect_handle_t self, 1398a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t cmdCode, 1399a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t cmdSize, 1400a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent void *pCmdData, 1401a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t *replySize, 1402a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent void *pReplyData) 1403a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1404a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_effect_t * effect = (preproc_effect_t *) self; 1405a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int retsize; 1406a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status; 1407a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1408a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect == NULL){ 1409a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1410a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1411a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 14123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block //ALOGV("PreProcessingFx_Command: command %d cmdSize %d",cmdCode, cmdSize); 1413a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1414a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent switch (cmdCode){ 1415a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_INIT: 1416a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (pReplyData == NULL || *replySize != sizeof(int)){ 1417a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1418a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1419a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect->ops->init) { 1420a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->ops->init(effect); 1421a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1422a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(int *)pReplyData = 0; 1423a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1424a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 14253f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent case EFFECT_CMD_SET_CONFIG: { 1426a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (pCmdData == NULL|| 1427a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent cmdSize != sizeof(effect_config_t)|| 1428a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent pReplyData == NULL|| 1429a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *replySize != sizeof(int)){ 14303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Command cmdCode Case: " 14313d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent "EFFECT_CMD_SET_CONFIG: ERROR"); 1432a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1433a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 14343f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#ifdef DUAL_MIC_TEST 14353f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent // make sure that the config command is accepted by making as if all effects were 14363f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent // disabled: this is OK for functional tests 14373f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent uint32_t enabledMsk = effect->session->enabledMsk; 14383f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (gDualMicEnabled) { 14393f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent effect->session->enabledMsk = 0; 14403f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 14413f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#endif 1442a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(int *)pReplyData = Session_SetConfig(effect->session, (effect_config_t *)pCmdData); 14433f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#ifdef DUAL_MIC_TEST 14443f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (gDualMicEnabled) { 14453f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent effect->session->enabledMsk = enabledMsk; 14463f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 14473f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#endif 1448a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (*(int *)pReplyData != 0) { 1449a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1450a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 145176533e94500e5d221ec4a1a5d9c97ea3d75860e4Eric Laurent if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) { 145276533e94500e5d221ec4a1a5d9c97ea3d75860e4Eric Laurent *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG); 145376533e94500e5d221ec4a1a5d9c97ea3d75860e4Eric Laurent } 14543f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } break; 1455a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 14563d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent case EFFECT_CMD_GET_CONFIG: 14573d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent if (pReplyData == NULL || 14583d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent *replySize != sizeof(effect_config_t)) { 14593d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent ALOGV("\tLVM_ERROR : PreProcessingFx_Command cmdCode Case: " 14603d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent "EFFECT_CMD_GET_CONFIG: ERROR"); 14613d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent return -EINVAL; 14623d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent } 14633d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent 146494fef38613962c983c46ab0b97c58f5373412d2dEric Laurent Session_GetConfig(effect->session, (effect_config_t *)pReplyData); 14653d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent break; 14663d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent 14673d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent case EFFECT_CMD_SET_CONFIG_REVERSE: 14683d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent if (pCmdData == NULL || 14693d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent cmdSize != sizeof(effect_config_t) || 14703d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent pReplyData == NULL || 14713d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent *replySize != sizeof(int)) { 14723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Command cmdCode Case: " 14733d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent "EFFECT_CMD_SET_CONFIG_REVERSE: ERROR"); 1474a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1475a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1476a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(int *)pReplyData = Session_SetReverseConfig(effect->session, 1477a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (effect_config_t *)pCmdData); 1478a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (*(int *)pReplyData != 0) { 1479a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1480a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1481a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1482a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 14833d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent case EFFECT_CMD_GET_CONFIG_REVERSE: 14843d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent if (pReplyData == NULL || 14853d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent *replySize != sizeof(effect_config_t)){ 14863d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent ALOGV("PreProcessingFx_Command cmdCode Case: " 14873d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent "EFFECT_CMD_GET_CONFIG_REVERSE: ERROR"); 14883d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent return -EINVAL; 14893d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent } 14903d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent Session_GetReverseConfig(effect->session, (effect_config_t *)pCmdData); 14913d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent break; 14923d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent 1493a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_RESET: 1494a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect->ops->reset) { 1495a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->ops->reset(effect); 1496a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1497a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1498a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 14990f714a464d2425afe00d6450535e763131b40844Eric Laurent case EFFECT_CMD_GET_PARAM: { 15000f714a464d2425afe00d6450535e763131b40844Eric Laurent effect_param_t *p = (effect_param_t *)pCmdData; 15010f714a464d2425afe00d6450535e763131b40844Eric Laurent 15020f714a464d2425afe00d6450535e763131b40844Eric Laurent if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) || 15030f714a464d2425afe00d6450535e763131b40844Eric Laurent cmdSize < (sizeof(effect_param_t) + p->psize) || 15040f714a464d2425afe00d6450535e763131b40844Eric Laurent pReplyData == NULL || replySize == NULL || 15050f714a464d2425afe00d6450535e763131b40844Eric Laurent *replySize < (sizeof(effect_param_t) + p->psize)){ 15063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Command cmdCode Case: " 1507a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "EFFECT_CMD_GET_PARAM: ERROR"); 1508a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1509a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1510a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1511a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize); 1512a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1513a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent p = (effect_param_t *)pReplyData; 1514a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1515a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); 1516a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1517a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect->ops->get_parameter) { 1518a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent p->status = effect->ops->get_parameter(effect, p->data, 1519b302bd5d288be2d3363b80053ca2392560b00b25Ashok Bhat &p->vsize, 1520a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent p->data + voffset); 1521a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *replySize = sizeof(effect_param_t) + voffset + p->vsize; 1522a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1523a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } break; 1524a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1525a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_SET_PARAM:{ 1526a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (pCmdData == NULL|| 15270f714a464d2425afe00d6450535e763131b40844Eric Laurent cmdSize < sizeof(effect_param_t) || 15280f714a464d2425afe00d6450535e763131b40844Eric Laurent pReplyData == NULL || replySize == NULL || 1529a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *replySize != sizeof(int32_t)){ 15303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Command cmdCode Case: " 1531a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "EFFECT_CMD_SET_PARAM: ERROR"); 1532a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1533a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1534a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect_param_t *p = (effect_param_t *) pCmdData; 1535a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1536a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (p->psize != sizeof(int32_t)){ 15373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Command cmdCode Case: " 1538a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)"); 1539a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1540a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1541a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect->ops->set_parameter) { 1542a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(int *)pReplyData = effect->ops->set_parameter(effect, 1543a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (void *)p->data, 1544a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent p->data + p->psize); 1545a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1546a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } break; 1547a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1548a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_ENABLE: 15490f714a464d2425afe00d6450535e763131b40844Eric Laurent if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)){ 15503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_ENABLE: ERROR"); 1551a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1552a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1553a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_ACTIVE); 1554a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1555a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1556a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_DISABLE: 15570f714a464d2425afe00d6450535e763131b40844Eric Laurent if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)){ 15583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_DISABLE: ERROR"); 1559a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1560a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1561a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG); 1562a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1563a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1564a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_SET_DEVICE: 1565a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_SET_INPUT_DEVICE: 1566a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (pCmdData == NULL || 1567a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent cmdSize != sizeof(uint32_t)) { 15683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_DEVICE: ERROR"); 1569a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1570a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1571a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1572a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect->ops->set_device) { 1573a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->ops->set_device(effect, *(uint32_t *)pCmdData); 1574a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1575a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1576a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1577a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_SET_VOLUME: 1578a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent case EFFECT_CMD_SET_AUDIO_MODE: 1579a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent break; 1580a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 15813f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#ifdef DUAL_MIC_TEST 15823f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ///// test commands start 15833f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent case PREPROC_CMD_DUAL_MIC_ENABLE: { 15843f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (pCmdData == NULL|| cmdSize != sizeof(uint32_t) || 15853f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pReplyData == NULL || replySize == NULL) { 15863f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGE("PreProcessingFx_Command cmdCode Case: " 15873f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "PREPROC_CMD_DUAL_MIC_ENABLE: ERROR"); 15883f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = 0; 15893f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 15903f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 15913f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent gDualMicEnabled = *(bool *)pCmdData; 15923f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (gDualMicEnabled) { 15933f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent effect->aux_channels_on = sHasAuxChannels[effect->procId]; 15943f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } else { 15953f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent effect->aux_channels_on = false; 15963f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 15973f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent effect->cur_channel_config = (effect->session->inChannelCount == 1) ? 15983f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent CHANNEL_CFG_MONO : CHANNEL_CFG_STEREO; 15993f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 16003f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PREPROC_CMD_DUAL_MIC_ENABLE: %s", gDualMicEnabled ? "enabled" : "disabled"); 16013f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = sizeof(int); 16023f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(int *)pReplyData = 0; 16033f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } break; 16043f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent case PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: { 16053f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (pCmdData == NULL|| pReplyData == NULL || replySize == NULL) { 16063f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGE("PreProcessingFx_Command cmdCode Case: " 16073f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: ERROR"); 16083f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = 0; 16093f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 16103f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16113f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pthread_mutex_lock(&gPcmDumpLock); 16123f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (gPcmDumpFh != NULL) { 16133f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent fclose(gPcmDumpFh); 16143f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent gPcmDumpFh = NULL; 16153f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16163f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent char *path = strndup((char *)pCmdData, cmdSize); 16173f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent gPcmDumpFh = fopen((char *)path, "wb"); 16183f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pthread_mutex_unlock(&gPcmDumpLock); 16193f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_START: path %s gPcmDumpFh %p", 16203f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent path, gPcmDumpFh); 16213f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGE_IF(gPcmDumpFh <= 0, "gPcmDumpFh open error %d %s", errno, strerror(errno)); 16223f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent free(path); 16233f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = sizeof(int); 16243f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(int *)pReplyData = 0; 16253f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } break; 16263f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent case PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: { 16273f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (pReplyData == NULL || replySize == NULL) { 16283f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGE("PreProcessingFx_Command cmdCode Case: " 16293f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP: ERROR"); 16303f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = 0; 16313f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 16323f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16333f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pthread_mutex_lock(&gPcmDumpLock); 16343f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (gPcmDumpFh != NULL) { 16353f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent fclose(gPcmDumpFh); 16363f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent gPcmDumpFh = NULL; 16373f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16383f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pthread_mutex_unlock(&gPcmDumpLock); 16393f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PREPROC_CMD_DUAL_MIC_PCM_DUMP_STOP"); 16403f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = sizeof(int); 16413f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(int *)pReplyData = 0; 16423f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } break; 16433f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ///// test commands end 16443f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 16453f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent case EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: { 16463f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if(!gDualMicEnabled) { 16473f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 16483f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16493f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (pCmdData == NULL|| cmdSize != 2 * sizeof(uint32_t) || 16503f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pReplyData == NULL || replySize == NULL) { 16513f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGE("PreProcessingFx_Command cmdCode Case: " 16523f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS: ERROR"); 16533f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = 0; 16543f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 16553f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16563f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || 16573f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent !effect->aux_channels_on) { 16583f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PreProcessingFx_Command feature EFFECT_FEATURE_AUX_CHANNELS not supported by" 16593f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent " fx %d", effect->procId); 16603f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pReplyData = -ENOSYS; 16613f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = sizeof(uint32_t); 16623f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent break; 16633f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16643f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent size_t num_configs = *((uint32_t *)pCmdData + 1); 16653f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (*replySize < (2 * sizeof(uint32_t) + 16663f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent num_configs * sizeof(channel_config_t))) { 16673f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = 0; 16683f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 16693f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16703f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 16713f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *((uint32_t *)pReplyData + 1) = CHANNEL_CFG_CNT; 16723f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (num_configs < CHANNEL_CFG_CNT || 16733f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize < (2 * sizeof(uint32_t) + 16743f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent CHANNEL_CFG_CNT * sizeof(channel_config_t))) { 16753f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pReplyData = -ENOMEM; 16763f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } else { 16773f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent num_configs = CHANNEL_CFG_CNT; 16783f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pReplyData = 0; 16793f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16803f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS num config %d", 16813f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent num_configs); 16823f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent 16833f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = 2 * sizeof(uint32_t) + num_configs * sizeof(channel_config_t); 16843f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *((uint32_t *)pReplyData + 1) = num_configs; 16853f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent memcpy((uint32_t *)pReplyData + 2, &sDualMicConfigs, num_configs * sizeof(channel_config_t)); 16863f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } break; 16873f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent case EFFECT_CMD_GET_FEATURE_CONFIG: 16883f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if(!gDualMicEnabled) { 16893f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 16903f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16913f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (pCmdData == NULL|| cmdSize != sizeof(uint32_t) || 16923f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pReplyData == NULL || replySize == NULL || 16933f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize < sizeof(uint32_t) + sizeof(channel_config_t)) { 16943f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGE("PreProcessingFx_Command cmdCode Case: " 16953f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "EFFECT_CMD_GET_FEATURE_CONFIG: ERROR"); 16963f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 16973f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 16983f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) { 16993f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pReplyData = -ENOSYS; 17003f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = sizeof(uint32_t); 17013f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent break; 17023f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 17033f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PreProcessingFx_Command EFFECT_CMD_GET_FEATURE_CONFIG"); 17043f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pReplyData = 0; 17053f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = sizeof(uint32_t) + sizeof(channel_config_t); 17063f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent memcpy((uint32_t *)pReplyData + 1, 17073f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent &sDualMicConfigs[effect->cur_channel_config], 17083f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent sizeof(channel_config_t)); 17093f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent break; 17103f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent case EFFECT_CMD_SET_FEATURE_CONFIG: { 17113f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG: " 17123f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "gDualMicEnabled %d effect->aux_channels_on %d", 17133f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent gDualMicEnabled, effect->aux_channels_on); 17143f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if(!gDualMicEnabled) { 17153f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 17163f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 17173f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (pCmdData == NULL|| cmdSize != (sizeof(uint32_t) + sizeof(channel_config_t)) || 17183f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pReplyData == NULL || replySize == NULL || 17193f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize < sizeof(uint32_t)) { 17203f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGE("PreProcessingFx_Command cmdCode Case: " 17213f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n" 17223f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "pCmdData %p cmdSize %d pReplyData %p replySize %p *replySize %d", 17233f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent pCmdData, cmdSize, pReplyData, replySize, replySize ? *replySize : -1); 17243f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent return -EINVAL; 17253f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 17263f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *replySize = sizeof(uint32_t); 17273f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (*(uint32_t *)pCmdData != EFFECT_FEATURE_AUX_CHANNELS || !effect->aux_channels_on) { 17283f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pReplyData = -ENOSYS; 17293f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PreProcessingFx_Command cmdCode Case: " 17303f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "EFFECT_CMD_SET_FEATURE_CONFIG: ERROR\n" 17313f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "CmdData %d effect->aux_channels_on %d", 17323f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pCmdData, effect->aux_channels_on); 17333f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent break; 17343f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 17353f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent size_t i; 17363f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent for (i = 0; i < CHANNEL_CFG_CNT;i++) { 17373f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (memcmp((uint32_t *)pCmdData + 1, 17383f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent &sDualMicConfigs[i], sizeof(channel_config_t)) == 0) { 17393f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent break; 17403f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 17413f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 17423f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent if (i == CHANNEL_CFG_CNT) { 17433f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pReplyData = -EINVAL; 17443f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGW("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG invalid config" 17453f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "[%08x].[%08x]", *((uint32_t *)pCmdData + 1), *((uint32_t *)pCmdData + 2)); 17463f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } else { 17473f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent effect->cur_channel_config = i; 17483f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent *(uint32_t *)pReplyData = 0; 17493f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent ALOGV("PreProcessingFx_Command EFFECT_CMD_SET_FEATURE_CONFIG New config" 17503f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent "[%08x].[%08x]", sDualMicConfigs[i].main_channels, sDualMicConfigs[i].aux_channels); 17513f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } 17523f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent } break; 17533f9c84c0a5af83fceb8669390e2d71b75ec7b550Eric Laurent#endif 1754a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent default: 1755a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1756a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1757a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1758a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1759a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1760a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1761a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint PreProcessingFx_GetDescriptor(effect_handle_t self, 1762a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect_descriptor_t *pDescriptor) 1763a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1764a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_effect_t * effect = (preproc_effect_t *) self; 1765a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1766a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect == NULL || pDescriptor == NULL) { 1767a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1768a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1769a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1770a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten *pDescriptor = *sDescriptors[effect->procId]; 1771a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1772a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1773a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1774a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1775a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint PreProcessingFx_ProcessReverse(effect_handle_t self, 1776a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent audio_buffer_t *inBuffer, 17770f714a464d2425afe00d6450535e763131b40844Eric Laurent audio_buffer_t *outBuffer __unused) 1778a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1779a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_effect_t * effect = (preproc_effect_t *)self; 1780a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status = 0; 1781a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1782a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (effect == NULL){ 17835ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("PreProcessingFx_ProcessReverse() ERROR effect == NULL"); 1784a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1785a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1786a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_session_t * session = (preproc_session_t *)effect->session; 1787a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1788a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (inBuffer == NULL || inBuffer->raw == NULL){ 17895ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("PreProcessingFx_ProcessReverse() ERROR bad pointer"); 1790a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1791a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1792a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1793a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revProcessedMsk |= (1<<effect->procId); 1794a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 17953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block// ALOGV("PreProcessingFx_ProcessReverse In %d frames revEnabledMsk %08x revProcessedMsk %08x", 1796a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// inBuffer->frameCount, session->revEnabledMsk, session->revProcessedMsk); 1797a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1798a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1799a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if ((session->revProcessedMsk & session->revEnabledMsk) == session->revEnabledMsk) { 1800a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->session->revProcessedMsk = 0; 1801a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->revResampler != NULL) { 1802a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t fr = session->frameCount - session->framesRev; 1803a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (inBuffer->frameCount < fr) { 1804a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr = inBuffer->frameCount; 1805a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1806a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->revBufSize < session->framesRev + fr) { 1807679650f008a6dee59d89238fab17edd208a1878eEric Laurent int16_t *buf; 1808a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revBufSize = session->framesRev + fr; 1809679650f008a6dee59d89238fab17edd208a1878eEric Laurent buf = (int16_t *)realloc(session->revBuf, 1810679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->revBufSize * session->inChannelCount * sizeof(int16_t)); 1811679650f008a6dee59d89238fab17edd208a1878eEric Laurent if (buf == NULL) { 1812679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->framesRev = 0; 1813679650f008a6dee59d89238fab17edd208a1878eEric Laurent free(session->revBuf); 1814679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->revBuf = NULL; 1815679650f008a6dee59d89238fab17edd208a1878eEric Laurent return -ENOMEM; 1816679650f008a6dee59d89238fab17edd208a1878eEric Laurent } 1817679650f008a6dee59d89238fab17edd208a1878eEric Laurent session->revBuf = buf; 1818a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1819a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(session->revBuf + session->framesRev * session->inChannelCount, 1820a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->s16, 1821a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr * session->inChannelCount * sizeof(int16_t)); 1822a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1823a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesRev += fr; 1824a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->frameCount = fr; 1825a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->framesRev < session->frameCount) { 1826a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1827a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1828377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT spx_uint32_t frIn = session->framesRev; 1829377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT spx_uint32_t frOut = session->apmFrameCount; 1830a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->inChannelCount == 1) { 1831a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_process_int(session->revResampler, 1832a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 0, 1833a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revBuf, 1834a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frIn, 1835de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->revFrame->data_, 1836a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frOut); 1837a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1838a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent speex_resampler_process_interleaved_int(session->revResampler, 1839a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revBuf, 1840a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frIn, 1841de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh session->revFrame->data_, 1842a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent &frOut); 1843a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1844a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent memcpy(session->revBuf, 1845a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->revBuf + frIn * session->inChannelCount, 1846a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent (session->framesRev - frIn) * session->inChannelCount * sizeof(int16_t)); 1847a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesRev -= frIn; 1848a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1849a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent size_t fr = session->frameCount - session->framesRev; 1850a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (inBuffer->frameCount < fr) { 1851a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr = inBuffer->frameCount; 1852a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1853de7fa31668bd90dba80ff2c0c462492fed873c3dChih-Hung Hsieh memcpy(session->revFrame->data_ + session->framesRev * session->inChannelCount, 1854a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->s16, 1855a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent fr * session->inChannelCount * sizeof(int16_t)); 1856a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesRev += fr; 1857a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent inBuffer->frameCount = fr; 1858a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session->framesRev < session->frameCount) { 1859a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1860a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1861a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->framesRev = 0; 1862a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1863766bf734984a0d5765980f8bd154d111de08ec19Alex Luebs session->revFrame->samples_per_channel_ = session->apmFrameCount; 1864a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect->session->apm->AnalyzeReverseStream(session->revFrame); 1865a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1866a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } else { 1867a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -ENODATA; 1868a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1869a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1870a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1871a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1872a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// effect_handle_t interface implementation for effect 1873a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentconst struct effect_interface_s sEffectInterface = { 1874a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PreProcessingFx_Process, 1875a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PreProcessingFx_Command, 1876a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PreProcessingFx_GetDescriptor, 1877a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent NULL 1878a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 1879a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1880a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentconst struct effect_interface_s sEffectInterfaceReverse = { 1881a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PreProcessingFx_Process, 1882a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PreProcessingFx_Command, 1883a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PreProcessingFx_GetDescriptor, 1884a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent PreProcessingFx_ProcessReverse 1885a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 1886a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1887a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 1888a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent// Effect Library Interface Implementation 1889a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent//------------------------------------------------------------------------------ 1890a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 18915e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint PreProcessingLib_Create(const effect_uuid_t *uuid, 1892a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int32_t sessionId, 1893a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int32_t ioId, 1894a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect_handle_t *pInterface) 1895a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 18963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate: uuid: %08x session %d IO: %d", uuid->timeLow, sessionId, ioId); 1897a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1898a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status; 1899a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent const effect_descriptor_t *desc; 1900a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_session_t *session; 1901a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent uint32_t procId; 1902a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1903a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (PreProc_Init() != 0) { 1904a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return sInitStatus; 1905a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1906a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent desc = PreProc_GetDescriptor(uuid); 1907a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (desc == NULL) { 19085ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("EffectCreate: fx not found uuid: %08x", uuid->timeLow); 1909a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1910a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1911a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent procId = UuidToProcId(&desc->type); 1912a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1913a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session = PreProc_GetSession(procId, sessionId, ioId); 1914a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (session == NULL) { 19155ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("EffectCreate: no more session available"); 1916a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1917a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1918a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1919a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent status = Session_CreateEffect(session, procId, pInterface); 1920a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1921a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (status < 0 && session->createdMsk == 0) { 1922a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent session->io = 0; 1923a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1924a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return status; 1925a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1926a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1927a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentint PreProcessingLib_Release(effect_handle_t interface) 1928a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent{ 1929a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent int status; 19303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectRelease start %p", interface); 1931a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (PreProc_Init() != 0) { 1932a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return sInitStatus; 1933a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1934a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1935a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent preproc_effect_t *fx = (preproc_effect_t *)interface; 1936a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1937a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (fx->session->io == 0) { 1938a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1939a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1940a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return Session_ReleaseEffect(fx->session, fx); 1941a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1942a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 19435e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint PreProcessingLib_GetDescriptor(const effect_uuid_t *uuid, 1944a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent effect_descriptor_t *pDescriptor) { 1945a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1946a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (pDescriptor == NULL || uuid == NULL){ 1947a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1948a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1949a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1950a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent const effect_descriptor_t *desc = PreProc_GetDescriptor(uuid); 1951a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent if (desc == NULL) { 19523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingLib_GetDescriptor() not found"); 1953a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return -EINVAL; 1954a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent } 1955a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 19563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PreProcessingLib_GetDescriptor() got fx %s", desc->name); 1957a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1958a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten *pDescriptor = *desc; 1959a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent return 0; 1960a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent} 1961a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 19627f16b197c76fbae9399242f055a7ee16dcd0fd6dMarco Nelissen// This is the only symbol that needs to be exported 19637f16b197c76fbae9399242f055a7ee16dcd0fd6dMarco Nelissen__attribute__ ((visibility ("default"))) 1964a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurentaudio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 1965c9d8ea7f8f9a1ca8ecd266695e3cac423790b2f9synergydev .tag = AUDIO_EFFECT_LIBRARY_TAG, 1966c9d8ea7f8f9a1ca8ecd266695e3cac423790b2f9synergydev .version = EFFECT_LIBRARY_API_VERSION, 1967c9d8ea7f8f9a1ca8ecd266695e3cac423790b2f9synergydev .name = "Audio Preprocessing Library", 1968c9d8ea7f8f9a1ca8ecd266695e3cac423790b2f9synergydev .implementor = "The Android Open Source Project", 1969c9d8ea7f8f9a1ca8ecd266695e3cac423790b2f9synergydev .create_effect = PreProcessingLib_Create, 1970c9d8ea7f8f9a1ca8ecd266695e3cac423790b2f9synergydev .release_effect = PreProcessingLib_Release, 1971c9d8ea7f8f9a1ca8ecd266695e3cac423790b2f9synergydev .get_descriptor = PreProcessingLib_GetDescriptor 1972a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; 1973a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent 1974a9390d4d571817cdb1d659b4b22b04130dc77a48Eric Laurent}; // extern "C" 1975