161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* 261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Copyright (C) 2013 The Android Open Source Project 361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * 461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Licensed under the Apache License, Version 2.0 (the "License"); 561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * you may not use this file except in compliance with the License. 661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * You may obtain a copy of the License at 761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * 861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * http://www.apache.org/licenses/LICENSE-2.0 961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * 1061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Unless required by applicable law or agreed to in writing, software 1161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * distributed under the License is distributed on an "AS IS" BASIS, 1261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * See the License for the specific language governing permissions and 1461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * limitations under the License. 1561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti */ 1661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 1761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define LOG_TAG "offload_visualizer" 1861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/*#define LOG_NDEBUG 0*/ 1961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <assert.h> 2061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <math.h> 2161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <stdlib.h> 2261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <string.h> 2361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <time.h> 2461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <sys/prctl.h> 2561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 2661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <cutils/list.h> 2761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <cutils/log.h> 2861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <system/thread_defs.h> 2961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <tinyalsa/asoundlib.h> 3061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#include <audio_effects/effect_visualizer.h> 3161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 3261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 3361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletienum { 3461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti EFFECT_STATE_UNINITIALIZED, 3561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti EFFECT_STATE_INITIALIZED, 3661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti EFFECT_STATE_ACTIVE, 3761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti}; 3861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 3961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletitypedef struct effect_context_s effect_context_t; 4061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletitypedef struct output_context_s output_context_t; 4161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 4261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* effect specific operations. Only the init() and process() operations must be defined. 4361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Others are optional. 4461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti */ 4561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletitypedef struct effect_ops_s { 4661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*init)(effect_context_t *context); 4761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*release)(effect_context_t *context); 4861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*reset)(effect_context_t *context); 4961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*enable)(effect_context_t *context); 5061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*disable)(effect_context_t *context); 5161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*start)(effect_context_t *context, output_context_t *output); 5261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*stop)(effect_context_t *context, output_context_t *output); 5361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*process)(effect_context_t *context, audio_buffer_t *in, audio_buffer_t *out); 5461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*set_parameter)(effect_context_t *context, effect_param_t *param, uint32_t size); 5561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*get_parameter)(effect_context_t *context, effect_param_t *param, uint32_t *size); 5661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int (*command)(effect_context_t *context, uint32_t cmdCode, uint32_t cmdSize, 5761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti void *pCmdData, uint32_t *replySize, void *pReplyData); 5861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} effect_ops_t; 5961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 6061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletistruct effect_context_s { 6161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti const struct effect_interface_s *itfe; 6261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode effects_list_node; /* node in created_effects_list */ 6361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode output_node; /* node in output_context_t.effects_list */ 6461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_config_t config; 6561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti const effect_descriptor_t *desc; 6661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti audio_io_handle_t out_handle; /* io handle of the output the effect is attached to */ 6761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t state; 6861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti bool offload_enabled; /* when offload is enabled we process VISUALIZER_CMD_CAPTURE command. 6961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti Otherwise non offloaded visualizer has already processed the command 7061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti and we must not overwrite the reply. */ 7161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_ops_t ops; 7261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti}; 7361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 7461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletitypedef struct output_context_s { 7561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode outputs_list_node; /* node in active_outputs_list */ 7661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti audio_io_handle_t handle; /* io handle */ 7761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode effects_list; /* list of effects attached to this output */ 7861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} output_context_t; 7961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 8061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 8161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* maximum time since last capture buffer update before resetting capture buffer. This means 8261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti that the framework has stopped playing audio and we must start returning silence */ 8361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define MAX_STALL_TIME_MS 1000 8461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 8561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define CAPTURE_BUF_SIZE 65536 /* "64k should be enough for everyone" */ 8661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 8761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define DISCARD_MEASUREMENTS_TIME_MS 2000 /* discard measurements older than this number of ms */ 8861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 8961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* maximum number of buffers for which we keep track of the measurements */ 9061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS 25 /* note: buffer index is stored in uint8_t */ 9161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 9261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletitypedef struct buffer_stats_s { 9361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti bool is_valid; 9461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint16_t peak_u16; /* the positive peak of the absolute value of the samples in a buffer */ 9561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti float rms_squared; /* the average square of the samples in a buffer */ 9661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} buffer_stats_t; 9761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 9861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletitypedef struct visualizer_context_s { 9961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t common; 10061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 10161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t capture_idx; 10261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t capture_size; 10361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t scaling_mode; 10461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t last_capture_idx; 10561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t latency; 10661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct timespec buffer_update_time; 10761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint8_t capture_buf[CAPTURE_BUF_SIZE]; 10861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* for measurements */ 10961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint8_t channel_count; /* to avoid recomputing it every time a buffer is processed */ 11061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t meas_mode; 11161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint8_t meas_wndw_size_in_buffers; 11261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint8_t meas_buffer_idx; 11361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti buffer_stats_t past_meas[MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS]; 11461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} visualizer_context_t; 11561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 11661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 11761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiextern const struct effect_interface_s effect_interface; 11861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 11961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* Offload visualizer UUID: 7a8044a0-1a71-11e3-a184-0002a5d5c51b */ 12061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleticonst effect_descriptor_t visualizer_descriptor = { 12161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti {0xe46b26a0, 0xdddd, 0x11db, 0x8afd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, 12261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti {0x7a8044a0, 0x1a71, 0x11e3, 0xa184, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, 12361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti EFFECT_CONTROL_API_VERSION, 12461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_HW_ACC_TUNNEL ), 12561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 0, /* TODO */ 12661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 1, 12761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti "QCOM MSM offload visualizer", 12861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti "The Android Open Source Project", 12961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti}; 13061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 13161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleticonst effect_descriptor_t *descriptors[] = { 13261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti &visualizer_descriptor, 13361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti NULL, 13461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti}; 13561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 13661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 13761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletipthread_once_t once = PTHREAD_ONCE_INIT; 13861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint init_status; 13961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 14061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* list of created effects. Updated by visualizer_hal_start_output() 14161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * and visualizer_hal_stop_output() */ 14261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletistruct listnode created_effects_list; 14361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* list of active output streams. Updated by visualizer_hal_start_output() 14461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * and visualizer_hal_stop_output() */ 14561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletistruct listnode active_outputs_list; 14661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 14761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* thread capturing PCM from Proxy port and calling the process function on each enabled effect 14861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * attached to an active output stream */ 14961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletipthread_t capture_thread; 15061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* lock must be held when modifying or accessing created_effects_list or active_outputs_list */ 15161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletipthread_mutex_t lock; 15261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* thread_lock must be held when starting or stopping the capture thread. 15361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Locking order: thread_lock -> lock */ 15461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletipthread_mutex_t thread_lock; 15561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* cond is signaled when an output is started or stopped or an effect is enabled or disable: the 15661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * capture thread will reevaluate the capture and effect rocess conditions. */ 15761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletipthread_cond_t cond; 15861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* true when requesting the capture thread to exit */ 15961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletibool exit_thread; 16061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* 0 if the capture thread was created successfully */ 16161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint thread_status; 16261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 16361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 16461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define DSP_OUTPUT_LATENCY_MS 0 /* Fudge factor for latency after capture point in audio DSP */ 16561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 16661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* Retry for delay for mixer open */ 16761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define RETRY_NUMBER 10 16861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define RETRY_US 500000 16961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 17061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define MIXER_CARD 0 17161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define SOUND_CARD 0 17261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define CAPTURE_DEVICE 8 17361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 17461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* Proxy port supports only MMAP read and those fixed parameters*/ 17561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define AUDIO_CAPTURE_CHANNEL_COUNT 2 17661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define AUDIO_CAPTURE_SMP_RATE 48000 17761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define AUDIO_CAPTURE_PERIOD_SIZE (768) 17861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti#define AUDIO_CAPTURE_PERIOD_COUNT 32 17961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 18061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletistruct pcm_config pcm_config_capture = { 18161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti .channels = AUDIO_CAPTURE_CHANNEL_COUNT, 18261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti .rate = AUDIO_CAPTURE_SMP_RATE, 18361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti .period_size = AUDIO_CAPTURE_PERIOD_SIZE, 18461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti .period_count = AUDIO_CAPTURE_PERIOD_COUNT, 18561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti .format = PCM_FORMAT_S16_LE, 18661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti .start_threshold = AUDIO_CAPTURE_PERIOD_SIZE / 4, 18761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti .stop_threshold = INT_MAX, 18861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti .avail_min = AUDIO_CAPTURE_PERIOD_SIZE / 4, 18961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti}; 19061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 19161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 19261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* 19361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Local functions 19461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti */ 19561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 19661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletistatic void init_once() { 19761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_init(&created_effects_list); 19861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_init(&active_outputs_list); 19961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 20061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_init(&lock, NULL); 20161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_init(&thread_lock, NULL); 20261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_cond_init(&cond, NULL); 20361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti exit_thread = false; 20461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti thread_status = -1; 20561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 20661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti init_status = 0; 20761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 20861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 20961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint lib_init() { 21061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_once(&once, init_once); 21161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return init_status; 21261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 21361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 21461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletibool effect_exists(effect_context_t *context) { 21561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *node; 21661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 21761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(node, &created_effects_list) { 21861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *fx_ctxt = node_to_item(node, 21961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t, 22061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effects_list_node); 22161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (fx_ctxt == context) { 22261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return true; 22361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 22461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 22561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return false; 22661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 22761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 22861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletioutput_context_t *get_output(audio_io_handle_t output) { 22961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *node; 23061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 23161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(node, &active_outputs_list) { 23261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t *out_ctxt = node_to_item(node, 23361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t, 23461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti outputs_list_node); 23561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (out_ctxt->handle == output) { 23661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return out_ctxt; 23761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 23861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 23961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return NULL; 24061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 24161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 24261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletivoid add_effect_to_output(output_context_t * output, effect_context_t *context) { 24361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *fx_node; 24461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 24561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(fx_node, &output->effects_list) { 24661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *fx_ctxt = node_to_item(fx_node, 24761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t, 24861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_node); 24961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (fx_ctxt == context) 25061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return; 25161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 25261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_add_tail(&output->effects_list, &context->output_node); 25361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.start) 25461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.start(context, output); 25561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 25661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 25761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletivoid remove_effect_from_output(output_context_t * output, effect_context_t *context) { 25861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *fx_node; 25961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 26061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(fx_node, &output->effects_list) { 26161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *fx_ctxt = node_to_item(fx_node, 26261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t, 26361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_node); 26461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (fx_ctxt == context) { 26561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.stop) 26661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.stop(context, output); 26761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_remove(&context->output_node); 26861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return; 26961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 27061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 27161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 27261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 27361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletibool effects_enabled() { 27461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *out_node; 27561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 27661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(out_node, &active_outputs_list) { 27761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *fx_node; 27861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t *out_ctxt = node_to_item(out_node, 27961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t, 28061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti outputs_list_node); 28161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 28261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(fx_node, &out_ctxt->effects_list) { 28361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *fx_ctxt = node_to_item(fx_node, 28461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t, 28561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_node); 28661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (fx_ctxt->state == EFFECT_STATE_ACTIVE && fx_ctxt->ops.process != NULL) 28761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return true; 28861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 28961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 29061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return false; 29161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 29261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 29361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint configure_proxy_capture(struct mixer *mixer, int value) { 29461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti const char *proxy_ctl_name = "AFE_PCM_RX Audio Mixer MultiMedia4"; 29561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct mixer_ctl *ctl; 29661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 29761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ctl = mixer_get_ctl_by_name(mixer, proxy_ctl_name); 29861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (ctl == NULL) { 29961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s: could not get %s ctl", __func__, proxy_ctl_name); 30061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 30161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 30261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (mixer_ctl_set_value(ctl, 0, value) != 0) 30361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s: error setting value %d on %s ", __func__, value, proxy_ctl_name); 30461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 30561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 30661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 30761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 30861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 30961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletivoid *capture_thread_loop(void *arg) 31061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 31161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int16_t data[AUDIO_CAPTURE_PERIOD_SIZE * AUDIO_CAPTURE_CHANNEL_COUNT * sizeof(int16_t)]; 31261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti audio_buffer_t buf; 31361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti buf.frameCount = AUDIO_CAPTURE_PERIOD_SIZE; 31461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti buf.s16 = data; 31561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti bool capture_enabled = false; 31661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct mixer *mixer; 31761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct pcm *pcm = NULL; 31861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int ret; 31961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int retry_num = 0; 32061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 32161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGD("thread enter"); 32261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 32361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti prctl(PR_SET_NAME, (unsigned long)"visualizer capture", 0, 0, 0); 32461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 32561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 32661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 32761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti mixer = mixer_open(MIXER_CARD); 32861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti while (mixer == NULL && retry_num < RETRY_NUMBER) { 32961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti usleep(RETRY_US); 33061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti mixer = mixer_open(MIXER_CARD); 33161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti retry_num++; 33261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 33361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (mixer == NULL) { 33461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 33561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return NULL; 33661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 33761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 33861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (;;) { 33961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (exit_thread) { 34061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 34161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 34261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (effects_enabled()) { 34361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!capture_enabled) { 34461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ret = configure_proxy_capture(mixer, 1); 34561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (ret == 0) { 34661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pcm = pcm_open(SOUND_CARD, CAPTURE_DEVICE, 34761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti PCM_IN|PCM_MMAP|PCM_NOIRQ, &pcm_config_capture); 34861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pcm && !pcm_is_ready(pcm)) { 34961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s: %s", __func__, pcm_get_error(pcm)); 35061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pcm_close(pcm); 35161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pcm = NULL; 35261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti configure_proxy_capture(mixer, 0); 35361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 35461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti capture_enabled = true; 35561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGD("%s: capture ENABLED", __func__); 35661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 35761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 35861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 35961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 36061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (capture_enabled) { 36161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pcm != NULL) 36261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pcm_close(pcm); 36361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti configure_proxy_capture(mixer, 0); 36461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGD("%s: capture DISABLED", __func__); 36561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti capture_enabled = false; 36661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 36761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_cond_wait(&cond, &lock); 36861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 36961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!capture_enabled) 37061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti continue; 37161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 37261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 37361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ret = pcm_mmap_read(pcm, data, sizeof(data)); 37461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 37561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 37661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (ret == 0) { 37761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *out_node; 37861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 37961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(out_node, &active_outputs_list) { 38061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t *out_ctxt = node_to_item(out_node, 38161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t, 38261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti outputs_list_node); 38361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *fx_node; 38461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 38561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(fx_node, &out_ctxt->effects_list) { 38661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *fx_ctxt = node_to_item(fx_node, 38761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t, 38861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_node); 38961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (fx_ctxt->ops.process != NULL) 39061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti fx_ctxt->ops.process(fx_ctxt, &buf, &buf); 39161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 39261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 39361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 39461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s: read status %d %s", __func__, ret, pcm_get_error(pcm)); 39561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 39661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 39761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 39861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (capture_enabled) { 39961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pcm != NULL) 40061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pcm_close(pcm); 40161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti configure_proxy_capture(mixer, 0); 40261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 40361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti mixer_close(mixer); 40461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 40561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 40661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGD("thread exit"); 40761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 40861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return NULL; 40961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 41061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 41161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* 41261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Interface from audio HAL 41361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti */ 41461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 41561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti__attribute__ ((visibility ("default"))) 41661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint visualizer_hal_start_output(audio_io_handle_t output, int pcm_id) { 41761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int ret; 41861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *node; 41961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 42061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s output %d pcm_id %d", __func__, output, pcm_id); 42161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 42261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (lib_init() != 0) 42361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return init_status; 42461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 42561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&thread_lock); 42661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 42761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (get_output(output) != NULL) { 42861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s output already started", __func__); 42961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ret = -ENOSYS; 43061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 43161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 43261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 43361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t *out_ctxt = (output_context_t *)malloc(sizeof(output_context_t)); 43461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (out_ctxt == NULL) { 43561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGE("%s fail to allocate memory", __func__); 43661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ret = -ENOMEM; 43761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 43861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 43961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti out_ctxt->handle = output; 44061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_init(&out_ctxt->effects_list); 44161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 44261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(node, &created_effects_list) { 44361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *fx_ctxt = node_to_item(node, 44461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t, 44561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effects_list_node); 44661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (fx_ctxt->out_handle == output) { 44761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (fx_ctxt->ops.start) 44861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti fx_ctxt->ops.start(fx_ctxt, out_ctxt); 44961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_add_tail(&out_ctxt->effects_list, &fx_ctxt->output_node); 45061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 45161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 45261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (list_empty(&active_outputs_list)) { 45361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti exit_thread = false; 45461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti thread_status = pthread_create(&capture_thread, (const pthread_attr_t *) NULL, 45561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti capture_thread_loop, NULL); 45661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 45761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_add_tail(&active_outputs_list, &out_ctxt->outputs_list_node); 45861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_cond_signal(&cond); 45961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 46061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiexit: 46161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 46261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&thread_lock); 46361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return ret; 46461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 46561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 46661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti__attribute__ ((visibility ("default"))) 46761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint visualizer_hal_stop_output(audio_io_handle_t output, int pcm_id) { 46861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int ret; 46961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *node; 47061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct listnode *fx_node; 47161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t *out_ctxt; 47261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 47361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s output %d pcm_id %d", __func__, output, pcm_id); 47461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 47561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (lib_init() != 0) 47661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return init_status; 47761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 47861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&thread_lock); 47961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 48061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 48161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti out_ctxt = get_output(output); 48261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (out_ctxt == NULL) { 48361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s output not started", __func__); 48461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ret = -ENOSYS; 48561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 48661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 48761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_for_each(fx_node, &out_ctxt->effects_list) { 48861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *fx_ctxt = node_to_item(fx_node, 48961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t, 49061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_node); 49161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (fx_ctxt->ops.stop) 49261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti fx_ctxt->ops.stop(fx_ctxt, out_ctxt); 49361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 49461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_remove(&out_ctxt->outputs_list_node); 49561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_cond_signal(&cond); 49661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 49761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (list_empty(&active_outputs_list)) { 49861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (thread_status == 0) { 49961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti exit_thread = true; 50061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_cond_signal(&cond); 50161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 50261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_join(capture_thread, (void **) NULL); 50361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 50461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti thread_status = -1; 50561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 50661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 50761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 50861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti free(out_ctxt); 50961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 51061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiexit: 51161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 51261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&thread_lock); 51361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return ret; 51461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 51561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 51661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 51761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* 51861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Effect operations 51961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti */ 52061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 52161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint set_config(effect_context_t *context, effect_config_t *config) 52261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 52361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (config->inputCfg.samplingRate != config->outputCfg.samplingRate) return -EINVAL; 52461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (config->inputCfg.channels != config->outputCfg.channels) return -EINVAL; 52561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (config->inputCfg.format != config->outputCfg.format) return -EINVAL; 52661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (config->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) return -EINVAL; 52761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (config->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE && 52861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti config->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL; 52961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL; 53061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 53161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config = *config; 53261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 53361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.reset) 53461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.reset(context); 53561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 53661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 53761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 53861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 53961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletivoid get_config(effect_context_t *context, effect_config_t *config) 54061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 54161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *config = context->config; 54261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 54361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 54461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 54561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* 54661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Visualizer operations 54761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti */ 54861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 54961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiuint32_t visualizer_get_delta_time_ms_from_updated_time(visualizer_context_t* visu_ctxt) { 55061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t delta_ms = 0; 55161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (visu_ctxt->buffer_update_time.tv_sec != 0) { 55261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti struct timespec ts; 55361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 55461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti time_t secs = ts.tv_sec - visu_ctxt->buffer_update_time.tv_sec; 55561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti long nsec = ts.tv_nsec - visu_ctxt->buffer_update_time.tv_nsec; 55661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (nsec < 0) { 55761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti --secs; 55861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti nsec += 1000000000; 55961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 56061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti delta_ms = secs * 1000 + nsec / 1000000; 56161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 56261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 56361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return delta_ms; 56461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 56561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 56661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint visualizer_reset(effect_context_t *context) 56761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 56861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visualizer_context_t * visu_ctxt = (visualizer_context_t *)context; 56961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 57061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->capture_idx = 0; 57161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->last_capture_idx = 0; 57261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->buffer_update_time.tv_sec = 0; 57361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->latency = DSP_OUTPUT_LATENCY_MS; 57461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti memset(visu_ctxt->capture_buf, 0x80, CAPTURE_BUF_SIZE); 57561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 57661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 57761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 57861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint visualizer_init(effect_context_t *context) 57961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 58061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t i; 58161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 58261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visualizer_context_t * visu_ctxt = (visualizer_context_t *)context; 58361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 58461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; 58561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 58661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 58761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.inputCfg.samplingRate = 44100; 58861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.inputCfg.bufferProvider.getBuffer = NULL; 58961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.inputCfg.bufferProvider.releaseBuffer = NULL; 59061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.inputCfg.bufferProvider.cookie = NULL; 59161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.inputCfg.mask = EFFECT_CONFIG_ALL; 59261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; 59361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 59461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 59561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.outputCfg.samplingRate = 44100; 59661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.outputCfg.bufferProvider.getBuffer = NULL; 59761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.outputCfg.bufferProvider.releaseBuffer = NULL; 59861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.outputCfg.bufferProvider.cookie = NULL; 59961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->config.outputCfg.mask = EFFECT_CONFIG_ALL; 60061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 60161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->capture_size = VISUALIZER_CAPTURE_SIZE_MAX; 60261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->scaling_mode = VISUALIZER_SCALING_MODE_NORMALIZED; 60361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 60461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti // measurement initialization 60561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->channel_count = popcount(context->config.inputCfg.channels); 60661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->meas_mode = MEASUREMENT_MODE_NONE; 60761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->meas_wndw_size_in_buffers = MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS; 60861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->meas_buffer_idx = 0; 60961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (i=0 ; i<visu_ctxt->meas_wndw_size_in_buffers ; i++) { 61061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[i].is_valid = false; 61161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[i].peak_u16 = 0; 61261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[i].rms_squared = 0; 61361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 61461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 61561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti set_config(context, &context->config); 61661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 61761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 61861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 61961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 62061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint visualizer_get_parameter(effect_context_t *context, effect_param_t *p, uint32_t *size) 62161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 62261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visualizer_context_t *visu_ctxt = (visualizer_context_t *)context; 62361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 62461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p->status = 0; 62561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *size = sizeof(effect_param_t) + sizeof(uint32_t); 62661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (p->psize != sizeof(uint32_t)) { 62761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p->status = -EINVAL; 62861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 62961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 63061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti switch (*(uint32_t *)p->data) { 63161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_PARAM_CAPTURE_SIZE: 63261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s get capture_size = %d", __func__, visu_ctxt->capture_size); 63361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *((uint32_t *)p->data + 1) = visu_ctxt->capture_size; 63461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p->vsize = sizeof(uint32_t); 63561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *size += sizeof(uint32_t); 63661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 63761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_PARAM_SCALING_MODE: 63861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s get scaling_mode = %d", __func__, visu_ctxt->scaling_mode); 63961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *((uint32_t *)p->data + 1) = visu_ctxt->scaling_mode; 64061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p->vsize = sizeof(uint32_t); 64161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *size += sizeof(uint32_t); 64261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 64361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_PARAM_MEASUREMENT_MODE: 64461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s get meas_mode = %d", __func__, visu_ctxt->meas_mode); 64561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *((uint32_t *)p->data + 1) = visu_ctxt->meas_mode; 64661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p->vsize = sizeof(uint32_t); 64761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *size += sizeof(uint32_t); 64861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 64961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti default: 65061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p->status = -EINVAL; 65161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 65261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 65361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 65461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 65561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint visualizer_set_parameter(effect_context_t *context, effect_param_t *p, uint32_t size) 65661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 65761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visualizer_context_t *visu_ctxt = (visualizer_context_t *)context; 65861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 65961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (p->psize != sizeof(uint32_t) || p->vsize != sizeof(uint32_t)) 66061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 66161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 66261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti switch (*(uint32_t *)p->data) { 66361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_PARAM_CAPTURE_SIZE: 66461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->capture_size = *((uint32_t *)p->data + 1); 66561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s set capture_size = %d", __func__, visu_ctxt->capture_size); 66661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 66761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_PARAM_SCALING_MODE: 66861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->scaling_mode = *((uint32_t *)p->data + 1); 66961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s set scaling_mode = %d", __func__, visu_ctxt->scaling_mode); 67061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 67161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_PARAM_LATENCY: 67261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* Ignore latency as we capture at DSP output 67361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * visu_ctxt->latency = *((uint32_t *)p->data + 1); */ 67461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s set latency = %d", __func__, visu_ctxt->latency); 67561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 67661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_PARAM_MEASUREMENT_MODE: 67761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->meas_mode = *((uint32_t *)p->data + 1); 67861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s set meas_mode = %d", __func__, visu_ctxt->meas_mode); 67961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 68061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti default: 68161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 68261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 68361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 68461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 68561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 68661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* Real process function called from capture thread. Called with lock held */ 68761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint visualizer_process(effect_context_t *context, 68861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti audio_buffer_t *inBuffer, 68961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti audio_buffer_t *outBuffer) 69061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 69161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visualizer_context_t *visu_ctxt = (visualizer_context_t *)context; 69261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 69361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!effect_exists(context)) 69461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 69561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 69661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (inBuffer == NULL || inBuffer->raw == NULL || 69761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti outBuffer == NULL || outBuffer->raw == NULL || 69861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti inBuffer->frameCount != outBuffer->frameCount || 69961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti inBuffer->frameCount == 0) { 70061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 70161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 70261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 70361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti // perform measurements if needed 70461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (visu_ctxt->meas_mode & MEASUREMENT_MODE_PEAK_RMS) { 70561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti // find the peak and RMS squared for the new buffer 70661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t inIdx; 70761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int16_t max_sample = 0; 70861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti float rms_squared_acc = 0; 70961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (inIdx = 0 ; inIdx < inBuffer->frameCount * visu_ctxt->channel_count ; inIdx++) { 71061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (inBuffer->s16[inIdx] > max_sample) { 71161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti max_sample = inBuffer->s16[inIdx]; 71261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else if (-inBuffer->s16[inIdx] > max_sample) { 71361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti max_sample = -inBuffer->s16[inIdx]; 71461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 71561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti rms_squared_acc += (inBuffer->s16[inIdx] * inBuffer->s16[inIdx]); 71661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 71761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti // store the measurement 71861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[visu_ctxt->meas_buffer_idx].peak_u16 = (uint16_t)max_sample; 71961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[visu_ctxt->meas_buffer_idx].rms_squared = 72061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti rms_squared_acc / (inBuffer->frameCount * visu_ctxt->channel_count); 72161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[visu_ctxt->meas_buffer_idx].is_valid = true; 72261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (++visu_ctxt->meas_buffer_idx >= visu_ctxt->meas_wndw_size_in_buffers) { 72361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->meas_buffer_idx = 0; 72461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 72561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 72661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 72761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* all code below assumes stereo 16 bit PCM output and input */ 72861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t shift; 72961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 73061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (visu_ctxt->scaling_mode == VISUALIZER_SCALING_MODE_NORMALIZED) { 73161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* derive capture scaling factor from peak value in current buffer 73261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * this gives more interesting captures for display. */ 73361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti shift = 32; 73461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int len = inBuffer->frameCount * 2; 73561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int i; 73661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (i = 0; i < len; i++) { 73761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t smp = inBuffer->s16[i]; 73861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (smp < 0) smp = -smp - 1; /* take care to keep the max negative in range */ 73961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t clz = __builtin_clz(smp); 74061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (shift > clz) shift = clz; 74161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 74261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* A maximum amplitude signal will have 17 leading zeros, which we want to 74361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * translate to a shift of 8 (for converting 16 bit to 8 bit) */ 74461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti shift = 25 - shift; 74561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* Never scale by less than 8 to avoid returning unaltered PCM signal. */ 74661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (shift < 3) { 74761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti shift = 3; 74861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 74961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* add one to combine the division by 2 needed after summing 75061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * left and right channels below */ 75161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti shift++; 75261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 75361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti assert(visu_ctxt->scaling_mode == VISUALIZER_SCALING_MODE_AS_PLAYED); 75461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti shift = 9; 75561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 75661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 75761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t capt_idx; 75861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t in_idx; 75961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint8_t *buf = visu_ctxt->capture_buf; 76061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (in_idx = 0, capt_idx = visu_ctxt->capture_idx; 76161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti in_idx < inBuffer->frameCount; 76261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti in_idx++, capt_idx++) { 76361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (capt_idx >= CAPTURE_BUF_SIZE) { 76461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* wrap around */ 76561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti capt_idx = 0; 76661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 76761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t smp = inBuffer->s16[2 * in_idx] + inBuffer->s16[2 * in_idx + 1]; 76861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti smp = smp >> shift; 76961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti buf[capt_idx] = ((uint8_t)smp)^0x80; 77061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 77161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 77261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* XXX the following two should really be atomic, though it probably doesn't 77361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * matter much for visualization purposes */ 77461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->capture_idx = capt_idx; 77561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* update last buffer update time stamp */ 77661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (clock_gettime(CLOCK_MONOTONIC, &visu_ctxt->buffer_update_time) < 0) { 77761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->buffer_update_time.tv_sec = 0; 77861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 77961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 78061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->state != EFFECT_STATE_ACTIVE) { 78161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s DONE inactive", __func__); 78261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -ENODATA; 78361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 78461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 78561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 78661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 78761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 78861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint visualizer_command(effect_context_t * context, uint32_t cmdCode, uint32_t cmdSize, 78961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti void *pCmdData, uint32_t *replySize, void *pReplyData) 79061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 79161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visualizer_context_t * visu_ctxt = (visualizer_context_t *)context; 79261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 79361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti switch (cmdCode) { 79461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_CMD_CAPTURE: 79561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pReplyData == NULL || *replySize != visu_ctxt->capture_size) { 79661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s VISUALIZER_CMD_CAPTURE error *replySize %d context->capture_size %d", 79761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti __func__, *replySize, visu_ctxt->capture_size); 79861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 79961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 80061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 80161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!context->offload_enabled) 80261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 80361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 80461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->state == EFFECT_STATE_ACTIVE) { 80561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t latency_ms = visu_ctxt->latency; 80661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti const uint32_t delta_ms = visualizer_get_delta_time_ms_from_updated_time(visu_ctxt); 80761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti latency_ms -= delta_ms; 80861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (latency_ms < 0) { 80961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti latency_ms = 0; 81061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 81161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti const uint32_t delta_smp = context->config.inputCfg.samplingRate * latency_ms / 1000; 81261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 81361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t capture_point = visu_ctxt->capture_idx - visu_ctxt->capture_size - delta_smp; 81461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t capture_size = visu_ctxt->capture_size; 81561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (capture_point < 0) { 81661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t size = -capture_point; 81761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (size > capture_size) 81861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti size = capture_size; 81961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 82061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti memcpy(pReplyData, 82161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->capture_buf + CAPTURE_BUF_SIZE + capture_point, 82261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti size); 82361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pReplyData = (void *)((size_t)pReplyData + size); 82461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti capture_size -= size; 82561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti capture_point = 0; 82661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 82761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti memcpy(pReplyData, 82861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->capture_buf + capture_point, 82961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti capture_size); 83061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 83161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 83261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* if audio framework has stopped playing audio although the effect is still 83361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * active we must clear the capture buffer to return silence */ 83461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if ((visu_ctxt->last_capture_idx == visu_ctxt->capture_idx) && 83561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti (visu_ctxt->buffer_update_time.tv_sec != 0)) { 83661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (delta_ms > MAX_STALL_TIME_MS) { 83761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s capture going to idle", __func__); 83861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->buffer_update_time.tv_sec = 0; 83961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti memset(pReplyData, 0x80, visu_ctxt->capture_size); 84061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 84161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 84261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->last_capture_idx = visu_ctxt->capture_idx; 84361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 84461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti memset(pReplyData, 0x80, visu_ctxt->capture_size); 84561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 84661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 84761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 84861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case VISUALIZER_CMD_MEASURE: { 84961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint16_t peak_u16 = 0; 85061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti float sum_rms_squared = 0.0f; 85161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint8_t nb_valid_meas = 0; 85261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* reset measurements if last measurement was too long ago (which implies stored 85361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * measurements aren't relevant anymore and shouldn't bias the new one) */ 85461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti const int32_t delay_ms = visualizer_get_delta_time_ms_from_updated_time(visu_ctxt); 85561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (delay_ms > DISCARD_MEASUREMENTS_TIME_MS) { 85661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t i; 85761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("Discarding measurements, last measurement is %dms old", delay_ms); 85861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (i=0 ; i<visu_ctxt->meas_wndw_size_in_buffers ; i++) { 85961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[i].is_valid = false; 86061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[i].peak_u16 = 0; 86161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->past_meas[i].rms_squared = 0; 86261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 86361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visu_ctxt->meas_buffer_idx = 0; 86461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 86561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* only use actual measurements, otherwise the first RMS measure happening before 86661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS have been played will always be artificially 86761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * low */ 86861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti uint32_t i; 86961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (i=0 ; i < visu_ctxt->meas_wndw_size_in_buffers ; i++) { 87061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (visu_ctxt->past_meas[i].is_valid) { 87161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (visu_ctxt->past_meas[i].peak_u16 > peak_u16) { 87261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti peak_u16 = visu_ctxt->past_meas[i].peak_u16; 87361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 87461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti sum_rms_squared += visu_ctxt->past_meas[i].rms_squared; 87561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti nb_valid_meas++; 87661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 87761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 87861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 87961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti float rms = nb_valid_meas == 0 ? 0.0f : sqrtf(sum_rms_squared / nb_valid_meas); 88061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t* p_int_reply_data = (int32_t*)pReplyData; 88161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* convert from I16 sample values to mB and write results */ 88261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (rms < 0.000016f) { 88361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p_int_reply_data[MEASUREMENT_IDX_RMS] = -9600; //-96dB 88461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 88561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p_int_reply_data[MEASUREMENT_IDX_RMS] = (int32_t) (2000 * log10(rms / 32767.0f)); 88661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 88761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (peak_u16 == 0) { 88861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p_int_reply_data[MEASUREMENT_IDX_PEAK] = -9600; //-96dB 88961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 89061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti p_int_reply_data[MEASUREMENT_IDX_PEAK] = (int32_t) (2000 * log10(peak_u16 / 32767.0f)); 89161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 89261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("VISUALIZER_CMD_MEASURE peak=%d (%dmB), rms=%.1f (%dmB)", 89361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti peak_u16, p_int_reply_data[MEASUREMENT_IDX_PEAK], 89461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti rms, p_int_reply_data[MEASUREMENT_IDX_RMS]); 89561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 89661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 89761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 89861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti default: 89961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s invalid command %d", __func__, cmdCode); 90061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 90161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 90261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 90361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 90461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 90561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 90661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* 90761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Effect Library Interface Implementation 90861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti */ 90961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 91061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint effect_lib_create(const effect_uuid_t *uuid, 91161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t sessionId, 91261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int32_t ioId, 91361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_handle_t *pHandle) { 91461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int ret; 91561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int i; 91661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 91761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (lib_init() != 0) 91861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return init_status; 91961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 92061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pHandle == NULL || uuid == NULL) 92161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 92261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 92361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (i = 0; descriptors[i] != NULL; i++) { 92461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) 92561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 92661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 92761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 92861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (descriptors[i] == NULL) 92961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 93061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 93161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *context; 93261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (memcmp(uuid, &visualizer_descriptor.uuid, sizeof(effect_uuid_t)) == 0) { 93361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti visualizer_context_t *visu_ctxt = (visualizer_context_t *)calloc(1, 93461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti sizeof(visualizer_context_t)); 93561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (visu_ctxt == NULL) { 93661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGE("%s fail to allocate memory", __func__); 93761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -ENOMEM; 93861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 93961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context = (effect_context_t *)visu_ctxt; 94061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.init = visualizer_init; 94161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.reset = visualizer_reset; 94261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.process = visualizer_process; 94361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.set_parameter = visualizer_set_parameter; 94461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.get_parameter = visualizer_get_parameter; 94561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.command = visualizer_command; 94661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->desc = &visualizer_descriptor; 94761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } else { 94861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 94961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 95061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 95161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->itfe = &effect_interface; 95261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->state = EFFECT_STATE_UNINITIALIZED; 95361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->out_handle = (audio_io_handle_t)ioId; 95461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 95561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ret = context->ops.init(context); 95661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (ret < 0) { 95761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s init failed", __func__); 95861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti free(context); 95961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return ret; 96061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 96161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 96261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->state = EFFECT_STATE_INITIALIZED; 96361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 96461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 96561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_add_tail(&created_effects_list, &context->effects_list_node); 96661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t *out_ctxt = get_output(ioId); 96761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (out_ctxt != NULL) 96861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti add_effect_to_output(out_ctxt, context); 96961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 97061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 97161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *pHandle = (effect_handle_t)context; 97261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 97361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s created context %p", __func__, context); 97461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 97561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 97661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 97761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 97861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 97961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint effect_lib_release(effect_handle_t handle) { 98061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *context = (effect_context_t *)handle; 98161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int status; 98261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 98361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (lib_init() != 0) 98461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return init_status; 98561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 98661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s context %p", __func__, handle); 98761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 98861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 98961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (effect_exists(context)) { 99061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t *out_ctxt = get_output(context->out_handle); 99161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (out_ctxt != NULL) 99261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti remove_effect_from_output(out_ctxt, context); 99361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti list_remove(&context->effects_list_node); 99461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.release) 99561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.release(context); 99661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti free(context); 99761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = 0; 99861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 99961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 100061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 100161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return status; 100261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 100361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 100461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint effect_lib_get_descriptor(const effect_uuid_t *uuid, 100561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_descriptor_t *descriptor) { 100661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int i; 100761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 100861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (lib_init() != 0) 100961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return init_status; 101061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 101161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (descriptor == NULL || uuid == NULL) { 101261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s called with NULL pointer", __func__); 101361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 101461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 101561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 101661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti for (i = 0; descriptors[i] != NULL; i++) { 101761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) { 101861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *descriptor = *descriptors[i]; 101961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 102061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 102161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 102261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 102361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 102461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 102561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 102661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* 102761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti * Effect Control Interface Implementation 102861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti */ 102961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 103061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti /* Stub function for effect interface: never called for offloaded effects */ 103161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint effect_process(effect_handle_t self, 103261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti audio_buffer_t *inBuffer, 103361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti audio_buffer_t *outBuffer) 103461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 103561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t * context = (effect_context_t *)self; 103661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int status = 0; 103761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 103861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s Called ?????", __func__); 103961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 104061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 104161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!effect_exists(context)) { 104261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 104361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 104461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 104561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 104661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->state != EFFECT_STATE_ACTIVE) { 104761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 104861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 104961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 105061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 105161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiexit: 105261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 105361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return status; 105461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 105561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 105661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint effect_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, 105761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti void *pCmdData, uint32_t *replySize, void *pReplyData) 105861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 105961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 106061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t * context = (effect_context_t *)self; 106161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int retsize; 106261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti int status = 0; 106361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 106461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_lock(&lock); 106561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 106661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!effect_exists(context)) { 106761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 106861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 106961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 107061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 107161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context == NULL || context->state == EFFECT_STATE_UNINITIALIZED) { 107261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 107361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 107461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 107561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 107661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti// ALOGV_IF(cmdCode != VISUALIZER_CMD_CAPTURE, 107761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti// "%s command %d cmdSize %d", __func__, cmdCode, cmdSize); 107861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 107961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti switch (cmdCode) { 108061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_INIT: 108161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pReplyData == NULL || *replySize != sizeof(int)) { 108261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 108361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 108461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 108561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.init) 108661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *(int *) pReplyData = context->ops.init(context); 108761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti else 108861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *(int *) pReplyData = 0; 108961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 109061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_SET_CONFIG: 109161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) 109261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti || pReplyData == NULL || *replySize != sizeof(int)) { 109361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 109461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 109561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 109661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *(int *) pReplyData = set_config(context, (effect_config_t *) pCmdData); 109761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 109861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_GET_CONFIG: 109961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pReplyData == NULL || 110061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *replySize != sizeof(effect_config_t)) { 110161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 110261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 110361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 110461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!context->offload_enabled) { 110561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 110661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 110761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 110861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 110961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti get_config(context, (effect_config_t *)pReplyData); 111061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 111161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_RESET: 111261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.reset) 111361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.reset(context); 111461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 111561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_ENABLE: 111661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pReplyData == NULL || *replySize != sizeof(int)) { 111761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 111861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 111961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 112061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->state != EFFECT_STATE_INITIALIZED) { 112161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -ENOSYS; 112261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 112361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 112461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->state = EFFECT_STATE_ACTIVE; 112561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.enable) 112661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.enable(context); 112761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_cond_signal(&cond); 112861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s EFFECT_CMD_ENABLE", __func__); 112961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *(int *)pReplyData = 0; 113061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 113161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_DISABLE: 113261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pReplyData == NULL || *replySize != sizeof(int)) { 113361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 113461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 113561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 113661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->state != EFFECT_STATE_ACTIVE) { 113761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -ENOSYS; 113861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 113961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 114061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->state = EFFECT_STATE_INITIALIZED; 114161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.disable) 114261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.disable(context); 114361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_cond_signal(&cond); 114461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s EFFECT_CMD_DISABLE", __func__); 114561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *(int *)pReplyData = 0; 114661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 114761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_GET_PARAM: { 114861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pCmdData == NULL || 114961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t)) || 115061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pReplyData == NULL || 115161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t))) { 115261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 115361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 115461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 115561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!context->offload_enabled) { 115661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 115761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 115861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 115961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + sizeof(uint32_t)); 116061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_param_t *p = (effect_param_t *)pReplyData; 116161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.get_parameter) 116261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->ops.get_parameter(context, p, replySize); 116361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } break; 116461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_SET_PARAM: { 116561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (pCmdData == NULL || 116661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t)) || 116761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pReplyData == NULL || *replySize != sizeof(int32_t)) { 116861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 116961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti goto exit; 117061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 117161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *(int32_t *)pReplyData = 0; 117261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_param_t *p = (effect_param_t *)pCmdData; 117361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->ops.set_parameter) 117461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *(int32_t *)pReplyData = context->ops.set_parameter(context, p, *replySize); 117561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 117661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } break; 117761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_SET_DEVICE: 117861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_SET_VOLUME: 117961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_SET_AUDIO_MODE: 118061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 118161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 118261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti case EFFECT_CMD_OFFLOAD: { 118361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti output_context_t *out_ctxt; 118461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 118561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (cmdSize != sizeof(effect_offload_param_t) || pCmdData == NULL 118661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti || pReplyData == NULL || *replySize != sizeof(int)) { 118761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s EFFECT_CMD_OFFLOAD bad format", __func__); 118861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 118961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 119061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 119161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 119261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_offload_param_t* offload_param = (effect_offload_param_t*)pCmdData; 119361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 119461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGV("%s EFFECT_CMD_OFFLOAD offload %d output %d", 119561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti __func__, offload_param->isOffload, offload_param->ioHandle); 119661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 119761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *(int *)pReplyData = 0; 119861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 119961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->offload_enabled = offload_param->isOffload; 120061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (context->out_handle == offload_param->ioHandle) 120161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 120261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 120361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti out_ctxt = get_output(context->out_handle); 120461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (out_ctxt != NULL) 120561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti remove_effect_from_output(out_ctxt, context); 120661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 120761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti context->out_handle = offload_param->ioHandle; 120861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti out_ctxt = get_output(offload_param->ioHandle); 120961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (out_ctxt != NULL) 121061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti add_effect_to_output(out_ctxt, context); 121161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 121261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } break; 121361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 121461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 121561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti default: 121661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (cmdCode >= EFFECT_CMD_FIRST_PROPRIETARY && context->ops.command) 121761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = context->ops.command(context, cmdCode, cmdSize, 121861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pCmdData, replySize, pReplyData); 121961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti else { 122061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti ALOGW("%s invalid command %d", __func__, cmdCode); 122161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti status = -EINVAL; 122261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 122361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti break; 122461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti } 122561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 122661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiexit: 122761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti pthread_mutex_unlock(&lock); 122861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 122961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti// ALOGV_IF(cmdCode != VISUALIZER_CMD_CAPTURE,"%s DONE", __func__); 123061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return status; 123161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 123261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 123361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* Effect Control Interface Implementation: get_descriptor */ 123461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiint effect_get_descriptor(effect_handle_t self, 123561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_descriptor_t *descriptor) 123661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti{ 123761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_context_t *context = (effect_context_t *)self; 123861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 123961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (!effect_exists(context)) 124061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 124161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 124261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti if (descriptor == NULL) 124361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return -EINVAL; 124461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 124561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti *descriptor = *context->desc; 124661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 124761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti return 0; 124861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti} 124961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 125061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti/* effect_handle_t interface implementation for visualizer effect */ 125161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleticonst struct effect_interface_s effect_interface = { 125261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_process, 125361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_command, 125461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti effect_get_descriptor, 125561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti NULL, 125661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti}; 125761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti 125861e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti__attribute__ ((visibility ("default"))) 125961e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuletiaudio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 126061e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti tag : AUDIO_EFFECT_LIBRARY_TAG, 126161e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti version : EFFECT_LIBRARY_API_VERSION, 126261e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti name : "Visualizer Library", 126361e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti implementor : "The Android Open Source Project", 126461e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti create_effect : effect_lib_create, 126561e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti release_effect : effect_lib_release, 126661e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti get_descriptor : effect_lib_get_descriptor, 126761e21a4fe27118141afc13323807f83b733cf426Uday Kishore Pasupuleti}; 1268