Visualizer.cpp revision 40bc906252974d0b389ae4a147232d0c9a97193f
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> 311ab85ec401801ef9a9184650d0f5a1639b45eeb9Glenn Kasten#include <utils/Thread.h> 32da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 33da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentnamespace android { 34da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 35da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent// --------------------------------------------------------------------------- 36da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 37da7581b7b61b84f15e8d671c86fd117c322b009eEric LaurentVisualizer::Visualizer (int32_t priority, 38da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_callback_t cbf, 39da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent void* user, 40da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent int sessionId) 41da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent : AudioEffect(SL_IID_VISUALIZATION, NULL, priority, cbf, user, sessionId), 42da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureRate(CAPTURE_RATE_DEF), 43da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize(CAPTURE_SIZE_DEF), 44da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mSampleRate(44100000), 453476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED), 4609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi mMeasurementMode(MEASUREMENT_MODE_NONE), 47da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack(NULL), 48da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCbkUser(NULL) 49da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 50da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent initCaptureSize(); 51da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 52da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 53da7581b7b61b84f15e8d671c86fd117c322b009eEric LaurentVisualizer::~Visualizer() 54da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 5563f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George ALOGV("Visualizer::~Visualizer()"); 5663f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George if (mCaptureThread != NULL) { 5763f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureThread->requestExitAndWait(); 5863f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureThread.clear(); 5963f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George } 6063f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureCallBack = NULL; 6163f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureFlags = 0; 62da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 63da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 64da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setEnabled(bool enabled) 65da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 66a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 67da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 68da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent sp<CaptureThread> t = mCaptureThread; 69da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 70da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (enabled) { 71da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t->exitPending()) { 72da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t->requestExitAndWait() == WOULD_BLOCK) { 7329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Visualizer::enable() called from thread"); 74da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 75da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 76da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 77da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 78da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->mLock.lock(); 79e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 80da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 81da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = AudioEffect::setEnabled(enabled); 82da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 83da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 84da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 85da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (enabled) { 869096f3471434d7f0d2419ac0ee2a618045489718Glenn Kasten t->run("Visualizer"); 87da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 88da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->requestExit(); 89da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 90da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 91da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 92da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 93da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 94da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->mLock.unlock(); 95da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 96da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 97da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 98da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 99da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 10085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenstatus_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, 10185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten uint32_t rate) 102da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 103da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (rate > CAPTURE_RATE_MAX) { 104da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 105da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 106a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 107da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 108da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 109da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 110da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 111da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 11263f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George if (mCaptureThread != 0) { 11363f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureLock.unlock(); 11463f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureThread->requestExitAndWait(); 11563f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureLock.lock(); 116da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 11763f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George 118da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureThread.clear(); 119da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack = cbk; 120da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCbkUser = user; 121da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureFlags = flags; 122da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureRate = rate; 123da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 124da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (cbk != NULL) { 125da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureThread = new CaptureThread(*this, rate, ((flags & CAPTURE_CALL_JAVA) != 0)); 126da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 1273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x", 128da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent rate, mCaptureThread.get(), mCaptureFlags); 129da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_ERROR; 130da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 131da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 132da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setCaptureSize(uint32_t size) 133da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 134da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (size > VISUALIZER_CAPTURE_SIZE_MAX || 135da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent size < VISUALIZER_CAPTURE_SIZE_MIN || 136fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin popcount(size) != 1) { 137da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 138da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 139da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 140a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 141da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 142da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 143da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 144da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 145da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 146da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_param_t *p = (effect_param_t *)buf32; 147da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 148da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->psize = sizeof(uint32_t); 149da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->vsize = sizeof(uint32_t); 1506d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE; 151da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent *((int32_t *)p->data + 1)= size; 152da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = setParameter(p); 153da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 1543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setCaptureSize size %d status %d p->status %d", size, status, p->status); 155da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 156da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 157da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = p->status; 1583476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (status == NO_ERROR) { 1593476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mCaptureSize = size; 1603476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 161da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 1623476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1633476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi return status; 1643476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi} 1653476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1663476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivistatus_t Visualizer::setScalingMode(uint32_t mode) { 1673476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if ((mode != VISUALIZER_SCALING_MODE_NORMALIZED) 1683476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi && (mode != VISUALIZER_SCALING_MODE_AS_PLAYED)) { 1693476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi return BAD_VALUE; 1703476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 1713476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1723476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi Mutex::Autolock _l(mCaptureLock); 1733476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1743476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 1753476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi effect_param_t *p = (effect_param_t *)buf32; 1763476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1773476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi p->psize = sizeof(uint32_t); 1783476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi p->vsize = sizeof(uint32_t); 1793476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi *(int32_t *)p->data = VISUALIZER_PARAM_SCALING_MODE; 1803476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi *((int32_t *)p->data + 1)= mode; 1813476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi status_t status = setParameter(p); 1823476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1833476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV("setScalingMode mode %d status %d p->status %d", mode, status, p->status); 1843476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 185da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 1863476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi status = p->status; 1873476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (status == NO_ERROR) { 1883476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mScalingMode = mode; 1893476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 190da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 191da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 192da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 193da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 194da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 19509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivistatus_t Visualizer::setMeasurementMode(uint32_t mode) { 19609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if ((mode != MEASUREMENT_MODE_NONE) 19709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi //Note: needs to be handled as a mask when more measurement modes are added 19809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi && ((mode & MEASUREMENT_MODE_PEAK_RMS) != mode)) { 19909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return BAD_VALUE; 20009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 20109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 20209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi Mutex::Autolock _l(mCaptureLock); 20309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 20409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 20509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi effect_param_t *p = (effect_param_t *)buf32; 20609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 20709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi p->psize = sizeof(uint32_t); 20809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi p->vsize = sizeof(uint32_t); 20909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi *(int32_t *)p->data = VISUALIZER_PARAM_MEASUREMENT_MODE; 21009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi *((int32_t *)p->data + 1)= mode; 21109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status_t status = setParameter(p); 21209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 21309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGV("setMeasurementMode mode %d status %d p->status %d", mode, status, p->status); 21409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 21509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (status == NO_ERROR) { 21609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status = p->status; 21709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (status == NO_ERROR) { 21809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi mMeasurementMode = mode; 21909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 22009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 22109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return status; 22209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi} 22309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 22409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivistatus_t Visualizer::getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements) { 22509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (mMeasurementMode == MEASUREMENT_MODE_NONE) { 22609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGE("Cannot retrieve int measurements, no measurement mode set"); 22709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return INVALID_OPERATION; 22809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 22909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (!(mMeasurementMode & type)) { 23009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi // measurement type has not been set on this Visualizer 23109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGE("Cannot retrieve int measurements, requested measurement mode 0x%x not set(0x%x)", 23209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi type, mMeasurementMode); 23309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return INVALID_OPERATION; 23409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 23509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi // only peak+RMS measurement supported 23609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if ((type != MEASUREMENT_MODE_PEAK_RMS) 23709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi // for peak+RMS measurement, the results are 2 int32_t values 23809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi || (number != 2)) { 23909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGE("Cannot retrieve int measurements, MEASUREMENT_MODE_PEAK_RMS returns 2 ints, not %d", 24009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi number); 24109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return BAD_VALUE; 24209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 24309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 24409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status_t status = NO_ERROR; 24509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (mEnabled) { 24609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi uint32_t replySize = number * sizeof(int32_t); 24709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status = command(VISUALIZER_CMD_MEASURE, 24809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi sizeof(uint32_t) /*cmdSize*/, 24909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi &type /*cmdData*/, 25009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi &replySize, measurements); 25109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGV("getMeasurements() command returned %d", status); 25209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if ((status == NO_ERROR) && (replySize == 0)) { 25309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status = NOT_ENOUGH_DATA; 25409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 25509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } else { 25609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGV("getMeasurements() disabled"); 25709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return INVALID_OPERATION; 25809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 25909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return status; 26009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi} 26109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 262da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::getWaveForm(uint8_t *waveform) 263da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 264da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (waveform == NULL) { 265da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 266da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 267da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureSize == 0) { 268da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_INIT; 269da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 270da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 271da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = NO_ERROR; 272da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 27325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t replySize = mCaptureSize; 2746d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform); 2753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getWaveForm() command returned %d", status); 276af7d8189f91c45ab919a6c9ac386b268c8d91168John Grossman if ((status == NO_ERROR) && (replySize == 0)) { 277da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = NOT_ENOUGH_DATA; 278da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 279da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 2803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getWaveForm() disabled"); 281da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent memset(waveform, 0x80, mCaptureSize); 282da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 283da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 284da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 285da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 286da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::getFft(uint8_t *fft) 287da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 288da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (fft == NULL) { 289da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 290da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 291da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureSize == 0) { 292da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_INIT; 293da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 294da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 295da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = NO_ERROR; 296da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 297da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t buf[mCaptureSize]; 2980fa449cc475580d995e9d56756c3da5507d2b6f6Eric Laurent status = getWaveForm(buf); 299da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 300da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = doFft(fft, buf); 301da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 302da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 303da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent memset(fft, 0, mCaptureSize); 304da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 305da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 306da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 307da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 308da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform) 309da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 310dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh int32_t workspace[mCaptureSize >> 1]; 311dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh int32_t nonzero = 0; 312dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 313dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh for (uint32_t i = 0; i < mCaptureSize; i += 2) { 3146b6a736ec71c692c165952fe653a7766075e94bbChia-chi Yeh workspace[i >> 1] = 3156b6a736ec71c692c165952fe653a7766075e94bbChia-chi Yeh ((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8); 316dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh nonzero |= workspace[i >> 1]; 317da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 318da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 319dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh if (nonzero) { 320dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh fixed_fft_real(mCaptureSize >> 1, workspace); 321da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 322dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 323dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh for (uint32_t i = 0; i < mCaptureSize; i += 2) { 324209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen short tmp = workspace[i >> 1] >> 21; 325209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen while (tmp > 127 || tmp < -128) tmp >>= 1; 326209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen fft[i] = tmp; 327209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen tmp = workspace[i >> 1]; 328209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen tmp >>= 5; 329209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen while (tmp > 127 || tmp < -128) tmp >>= 1; 330209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen fft[i + 1] = tmp; 331da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 332dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 333da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_ERROR; 334da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 335da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 336da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentvoid Visualizer::periodicCapture() 337da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 338a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 3393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("periodicCapture() %p mCaptureCallBack %p mCaptureFlags 0x%08x", 340da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent this, mCaptureCallBack, mCaptureFlags); 341da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureCallBack != NULL && 342da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent (mCaptureFlags & (CAPTURE_WAVEFORM|CAPTURE_FFT)) && 343da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize != 0) { 344da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t waveform[mCaptureSize]; 345da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = getWaveForm(waveform); 346da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status != NO_ERROR) { 347da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return; 348da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 349da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t fft[mCaptureSize]; 350da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_FFT) { 351da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = doFft(fft, waveform); 352da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 353da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status != NO_ERROR) { 354da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return; 355da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 356da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t *wavePtr = NULL; 357da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t *fftPtr = NULL; 358da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t waveSize = 0; 359da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t fftSize = 0; 360da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_WAVEFORM) { 361da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent wavePtr = waveform; 362da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent waveSize = mCaptureSize; 363da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 364da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_FFT) { 365da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent fftPtr = fft; 366da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent fftSize = mCaptureSize; 367da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 368da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack(mCaptureCbkUser, waveSize, wavePtr, fftSize, fftPtr, mSampleRate); 369da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 370da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 371da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 372da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentuint32_t Visualizer::initCaptureSize() 373da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 374da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 375da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_param_t *p = (effect_param_t *)buf32; 376da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 377da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->psize = sizeof(uint32_t); 378da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->vsize = sizeof(uint32_t); 3796d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE; 380da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = getParameter(p); 381da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 382da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 383da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = p->status; 384da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 385da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 386da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t size = 0; 387da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 388da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent size = *((int32_t *)p->data + 1); 389da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 390da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize = size; 391da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 3923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("initCaptureSize size %d status %d", mCaptureSize, status); 393da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 394da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return size; 395da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 396da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 3973476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivivoid Visualizer::controlStatusChanged(bool controlGranted) { 3983476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (controlGranted) { 3993476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi // this Visualizer instance regained control of the effect, reset the scaling mode 4003476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi // and capture size as has been cached through it. 4013476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV("controlStatusChanged(true) causes effect parameter reset:"); 4023476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV(" scaling mode reset to %d", mScalingMode); 4033476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi setScalingMode(mScalingMode); 4043476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV(" capture size reset to %d", mCaptureSize); 4053476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi setCaptureSize(mCaptureSize); 4063476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 4073476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi AudioEffect::controlStatusChanged(controlGranted); 4083476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi} 4093476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 410da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent//------------------------------------------------------------------------- 411da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 41285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn KastenVisualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, 41385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten bool bCanCallJava) 414da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent : Thread(bCanCallJava), mReceiver(receiver) 415da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 416da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mSleepTimeUs = 1000000000 / captureRate; 4173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread cstor %p captureRate %d mSleepTimeUs %d", this, captureRate, mSleepTimeUs); 418da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 419da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 420da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentbool Visualizer::CaptureThread::threadLoop() 421da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 4223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread %p enter", this); 423da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent while (!exitPending()) 424da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent { 425da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent usleep(mSleepTimeUs); 426da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mReceiver.periodicCapture(); 427da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 4283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread %p exiting", this); 429da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return false; 430da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 431da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 43240bc906252974d0b389ae4a147232d0c9a97193fGlenn Kasten} // namespace android 433