173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent/* 273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * Copyright (C) 2013 The Android Open Source Project 373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * 473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * you may not use this file except in compliance with the License. 673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * You may obtain a copy of the License at 773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * 873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * 1073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * Unless required by applicable law or agreed to in writing, software 1173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 1273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * See the License for the specific language governing permissions and 1473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent * limitations under the License. 1573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent */ 1673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 1773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent#define LOG_TAG "voice_processing" 1873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent/*#define LOG_NDEBUG 0*/ 19bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent#include <dlfcn.h> 2073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent#include <cutils/log.h> 2173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent#include <cutils/list.h> 2273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent#include <hardware/audio_effect.h> 2373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent#include <audio_effects/effect_aec.h> 2473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent#include <audio_effects/effect_agc.h> 2573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent#include <audio_effects/effect_ns.h> 2673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 2773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 2873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 2973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// local definitions 3073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 3173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 32bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent#define EFFECTS_DESCRIPTOR_LIBRARY_PATH "/system/lib/soundfx/libqcomvoiceprocessingdescriptors.so" 33bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent 3473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// types of pre processing modules 3573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentenum effect_id 3673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 3773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent AEC_ID, // Acoustic Echo Canceler 3873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent NS_ID, // Noise Suppressor 3973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//ENABLE_AGC AGC_ID, // Automatic Gain Control 4073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent NUM_ID 4173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 4273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 4373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Session state 4473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentenum session_state { 4573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent SESSION_STATE_INIT, // initialized 4673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent SESSION_STATE_CONFIG // configuration received 4773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 4873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 4973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Effect/Preprocessor state 5073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentenum effect_state { 5173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent EFFECT_STATE_INIT, // initialized 5273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent EFFECT_STATE_CREATED, // webRTC engine created 5373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent EFFECT_STATE_CONFIG, // configuration received/disabled 5473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent EFFECT_STATE_ACTIVE // active/enabled 5573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 5673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 5773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Effect context 5873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstruct effect_s { 5973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent const struct effect_interface_s *itfe; 6073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t id; // type of pre processor (enum effect_id) 6173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t state; // current state (enum effect_state) 6273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct session_s *session; // session the effect is on 6373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 6473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 6573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Session context 6673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstruct session_s { 6773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct listnode node; 6873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect_config_t config; 6973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct effect_s effects[NUM_ID]; // effects in this session 7073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t state; // current state (enum session_state) 7173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int id; // audio session ID 7273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int io; // handle of input stream this session is on 7373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t created_msk; // bit field containing IDs of crested pre processors 7473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t enabled_msk; // bit field containing IDs of enabled pre processors 7573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t processed_msk; // bit field containing IDs of pre processors already 7673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 7773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 7873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 7973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 80bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent// Default Effect descriptors. Device specific descriptors should be defined in 81bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent// libqcomvoiceprocessing.<product_name>.so if needed. 8273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 8373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 8473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// UUIDs for effect types have been generated from http://www.itu.int/ITU-T/asn1/uuid.html 8573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// as the pre processing effects are not defined by OpenSL ES 8673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 8773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Acoustic Echo Cancellation 88bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurentstatic const effect_descriptor_t qcom_default_aec_descriptor = { 8973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent { 0x7b491460, 0x8d4d, 0x11e0, 0xbd61, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type 9073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent { 0x0f8d0d2a, 0x59e5, 0x45fe, 0xb6e4, { 0x24, 0x8c, 0x8a, 0x79, 0x91, 0x09 } }, // uuid 9173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent EFFECT_CONTROL_API_VERSION, 9273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 9373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 0, 9473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 0, 9573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent "Acoustic Echo Canceler", 9673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent "Qualcomm Fluence" 9773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 9873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 9973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Noise suppression 100bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurentstatic const effect_descriptor_t qcom_default_ns_descriptor = { 10173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent { 0x58b4b260, 0x8e06, 0x11e0, 0xaa8e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type 10273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent { 0x1d97bb0b, 0x9e2f, 0x4403, 0x9ae3, { 0x58, 0xc2, 0x55, 0x43, 0x06, 0xf8 } }, // uuid 10373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent EFFECT_CONTROL_API_VERSION, 10473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 10573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 0, 10673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 0, 10773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent "Noise Suppression", 10873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent "Qualcomm Fluence" 10973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 11073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 11173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//ENABLE_AGC 11273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Automatic Gain Control 113bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent//static const effect_descriptor_t qcom_default_agc_descriptor = { 11473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// { 0x0a8abfe0, 0x654c, 0x11e0, 0xba26, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // type 11573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// { 0x0dd49521, 0x8c59, 0x40b1, 0xb403, { 0xe0, 0x8d, 0x5f, 0x01, 0x87, 0x5e } }, // uuid 11673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// EFFECT_CONTROL_API_VERSION, 11773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 11873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// 0, 11973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// 0, 12073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// "Automatic Gain Control", 12173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// "Qualcomm Fluence" 12273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//}; 12373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 124bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurentconst effect_descriptor_t *descriptors[NUM_ID] = { 125bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent &qcom_default_aec_descriptor, 126bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent &qcom_default_ns_descriptor, 127bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent//ENABLE_AGC &qcom_default_agc_descriptor, 12873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 12973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 13073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 13173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int init_status = 1; 13273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstruct listnode session_list; 13373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic const struct effect_interface_s effect_interface; 13473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic const effect_uuid_t * uuid_to_id_table[NUM_ID]; 13573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 13673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 13773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Helper functions 13873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 13973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 14073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic const effect_uuid_t * id_to_uuid(int id) 14173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 14273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (id >= NUM_ID) 14373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return EFFECT_UUID_NULL; 14473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 14573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return uuid_to_id_table[id]; 14673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 14773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 14873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic uint32_t uuid_to_id(const effect_uuid_t * uuid) 14973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 15073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent size_t i; 15173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent for (i = 0; i < NUM_ID; i++) 15273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (memcmp(uuid, uuid_to_id_table[i], sizeof(*uuid)) == 0) 15373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 15473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 15573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return i; 15673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 15773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 15873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 15973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Effect functions 16073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 16173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 16273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic void session_set_fx_enabled(struct session_s *session, uint32_t id, bool enabled); 16373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 16473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent#define BAD_STATE_ABORT(from, to) \ 16573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to); 16673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 16773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int effect_set_state(struct effect_s *effect, uint32_t state) 16873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 16973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int status = 0; 17073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("effect_set_state() id %d, new %d old %d", effect->id, state, effect->state); 17173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent switch(state) { 17273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_INIT: 17373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent switch(effect->state) { 17473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_ACTIVE: 17573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session_set_fx_enabled(effect->session, effect->id, false); 17673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CONFIG: 17773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CREATED: 17873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_INIT: 17973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 18073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent default: 18173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent BAD_STATE_ABORT(effect->state, state); 18273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 18373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 18473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CREATED: 18573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent switch(effect->state) { 18673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_INIT: 18773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 18873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CREATED: 18973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_ACTIVE: 19073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CONFIG: 19173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGE("effect_set_state() invalid transition"); 19273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent status = -ENOSYS; 19373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 19473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent default: 19573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent BAD_STATE_ABORT(effect->state, state); 19673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 19773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 19873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CONFIG: 19973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent switch(effect->state) { 20073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_INIT: 20173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGE("effect_set_state() invalid transition"); 20273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent status = -ENOSYS; 20373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 20473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_ACTIVE: 20573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session_set_fx_enabled(effect->session, effect->id, false); 20673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 20773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CREATED: 20873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CONFIG: 20973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 21073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent default: 21173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent BAD_STATE_ABORT(effect->state, state); 21273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 21373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 21473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_ACTIVE: 21573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent switch(effect->state) { 21673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_INIT: 21773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CREATED: 21873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGE("effect_set_state() invalid transition"); 21973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent status = -ENOSYS; 22073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 22173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_ACTIVE: 22273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent // enabling an already enabled effect is just ignored 22373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 22473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_STATE_CONFIG: 22573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session_set_fx_enabled(effect->session, effect->id, true); 22673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 22773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent default: 22873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent BAD_STATE_ABORT(effect->state, state); 22973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 23073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 23173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent default: 23273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent BAD_STATE_ABORT(effect->state, state); 23373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 23473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 23573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (status == 0) 23673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect->state = state; 23773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 23873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return status; 23973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 24073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 24173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int effect_init(struct effect_s *effect, uint32_t id) 24273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 24373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect->itfe = &effect_interface; 24473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect->id = id; 24573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect->state = EFFECT_STATE_INIT; 24673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 24773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 24873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 24973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int effect_create(struct effect_s *effect, 25073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct session_s *session, 25173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect_handle_t *interface) 25273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 25373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect->session = session; 25473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *interface = (effect_handle_t)&effect->itfe; 25573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return effect_set_state(effect, EFFECT_STATE_CREATED); 25673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 25773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 25873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int effect_release(struct effect_s *effect) 25973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 26073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return effect_set_state(effect, EFFECT_STATE_INIT); 26173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 26273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 26373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 26473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 26573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Session functions 26673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 26773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 26873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int session_init(struct session_s *session) 26973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 27073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent size_t i; 27173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int status = 0; 27273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 27373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->state = SESSION_STATE_INIT; 27473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->id = 0; 27573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->io = 0; 27673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->created_msk = 0; 27773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent for (i = 0; i < NUM_ID && status == 0; i++) 27873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent status = effect_init(&session->effects[i], i); 27973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 28073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return status; 28173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 28273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 28373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 28473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int session_create_effect(struct session_s *session, 28573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int32_t id, 28673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect_handle_t *interface) 28773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 28873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int status = -ENOMEM; 28973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 29073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("session_create_effect() %s, created_msk %08x", 29173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent id == AEC_ID ? "AEC" : id == NS_ID ? "NS" : "?", session->created_msk); 29273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 29373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (session->created_msk == 0) { 29473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->config.inputCfg.samplingRate = 16000; 29573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->config.inputCfg.channels = AUDIO_CHANNEL_IN_MONO; 29673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 29773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->config.outputCfg.samplingRate = 16000; 29873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->config.outputCfg.channels = AUDIO_CHANNEL_IN_MONO; 29973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 30073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->enabled_msk = 0; 30173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->processed_msk = 0; 30273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 30373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent status = effect_create(&session->effects[id], session, interface); 30473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (status < 0) 30573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent goto error; 30673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 30773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("session_create_effect() OK"); 30873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->created_msk |= (1<<id); 30973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return status; 31073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 31173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurenterror: 31273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return status; 31373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 31473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 31573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int session_release_effect(struct session_s *session, 31673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct effect_s *fx) 31773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 31873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGW_IF(effect_release(fx) != 0, " session_release_effect() failed for id %d", fx->id); 31973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 32073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->created_msk &= ~(1<<fx->id); 32173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (session->created_msk == 0) 32273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent { 32373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("session_release_effect() last effect: removing session"); 32473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent list_remove(&session->node); 32573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent free(session); 32673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 32773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 32873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 32973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 33073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 33173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 33273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int session_set_config(struct session_s *session, effect_config_t *config) 33373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 33473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int status; 33573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 33673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (config->inputCfg.samplingRate != config->outputCfg.samplingRate || 33773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent config->inputCfg.format != config->outputCfg.format || 33873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) 33973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 34073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 34173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("session_set_config() sampling rate %d channels %08x", 34273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent config->inputCfg.samplingRate, config->inputCfg.channels); 34373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 34473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent // if at least one process is enabled, do not accept configuration changes 34573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (session->enabled_msk) { 34673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (session->config.inputCfg.samplingRate != config->inputCfg.samplingRate || 34773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->config.inputCfg.channels != config->inputCfg.channels || 34873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->config.outputCfg.channels != config->outputCfg.channels) 34973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -ENOSYS; 35073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent else 35173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 35273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 35373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 35473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent memcpy(&session->config, config, sizeof(effect_config_t)); 35573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 35673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->state = SESSION_STATE_CONFIG; 35773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 35873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 35973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 36073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic void session_get_config(struct session_s *session, effect_config_t *config) 36173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 36273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent memcpy(config, &session->config, sizeof(effect_config_t)); 36373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 36473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent config->inputCfg.mask = config->outputCfg.mask = 36573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent (EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT); 36673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 36773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 36873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 36973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic void session_set_fx_enabled(struct session_s *session, uint32_t id, bool enabled) 37073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 37173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (enabled) { 37273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if(session->enabled_msk == 0) { 37373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent /* do first enable here */ 37473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 37573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->enabled_msk |= (1 << id); 37673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } else { 37773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->enabled_msk &= ~(1 << id); 37873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if(session->enabled_msk == 0) { 37973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent /* do last enable here */ 38073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 38173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 38273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("session_set_fx_enabled() id %d, enabled %d enabled_msk %08x", 38373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent id, enabled, session->enabled_msk); 38473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->processed_msk = 0; 38573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 38673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 38773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 38873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Global functions 38973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 39073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 39173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic struct session_s *get_session(int32_t id, int32_t sessionId, int32_t ioId) 39273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 39373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent size_t i; 39473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int free = -1; 39573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct listnode *node; 39673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct session_s *session; 39773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 39873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent list_for_each(node, &session_list) { 39973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session = node_to_item(node, struct session_s, node); 40073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (session->io == ioId) { 40173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (session->created_msk & (1 << id)) { 40273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("get_session() effect %d already created", id); 40373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return NULL; 40473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 40573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("get_session() found session %p", session); 40673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return session; 40773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 40873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 40973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 41073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session = (struct session_s *)calloc(1, sizeof(struct session_s)); 41173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session_init(session); 41273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->id = sessionId; 41373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->io = ioId; 41473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent list_add_tail(&session_list, &session->node); 41573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 41673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("get_session() created session %p", session); 41773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 41873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return session; 41973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 42073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 42173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int init() { 422bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent void *lib_handle; 423bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent const effect_descriptor_t *desc; 42473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 42573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (init_status <= 0) 42673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return init_status; 42773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 428bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent if (access(EFFECTS_DESCRIPTOR_LIBRARY_PATH, R_OK) == 0) { 429bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent lib_handle = dlopen(EFFECTS_DESCRIPTOR_LIBRARY_PATH, RTLD_NOW); 430bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent if (lib_handle == NULL) { 431bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent ALOGE("%s: DLOPEN failed for %s", __func__, EFFECTS_DESCRIPTOR_LIBRARY_PATH); 432bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent } else { 433bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent ALOGV("%s: DLOPEN successful for %s", __func__, EFFECTS_DESCRIPTOR_LIBRARY_PATH); 434bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent desc = (const effect_descriptor_t *)dlsym(lib_handle, 435bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent "qcom_product_aec_descriptor"); 436bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent if (desc) 437bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent descriptors[AEC_ID] = desc; 438bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent 439bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent desc = (const effect_descriptor_t *)dlsym(lib_handle, 440bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent "qcom_product_ns_descriptor"); 441bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent if (desc) 442bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent descriptors[NS_ID] = desc; 443bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent 444bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent//ENABLE_AGC 445bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent// desc = (const effect_descriptor_t *)dlsym(lib_handle, 446bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent// "qcom_product_agc_descriptor"); 447bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent// if (desc) 448bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent// descriptors[AGC_ID] = desc; 449bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent } 450bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent } 451bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent 45273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uuid_to_id_table[AEC_ID] = FX_IID_AEC; 45373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uuid_to_id_table[NS_ID] = FX_IID_NS; 454bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent//ENABLE_AGC uuid_to_id_table[AGC_ID] = FX_IID_AGC; 45573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 45673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent list_init(&session_list); 45773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 45873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent init_status = 0; 45973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return init_status; 46073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 46173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 46273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic const effect_descriptor_t *get_descriptor(const effect_uuid_t *uuid) 46373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 46473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent size_t i; 46573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent for (i = 0; i < NUM_ID; i++) 46673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (memcmp(&descriptors[i]->uuid, uuid, sizeof(effect_uuid_t)) == 0) 46773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return descriptors[i]; 46873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 46973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return NULL; 47073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 47173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 47273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 47373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 47473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Effect Control Interface Implementation 47573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 47673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 47773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int fx_process(effect_handle_t self, 47873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent audio_buffer_t *inBuffer, 47973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent audio_buffer_t *outBuffer) 48073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 48173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct effect_s *effect = (struct effect_s *)self; 48273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct session_s *session; 48373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 48473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (effect == NULL) { 48573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_process() ERROR effect == NULL"); 48673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 48773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 48873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 48973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (inBuffer == NULL || inBuffer->raw == NULL || 49073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent outBuffer == NULL || outBuffer->raw == NULL) { 49173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGW("fx_process() ERROR bad pointer"); 49273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 49373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 49473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 49573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session = (struct session_s *)effect->session; 49673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 49773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session->processed_msk |= (1<<effect->id); 49873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 49973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if ((session->processed_msk & session->enabled_msk) == session->enabled_msk) { 50073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect->session->processed_msk = 0; 50173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 50273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } else 50373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -ENODATA; 50473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 50573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 50673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int fx_command(effect_handle_t self, 50773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t cmdCode, 50873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t cmdSize, 50973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent void *pCmdData, 51073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t *replySize, 51173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent void *pReplyData) 51273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 51373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct effect_s *effect = (struct effect_s *)self; 51473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 51573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (effect == NULL) 51673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 51773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 51873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent //ALOGV("fx_command: command %d cmdSize %d",cmdCode, cmdSize); 51973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 52073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent switch (cmdCode) { 52173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_INIT: 52273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pReplyData == NULL || *replySize != sizeof(int)) 52373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 52473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 52573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *(int *)pReplyData = 0; 52673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 52773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 52873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_SET_CONFIG: { 52973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pCmdData == NULL|| 53073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdSize != sizeof(effect_config_t)|| 53173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent pReplyData == NULL|| 53273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *replySize != sizeof(int)) { 53373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() EFFECT_CMD_SET_CONFIG invalid args"); 53473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 53573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 53673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *(int *)pReplyData = session_set_config(effect->session, (effect_config_t *)pCmdData); 53773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (*(int *)pReplyData != 0) 53873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 53973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 54073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (effect->state != EFFECT_STATE_ACTIVE) 54173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *(int *)pReplyData = effect_set_state(effect, EFFECT_STATE_CONFIG); 54273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 54373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } break; 54473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 54573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_GET_CONFIG: 54673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pReplyData == NULL || 54773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *replySize != sizeof(effect_config_t)) { 54873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() EFFECT_CMD_GET_CONFIG invalid args"); 54973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 55073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 55173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 55273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session_get_config(effect->session, (effect_config_t *)pReplyData); 55373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 55473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 55573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_RESET: 55673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 55773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 55873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_GET_PARAM: { 55973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pCmdData == NULL || 56073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdSize < (int)sizeof(effect_param_t) || 56173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent pReplyData == NULL || 56273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *replySize < (int)sizeof(effect_param_t)) { 56373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() EFFECT_CMD_GET_PARAM invalid args"); 56473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 56573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 56673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect_param_t *p = (effect_param_t *)pCmdData; 56773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 56873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize); 56973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent p = (effect_param_t *)pReplyData; 57073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent p->status = -ENOSYS; 57173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 57273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } break; 57373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 57473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_SET_PARAM: { 57573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pCmdData == NULL|| 57673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdSize < (int)sizeof(effect_param_t) || 57773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent pReplyData == NULL || 57873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *replySize != sizeof(int32_t)) { 57973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() EFFECT_CMD_SET_PARAM invalid args"); 58073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 58173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 58273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect_param_t *p = (effect_param_t *) pCmdData; 58373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 58473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (p->psize != sizeof(int32_t)) { 58573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() EFFECT_CMD_SET_PARAM invalid param format"); 58673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 58773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 58873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *(int *)pReplyData = -ENOSYS; 58973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } break; 59073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 59173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_ENABLE: 59273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pReplyData == NULL || *replySize != sizeof(int)) { 59373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() EFFECT_CMD_ENABLE invalid args"); 59473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 59573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 59673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *(int *)pReplyData = effect_set_state(effect, EFFECT_STATE_ACTIVE); 59773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 59873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 59973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_DISABLE: 60073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pReplyData == NULL || *replySize != sizeof(int)) { 60173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() EFFECT_CMD_DISABLE invalid args"); 60273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 60373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 60473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *(int *)pReplyData = effect_set_state(effect, EFFECT_STATE_CONFIG); 60573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 60673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 60773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_SET_DEVICE: 60873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_SET_INPUT_DEVICE: 60973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_SET_VOLUME: 61073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent case EFFECT_CMD_SET_AUDIO_MODE: 61173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pCmdData == NULL || 61273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdSize != sizeof(uint32_t)) { 61373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() %s invalid args", 61473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdCode == EFFECT_CMD_SET_DEVICE ? "EFFECT_CMD_SET_DEVICE" : 61573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdCode == EFFECT_CMD_SET_INPUT_DEVICE ? "EFFECT_CMD_SET_INPUT_DEVICE" : 61673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdCode == EFFECT_CMD_SET_VOLUME ? "EFFECT_CMD_SET_VOLUME" : 61773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdCode == EFFECT_CMD_SET_AUDIO_MODE ? "EFFECT_CMD_SET_AUDIO_MODE" : 61873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ""); 61973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 62073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 62173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("fx_command() %s value %08x", 62273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdCode == EFFECT_CMD_SET_DEVICE ? "EFFECT_CMD_SET_DEVICE" : 62373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdCode == EFFECT_CMD_SET_INPUT_DEVICE ? "EFFECT_CMD_SET_INPUT_DEVICE" : 62473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdCode == EFFECT_CMD_SET_VOLUME ? "EFFECT_CMD_SET_VOLUME" : 62573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent cmdCode == EFFECT_CMD_SET_AUDIO_MODE ? "EFFECT_CMD_SET_AUDIO_MODE": 62673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent "", 62773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *(int *)pCmdData); 62873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent break; 62973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 63073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent default: 63173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 63273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 63373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 63473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 63573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 63673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 63773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int fx_get_descriptor(effect_handle_t self, 63873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect_descriptor_t *pDescriptor) 63973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 64073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct effect_s *effect = (struct effect_s *)self; 64173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 64273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (effect == NULL || pDescriptor == NULL) 64373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 64473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 64573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *pDescriptor = *descriptors[effect->id]; 64673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 64773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 64873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 64973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 65073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 65173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// effect_handle_t interface implementation for effect 65273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic const struct effect_interface_s effect_interface = { 65373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent fx_process, 65473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent fx_command, 65573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent fx_get_descriptor, 65673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent NULL 65773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 65873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 65973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 66073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// Effect Library Interface Implementation 66173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent//------------------------------------------------------------------------------ 66273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 66373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int lib_create(const effect_uuid_t *uuid, 66473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int32_t sessionId, 66573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int32_t ioId, 66673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect_handle_t *pInterface) 66773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 66873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("lib_create: uuid: %08x session %d IO: %d", uuid->timeLow, sessionId, ioId); 66973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 67073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent int status; 67173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent const effect_descriptor_t *desc; 67273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct session_s *session; 67373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent uint32_t id; 67473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 67573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (init() != 0) 67673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return init_status; 67773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 67873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent desc = get_descriptor(uuid); 67973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 68073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (desc == NULL) { 68173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGW("lib_create: fx not found uuid: %08x", uuid->timeLow); 68273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 68373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 68473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent id = uuid_to_id(&desc->type); 68573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 68673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session = get_session(id, sessionId, ioId); 68773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 68873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (session == NULL) { 68973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGW("lib_create: no more session available"); 69073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 69173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 69273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 69373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent status = session_create_effect(session, id, pInterface); 69473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 69573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (status < 0 && session->created_msk == 0) { 69673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent list_remove(&session->node); 69773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent free(session); 69873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 69973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return status; 70073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 70173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 70273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int lib_release(effect_handle_t interface) 70373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 70473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct listnode *node; 70573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct session_s *session; 70673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 70773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("lib_release %p", interface); 70873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (init() != 0) 70973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return init_status; 71073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 71173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent struct effect_s *fx = (struct effect_s *)interface; 71273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 71373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent list_for_each(node, &session_list) { 71473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session = node_to_item(node, struct session_s, node); 71573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (session == fx->session) { 71673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent session_release_effect(fx->session, fx); 71773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 71873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 71973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 72073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 72173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 72273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 72373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 72473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentstatic int lib_get_descriptor(const effect_uuid_t *uuid, 72573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent effect_descriptor_t *pDescriptor) 72673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent{ 72773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent const effect_descriptor_t *desc; 72873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 72973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (pDescriptor == NULL || uuid == NULL) 73073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 73173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 732bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent if (init() != 0) 733bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent return init_status; 734bdfd2924d535d8d3de1bd63c407568134641ef18Eric Laurent 73573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent desc = get_descriptor(uuid); 73673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent if (desc == NULL) { 73773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("lib_get_descriptor() not found"); 73873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return -EINVAL; 73973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent } 74073fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 74173fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent ALOGV("lib_get_descriptor() got fx %s", desc->name); 74273fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 74373fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent *pDescriptor = *desc; 74473fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent return 0; 74573fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent} 74673fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent 74773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent// This is the only symbol that needs to be exported 74873fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent__attribute__ ((visibility ("default"))) 74973fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurentaudio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 75030337434288e9abda1c6b59e88c17d76e84755e1synergydev .tag = AUDIO_EFFECT_LIBRARY_TAG, 75130337434288e9abda1c6b59e88c17d76e84755e1synergydev .version = EFFECT_LIBRARY_API_VERSION, 75230337434288e9abda1c6b59e88c17d76e84755e1synergydev .name = "MSM8960 Audio Preprocessing Library", 75330337434288e9abda1c6b59e88c17d76e84755e1synergydev .implementor = "The Android Open Source Project", 75430337434288e9abda1c6b59e88c17d76e84755e1synergydev .create_effect = lib_create, 75530337434288e9abda1c6b59e88c17d76e84755e1synergydev .release_effect = lib_release, 75630337434288e9abda1c6b59e88c17d76e84755e1synergydev .get_descriptor = lib_get_descriptor 75773fb11d93274bc1c3675b24e910a4cb87571ffd0Eric Laurent}; 758