1b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* 2b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Copyright (C) 2011 The Android Open Source Project 3b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * 4b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Licensed under the Apache License, Version 2.0 (the "License"); 5b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * you may not use this file except in compliance with the License. 6b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * You may obtain a copy of the License at 7b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * 8b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * http://www.apache.org/licenses/LICENSE-2.0 9b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * 10b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Unless required by applicable law or agreed to in writing, software 11b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * distributed under the License is distributed on an "AS IS" BASIS, 12b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * See the License for the specific language governing permissions and 14b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * limitations under the License. 15b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande */ 16b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 17b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define LOG_TAG "nv_offload_visualizer" 18b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande//#define LOG_NDEBUG 1 19b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <assert.h> 20b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <math.h> 21b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <stdlib.h> 22b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <string.h> 23b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <time.h> 24b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <sys/prctl.h> 25b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 26b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <cutils/list.h> 27b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <cutils/log.h> 28b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <system/thread_defs.h> 29b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <tinyalsa/asoundlib.h> 30b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#include <audio_effects/effect_visualizer.h> 31b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 32b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 33b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeenum { 34b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande EFFECT_STATE_UNINITIALIZED, 35b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande EFFECT_STATE_INITIALIZED, 36b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande EFFECT_STATE_ACTIVE, 37b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande}; 38b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 39b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandetypedef struct effect_context_s effect_context_t; 40b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandetypedef struct output_context_s output_context_t; 41b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 42b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* effect specific operations. Only the init() and process() operations must be defined. 43b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Others are optional. 44b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande */ 45b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandetypedef struct effect_ops_s { 46b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*init)(effect_context_t *context); 47b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*release)(effect_context_t *context); 48b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*reset)(effect_context_t *context); 49b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*enable)(effect_context_t *context); 50b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*disable)(effect_context_t *context); 51b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*start)(effect_context_t *context, output_context_t *output); 52b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*stop)(effect_context_t *context, output_context_t *output); 53b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*process)(effect_context_t *context, audio_buffer_t *in, audio_buffer_t *out); 54b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*set_parameter)(effect_context_t *context, effect_param_t *param, uint32_t size); 55b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*get_parameter)(effect_context_t *context, effect_param_t *param, uint32_t *size); 56b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int (*command)(effect_context_t *context, uint32_t cmdCode, uint32_t cmdSize, 57b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande void *pCmdData, uint32_t *replySize, void *pReplyData); 58b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} effect_ops_t; 59b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 60b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandestruct effect_context_s { 61b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande const struct effect_interface_s *itfe; 62b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode effects_list_node; 63b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode output_node; 64b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_config_t config; 65b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande const effect_descriptor_t *desc; 66b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande audio_io_handle_t out_handle; /* io handle of the output the effect is attached to */ 67b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t state; 68b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande bool offload_enabled; /* when offload is enabled we process VISUALIZER_CMD_CAPTURE command. 69b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande Otherwise non offloaded visualizer has already processed the command 70b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande and we must not overwrite the reply. */ 71b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_ops_t ops; 72b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande}; 73b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 74b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandetypedef struct output_context_s { 75b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode outputs_list_node; /* node in active_outputs_list */ 76b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande audio_io_handle_t handle; /* io handle */ 77b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode effects_list; /* list of effects attached to this output */ 78b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} output_context_t; 79b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 80b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 81b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* maximum time since last capture buffer update before resetting capture buffer. This means 82b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande that the framework has stopped playing audio and we must start returning silence */ 83b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define MAX_STALL_TIME_MS 1000 84b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 85b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define CAPTURE_BUF_SIZE 65536 /* "64k should be enough for everyone" */ 86b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 87b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define DISCARD_MEASUREMENTS_TIME_MS 2000 /* discard measurements older than this number of ms */ 88b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 89b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* maximum number of buffers for which we keep track of the measurements */ 90b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS 25 /* note: buffer index is stored in uint8_t */ 91b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 92b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandetypedef struct buffer_stats_s { 93b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande bool is_valid; 94b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint16_t peak_u16; /* the positive peak of the absolute value of the samples in a buffer */ 95b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande float rms_squared; /* the average square of the samples in a buffer */ 96b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} buffer_stats_t; 97b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 98b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandetypedef struct visualizer_context_s { 99b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t common; 100b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 101b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t capture_idx; 102b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t capture_size; 103b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t scaling_mode; 104b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t last_capture_idx; 105b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t latency; 106b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct timespec buffer_update_time; 107b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint8_t capture_buf[CAPTURE_BUF_SIZE]; 108b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* for measurements */ 109b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint8_t channel_count; /* to avoid recomputing it every time a buffer is processed */ 110b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t meas_mode; 111b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint8_t meas_wndw_size_in_buffers; 112b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint8_t meas_buffer_idx; 113b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande buffer_stats_t past_meas[MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS]; 114b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} visualizer_context_t; 115b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 116b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 117b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeextern const struct effect_interface_s effect_interface; 118b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 119b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* Visualizer UUID: 09f673c0-10bc-11e4-9589-0002a5d5c51b */ 120b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeconst effect_descriptor_t visualizer_descriptor = { 121b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande {0xe46b26a0, 0xdddd, 0x11db, 0x8afd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, 122b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande {0x09f673c0, 0x10bc, 0x11e4, 0x9589, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, 123b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande EFFECT_CONTROL_API_VERSION, 124b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_HW_ACC_TUNNEL ), 125b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 0, 126b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1, 127b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande "Nvidia offload visualizer", 128b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande "The Android Open Source Project", 129b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande}; 130b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 131b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeconst effect_descriptor_t *descriptors[] = { 132b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande &visualizer_descriptor, 133b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande NULL, 134b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande}; 135b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 136b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 137b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandepthread_once_t once = PTHREAD_ONCE_INIT; 138b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint init_status; 139b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 140b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* list of created effects. Updated by visualizer_hal_start_output() 141b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * and visualizer_hal_stop_output() */ 142b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandestruct listnode created_effects_list; 143b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* list of active output streams. Updated by visualizer_hal_start_output() 144b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * and visualizer_hal_stop_output() */ 145b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandestruct listnode active_outputs_list; 146b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 147b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* thread capturing PCM from Proxy port and calling the process function on each enabled effect 148b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * attached to an active output stream */ 149b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandepthread_t capture_thread; 150b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* lock must be held when modifying or accessing created_effects_list or active_outputs_list */ 151b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandepthread_mutex_t lock; 152b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* thread_lock must be held when starting or stopping the capture thread. 153b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Locking order: thread_lock -> lock */ 154b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandepthread_mutex_t thread_lock; 155b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* cond is signaled when an output is started or stopped or an effect is enabled or disable: the 156b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * capture thread will reevaluate the capture and effect rocess conditions. */ 157b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandepthread_cond_t cond; 158b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* true when requesting the capture thread to exit */ 159b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandebool exit_thread; 160b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* 0 if the capture thread was created successfully */ 161b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint thread_status; 162b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 163fdd377e0329fd38076966332c14d5dd6d0750f59Xia Yang#define SOUND_CARD 0 164b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define CAPTURE_DEVICE 8 /* Effects capture node */ 165b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 166b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define AUDIO_CAPTURE_CHANNEL_COUNT 2 167b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define AUDIO_CAPTURE_SMP_RATE 48000 168b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande#define AUDIO_CAPTURE_PERIOD_SIZE 1024 169b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandestruct pcm_config pcm_config_capture = { 170b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande .channels = AUDIO_CAPTURE_CHANNEL_COUNT, 171b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande .rate = AUDIO_CAPTURE_SMP_RATE, 172b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande .period_size = AUDIO_CAPTURE_PERIOD_SIZE, 173b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande .period_count = 4, 174b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande .format = PCM_FORMAT_S16_LE, 175b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande .start_threshold = 4095, 176b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande .stop_threshold = 4096, 177b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande .avail_min = 1, 178b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande}; 179b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 180b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* 181b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Local functions 182b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande */ 183b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 184b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandestatic void init_once() { 185b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_init(&created_effects_list); 186b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_init(&active_outputs_list); 187b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 188b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_init(&lock, NULL); 189b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_init(&thread_lock, NULL); 190b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_cond_init(&cond, NULL); 191b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande exit_thread = false; 192b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande thread_status = -1; 193b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 194b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande init_status = 0; 195b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 196b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 197b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint lib_init() { 198b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_once(&once, init_once); 199b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return init_status; 200b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 201b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 202b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandebool effect_exists(effect_context_t *context) { 203b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *node; 204b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 205b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(node, &created_effects_list) { 206b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *fx_ctxt = node_to_item(node, 207b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t, 208b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effects_list_node); 209b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (fx_ctxt == context) { 210b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return true; 211b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 212b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 213b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return false; 214b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 215b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 216b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeoutput_context_t *get_output(audio_io_handle_t output) { 217b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *node; 218b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 219b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(node, &active_outputs_list) { 220b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t *out_ctxt = node_to_item(node, 221b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t, 222b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande outputs_list_node); 223b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (out_ctxt->handle == output) { 224b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return out_ctxt; 225b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 226b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 227b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return NULL; 228b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 229b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 230b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandevoid add_effect_to_output(output_context_t * output, effect_context_t *context) { 231b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *fx_node; 232b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 233b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(fx_node, &output->effects_list) { 234b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *fx_ctxt = node_to_item(fx_node, 235b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t, 236b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_node); 237b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (fx_ctxt == context) 238b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return; 239b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 240b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_add_tail(&output->effects_list, &context->output_node); 241b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.start) 242b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.start(context, output); 243b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 244b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 245b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandevoid remove_effect_from_output(output_context_t * output, effect_context_t *context) { 246b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *fx_node; 247b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 248b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(fx_node, &output->effects_list) { 249b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *fx_ctxt = node_to_item(fx_node, 250b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t, 251b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_node); 252b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (fx_ctxt == context) { 253b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.stop) 254b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.stop(context, output); 255b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_remove(&context->output_node); 256b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return; 257b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 258b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 259b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 260b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 261b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandebool effects_enabled() { 262b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *out_node; 263b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 264b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(out_node, &active_outputs_list) { 265b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *fx_node; 266b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t *out_ctxt = node_to_item(out_node, 267b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t, 268b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande outputs_list_node); 269b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 270b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(fx_node, &out_ctxt->effects_list) { 271b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *fx_ctxt = node_to_item(fx_node, 272b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t, 273b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_node); 274b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (fx_ctxt->state == EFFECT_STATE_ACTIVE && fx_ctxt->ops.process != NULL) 275b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return true; 276b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 277b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 278b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return false; 279b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 280b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 281b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandevoid *effects_capture_thread_loop(void *arg __unused) 282b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 283b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int16_t data[AUDIO_CAPTURE_PERIOD_SIZE * AUDIO_CAPTURE_CHANNEL_COUNT * sizeof(int16_t)]; 284b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande audio_buffer_t buf; 285b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande buf.frameCount = AUDIO_CAPTURE_PERIOD_SIZE; 286b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande buf.s16 = data; 287b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande bool capture_enabled = false; 288b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct pcm *pcm = NULL; 289b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int ret; 290b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int retry_num = 0; 291b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 292b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande prctl(PR_SET_NAME, (unsigned long)"visualizer capture", 0, 0, 0); 293b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 294b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 295b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 296b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (;;) { 297b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (exit_thread) { 298b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 299b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 300b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (effects_enabled()) { 301b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!capture_enabled) { 302b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pcm = pcm_open(SOUND_CARD, CAPTURE_DEVICE, 303b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande PCM_IN, &pcm_config_capture); 304b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pcm && !pcm_is_ready(pcm)) { 305b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGW("%s: %s", __func__, pcm_get_error(pcm)); 306b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pcm_close(pcm); 307b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pcm = NULL; 308b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 309b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande capture_enabled = true; 310b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGD("%s: capture ENABLED", __func__); 311b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 312b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 313b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 314b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (capture_enabled) { 315b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pcm != NULL) { 316b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGD("%s:Closing pcm\n", __func__); 317b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pcm_close(pcm); 318b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 319b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGD("%s: capture DISABLED", __func__); 320b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande capture_enabled = false; 321b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 322b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_cond_wait(&cond, &lock); 323b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 324b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!capture_enabled) 325b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande continue; 326b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 327b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 328b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ret = pcm_read(pcm, data, sizeof(data)); 329b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 330b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 331b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (ret == 0) { 332b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *out_node; 333b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 334b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(out_node, &active_outputs_list) { 335b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t *out_ctxt = node_to_item(out_node, 336b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t, 337b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande outputs_list_node); 338b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *fx_node; 339b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 340b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(fx_node, &out_ctxt->effects_list) { 341b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *fx_ctxt = node_to_item(fx_node, 342b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t, 343b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_node); 344b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (fx_ctxt->ops.process != NULL) 345b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande fx_ctxt->ops.process(fx_ctxt, &buf, &buf); 346b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 347b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 348b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 349b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGW("%s: read status %d %s", __func__, ret, pcm_get_error(pcm)); 350b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 351b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 352b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 353b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (capture_enabled) { 354b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pcm != NULL) 355b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pcm_close(pcm); 356b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 357b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 358b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 359b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGD("thread exit"); 360b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 361b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return NULL; 362b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 363b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 364b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* 365b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Interface from audio HAL 366b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande */ 367b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 368b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande__attribute__ ((visibility ("default"))) 369b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint visualizer_hal_start_output(audio_io_handle_t output, int pcm_id) { 370b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int ret; 371b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *node; 372b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 373b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s output %d pcm_id %d", __func__, output, pcm_id); 374b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 375b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (lib_init() != 0) 376b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return init_status; 377b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 378b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&thread_lock); 379b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 380b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (get_output(output) != NULL) { 381b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGE("%s output already started", __func__); 382b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ret = -ENOSYS; 383b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 384b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 385b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 386b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t *out_ctxt = (output_context_t *)malloc(sizeof(output_context_t)); 387b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande out_ctxt->handle = output; 388b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_init(&out_ctxt->effects_list); 389b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 390b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(node, &created_effects_list) { 391b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *fx_ctxt = node_to_item(node, 392b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t, 393b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effects_list_node); 394b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (fx_ctxt->out_handle == output) { 395b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (fx_ctxt->ops.start) 396b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande fx_ctxt->ops.start(fx_ctxt, out_ctxt); 397b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_add_tail(&out_ctxt->effects_list, &fx_ctxt->output_node); 398b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 399b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 400b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (list_empty(&active_outputs_list)) { 401b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande exit_thread = false; 402b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande thread_status = pthread_create(&capture_thread, (const pthread_attr_t *) NULL, 403b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effects_capture_thread_loop, NULL); 404b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 405b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_add_tail(&active_outputs_list, &out_ctxt->outputs_list_node); 406b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_cond_signal(&cond); 407b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 408b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeexit: 409b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 410b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&thread_lock); 411b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return ret; 412b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 413b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 414b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande__attribute__ ((visibility ("default"))) 415b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint visualizer_hal_stop_output(audio_io_handle_t output, int pcm_id) { 416b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int ret; 417b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *node; 418b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct listnode *fx_node; 419b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t *out_ctxt; 420b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 421b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s output %d pcm_id %d", __func__, output, pcm_id); 422b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 423b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (lib_init() != 0) 424b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return init_status; 425b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 426b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&thread_lock); 427b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 428b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 429b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande out_ctxt = get_output(output); 430b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (out_ctxt == NULL) { 431b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGW("%s output not started", __func__); 432b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ret = -ENOSYS; 433b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 434b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 435b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_for_each(fx_node, &out_ctxt->effects_list) { 436b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *fx_ctxt = node_to_item(fx_node, 437b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t, 438b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_node); 439b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (fx_ctxt->ops.stop) 440b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande fx_ctxt->ops.stop(fx_ctxt, out_ctxt); 441b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 442b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_remove(&out_ctxt->outputs_list_node); 443b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_cond_signal(&cond); 444b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 445b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (list_empty(&active_outputs_list)) { 446b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (thread_status == 0) { 447b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande exit_thread = true; 448b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_cond_signal(&cond); 449b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 450b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_join(capture_thread, (void **) NULL); 451b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 452b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande thread_status = -1; 453b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 454b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 455b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 456b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande free(out_ctxt); 457b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 458b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeexit: 459b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 460b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&thread_lock); 461b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return ret; 462b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 463b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 464b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 465b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* 466b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Effect operations 467b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande */ 468b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 469b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint set_config(effect_context_t *context, effect_config_t *config) 470b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 471b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (config->inputCfg.samplingRate != config->outputCfg.samplingRate) return -EINVAL; 472b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (config->inputCfg.channels != config->outputCfg.channels) return -EINVAL; 473b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (config->inputCfg.format != config->outputCfg.format) return -EINVAL; 474b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (config->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) return -EINVAL; 475b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (config->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE && 476b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande config->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL; 477b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL; 478b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 479b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config = *config; 480b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 481b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.reset) 482b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.reset(context); 483b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 484b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 485b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 486b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 487b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandevoid get_config(effect_context_t *context, effect_config_t *config) 488b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 489b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *config = context->config; 490b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 491b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 492b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 493b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* 494b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Visualizer operations 495b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande */ 496b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 497b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeuint32_t visualizer_get_delta_time_ms_from_updated_time(visualizer_context_t* visu_ctxt) { 498b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t delta_ms = 0; 499b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (visu_ctxt->buffer_update_time.tv_sec != 0) { 500b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande struct timespec ts; 501b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 502b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande time_t secs = ts.tv_sec - visu_ctxt->buffer_update_time.tv_sec; 503b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande long nsec = ts.tv_nsec - visu_ctxt->buffer_update_time.tv_nsec; 504b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (nsec < 0) { 505b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande --secs; 506b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande nsec += 1000000000; 507b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 508b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande delta_ms = secs * 1000 + nsec / 1000000; 509b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 510b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 511b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return delta_ms; 512b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 513b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 514b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint visualizer_reset(effect_context_t *context) 515b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 516b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visualizer_context_t * visu_ctxt = (visualizer_context_t *)context; 517b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 518b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->capture_idx = 0; 519b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->last_capture_idx = 0; 520b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->buffer_update_time.tv_sec = 0; 521b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->latency = 0; 522b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande memset(visu_ctxt->capture_buf, 0x80, CAPTURE_BUF_SIZE); 523b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 524b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 525b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 526b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint visualizer_init(effect_context_t *context) 527b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 528b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t i; 529b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 530b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visualizer_context_t * visu_ctxt = (visualizer_context_t *)context; 531b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 532b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; 533b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 534b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 535b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.inputCfg.samplingRate = 44100; 536b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.inputCfg.bufferProvider.getBuffer = NULL; 537b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.inputCfg.bufferProvider.releaseBuffer = NULL; 538b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.inputCfg.bufferProvider.cookie = NULL; 539b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.inputCfg.mask = EFFECT_CONFIG_ALL; 540b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; 541b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; 542b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 543b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.outputCfg.samplingRate = 44100; 544b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.outputCfg.bufferProvider.getBuffer = NULL; 545b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.outputCfg.bufferProvider.releaseBuffer = NULL; 546b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.outputCfg.bufferProvider.cookie = NULL; 547b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->config.outputCfg.mask = EFFECT_CONFIG_ALL; 548b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 549b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->capture_size = VISUALIZER_CAPTURE_SIZE_MAX; 550b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->scaling_mode = VISUALIZER_SCALING_MODE_NORMALIZED; 551b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 552b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande // measurement initialization 553b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->channel_count = popcount(context->config.inputCfg.channels); 554b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->meas_mode = MEASUREMENT_MODE_NONE; 555b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->meas_wndw_size_in_buffers = MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS; 556b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->meas_buffer_idx = 0; 557b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (i=0 ; i<visu_ctxt->meas_wndw_size_in_buffers ; i++) { 558b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[i].is_valid = false; 559b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[i].peak_u16 = 0; 560b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[i].rms_squared = 0; 561b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 562b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 563b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande set_config(context, &context->config); 564b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 565b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 566b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 567b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 568b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint visualizer_get_parameter(effect_context_t *context, effect_param_t *p, uint32_t *size) 569b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 570b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visualizer_context_t *visu_ctxt = (visualizer_context_t *)context; 571b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 572b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p->status = 0; 573b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *size = sizeof(effect_param_t) + sizeof(uint32_t); 574b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (p->psize != sizeof(uint32_t)) { 575b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p->status = -EINVAL; 576b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 577b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 578b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande switch (*(uint32_t *)p->data) { 579b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_PARAM_CAPTURE_SIZE: 580b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s get capture_size = %d", __func__, visu_ctxt->capture_size); 581b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *((uint32_t *)p->data + 1) = visu_ctxt->capture_size; 582b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p->vsize = sizeof(uint32_t); 583b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *size += sizeof(uint32_t); 584b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 585b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_PARAM_SCALING_MODE: 586b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s get scaling_mode = %d", __func__, visu_ctxt->scaling_mode); 587b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *((uint32_t *)p->data + 1) = visu_ctxt->scaling_mode; 588b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p->vsize = sizeof(uint32_t); 589b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *size += sizeof(uint32_t); 590b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 591b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_PARAM_MEASUREMENT_MODE: 592b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s get meas_mode = %d", __func__, visu_ctxt->meas_mode); 593b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *((uint32_t *)p->data + 1) = visu_ctxt->meas_mode; 594b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p->vsize = sizeof(uint32_t); 595b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *size += sizeof(uint32_t); 596b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 597b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande default: 598b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p->status = -EINVAL; 599b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 600b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 601b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 602b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 603b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint visualizer_set_parameter(effect_context_t *context, effect_param_t *p, uint32_t size __unused) 604b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 605b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visualizer_context_t *visu_ctxt = (visualizer_context_t *)context; 606b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 607b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (p->psize != sizeof(uint32_t) || p->vsize != sizeof(uint32_t)) 608b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 609b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 610b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande switch (*(uint32_t *)p->data) { 611b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_PARAM_CAPTURE_SIZE: 612b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->capture_size = *((uint32_t *)p->data + 1); 613b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s set capture_size = %d", __func__, visu_ctxt->capture_size); 614b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 615b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_PARAM_SCALING_MODE: 616b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->scaling_mode = *((uint32_t *)p->data + 1); 617b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s set scaling_mode = %d", __func__, visu_ctxt->scaling_mode); 618b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 619b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_PARAM_LATENCY: 620b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s set latency = %d", __func__, visu_ctxt->latency); 621b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 622b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_PARAM_MEASUREMENT_MODE: 623b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->meas_mode = *((uint32_t *)p->data + 1); 624b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s set meas_mode = %d", __func__, visu_ctxt->meas_mode); 625b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 626b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande default: 627b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 628b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 629b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 630b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 631b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 632b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* Real process function called from capture thread. Called with lock held */ 633b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint visualizer_process(effect_context_t *context, 634b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande audio_buffer_t *inBuffer, 635b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande audio_buffer_t *outBuffer) 636b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 637b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visualizer_context_t *visu_ctxt = (visualizer_context_t *)context; 638b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 639b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!effect_exists(context)) 640b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 641b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 642b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (inBuffer == NULL || inBuffer->raw == NULL || 643b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande outBuffer == NULL || outBuffer->raw == NULL || 644b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande inBuffer->frameCount != outBuffer->frameCount || 645b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande inBuffer->frameCount == 0) { 646b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 647b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 648b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 649b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande // perform measurements if needed 650b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (visu_ctxt->meas_mode & MEASUREMENT_MODE_PEAK_RMS) { 651b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande // find the peak and RMS squared for the new buffer 652b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t inIdx; 653b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int16_t max_sample = 0; 654b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande float rms_squared_acc = 0; 655b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (inIdx = 0 ; inIdx < inBuffer->frameCount * visu_ctxt->channel_count ; inIdx++) { 656b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (inBuffer->s16[inIdx] > max_sample) { 657b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande max_sample = inBuffer->s16[inIdx]; 658b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else if (-inBuffer->s16[inIdx] > max_sample) { 659b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande max_sample = -inBuffer->s16[inIdx]; 660b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 661b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande rms_squared_acc += (inBuffer->s16[inIdx] * inBuffer->s16[inIdx]); 662b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 663b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande // store the measurement 664b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[visu_ctxt->meas_buffer_idx].peak_u16 = (uint16_t)max_sample; 665b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[visu_ctxt->meas_buffer_idx].rms_squared = 666b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande rms_squared_acc / (inBuffer->frameCount * visu_ctxt->channel_count); 667b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[visu_ctxt->meas_buffer_idx].is_valid = true; 668b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (++visu_ctxt->meas_buffer_idx >= visu_ctxt->meas_wndw_size_in_buffers) { 669b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->meas_buffer_idx = 0; 670b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 671b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 672b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 673b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* all code below assumes stereo 16 bit PCM output and input */ 674b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t shift; 675b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 676b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (visu_ctxt->scaling_mode == VISUALIZER_SCALING_MODE_NORMALIZED) { 677b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* derive capture scaling factor from peak value in current buffer 678b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * this gives more interesting captures for display. */ 679b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande shift = 32; 680b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int len = inBuffer->frameCount * 2; 681b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int i; 682b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (i = 0; i < len; i++) { 683b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t smp = inBuffer->s16[i]; 684b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (smp < 0) smp = -smp - 1; /* take care to keep the max negative in range */ 685b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t clz = __builtin_clz(smp); 686b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (shift > clz) shift = clz; 687b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 688b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* A maximum amplitude signal will have 17 leading zeros, which we want to 689b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * translate to a shift of 8 (for converting 16 bit to 8 bit) */ 690b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande shift = 25 - shift; 691b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* Never scale by less than 8 to avoid returning unaltered PCM signal. */ 692b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (shift < 3) { 693b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande shift = 3; 694b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 695b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* add one to combine the division by 2 needed after summing 696b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * left and right channels below */ 697b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande shift++; 698b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 699b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande assert(visu_ctxt->scaling_mode == VISUALIZER_SCALING_MODE_AS_PLAYED); 700b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande shift = 9; 701b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 702b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 703b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t capt_idx; 704b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t in_idx; 705b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint8_t *buf = visu_ctxt->capture_buf; 706b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (in_idx = 0, capt_idx = visu_ctxt->capture_idx; 707b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande in_idx < inBuffer->frameCount; 708b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande in_idx++, capt_idx++) { 709b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (capt_idx >= CAPTURE_BUF_SIZE) { 710b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* wrap around */ 711b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande capt_idx = 0; 712b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 713b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t smp = inBuffer->s16[2 * in_idx] + inBuffer->s16[2 * in_idx + 1]; 714b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande smp = smp >> shift; 715b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande buf[capt_idx] = ((uint8_t)smp)^0x80; 716b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 717b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 718b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* XXX the following two should really be atomic, though it probably doesn't 719b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * matter much for visualization purposes */ 720b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->capture_idx = capt_idx; 721b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* update last buffer update time stamp */ 722b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (clock_gettime(CLOCK_MONOTONIC, &visu_ctxt->buffer_update_time) < 0) { 723b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->buffer_update_time.tv_sec = 0; 724b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 725b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 726b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->state != EFFECT_STATE_ACTIVE) { 727b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s DONE inactive", __func__); 728b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -ENODATA; 729b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 730b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 731b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 732b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 733b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 734b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint visualizer_command(effect_context_t * context, uint32_t cmdCode, uint32_t cmdSize __unused, 735b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande void *pCmdData __unused, uint32_t *replySize, void *pReplyData) 736b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 737b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visualizer_context_t * visu_ctxt = (visualizer_context_t *)context; 738b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 739b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande switch (cmdCode) { 740b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_CMD_CAPTURE: 741b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pReplyData == NULL || *replySize != visu_ctxt->capture_size) { 742b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s VISUALIZER_CMD_CAPTURE error *replySize %d context->capture_size %d", 743b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande __func__, *replySize, visu_ctxt->capture_size); 744b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 745b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 746b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 747b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!context->offload_enabled) 748b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 749b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 750b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->state == EFFECT_STATE_ACTIVE) { 751b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t latency_ms = visu_ctxt->latency; 752b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande const uint32_t delta_ms = visualizer_get_delta_time_ms_from_updated_time(visu_ctxt); 753b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande latency_ms -= delta_ms; 754b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (latency_ms < 0) { 755b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande latency_ms = 0; 756b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 757b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande const uint32_t delta_smp = context->config.inputCfg.samplingRate * latency_ms / 1000; 758b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 759b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t capture_point = visu_ctxt->capture_idx - visu_ctxt->capture_size - delta_smp; 760b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t capture_size = visu_ctxt->capture_size; 761b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (capture_point < 0) { 762b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t size = -capture_point; 763b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (size > capture_size) 764b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande size = capture_size; 765b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 766b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande memcpy(pReplyData, 767b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->capture_buf + CAPTURE_BUF_SIZE + capture_point, 768b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande size); 769b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pReplyData = (void *)((size_t)pReplyData + size); 770b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande capture_size -= size; 771b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande capture_point = 0; 772b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 773b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande memcpy(pReplyData, 774b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->capture_buf + capture_point, 775b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande capture_size); 776b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 777b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 778b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* if audio framework has stopped playing audio although the effect is still 779b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * active we must clear the capture buffer to return silence */ 780b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if ((visu_ctxt->last_capture_idx == visu_ctxt->capture_idx) && 781b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande (visu_ctxt->buffer_update_time.tv_sec != 0)) { 782b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (delta_ms > MAX_STALL_TIME_MS) { 783b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s capture going to idle", __func__); 784b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->buffer_update_time.tv_sec = 0; 785b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande memset(pReplyData, 0x80, visu_ctxt->capture_size); 786b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 787b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 788b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->last_capture_idx = visu_ctxt->capture_idx; 789b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 790b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande memset(pReplyData, 0x80, visu_ctxt->capture_size); 791b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 792b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 793b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 794b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case VISUALIZER_CMD_MEASURE: { 795b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint16_t peak_u16 = 0; 796b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande float sum_rms_squared = 0.0f; 797b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint8_t nb_valid_meas = 0; 798b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* reset measurements if last measurement was too long ago (which implies stored 799b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * measurements aren't relevant anymore and shouldn't bias the new one) */ 800b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande const int32_t delay_ms = visualizer_get_delta_time_ms_from_updated_time(visu_ctxt); 801b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (delay_ms > DISCARD_MEASUREMENTS_TIME_MS) { 802b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t i; 803b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("Discarding measurements, last measurement is %dms old", delay_ms); 804b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (i=0 ; i<visu_ctxt->meas_wndw_size_in_buffers ; i++) { 805b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[i].is_valid = false; 806b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[i].peak_u16 = 0; 807b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->past_meas[i].rms_squared = 0; 808b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 809b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visu_ctxt->meas_buffer_idx = 0; 810b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 811b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* only use actual measurements, otherwise the first RMS measure happening before 812b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS have been played will always be artificially 813b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * low */ 814b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande uint32_t i; 815b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (i=0 ; i < visu_ctxt->meas_wndw_size_in_buffers ; i++) { 816b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (visu_ctxt->past_meas[i].is_valid) { 817b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (visu_ctxt->past_meas[i].peak_u16 > peak_u16) { 818b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande peak_u16 = visu_ctxt->past_meas[i].peak_u16; 819b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 820b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande sum_rms_squared += visu_ctxt->past_meas[i].rms_squared; 821b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande nb_valid_meas++; 822b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 823b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 824b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 825b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande float rms = nb_valid_meas == 0 ? 0.0f : sqrtf(sum_rms_squared / nb_valid_meas); 826b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t* p_int_reply_data = (int32_t*)pReplyData; 827b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* convert from I16 sample values to mB and write results */ 828b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (rms < 0.000016f) { 829b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p_int_reply_data[MEASUREMENT_IDX_RMS] = -9600; //-96dB 830b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 831b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p_int_reply_data[MEASUREMENT_IDX_RMS] = (int32_t) (2000 * log10(rms / 32767.0f)); 832b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 833b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (peak_u16 == 0) { 834b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p_int_reply_data[MEASUREMENT_IDX_PEAK] = -9600; //-96dB 835b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 836b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande p_int_reply_data[MEASUREMENT_IDX_PEAK] = (int32_t) (2000 * log10(peak_u16 / 32767.0f)); 837b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 838b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("VISUALIZER_CMD_MEASURE peak=%d (%dmB), rms=%.1f (%dmB)", 839b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande peak_u16, p_int_reply_data[MEASUREMENT_IDX_PEAK], 840b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande rms, p_int_reply_data[MEASUREMENT_IDX_RMS]); 841b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 842b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 843b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 844b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande default: 845b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGW("%s invalid command %d", __func__, cmdCode); 846b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 847b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 848b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 849b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 850b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 851b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 852b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* 853b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Effect Library Interface Implementation 854b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande */ 855b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 856b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint effect_lib_create(const effect_uuid_t *uuid, 857b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t sessionId __unused, 858b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int32_t ioId, 859b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_handle_t *pHandle) { 860b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int ret; 861b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int i; 862b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 863b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (lib_init() != 0) 864b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return init_status; 865b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 866b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pHandle == NULL || uuid == NULL) 867b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 868b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 869b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (i = 0; descriptors[i] != NULL; i++) { 870b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) 871b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 872b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 873b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 874b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (descriptors[i] == NULL) 875b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 876b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 877b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *context; 878b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (memcmp(uuid, &visualizer_descriptor.uuid, sizeof(effect_uuid_t)) == 0) { 879b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande visualizer_context_t *visu_ctxt = (visualizer_context_t *)calloc(1, 880b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande sizeof(visualizer_context_t)); 881b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context = (effect_context_t *)visu_ctxt; 882b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.init = visualizer_init; 883b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.reset = visualizer_reset; 884b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.process = visualizer_process; 885b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.set_parameter = visualizer_set_parameter; 886b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.get_parameter = visualizer_get_parameter; 887b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.command = visualizer_command; 888b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->desc = &visualizer_descriptor; 889b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } else { 890b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 891b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 892b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 893b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->itfe = &effect_interface; 894b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->state = EFFECT_STATE_UNINITIALIZED; 895b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->out_handle = (audio_io_handle_t)ioId; 896b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 897b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ret = context->ops.init(context); 898b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (ret < 0) { 899b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGW("%s init failed", __func__); 900b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande free(context); 901b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return ret; 902b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 903b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 904b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->state = EFFECT_STATE_INITIALIZED; 905b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 906b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 907b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_add_tail(&created_effects_list, &context->effects_list_node); 908b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t *out_ctxt = get_output(ioId); 909b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (out_ctxt != NULL) 910b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande add_effect_to_output(out_ctxt, context); 911b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 912b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 913b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *pHandle = (effect_handle_t)context; 914b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 915b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s created context %p", __func__, context); 916b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 917b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 918b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 919b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 920b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 921b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint effect_lib_release(effect_handle_t handle) { 922b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *context = (effect_context_t *)handle; 923b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int status; 924b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 925b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (lib_init() != 0) 926b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return init_status; 927b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 928b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s context %p", __func__, handle); 929b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 930b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 931b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (effect_exists(context)) { 932b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t *out_ctxt = get_output(context->out_handle); 933b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (out_ctxt != NULL) 934b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande remove_effect_from_output(out_ctxt, context); 935b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande list_remove(&context->effects_list_node); 936b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.release) 937b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.release(context); 938b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande free(context); 939b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = 0; 940b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 941b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 942b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 943b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return status; 944b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 945b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 946b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint effect_lib_get_descriptor(const effect_uuid_t *uuid, 947b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_descriptor_t *descriptor) { 948b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int i; 949b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 950b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (lib_init() != 0) 951b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return init_status; 952b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 953b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (descriptor == NULL || uuid == NULL) { 954b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s called with NULL pointer", __func__); 955b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 956b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 957b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 958b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande for (i = 0; descriptors[i] != NULL; i++) { 959b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) { 960b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *descriptor = *descriptors[i]; 961b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 962b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 963b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 964b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 965b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 966b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 967b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 968b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* 969b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande * Effect Control Interface Implementation 970b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande */ 971b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 972b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande /* Stub function for effect interface: never called for offloaded effects */ 973b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint effect_process(effect_handle_t self, 974b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande audio_buffer_t *inBuffer __unused, 975b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande audio_buffer_t *outBuffer __unused) 976b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 977b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t * context = (effect_context_t *)self; 978b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int status = 0; 979b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 980b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande //ALOGW("%s Called ?????", __func__); 981b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 982b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 983b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!effect_exists(context)) { 984b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 985b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 986b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 987b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 988b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->state != EFFECT_STATE_ACTIVE) { 989b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 990b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 991b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 992b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 993b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeexit: 994b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 995b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return status; 996b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 997b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 998b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint effect_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, 999b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande void *pCmdData, uint32_t *replySize, void *pReplyData) 1000b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 1001b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1002b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t * context = (effect_context_t *)self; 1003b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int retsize; 1004b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande int status = 0; 1005b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1006b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_lock(&lock); 1007b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1008b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!effect_exists(context)) { 1009b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1010b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1011b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1012b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1013b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context == NULL || context->state == EFFECT_STATE_UNINITIALIZED) { 1014b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1015b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1016b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1017b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1018b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande// ALOGV_IF(cmdCode != VISUALIZER_CMD_CAPTURE, 1019b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande// "%s command %d cmdSize %d", __func__, cmdCode, cmdSize); 1020b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1021b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande switch (cmdCode) { 1022b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_INIT: 1023b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pReplyData == NULL || *replySize != sizeof(int)) { 1024b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1025b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1026b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1027b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.init) 1028b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *(int *) pReplyData = context->ops.init(context); 1029b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande else 1030b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *(int *) pReplyData = 0; 1031b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1032b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_SET_CONFIG: 1033b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) 1034b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande || pReplyData == NULL || *replySize != sizeof(int)) { 1035b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1036b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1037b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1038b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *(int *) pReplyData = set_config(context, (effect_config_t *) pCmdData); 1039b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1040b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_GET_CONFIG: 1041b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pReplyData == NULL || 1042b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *replySize != sizeof(effect_config_t)) { 1043b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1044b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1045b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1046b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!context->offload_enabled) { 1047b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1048b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1049b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1050b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1051b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande get_config(context, (effect_config_t *)pReplyData); 1052b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1053b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_RESET: 1054b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.reset) 1055b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.reset(context); 1056b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1057b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_ENABLE: 1058b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pReplyData == NULL || *replySize != sizeof(int)) { 1059b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1060b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1061b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1062b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->state != EFFECT_STATE_INITIALIZED) { 1063b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -ENOSYS; 1064b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1065b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1066b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->state = EFFECT_STATE_ACTIVE; 1067b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.enable) { 1068b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.enable(context); 1069b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1070b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_cond_signal(&cond); 1071b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *(int *)pReplyData = 0; 1072b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1073b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_DISABLE: 1074b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pReplyData == NULL || *replySize != sizeof(int)) { 1075b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1076b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1077b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1078b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->state != EFFECT_STATE_ACTIVE) { 1079b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -ENOSYS; 1080b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1081b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1082b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->state = EFFECT_STATE_INITIALIZED; 1083b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.disable) 1084b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.disable(context); 1085b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_cond_signal(&cond); 1086b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s EFFECT_CMD_DISABLE", __func__); 1087b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *(int *)pReplyData = 0; 1088b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1089b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_GET_PARAM: { 1090b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pCmdData == NULL || 1091b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t)) || 1092b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pReplyData == NULL || 1093b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t))) { 1094b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1095b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1096b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1097b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!context->offload_enabled) { 1098b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1099b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1100b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1101b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + sizeof(uint32_t)); 1102b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_param_t *p = (effect_param_t *)pReplyData; 1103b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.get_parameter) 1104b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->ops.get_parameter(context, p, replySize); 1105b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } break; 1106b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_SET_PARAM: { 1107b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (pCmdData == NULL || 1108b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t)) || 1109b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pReplyData == NULL || *replySize != sizeof(int32_t)) { 1110b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1111b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande goto exit; 1112b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1113b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *(int32_t *)pReplyData = 0; 1114b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_param_t *p = (effect_param_t *)pCmdData; 1115b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->ops.set_parameter) 1116b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *(int32_t *)pReplyData = context->ops.set_parameter(context, p, *replySize); 1117b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1118b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } break; 1119b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_SET_DEVICE: 1120b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_SET_VOLUME: 1121b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_SET_AUDIO_MODE: 1122b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1123b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1124b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande case EFFECT_CMD_OFFLOAD: { 1125b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande output_context_t *out_ctxt; 1126b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1127b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (cmdSize != sizeof(effect_offload_param_t) || pCmdData == NULL 1128b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande || pReplyData == NULL || *replySize != sizeof(int)) { 1129b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s EFFECT_CMD_OFFLOAD bad format", __func__); 1130b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1131b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1132b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1133b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1134b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_offload_param_t* offload_param = (effect_offload_param_t*)pCmdData; 1135b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1136b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGV("%s EFFECT_CMD_OFFLOAD offload %d output %d", 1137b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande __func__, offload_param->isOffload, offload_param->ioHandle); 1138b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1139b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *(int *)pReplyData = 0; 1140b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1141b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->offload_enabled = offload_param->isOffload; 1142b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (context->out_handle == offload_param->ioHandle) 1143b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1144b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1145b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande out_ctxt = get_output(context->out_handle); 1146b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (out_ctxt != NULL) 1147b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande remove_effect_from_output(out_ctxt, context); 1148b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1149b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande context->out_handle = offload_param->ioHandle; 1150b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande out_ctxt = get_output(offload_param->ioHandle); 1151b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (out_ctxt != NULL) 1152b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande add_effect_to_output(out_ctxt, context); 1153b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1154b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } break; 1155b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1156b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1157b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande default: 1158b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (cmdCode >= EFFECT_CMD_FIRST_PROPRIETARY && context->ops.command) 1159b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = context->ops.command(context, cmdCode, cmdSize, 1160b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pCmdData, replySize, pReplyData); 1161b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande else { 1162b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande ALOGW("%s invalid command %d", __func__, cmdCode); 1163b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande status = -EINVAL; 1164b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1165b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande break; 1166b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande } 1167b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1168b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeexit: 1169b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande pthread_mutex_unlock(&lock); 1170b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1171b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande// ALOGV_IF(cmdCode != VISUALIZER_CMD_CAPTURE,"%s DONE", __func__); 1172b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return status; 1173b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 1174b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1175b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* Effect Control Interface Implementation: get_descriptor */ 1176b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeint effect_get_descriptor(effect_handle_t self, 1177b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_descriptor_t *descriptor) 1178b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande{ 1179b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_context_t *context = (effect_context_t *)self; 1180b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1181b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (!effect_exists(context)) 1182b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 1183b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1184b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande if (descriptor == NULL) 1185b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return -EINVAL; 1186b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1187b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande *descriptor = *context->desc; 1188b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1189b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande return 0; 1190b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande} 1191b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1192b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande/* effect_handle_t interface implementation for visualizer effect */ 1193b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeconst struct effect_interface_s effect_interface = { 1194b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_process, 1195b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_command, 1196b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande effect_get_descriptor, 1197b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande NULL, 1198b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande}; 1199b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande 1200b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande__attribute__ ((visibility ("default"))) 1201b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhandeaudio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 1202b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande tag : AUDIO_EFFECT_LIBRARY_TAG, 1203b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande version : EFFECT_LIBRARY_API_VERSION, 1204b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande name : "Visualizer Library", 1205b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande implementor : "Nvidia", 1206b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande create_effect : effect_lib_create, 1207b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande release_effect : effect_lib_release, 1208b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande get_descriptor : effect_lib_get_descriptor, 1209b3249fa6053a9973b159edcf9dcc02fc44aaffa0Ravindra Lokhande}; 1210