blob: e9b804259570ddcaff1c067af6011d8505809cb2 [file] [log] [blame]
Eric Laurentda7581b2010-07-02 08:12:41 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Visualizer"
18//#define LOG_NDEBUG 0
19#include <cutils/log.h>
20#include <assert.h>
21#include <stdlib.h>
22#include <string.h>
23#include <new>
Eric Laurent6d8b6942011-06-24 07:01:31 -070024#include <audio_effects/effect_visualizer.h>
Eric Laurentda7581b2010-07-02 08:12:41 -070025
Eric Laurentda7581b2010-07-02 08:12:41 -070026
Eric Laurente1315cf2011-05-17 19:16:02 -070027extern "C" {
28
29// effect_handle_t interface implementation for visualizer effect
30extern const struct effect_interface_s gVisualizerInterface;
Eric Laurentda7581b2010-07-02 08:12:41 -070031
32// Google Visualizer UUID: d069d9e0-8329-11df-9168-0002a5d5c51b
33const effect_descriptor_t gVisualizerDescriptor = {
34 {0xe46b26a0, 0xdddd, 0x11db, 0x8afd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
35 {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
Eric Laurente1315cf2011-05-17 19:16:02 -070036 EFFECT_CONTROL_API_VERSION,
Eric Laurentda7581b2010-07-02 08:12:41 -070037 (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST),
38 0, // TODO
39 1,
40 "Visualizer",
Eric Laurente1315cf2011-05-17 19:16:02 -070041 "The Android Open Source Project",
Eric Laurentda7581b2010-07-02 08:12:41 -070042};
43
44enum visualizer_state_e {
45 VISUALIZER_STATE_UNINITIALIZED,
46 VISUALIZER_STATE_INITIALIZED,
47 VISUALIZER_STATE_ACTIVE,
48};
49
Eric Laurent3df40a02011-11-10 10:02:18 -080050// maximum number of reads from same buffer before resetting capture buffer. This means
51// that the framework has stopped playing audio and we must start returning silence
52#define MAX_STALL_COUNT 10
53
Eric Laurentda7581b2010-07-02 08:12:41 -070054struct VisualizerContext {
55 const struct effect_interface_s *mItfe;
56 effect_config_t mConfig;
Eric Laurentda7581b2010-07-02 08:12:41 -070057 uint32_t mCaptureIdx;
58 uint32_t mCaptureSize;
Eric Laurent3df40a02011-11-10 10:02:18 -080059 uint8_t mState;
60 uint8_t mCurrentBuf;
61 uint8_t mLastBuf;
62 uint8_t mStallCount;
Eric Laurentda7581b2010-07-02 08:12:41 -070063 uint8_t mCaptureBuf[2][VISUALIZER_CAPTURE_SIZE_MAX];
64};
65
Eric Laurentda7581b2010-07-02 08:12:41 -070066//
67//--- Local functions
68//
69
70void Visualizer_reset(VisualizerContext *pContext)
71{
72 pContext->mCaptureIdx = 0;
73 pContext->mCurrentBuf = 0;
Eric Laurent3df40a02011-11-10 10:02:18 -080074 pContext->mLastBuf = 1;
75 pContext->mStallCount = 0;
Eric Laurent0fa449c2010-09-24 11:52:04 -070076 memset(pContext->mCaptureBuf[0], 0x80, VISUALIZER_CAPTURE_SIZE_MAX);
77 memset(pContext->mCaptureBuf[1], 0x80, VISUALIZER_CAPTURE_SIZE_MAX);
Eric Laurentda7581b2010-07-02 08:12:41 -070078}
79
80//----------------------------------------------------------------------------
81// Visualizer_configure()
82//----------------------------------------------------------------------------
83// Purpose: Set input and output audio configuration.
84//
85// Inputs:
86// pContext: effect engine context
87// pConfig: pointer to effect_config_t structure holding input and output
88// configuration parameters
89//
90// Outputs:
91//
92//----------------------------------------------------------------------------
93
94int Visualizer_configure(VisualizerContext *pContext, effect_config_t *pConfig)
95{
Steve Block3856b092011-10-20 11:56:00 +010096 ALOGV("Visualizer_configure start");
Eric Laurentda7581b2010-07-02 08:12:41 -070097
98 if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate) return -EINVAL;
99 if (pConfig->inputCfg.channels != pConfig->outputCfg.channels) return -EINVAL;
100 if (pConfig->inputCfg.format != pConfig->outputCfg.format) return -EINVAL;
Eric Laurente1315cf2011-05-17 19:16:02 -0700101 if (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) return -EINVAL;
Eric Laurentda7581b2010-07-02 08:12:41 -0700102 if (pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE &&
103 pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL;
Eric Laurente1315cf2011-05-17 19:16:02 -0700104 if (pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
Eric Laurentda7581b2010-07-02 08:12:41 -0700105
106 memcpy(&pContext->mConfig, pConfig, sizeof(effect_config_t));
107
108 Visualizer_reset(pContext);
109
110 return 0;
111}
112
113
114//----------------------------------------------------------------------------
115// Visualizer_init()
116//----------------------------------------------------------------------------
117// Purpose: Initialize engine with default configuration.
118//
119// Inputs:
120// pContext: effect engine context
121//
122// Outputs:
123//
124//----------------------------------------------------------------------------
125
126int Visualizer_init(VisualizerContext *pContext)
127{
128 pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
Eric Laurente1315cf2011-05-17 19:16:02 -0700129 pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
130 pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurentda7581b2010-07-02 08:12:41 -0700131 pContext->mConfig.inputCfg.samplingRate = 44100;
132 pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL;
133 pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
134 pContext->mConfig.inputCfg.bufferProvider.cookie = NULL;
135 pContext->mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
136 pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
Eric Laurente1315cf2011-05-17 19:16:02 -0700137 pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
138 pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurentda7581b2010-07-02 08:12:41 -0700139 pContext->mConfig.outputCfg.samplingRate = 44100;
140 pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL;
141 pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
142 pContext->mConfig.outputCfg.bufferProvider.cookie = NULL;
143 pContext->mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
144
145 pContext->mCaptureSize = VISUALIZER_CAPTURE_SIZE_MAX;
146
147 Visualizer_configure(pContext, &pContext->mConfig);
148
149 return 0;
150}
151
152//
153//--- Effect Library Interface Implementation
154//
155
Eric Laurente1315cf2011-05-17 19:16:02 -0700156int VisualizerLib_QueryNumberEffects(uint32_t *pNumEffects) {
Eric Laurentda7581b2010-07-02 08:12:41 -0700157 *pNumEffects = 1;
158 return 0;
159}
160
Eric Laurente1315cf2011-05-17 19:16:02 -0700161int VisualizerLib_QueryEffect(uint32_t index,
162 effect_descriptor_t *pDescriptor) {
Eric Laurentda7581b2010-07-02 08:12:41 -0700163 if (pDescriptor == NULL) {
164 return -EINVAL;
165 }
166 if (index > 0) {
167 return -EINVAL;
168 }
169 memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t));
170 return 0;
171}
172
Eric Laurente1315cf2011-05-17 19:16:02 -0700173int VisualizerLib_Create(effect_uuid_t *uuid,
174 int32_t sessionId,
175 int32_t ioId,
176 effect_handle_t *pHandle) {
Eric Laurentda7581b2010-07-02 08:12:41 -0700177 int ret;
178 int i;
179
Eric Laurente1315cf2011-05-17 19:16:02 -0700180 if (pHandle == NULL || uuid == NULL) {
Eric Laurentda7581b2010-07-02 08:12:41 -0700181 return -EINVAL;
182 }
183
184 if (memcmp(uuid, &gVisualizerDescriptor.uuid, sizeof(effect_uuid_t)) != 0) {
185 return -EINVAL;
186 }
187
188 VisualizerContext *pContext = new VisualizerContext;
189
190 pContext->mItfe = &gVisualizerInterface;
191 pContext->mState = VISUALIZER_STATE_UNINITIALIZED;
192
193 ret = Visualizer_init(pContext);
194 if (ret < 0) {
Eric Laurente1315cf2011-05-17 19:16:02 -0700195 LOGW("VisualizerLib_Create() init failed");
Eric Laurentda7581b2010-07-02 08:12:41 -0700196 delete pContext;
197 return ret;
198 }
199
Eric Laurente1315cf2011-05-17 19:16:02 -0700200 *pHandle = (effect_handle_t)pContext;
Eric Laurentda7581b2010-07-02 08:12:41 -0700201
202 pContext->mState = VISUALIZER_STATE_INITIALIZED;
203
Steve Block3856b092011-10-20 11:56:00 +0100204 ALOGV("VisualizerLib_Create %p", pContext);
Eric Laurentda7581b2010-07-02 08:12:41 -0700205
206 return 0;
207
208}
209
Eric Laurente1315cf2011-05-17 19:16:02 -0700210int VisualizerLib_Release(effect_handle_t handle) {
211 VisualizerContext * pContext = (VisualizerContext *)handle;
Eric Laurentda7581b2010-07-02 08:12:41 -0700212
Steve Block3856b092011-10-20 11:56:00 +0100213 ALOGV("VisualizerLib_Release %p", handle);
Eric Laurentda7581b2010-07-02 08:12:41 -0700214 if (pContext == NULL) {
215 return -EINVAL;
216 }
217 pContext->mState = VISUALIZER_STATE_UNINITIALIZED;
218 delete pContext;
219
220 return 0;
221}
222
Eric Laurente1315cf2011-05-17 19:16:02 -0700223int VisualizerLib_GetDescriptor(effect_uuid_t *uuid,
224 effect_descriptor_t *pDescriptor) {
225
226 if (pDescriptor == NULL || uuid == NULL){
Steve Block3856b092011-10-20 11:56:00 +0100227 ALOGV("VisualizerLib_GetDescriptor() called with NULL pointer");
Eric Laurente1315cf2011-05-17 19:16:02 -0700228 return -EINVAL;
229 }
230
231 if (memcmp(uuid, &gVisualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
232 memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t));
233 return 0;
234 }
235
236 return -EINVAL;
237} /* end VisualizerLib_GetDescriptor */
238
Eric Laurentda7581b2010-07-02 08:12:41 -0700239//
240//--- Effect Control Interface Implementation
241//
242
243static inline int16_t clamp16(int32_t sample)
244{
245 if ((sample>>15) ^ (sample>>31))
246 sample = 0x7FFF ^ (sample>>31);
247 return sample;
248}
249
Eric Laurente1315cf2011-05-17 19:16:02 -0700250int Visualizer_process(
251 effect_handle_t self,audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
Eric Laurentda7581b2010-07-02 08:12:41 -0700252{
Eric Laurente1315cf2011-05-17 19:16:02 -0700253 VisualizerContext * pContext = (VisualizerContext *)self;
Eric Laurentda7581b2010-07-02 08:12:41 -0700254
255 if (pContext == NULL) {
256 return -EINVAL;
257 }
Eric Laurentda7581b2010-07-02 08:12:41 -0700258
259 if (inBuffer == NULL || inBuffer->raw == NULL ||
260 outBuffer == NULL || outBuffer->raw == NULL ||
261 inBuffer->frameCount != outBuffer->frameCount ||
262 inBuffer->frameCount == 0) {
263 return -EINVAL;
264 }
265
266 // all code below assumes stereo 16 bit PCM output and input
Eric Laurent0e75f0f2010-09-21 14:52:01 -0700267
268 // derive capture scaling factor from peak value in current buffer
269 // this gives more interesting captures for display.
270 int32_t shift = 32;
Marco Nelissen64c3bde2010-10-27 09:06:01 -0700271 int len = inBuffer->frameCount * 2;
Eric Laurente1315cf2011-05-17 19:16:02 -0700272 for (int i = 0; i < len; i++) {
Eric Laurent0e75f0f2010-09-21 14:52:01 -0700273 int32_t smp = inBuffer->s16[i];
Marco Nelissen64c3bde2010-10-27 09:06:01 -0700274 if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range
Eric Laurent0e75f0f2010-09-21 14:52:01 -0700275 int32_t clz = __builtin_clz(smp);
276 if (shift > clz) shift = clz;
277 }
Marco Nelissen64c3bde2010-10-27 09:06:01 -0700278 // A maximum amplitude signal will have 17 leading zeros, which we want to
279 // translate to a shift of 8 (for converting 16 bit to 8 bit)
280 shift = 25 - shift;
281 // Never scale by less than 8 to avoid returning unaltered PCM signal.
282 if (shift < 3) {
283 shift = 3;
Eric Laurent0e75f0f2010-09-21 14:52:01 -0700284 }
Marco Nelissen64c3bde2010-10-27 09:06:01 -0700285 // add one to combine the division by 2 needed after summing left and right channels below
286 shift++;
Eric Laurent0e75f0f2010-09-21 14:52:01 -0700287
Eric Laurentda7581b2010-07-02 08:12:41 -0700288 uint32_t captIdx;
289 uint32_t inIdx;
290 uint8_t *buf = pContext->mCaptureBuf[pContext->mCurrentBuf];
291 for (inIdx = 0, captIdx = pContext->mCaptureIdx;
292 inIdx < inBuffer->frameCount && captIdx < pContext->mCaptureSize;
293 inIdx++, captIdx++) {
294 int32_t smp = inBuffer->s16[2 * inIdx] + inBuffer->s16[2 * inIdx + 1];
Marco Nelissen64c3bde2010-10-27 09:06:01 -0700295 smp = smp >> shift;
Eric Laurentda7581b2010-07-02 08:12:41 -0700296 buf[captIdx] = ((uint8_t)smp)^0x80;
297 }
298 pContext->mCaptureIdx = captIdx;
299
300 // go to next buffer when buffer full
301 if (pContext->mCaptureIdx == pContext->mCaptureSize) {
302 pContext->mCurrentBuf ^= 1;
303 pContext->mCaptureIdx = 0;
304 }
305
306 if (inBuffer->raw != outBuffer->raw) {
307 if (pContext->mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
308 for (size_t i = 0; i < outBuffer->frameCount*2; i++) {
309 outBuffer->s16[i] = clamp16(outBuffer->s16[i] + inBuffer->s16[i]);
310 }
311 } else {
312 memcpy(outBuffer->raw, inBuffer->raw, outBuffer->frameCount * 2 * sizeof(int16_t));
313 }
314 }
Eric Laurentf997cab2010-07-19 06:24:46 -0700315 if (pContext->mState != VISUALIZER_STATE_ACTIVE) {
316 return -ENODATA;
317 }
Eric Laurentda7581b2010-07-02 08:12:41 -0700318 return 0;
319} // end Visualizer_process
320
Eric Laurente1315cf2011-05-17 19:16:02 -0700321int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
Eric Laurent25f43952010-07-28 05:40:18 -0700322 void *pCmdData, uint32_t *replySize, void *pReplyData) {
Eric Laurentda7581b2010-07-02 08:12:41 -0700323
Eric Laurente1315cf2011-05-17 19:16:02 -0700324 VisualizerContext * pContext = (VisualizerContext *)self;
Eric Laurentda7581b2010-07-02 08:12:41 -0700325 int retsize;
326
327 if (pContext == NULL || pContext->mState == VISUALIZER_STATE_UNINITIALIZED) {
328 return -EINVAL;
329 }
330
Steve Block3856b092011-10-20 11:56:00 +0100331// ALOGV("Visualizer_command command %d cmdSize %d",cmdCode, cmdSize);
Eric Laurentda7581b2010-07-02 08:12:41 -0700332
333 switch (cmdCode) {
334 case EFFECT_CMD_INIT:
335 if (pReplyData == NULL || *replySize != sizeof(int)) {
336 return -EINVAL;
337 }
338 *(int *) pReplyData = Visualizer_init(pContext);
339 break;
340 case EFFECT_CMD_CONFIGURE:
341 if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
342 || pReplyData == NULL || *replySize != sizeof(int)) {
343 return -EINVAL;
344 }
345 *(int *) pReplyData = Visualizer_configure(pContext,
346 (effect_config_t *) pCmdData);
347 break;
348 case EFFECT_CMD_RESET:
349 Visualizer_reset(pContext);
350 break;
351 case EFFECT_CMD_ENABLE:
352 if (pReplyData == NULL || *replySize != sizeof(int)) {
353 return -EINVAL;
354 }
355 if (pContext->mState != VISUALIZER_STATE_INITIALIZED) {
356 return -ENOSYS;
357 }
358 pContext->mState = VISUALIZER_STATE_ACTIVE;
Steve Block3856b092011-10-20 11:56:00 +0100359 ALOGV("EFFECT_CMD_ENABLE() OK");
Eric Laurentda7581b2010-07-02 08:12:41 -0700360 *(int *)pReplyData = 0;
361 break;
362 case EFFECT_CMD_DISABLE:
363 if (pReplyData == NULL || *replySize != sizeof(int)) {
364 return -EINVAL;
365 }
366 if (pContext->mState != VISUALIZER_STATE_ACTIVE) {
367 return -ENOSYS;
368 }
369 pContext->mState = VISUALIZER_STATE_INITIALIZED;
Steve Block3856b092011-10-20 11:56:00 +0100370 ALOGV("EFFECT_CMD_DISABLE() OK");
Eric Laurentda7581b2010-07-02 08:12:41 -0700371 *(int *)pReplyData = 0;
372 break;
373 case EFFECT_CMD_GET_PARAM: {
374 if (pCmdData == NULL ||
375 cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t)) ||
376 pReplyData == NULL ||
377 *replySize < (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t))) {
378 return -EINVAL;
379 }
380 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + sizeof(uint32_t));
381 effect_param_t *p = (effect_param_t *)pReplyData;
382 p->status = 0;
383 *replySize = sizeof(effect_param_t) + sizeof(uint32_t);
384 if (p->psize != sizeof(uint32_t) ||
Eric Laurent6d8b6942011-06-24 07:01:31 -0700385 *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) {
Eric Laurentda7581b2010-07-02 08:12:41 -0700386 p->status = -EINVAL;
387 break;
388 }
Steve Block3856b092011-10-20 11:56:00 +0100389 ALOGV("get mCaptureSize = %d", pContext->mCaptureSize);
Eric Laurentda7581b2010-07-02 08:12:41 -0700390 *((uint32_t *)p->data + 1) = pContext->mCaptureSize;
391 p->vsize = sizeof(uint32_t);
392 *replySize += sizeof(uint32_t);
393 } break;
394 case EFFECT_CMD_SET_PARAM: {
395 if (pCmdData == NULL ||
396 cmdSize != (int)(sizeof(effect_param_t) + sizeof(uint32_t) + sizeof(uint32_t)) ||
397 pReplyData == NULL || *replySize != sizeof(int32_t)) {
398 return -EINVAL;
399 }
400 *(int32_t *)pReplyData = 0;
401 effect_param_t *p = (effect_param_t *)pCmdData;
402 if (p->psize != sizeof(uint32_t) ||
403 p->vsize != sizeof(uint32_t) ||
Eric Laurent6d8b6942011-06-24 07:01:31 -0700404 *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) {
Eric Laurentda7581b2010-07-02 08:12:41 -0700405 *(int32_t *)pReplyData = -EINVAL;
406 break;;
407 }
408 pContext->mCaptureSize = *((uint32_t *)p->data + 1);
Steve Block3856b092011-10-20 11:56:00 +0100409 ALOGV("set mCaptureSize = %d", pContext->mCaptureSize);
Eric Laurentda7581b2010-07-02 08:12:41 -0700410 } break;
411 case EFFECT_CMD_SET_DEVICE:
412 case EFFECT_CMD_SET_VOLUME:
413 case EFFECT_CMD_SET_AUDIO_MODE:
414 break;
415
416
Eric Laurent6d8b6942011-06-24 07:01:31 -0700417 case VISUALIZER_CMD_CAPTURE:
Eric Laurent0e75f0f2010-09-21 14:52:01 -0700418 if (pReplyData == NULL || *replySize != pContext->mCaptureSize) {
Steve Block3856b092011-10-20 11:56:00 +0100419 ALOGV("VISUALIZER_CMD_CAPTURE() error *replySize %d pContext->mCaptureSize %d",
Eric Laurentda7581b2010-07-02 08:12:41 -0700420 *replySize, pContext->mCaptureSize);
421 return -EINVAL;
422 }
423 if (pContext->mState == VISUALIZER_STATE_ACTIVE) {
424 memcpy(pReplyData,
425 pContext->mCaptureBuf[pContext->mCurrentBuf ^ 1],
426 pContext->mCaptureSize);
Eric Laurent3df40a02011-11-10 10:02:18 -0800427 // if audio framework has stopped playing audio although the effect is still
428 // active we must clear the capture buffer to return silence
429 if (pContext->mLastBuf == pContext->mCurrentBuf) {
430 if (pContext->mStallCount < MAX_STALL_COUNT) {
431 if (++pContext->mStallCount == MAX_STALL_COUNT) {
432 memset(pContext->mCaptureBuf[pContext->mCurrentBuf ^ 1],
433 0x80,
434 pContext->mCaptureSize);
435 }
436 }
437 } else {
438 pContext->mStallCount = 0;
439 }
440 pContext->mLastBuf = pContext->mCurrentBuf;
Eric Laurentda7581b2010-07-02 08:12:41 -0700441 } else {
442 memset(pReplyData, 0x80, pContext->mCaptureSize);
443 }
Eric Laurent3df40a02011-11-10 10:02:18 -0800444
Eric Laurentda7581b2010-07-02 08:12:41 -0700445 break;
446
447 default:
448 LOGW("Visualizer_command invalid command %d",cmdCode);
449 return -EINVAL;
450 }
451
452 return 0;
453}
454
Eric Laurente1315cf2011-05-17 19:16:02 -0700455/* Effect Control Interface Implementation: get_descriptor */
456int Visualizer_getDescriptor(effect_handle_t self,
457 effect_descriptor_t *pDescriptor)
458{
459 VisualizerContext * pContext = (VisualizerContext *) self;
460
461 if (pContext == NULL || pDescriptor == NULL) {
Steve Block3856b092011-10-20 11:56:00 +0100462 ALOGV("Visualizer_getDescriptor() invalid param");
Eric Laurente1315cf2011-05-17 19:16:02 -0700463 return -EINVAL;
464 }
465
466 memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t));
467
468 return 0;
469} /* end Visualizer_getDescriptor */
470
471// effect_handle_t interface implementation for visualizer effect
Eric Laurentda7581b2010-07-02 08:12:41 -0700472const struct effect_interface_s gVisualizerInterface = {
473 Visualizer_process,
Eric Laurente1315cf2011-05-17 19:16:02 -0700474 Visualizer_command,
Eric Laurentba7b8f82011-06-17 18:54:16 -0700475 Visualizer_getDescriptor,
476 NULL,
Eric Laurentda7581b2010-07-02 08:12:41 -0700477};
478
Eric Laurentda7581b2010-07-02 08:12:41 -0700479
Eric Laurente1315cf2011-05-17 19:16:02 -0700480audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
481 tag : AUDIO_EFFECT_LIBRARY_TAG,
482 version : EFFECT_LIBRARY_API_VERSION,
483 name : "Visualizer Library",
484 implementor : "The Android Open Source Project",
485 query_num_effects : VisualizerLib_QueryNumberEffects,
486 query_effect : VisualizerLib_QueryEffect,
487 create_effect : VisualizerLib_Create,
488 release_effect : VisualizerLib_Release,
489 get_descriptor : VisualizerLib_GetDescriptor,
490};
491
492}; // extern "C"