141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Copyright (C) 2014 The Android Open Source Project 341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * 441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Licensed under the Apache License, Version 2.0 (the "License"); 541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * you may not use this file except in compliance with the License. 641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * You may obtain a copy of the License at 741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * 841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * http://www.apache.org/licenses/LICENSE-2.0 941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * 1041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Unless required by applicable law or agreed to in writing, software 1141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * distributed under the License is distributed on an "AS IS" BASIS, 1241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * See the License for the specific language governing permissions and 1441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * limitations under the License. 1541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 1641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 1741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#define LOG_TAG "offload_effect_bundle" 1841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George//#define LOG_NDEBUG 0 1941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 2037a7699e96b3a4433e80b3899230809976d5e14bGlenn Kasten#include <stdlib.h> 2141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include <cutils/list.h> 2241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include <cutils/log.h> 2341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include <system/thread_defs.h> 2441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include <tinyalsa/asoundlib.h> 2541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include <hardware/audio_effect.h> 2641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 2741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include "bundle.h" 2841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include "equalizer.h" 2941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include "bass_boost.h" 3041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include "virtualizer.h" 3141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George#include "reverb.h" 3241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 3341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeenum { 3441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George EFFECT_STATE_UNINITIALIZED, 3541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George EFFECT_STATE_INITIALIZED, 3641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George EFFECT_STATE_ACTIVE, 3741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George}; 3841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 3941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeconst effect_descriptor_t *descriptors[] = { 4041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George &equalizer_descriptor, 4141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George &bassboost_descriptor, 4241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George &virtualizer_descriptor, 4341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George &aux_env_reverb_descriptor, 4441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George &ins_env_reverb_descriptor, 4541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George &aux_preset_reverb_descriptor, 4641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George &ins_preset_reverb_descriptor, 4741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George NULL, 4841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George}; 4941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 5041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgepthread_once_t once = PTHREAD_ONCE_INIT; 5141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint init_status; 5241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 5341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * list of created effects. 5441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Updated by offload_effects_bundle_hal_start_output() 5541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * and offload_effects_bundle_hal_stop_output() 5641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 5741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgestruct listnode created_effects_list; 5841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 5941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * list of active output streams. 6041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Updated by offload_effects_bundle_hal_start_output() 6141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * and offload_effects_bundle_hal_stop_output() 6241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 6341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgestruct listnode active_outputs_list; 6441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 6541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * lock must be held when modifying or accessing 6641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * created_effects_list or active_outputs_list 6741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 6841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgepthread_mutex_t lock; 6941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 7041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 7141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 7241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Local functions 7341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 7441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgestatic void init_once() { 7541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_init(&created_effects_list); 7641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_init(&active_outputs_list); 7741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 7841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_init(&lock, NULL); 7941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 8041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George init_status = 0; 8141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 8241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 8341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint lib_init() 8441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 8541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_once(&once, init_once); 8641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return init_status; 8741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 8841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 8941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgebool effect_exists(effect_context_t *context) 9041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 9141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *node; 9241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 9341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_for_each(node, &created_effects_list) { 9441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *fx_ctxt = node_to_item(node, 9541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t, 9641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effects_list_node); 9741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (fx_ctxt == context) { 9841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return true; 9941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 10041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 10141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return false; 10241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 10341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 10441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeoutput_context_t *get_output(audio_io_handle_t output) 10541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 10641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *node; 10741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 10841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_for_each(node, &active_outputs_list) { 10941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t *out_ctxt = node_to_item(node, 11041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t, 11141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George outputs_list_node); 11241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (out_ctxt->handle == output) 11341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return out_ctxt; 11441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 11541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return NULL; 11641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 11741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 11841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgevoid add_effect_to_output(output_context_t * output, effect_context_t *context) 11941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 12041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *fx_node; 12141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 12241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_for_each(fx_node, &output->effects_list) { 12341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *fx_ctxt = node_to_item(fx_node, 12441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t, 12541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_node); 12641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (fx_ctxt == context) 12741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return; 12841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 12941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_add_tail(&output->effects_list, &context->output_node); 13041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.start) 13141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.start(context, output); 13241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 13341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 13441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 13541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgevoid remove_effect_from_output(output_context_t * output, 13641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *context) 13741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 13841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *fx_node; 13941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 14041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_for_each(fx_node, &output->effects_list) { 14141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *fx_ctxt = node_to_item(fx_node, 14241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t, 14341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_node); 14441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (fx_ctxt == context) { 14541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.stop) 14641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.stop(context, output); 14741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_remove(&context->output_node); 14841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return; 14941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 15041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 15141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 15241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 15341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgebool effects_enabled() 15441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 15541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *out_node; 15641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 15741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_for_each(out_node, &active_outputs_list) { 15841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *fx_node; 15941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t *out_ctxt = node_to_item(out_node, 16041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t, 16141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George outputs_list_node); 16241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 16341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_for_each(fx_node, &out_ctxt->effects_list) { 16441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *fx_ctxt = node_to_item(fx_node, 16541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t, 16641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_node); 16741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if ((fx_ctxt->state == EFFECT_STATE_ACTIVE) && 16841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George (fx_ctxt->ops.process != NULL)) 16941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return true; 17041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 17141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 17241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return false; 17341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 17441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 17541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 17641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 17741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Interface from audio HAL 17841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 17941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George__attribute__ ((visibility ("default"))) 18041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint offload_effects_bundle_hal_start_output(audio_io_handle_t output, int pcm_id) 18141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 18241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int ret = 0; 18341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *node; 18441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George char mixer_string[128]; 18541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t * out_ctxt = NULL; 18641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 18741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s output %d pcm_id %d", __func__, output, pcm_id); 18841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 18941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (lib_init() != 0) 19041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return init_status; 19141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 19241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_lock(&lock); 19341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (get_output(output) != NULL) { 19441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGW("%s output already started", __func__); 19541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ret = -ENOSYS; 19641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 19741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 19841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 19941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt = (output_context_t *) 20041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George malloc(sizeof(output_context_t)); 20141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt->handle = output; 20241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt->pcm_device_id = pcm_id; 20341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 20441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George /* populate the mixer control to send offload parameters */ 20541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George snprintf(mixer_string, sizeof(mixer_string), 20641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George "%s %d", "Audio Effects Config", out_ctxt->pcm_device_id); 20741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt->mixer = mixer_open(MIXER_CARD); 20841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (!out_ctxt->mixer) { 20941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGE("Failed to open mixer"); 21041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt->ctl = NULL; 21141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ret = -EINVAL; 21241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George free(out_ctxt); 21341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 21441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } else { 21541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt->ctl = mixer_get_ctl_by_name(out_ctxt->mixer, mixer_string); 21641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (!out_ctxt->ctl) { 21741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGE("mixer_get_ctl_by_name failed"); 21841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George mixer_close(out_ctxt->mixer); 21941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt->mixer = NULL; 22041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ret = -EINVAL; 22141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George free(out_ctxt); 22241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 22341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 22441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 22541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 22641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_init(&out_ctxt->effects_list); 22741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 22841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_for_each(node, &created_effects_list) { 22941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *fx_ctxt = node_to_item(node, 23041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t, 23141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effects_list_node); 23241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (fx_ctxt->out_handle == output) { 23341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (fx_ctxt->ops.start) 23441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George fx_ctxt->ops.start(fx_ctxt, out_ctxt); 23541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_add_tail(&out_ctxt->effects_list, &fx_ctxt->output_node); 23641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 23741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 23841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_add_tail(&active_outputs_list, &out_ctxt->outputs_list_node); 23941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeexit: 24041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_unlock(&lock); 24141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return ret; 24241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 24341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 24441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George__attribute__ ((visibility ("default"))) 24541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint offload_effects_bundle_hal_stop_output(audio_io_handle_t output, int pcm_id) 24641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 24741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int ret; 24841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *node; 24941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George struct listnode *fx_node; 25041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t *out_ctxt; 25141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 25241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s output %d pcm_id %d", __func__, output, pcm_id); 25341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 25441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (lib_init() != 0) 25541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return init_status; 25641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 25741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_lock(&lock); 25841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 25941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt = get_output(output); 26041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (out_ctxt == NULL) { 26141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGW("%s output not started", __func__); 26241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ret = -ENOSYS; 26341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 26441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 26541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 26641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (out_ctxt->mixer) 26741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George mixer_close(out_ctxt->mixer); 26841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 26941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_for_each(fx_node, &out_ctxt->effects_list) { 27041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *fx_ctxt = node_to_item(fx_node, 27141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t, 27241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_node); 27341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (fx_ctxt->ops.stop) 27441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George fx_ctxt->ops.stop(fx_ctxt, out_ctxt); 27541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 27641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 27741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_remove(&out_ctxt->outputs_list_node); 27841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 27941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George free(out_ctxt); 28041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 28141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeexit: 28241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_unlock(&lock); 28341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return ret; 28441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 28541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 28641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 28741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 28841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Effect operations 28941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 29041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint set_config(effect_context_t *context, effect_config_t *config) 29141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 29241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->config = *config; 29341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 29441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.reset) 29541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.reset(context); 29641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 29741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return 0; 29841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 29941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 30041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgevoid get_config(effect_context_t *context, effect_config_t *config) 30141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 30241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *config = context->config; 30341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 30441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 30541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 30641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 30741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Effect Library Interface Implementation 30841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 30941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint effect_lib_create(const effect_uuid_t *uuid, 31041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int32_t sessionId, 31141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int32_t ioId, 31241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_handle_t *pHandle) { 31341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int ret; 31441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int i; 31541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 31641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s: sessionId: %d, ioId: %d", __func__, sessionId, ioId); 31741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (lib_init() != 0) 31841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return init_status; 31941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 32041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pHandle == NULL || uuid == NULL) 32141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return -EINVAL; 32241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 32341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George for (i = 0; descriptors[i] != NULL; i++) { 32441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) 32541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 32641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 32741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 32841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (descriptors[i] == NULL) 32941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return -EINVAL; 33041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 33141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *context; 33241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (memcmp(uuid, &equalizer_descriptor.uuid, 33341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) { 33441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George equalizer_context_t *eq_ctxt = (equalizer_context_t *) 33541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George calloc(1, sizeof(equalizer_context_t)); 33641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context = (effect_context_t *)eq_ctxt; 33741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.init = equalizer_init; 33841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.reset = equalizer_reset; 33941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_parameter = equalizer_set_parameter; 34041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.get_parameter = equalizer_get_parameter; 34141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_device = equalizer_set_device; 34241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.enable = equalizer_enable; 34341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.disable = equalizer_disable; 34441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.start = equalizer_start; 34541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.stop = equalizer_stop; 34641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 34741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->desc = &equalizer_descriptor; 34841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George eq_ctxt->ctl = NULL; 34941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } else if (memcmp(uuid, &bassboost_descriptor.uuid, 35041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) { 35141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George bassboost_context_t *bass_ctxt = (bassboost_context_t *) 35241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George calloc(1, sizeof(bassboost_context_t)); 35341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context = (effect_context_t *)bass_ctxt; 35441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.init = bassboost_init; 35541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.reset = bassboost_reset; 35641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_parameter = bassboost_set_parameter; 35741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.get_parameter = bassboost_get_parameter; 35841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_device = bassboost_set_device; 35941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.enable = bassboost_enable; 36041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.disable = bassboost_disable; 36141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.start = bassboost_start; 36241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.stop = bassboost_stop; 36341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 36441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->desc = &bassboost_descriptor; 36541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George bass_ctxt->ctl = NULL; 36641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } else if (memcmp(uuid, &virtualizer_descriptor.uuid, 36741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) { 36841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George virtualizer_context_t *virt_ctxt = (virtualizer_context_t *) 36941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George calloc(1, sizeof(virtualizer_context_t)); 37041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context = (effect_context_t *)virt_ctxt; 37141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.init = virtualizer_init; 37241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.reset = virtualizer_reset; 37341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_parameter = virtualizer_set_parameter; 37441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.get_parameter = virtualizer_get_parameter; 37541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_device = virtualizer_set_device; 37641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.enable = virtualizer_enable; 37741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.disable = virtualizer_disable; 37841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.start = virtualizer_start; 37941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.stop = virtualizer_stop; 38041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 38141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->desc = &virtualizer_descriptor; 38241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George virt_ctxt->ctl = NULL; 38341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } else if ((memcmp(uuid, &aux_env_reverb_descriptor.uuid, 38441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) || 38541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George (memcmp(uuid, &ins_env_reverb_descriptor.uuid, 38641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) || 38741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George (memcmp(uuid, &aux_preset_reverb_descriptor.uuid, 38841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) || 38941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George (memcmp(uuid, &ins_preset_reverb_descriptor.uuid, 39041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0)) { 39141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George reverb_context_t *reverb_ctxt = (reverb_context_t *) 39241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George calloc(1, sizeof(reverb_context_t)); 39341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context = (effect_context_t *)reverb_ctxt; 39441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.init = reverb_init; 39541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.reset = reverb_reset; 39641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_parameter = reverb_set_parameter; 39741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.get_parameter = reverb_get_parameter; 39841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_device = reverb_set_device; 39941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.enable = reverb_enable; 40041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.disable = reverb_disable; 40141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.start = reverb_start; 40241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.stop = reverb_stop; 40341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 40441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (memcmp(uuid, &aux_env_reverb_descriptor.uuid, 40541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) { 40641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->desc = &aux_env_reverb_descriptor; 40741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George reverb_auxiliary_init(reverb_ctxt); 40841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } else if (memcmp(uuid, &ins_env_reverb_descriptor.uuid, 40941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) { 41041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->desc = &ins_env_reverb_descriptor; 41141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George reverb_insert_init(reverb_ctxt); 41241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } else if (memcmp(uuid, &aux_preset_reverb_descriptor.uuid, 41341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) { 41441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->desc = &aux_preset_reverb_descriptor; 41541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George reverb_auxiliary_init(reverb_ctxt); 41641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } else if (memcmp(uuid, &ins_preset_reverb_descriptor.uuid, 41741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(effect_uuid_t)) == 0) { 41841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->desc = &ins_preset_reverb_descriptor; 41941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George reverb_preset_init(reverb_ctxt); 42041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 42141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George reverb_ctxt->ctl = NULL; 42241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } else { 42341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return -EINVAL; 42441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 42541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 42641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->itfe = &effect_interface; 42741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->state = EFFECT_STATE_UNINITIALIZED; 42841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->out_handle = (audio_io_handle_t)ioId; 42941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 43041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ret = context->ops.init(context); 43141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (ret < 0) { 43241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGW("%s init failed", __func__); 43341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George free(context); 43441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return ret; 43541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 43641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 43741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->state = EFFECT_STATE_INITIALIZED; 43841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 43941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_lock(&lock); 44041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_add_tail(&created_effects_list, &context->effects_list_node); 44141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t *out_ctxt = get_output(ioId); 44241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (out_ctxt != NULL) 44341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George add_effect_to_output(out_ctxt, context); 44441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_unlock(&lock); 44541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 44641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *pHandle = (effect_handle_t)context; 44741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 44841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s created context %p", __func__, context); 44941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 45041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return 0; 45141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 45241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 45341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 45441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint effect_lib_release(effect_handle_t handle) 45541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 45641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *context = (effect_context_t *)handle; 45741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int status; 45841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 45941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (lib_init() != 0) 46041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return init_status; 46141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 46241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s context %p", __func__, handle); 46341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_lock(&lock); 46441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 46541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (effect_exists(context)) { 46641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t *out_ctxt = get_output(context->out_handle); 46741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (out_ctxt != NULL) 46841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George remove_effect_from_output(out_ctxt, context); 46941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George list_remove(&context->effects_list_node); 47041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.release) 47141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.release(context); 47241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George free(context); 47341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = 0; 47441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 47541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_unlock(&lock); 47641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 47741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return status; 47841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 47941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 48041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint effect_lib_get_descriptor(const effect_uuid_t *uuid, 48141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_descriptor_t *descriptor) 48241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 48341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int i; 48441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 48541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (lib_init() != 0) 48641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return init_status; 48741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 48841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (descriptor == NULL || uuid == NULL) { 48941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s called with NULL pointer", __func__); 49041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return -EINVAL; 49141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 49241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 49341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George for (i = 0; descriptors[i] != NULL; i++) { 49441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) { 49541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *descriptor = *descriptors[i]; 49641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return 0; 49741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 49841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 49941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 50041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return -EINVAL; 50141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 50241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 50341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 50441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* 50541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George * Effect Control Interface Implementation 50641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George */ 50741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 50841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* Stub function for effect interface: never called for offloaded effects */ 50941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint effect_process(effect_handle_t self, 51097a1059da4d3aa8bfb0883d5f932f86b95876512Haynes Mathew George audio_buffer_t *inBuffer __unused, 51197a1059da4d3aa8bfb0883d5f932f86b95876512Haynes Mathew George audio_buffer_t *outBuffer __unused) 51241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 51341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t * context = (effect_context_t *)self; 51441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int status = 0; 51541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 51641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGW("%s Called ?????", __func__); 51741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 51841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_lock(&lock); 51941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (!effect_exists(context)) { 52041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -ENOSYS; 52141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 52241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 52341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 52441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->state != EFFECT_STATE_ACTIVE) { 52541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -ENODATA; 52641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 52741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 52841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 52941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeexit: 53041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_unlock(&lock); 53141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return status; 53241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 53341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 53441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint effect_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, 53541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George void *pCmdData, uint32_t *replySize, void *pReplyData) 53641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 53741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 53841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t * context = (effect_context_t *)self; 53941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int retsize; 54041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George int status = 0; 54141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 54241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_lock(&lock); 54341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 54441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (!effect_exists(context)) { 54541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -ENOSYS; 54641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 54741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 54841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 54941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context == NULL || context->state == EFFECT_STATE_UNINITIALIZED) { 55041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -ENOSYS; 55141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 55241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 55341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 55441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George switch (cmdCode) { 55541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_INIT: 55641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pReplyData == NULL || *replySize != sizeof(int)) { 55741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 55841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 55941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 56041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.init) 56141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *(int *) pReplyData = context->ops.init(context); 56241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George else 56341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *(int *) pReplyData = 0; 56441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 56541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_SET_CONFIG: 56641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) 56741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George || pReplyData == NULL || *replySize != sizeof(int)) { 56841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 56941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 57041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 57141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *(int *) pReplyData = set_config(context, (effect_config_t *) pCmdData); 57241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 57341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_GET_CONFIG: 57441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pReplyData == NULL || 57541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *replySize != sizeof(effect_config_t)) { 57641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 57741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 57841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 57941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (!context->offload_enabled) { 58041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 58141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 58241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 58341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 58441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George get_config(context, (effect_config_t *)pReplyData); 58541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 58641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_RESET: 58741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.reset) 58841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.reset(context); 58941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 59041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_ENABLE: 59141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pReplyData == NULL || *replySize != sizeof(int)) { 59241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 59341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 59441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 59541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->state != EFFECT_STATE_INITIALIZED) { 59641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -ENOSYS; 59741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 59841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 59941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->state = EFFECT_STATE_ACTIVE; 60041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.enable) 60141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.enable(context); 60241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s EFFECT_CMD_ENABLE", __func__); 60341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *(int *)pReplyData = 0; 60441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 60541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_DISABLE: 60641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pReplyData == NULL || *replySize != sizeof(int)) { 60741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 60841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 60941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 61041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->state != EFFECT_STATE_ACTIVE) { 61141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -ENOSYS; 61241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 61341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 61441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->state = EFFECT_STATE_INITIALIZED; 61541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.disable) 61641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.disable(context); 61741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s EFFECT_CMD_DISABLE", __func__); 61841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *(int *)pReplyData = 0; 61941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 62041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_GET_PARAM: { 62141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pCmdData == NULL || 62241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George cmdSize < (int)(sizeof(effect_param_t) + sizeof(uint32_t)) || 62341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pReplyData == NULL || 6241015d94fb02b3213c22c9ac4a16b20c4ed9498b6Andy Hung *replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint16_t)) || 6251015d94fb02b3213c22c9ac4a16b20c4ed9498b6Andy Hung // constrain memcpy below 6261015d94fb02b3213c22c9ac4a16b20c4ed9498b6Andy Hung ((effect_param_t *)pCmdData)->psize > *replySize - sizeof(effect_param_t)) { 62741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 62841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("EFFECT_CMD_GET_PARAM invalid command cmdSize %d *replySize %d", 62941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George cmdSize, *replySize); 63041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 63141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 63241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (!context->offload_enabled) { 63341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 63441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 63541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 63641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_param_t *q = (effect_param_t *)pCmdData; 63741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + q->psize); 63841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_param_t *p = (effect_param_t *)pReplyData; 63941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.get_parameter) 64041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.get_parameter(context, p, replySize); 64141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } break; 64241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_SET_PARAM: { 64341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pCmdData == NULL || 64441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George cmdSize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + 64541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George sizeof(uint16_t)) || 64641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pReplyData == NULL || *replySize != sizeof(int32_t)) { 64741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 64841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("EFFECT_CMD_SET_PARAM invalid command cmdSize %d *replySize %d", 64941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George cmdSize, *replySize); 65041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 65141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 65241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *(int32_t *)pReplyData = 0; 65341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_param_t *p = (effect_param_t *)pCmdData; 65441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.set_parameter) 65541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *(int32_t *)pReplyData = context->ops.set_parameter(context, p, 65641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *replySize); 65741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 65841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } break; 65941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_SET_DEVICE: { 66041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George uint32_t device; 66141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("\t EFFECT_CMD_SET_DEVICE start"); 66241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (pCmdData == NULL || cmdSize < sizeof(uint32_t)) { 66341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 66441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("EFFECT_CMD_SET_DEVICE invalid command cmdSize %d", cmdSize); 66541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George goto exit; 66641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 66741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George device = *(uint32_t *)pCmdData; 66841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->ops.set_device) 66941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->ops.set_device(context, device); 67041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } break; 67141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_SET_VOLUME: 67241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_SET_AUDIO_MODE: 67341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 67441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 67541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George case EFFECT_CMD_OFFLOAD: { 67641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George output_context_t *out_ctxt; 67741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 67841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (cmdSize != sizeof(effect_offload_param_t) || pCmdData == NULL 67941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George || pReplyData == NULL || *replySize != sizeof(int)) { 68041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s EFFECT_CMD_OFFLOAD bad format", __func__); 68141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 68241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 68341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 68441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 68541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_offload_param_t* offload_param = (effect_offload_param_t*)pCmdData; 68641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 68741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGV("%s EFFECT_CMD_OFFLOAD offload %d output %d", __func__, 68841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George offload_param->isOffload, offload_param->ioHandle); 68941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 69041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *(int *)pReplyData = 0; 69141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 69241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->offload_enabled = offload_param->isOffload; 69341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (context->out_handle == offload_param->ioHandle) 69441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 69541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 69641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt = get_output(context->out_handle); 69741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (out_ctxt != NULL) 69841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George remove_effect_from_output(out_ctxt, context); 69941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 70041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George context->out_handle = offload_param->ioHandle; 70141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George out_ctxt = get_output(context->out_handle); 70241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (out_ctxt != NULL) 70341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George add_effect_to_output(out_ctxt, context); 70441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 70541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } break; 70641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 70741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 70841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George default: 70941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (cmdCode >= EFFECT_CMD_FIRST_PROPRIETARY && context->ops.command) 71041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = context->ops.command(context, cmdCode, cmdSize, 71141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pCmdData, replySize, pReplyData); 71241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George else { 71341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George ALOGW("%s invalid command %d", __func__, cmdCode); 71441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George status = -EINVAL; 71541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 71641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George break; 71741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George } 71841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 71941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeexit: 72041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George pthread_mutex_unlock(&lock); 72141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 72241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return status; 72341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 72441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 72541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* Effect Control Interface Implementation: get_descriptor */ 72641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeint effect_get_descriptor(effect_handle_t self, 72741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_descriptor_t *descriptor) 72841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George{ 72941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_context_t *context = (effect_context_t *)self; 73041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 73141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George if (!effect_exists(context) || (descriptor == NULL)) 73241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return -EINVAL; 73341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 73441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George *descriptor = *context->desc; 73541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 73641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return 0; 73741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 73841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 73941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgebool effect_is_active(effect_context_t * ctxt) { 74041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George return ctxt->state == EFFECT_STATE_ACTIVE; 74141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George} 74241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 74341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George/* effect_handle_t interface implementation for offload effects */ 74441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeconst struct effect_interface_s effect_interface = { 74541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_process, 74641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_command, 74741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George effect_get_descriptor, 74841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George NULL, 74941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George}; 75041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George 75141f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George__attribute__ ((visibility ("default"))) 75241f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew Georgeaudio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 75341f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George tag : AUDIO_EFFECT_LIBRARY_TAG, 75441f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George version : EFFECT_LIBRARY_API_VERSION, 75541f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George name : "Offload Effects Bundle Library", 75641f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George implementor : "The Android Open Source Project", 75741f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George create_effect : effect_lib_create, 75841f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George release_effect : effect_lib_release, 75941f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George get_descriptor : effect_lib_get_descriptor, 76041f86651e362abc62d9d03f5c612c986bf15298fHaynes Mathew George}; 761