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