Visualizer.cpp revision 85ab62c4b433df3f1a9826bed1c9bec07a86c750
1da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent/* 2da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** 3da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** Copyright 2010, The Android Open Source Project 4da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** 5da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** Licensed under the Apache License, Version 2.0 (the "License"); 6da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** you may not use this file except in compliance with the License. 7da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** You may obtain a copy of the License at 8da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** 9da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** http://www.apache.org/licenses/LICENSE-2.0 10da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** 11da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** Unless required by applicable law or agreed to in writing, software 12da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** distributed under the License is distributed on an "AS IS" BASIS, 13da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** See the License for the specific language governing permissions and 15da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent** limitations under the License. 16da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent*/ 17da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 18da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 19da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent//#define LOG_NDEBUG 0 20da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent#define LOG_TAG "Visualizer" 21da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent#include <utils/Log.h> 22da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 23da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent#include <stdint.h> 24da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent#include <sys/types.h> 25da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent#include <limits.h> 26da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 27fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <cutils/bitops.h> 28fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin 29da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent#include <media/Visualizer.h> 303f6448e020969be59ad4d8df99c5296f237ffbd9Glenn Kasten#include <audio_utils/fixedfft.h> 31da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 32da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentnamespace android { 33da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 34da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent// --------------------------------------------------------------------------- 35da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 36da7581b7b61b84f15e8d671c86fd117c322b009eEric LaurentVisualizer::Visualizer (int32_t priority, 37da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_callback_t cbf, 38da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent void* user, 39da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent int sessionId) 40da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent : AudioEffect(SL_IID_VISUALIZATION, NULL, priority, cbf, user, sessionId), 41da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureRate(CAPTURE_RATE_DEF), 42da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize(CAPTURE_SIZE_DEF), 43da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mSampleRate(44100000), 443476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED), 45da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack(NULL), 46da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCbkUser(NULL) 47da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 48da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent initCaptureSize(); 49da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 50da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 51da7581b7b61b84f15e8d671c86fd117c322b009eEric LaurentVisualizer::~Visualizer() 52da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 53da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 54da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 55da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setEnabled(bool enabled) 56da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 57a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 58da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 59da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent sp<CaptureThread> t = mCaptureThread; 60da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 61da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (enabled) { 62da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t->exitPending()) { 63da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t->requestExitAndWait() == WOULD_BLOCK) { 6429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Visualizer::enable() called from thread"); 65da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 66da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 67da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 68da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 69da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->mLock.lock(); 70e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 71da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 72da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = AudioEffect::setEnabled(enabled); 73da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 74da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 75da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 76da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (enabled) { 779096f3471434d7f0d2419ac0ee2a618045489718Glenn Kasten t->run("Visualizer"); 78da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 79da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->requestExit(); 80da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 81da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 82da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 83da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 84da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 85da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->mLock.unlock(); 86da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 87da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 88da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 89da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 90da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 9185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenstatus_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, 9285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten uint32_t rate) 93da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 94da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (rate > CAPTURE_RATE_MAX) { 95da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 96da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 97a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 98da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 99da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 100da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 101da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 102da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 103da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent sp<CaptureThread> t = mCaptureThread; 104da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 105da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->mLock.lock(); 106da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 107da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureThread.clear(); 108da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack = cbk; 109da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCbkUser = user; 110da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureFlags = flags; 111da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureRate = rate; 112da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 113da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 114da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->mLock.unlock(); 115da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 116da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 117da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (cbk != NULL) { 118da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureThread = new CaptureThread(*this, rate, ((flags & CAPTURE_CALL_JAVA) != 0)); 119da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 1203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x", 121da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent rate, mCaptureThread.get(), mCaptureFlags); 122da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_ERROR; 123da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 124da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 125da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setCaptureSize(uint32_t size) 126da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 127da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (size > VISUALIZER_CAPTURE_SIZE_MAX || 128da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent size < VISUALIZER_CAPTURE_SIZE_MIN || 129fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin popcount(size) != 1) { 130da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 131da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 132da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 133a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 134da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 135da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 136da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 137da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 138da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 139da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_param_t *p = (effect_param_t *)buf32; 140da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 141da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->psize = sizeof(uint32_t); 142da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->vsize = sizeof(uint32_t); 1436d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE; 144da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent *((int32_t *)p->data + 1)= size; 145da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = setParameter(p); 146da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 1473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setCaptureSize size %d status %d p->status %d", size, status, p->status); 148da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 149da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 150da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = p->status; 1513476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (status == NO_ERROR) { 1523476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mCaptureSize = size; 1533476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 154da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 1553476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1563476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi return status; 1573476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi} 1583476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1593476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivistatus_t Visualizer::setScalingMode(uint32_t mode) { 1603476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if ((mode != VISUALIZER_SCALING_MODE_NORMALIZED) 1613476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi && (mode != VISUALIZER_SCALING_MODE_AS_PLAYED)) { 1623476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi return BAD_VALUE; 1633476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 1643476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1653476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi Mutex::Autolock _l(mCaptureLock); 1663476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1673476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 1683476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi effect_param_t *p = (effect_param_t *)buf32; 1693476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1703476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi p->psize = sizeof(uint32_t); 1713476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi p->vsize = sizeof(uint32_t); 1723476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi *(int32_t *)p->data = VISUALIZER_PARAM_SCALING_MODE; 1733476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi *((int32_t *)p->data + 1)= mode; 1743476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi status_t status = setParameter(p); 1753476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1763476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV("setScalingMode mode %d status %d p->status %d", mode, status, p->status); 1773476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 178da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 1793476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi status = p->status; 1803476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (status == NO_ERROR) { 1813476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mScalingMode = mode; 1823476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 183da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 184da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 185da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 186da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 187da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 188da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::getWaveForm(uint8_t *waveform) 189da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 190da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (waveform == NULL) { 191da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 192da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 193da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureSize == 0) { 194da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_INIT; 195da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 196da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 197da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = NO_ERROR; 198da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 19925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t replySize = mCaptureSize; 2006d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform); 2013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getWaveForm() command returned %d", status); 202af7d8189f91c45ab919a6c9ac386b268c8d91168John Grossman if ((status == NO_ERROR) && (replySize == 0)) { 203da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = NOT_ENOUGH_DATA; 204da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 205da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 2063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getWaveForm() disabled"); 207da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent memset(waveform, 0x80, mCaptureSize); 208da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 209da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 210da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 211da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 212da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::getFft(uint8_t *fft) 213da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 214da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (fft == NULL) { 215da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 216da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 217da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureSize == 0) { 218da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_INIT; 219da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 220da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 221da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = NO_ERROR; 222da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 223da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t buf[mCaptureSize]; 2240fa449cc475580d995e9d56756c3da5507d2b6f6Eric Laurent status = getWaveForm(buf); 225da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 226da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = doFft(fft, buf); 227da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 228da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 229da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent memset(fft, 0, mCaptureSize); 230da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 231da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 232da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 233da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 234da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform) 235da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 236dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh int32_t workspace[mCaptureSize >> 1]; 237dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh int32_t nonzero = 0; 238dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 239dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh for (uint32_t i = 0; i < mCaptureSize; i += 2) { 2406b6a736ec71c692c165952fe653a7766075e94bbChia-chi Yeh workspace[i >> 1] = 2416b6a736ec71c692c165952fe653a7766075e94bbChia-chi Yeh ((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8); 242dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh nonzero |= workspace[i >> 1]; 243da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 244da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 245dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh if (nonzero) { 246dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh fixed_fft_real(mCaptureSize >> 1, workspace); 247da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 248dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 249dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh for (uint32_t i = 0; i < mCaptureSize; i += 2) { 250209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen short tmp = workspace[i >> 1] >> 21; 251209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen while (tmp > 127 || tmp < -128) tmp >>= 1; 252209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen fft[i] = tmp; 253209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen tmp = workspace[i >> 1]; 254209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen tmp >>= 5; 255209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen while (tmp > 127 || tmp < -128) tmp >>= 1; 256209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen fft[i + 1] = tmp; 257da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 258dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 259da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_ERROR; 260da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 261da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 262da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentvoid Visualizer::periodicCapture() 263da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 264a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 2653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("periodicCapture() %p mCaptureCallBack %p mCaptureFlags 0x%08x", 266da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent this, mCaptureCallBack, mCaptureFlags); 267da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureCallBack != NULL && 268da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent (mCaptureFlags & (CAPTURE_WAVEFORM|CAPTURE_FFT)) && 269da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize != 0) { 270da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t waveform[mCaptureSize]; 271da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = getWaveForm(waveform); 272da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status != NO_ERROR) { 273da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return; 274da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 275da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t fft[mCaptureSize]; 276da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_FFT) { 277da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = doFft(fft, waveform); 278da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 279da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status != NO_ERROR) { 280da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return; 281da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 282da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t *wavePtr = NULL; 283da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t *fftPtr = NULL; 284da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t waveSize = 0; 285da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t fftSize = 0; 286da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_WAVEFORM) { 287da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent wavePtr = waveform; 288da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent waveSize = mCaptureSize; 289da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 290da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_FFT) { 291da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent fftPtr = fft; 292da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent fftSize = mCaptureSize; 293da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 294da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack(mCaptureCbkUser, waveSize, wavePtr, fftSize, fftPtr, mSampleRate); 295da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 296da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 297da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 298da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentuint32_t Visualizer::initCaptureSize() 299da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 300da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 301da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_param_t *p = (effect_param_t *)buf32; 302da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 303da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->psize = sizeof(uint32_t); 304da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->vsize = sizeof(uint32_t); 3056d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE; 306da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = getParameter(p); 307da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 308da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 309da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = p->status; 310da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 311da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 312da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t size = 0; 313da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 314da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent size = *((int32_t *)p->data + 1); 315da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 316da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize = size; 317da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 3183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("initCaptureSize size %d status %d", mCaptureSize, status); 319da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 320da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return size; 321da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 322da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 3233476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivivoid Visualizer::controlStatusChanged(bool controlGranted) { 3243476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (controlGranted) { 3253476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi // this Visualizer instance regained control of the effect, reset the scaling mode 3263476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi // and capture size as has been cached through it. 3273476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV("controlStatusChanged(true) causes effect parameter reset:"); 3283476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV(" scaling mode reset to %d", mScalingMode); 3293476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi setScalingMode(mScalingMode); 3303476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV(" capture size reset to %d", mCaptureSize); 3313476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi setCaptureSize(mCaptureSize); 3323476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 3333476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi AudioEffect::controlStatusChanged(controlGranted); 3343476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi} 3353476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 336da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent//------------------------------------------------------------------------- 337da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 33885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn KastenVisualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, 33985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten bool bCanCallJava) 340da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent : Thread(bCanCallJava), mReceiver(receiver) 341da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 342da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mSleepTimeUs = 1000000000 / captureRate; 3433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread cstor %p captureRate %d mSleepTimeUs %d", this, captureRate, mSleepTimeUs); 344da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 345da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 346da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentbool Visualizer::CaptureThread::threadLoop() 347da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 3483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread %p enter", this); 349da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent while (!exitPending()) 350da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent { 351da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent usleep(mSleepTimeUs); 352da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mReceiver.periodicCapture(); 353da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 3543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread %p exiting", this); 355da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return false; 356da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 357da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 358da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}; // namespace android 359