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 37be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet GanovVisualizer::Visualizer (const String16& opPackageName, 38be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov int32_t priority, 39da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_callback_t cbf, 40da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent void* user, 41d848eb48c121c119e8ba7583efc75415fe102570Glenn Kasten audio_session_t sessionId) 42be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov : AudioEffect(SL_IID_VISUALIZATION, opPackageName, NULL, priority, cbf, user, sessionId), 43da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureRate(CAPTURE_RATE_DEF), 44da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize(CAPTURE_SIZE_DEF), 45da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mSampleRate(44100000), 463476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED), 4709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi mMeasurementMode(MEASUREMENT_MODE_NONE), 48da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack(NULL), 49da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCbkUser(NULL) 50da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 51da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent initCaptureSize(); 52da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 53da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 54da7581b7b61b84f15e8d671c86fd117c322b009eEric LaurentVisualizer::~Visualizer() 55da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 5663f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George ALOGV("Visualizer::~Visualizer()"); 579b030df5ead9c039e4ebb16c745e2cc40e953d48Ricardo Garcia setEnabled(false); 589b030df5ead9c039e4ebb16c745e2cc40e953d48Ricardo Garcia setCaptureCallBack(NULL, NULL, 0, 0, true); 59da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 60da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 61da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setEnabled(bool enabled) 62da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 63a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 64da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 65da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent sp<CaptureThread> t = mCaptureThread; 66da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 67da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (enabled) { 68da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t->exitPending()) { 69da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t->requestExitAndWait() == WOULD_BLOCK) { 7029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Visualizer::enable() called from thread"); 71da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 72da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 73da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 74da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 75da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->mLock.lock(); 76e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } 77da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 78da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = AudioEffect::setEnabled(enabled); 79da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 80da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 81da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 82da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (enabled) { 839096f3471434d7f0d2419ac0ee2a618045489718Glenn Kasten t->run("Visualizer"); 84da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 85da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->requestExit(); 86da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 87da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 88da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 89da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 90da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (t != 0) { 91da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent t->mLock.unlock(); 92da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 93da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 94da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 95da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 96da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 9785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenstatus_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, 989b030df5ead9c039e4ebb16c745e2cc40e953d48Ricardo Garcia uint32_t rate, bool force) 99da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 100da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (rate > CAPTURE_RATE_MAX) { 101da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 102da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 103a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 104da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 1059b030df5ead9c039e4ebb16c745e2cc40e953d48Ricardo Garcia if (force || mEnabled) { 106da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 107da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 108da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 10963f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George if (mCaptureThread != 0) { 11063f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureLock.unlock(); 11163f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureThread->requestExitAndWait(); 11263f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George mCaptureLock.lock(); 113da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 11463f6ffb996a7ffc920012f05c3deca731614373fHaynes Mathew George 115da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureThread.clear(); 116da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack = cbk; 117da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCbkUser = user; 118da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureFlags = flags; 119da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureRate = rate; 120da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 121da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (cbk != NULL) { 122da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureThread = new CaptureThread(*this, rate, ((flags & CAPTURE_CALL_JAVA) != 0)); 123da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 1243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x", 125da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent rate, mCaptureThread.get(), mCaptureFlags); 126da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_ERROR; 127da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 128da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 129da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setCaptureSize(uint32_t size) 130da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 131da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (size > VISUALIZER_CAPTURE_SIZE_MAX || 132da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent size < VISUALIZER_CAPTURE_SIZE_MIN || 133fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin popcount(size) != 1) { 134da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 135da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 136da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 137a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 138da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 139da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return INVALID_OPERATION; 140da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 141da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 142da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 143da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_param_t *p = (effect_param_t *)buf32; 144da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 145da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->psize = sizeof(uint32_t); 146da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->vsize = sizeof(uint32_t); 1476d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE; 148da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent *((int32_t *)p->data + 1)= size; 149da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = setParameter(p); 150da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 1513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setCaptureSize size %d status %d p->status %d", size, status, p->status); 152da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 153da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 154da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = p->status; 1553476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (status == NO_ERROR) { 1563476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mCaptureSize = size; 1573476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 158da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 1593476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1603476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi return status; 1613476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi} 1623476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1633476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivistatus_t Visualizer::setScalingMode(uint32_t mode) { 1643476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if ((mode != VISUALIZER_SCALING_MODE_NORMALIZED) 1653476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi && (mode != VISUALIZER_SCALING_MODE_AS_PLAYED)) { 1663476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi return BAD_VALUE; 1673476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 1683476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1693476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi Mutex::Autolock _l(mCaptureLock); 1703476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1713476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 1723476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi effect_param_t *p = (effect_param_t *)buf32; 1733476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1743476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi p->psize = sizeof(uint32_t); 1753476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi p->vsize = sizeof(uint32_t); 1763476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi *(int32_t *)p->data = VISUALIZER_PARAM_SCALING_MODE; 1773476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi *((int32_t *)p->data + 1)= mode; 1783476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi status_t status = setParameter(p); 1793476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 1803476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV("setScalingMode mode %d status %d p->status %d", mode, status, p->status); 1813476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 182da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 1833476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi status = p->status; 1843476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (status == NO_ERROR) { 1853476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi mScalingMode = mode; 1863476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 187da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 188da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 189da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 190da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 191da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 19209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivistatus_t Visualizer::setMeasurementMode(uint32_t mode) { 19309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if ((mode != MEASUREMENT_MODE_NONE) 19409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi //Note: needs to be handled as a mask when more measurement modes are added 19509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi && ((mode & MEASUREMENT_MODE_PEAK_RMS) != mode)) { 19609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return BAD_VALUE; 19709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 19809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 19909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi Mutex::Autolock _l(mCaptureLock); 20009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 20109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 20209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi effect_param_t *p = (effect_param_t *)buf32; 20309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 20409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi p->psize = sizeof(uint32_t); 20509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi p->vsize = sizeof(uint32_t); 20609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi *(int32_t *)p->data = VISUALIZER_PARAM_MEASUREMENT_MODE; 20709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi *((int32_t *)p->data + 1)= mode; 20809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status_t status = setParameter(p); 20909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 21009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGV("setMeasurementMode mode %d status %d p->status %d", mode, status, p->status); 21109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 21209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (status == NO_ERROR) { 21309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status = p->status; 21409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (status == NO_ERROR) { 21509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi mMeasurementMode = mode; 21609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 21709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 21809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return status; 21909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi} 22009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 22109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivistatus_t Visualizer::getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements) { 22209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (mMeasurementMode == MEASUREMENT_MODE_NONE) { 22309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGE("Cannot retrieve int measurements, no measurement mode set"); 22409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return INVALID_OPERATION; 22509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 22609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (!(mMeasurementMode & type)) { 22709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi // measurement type has not been set on this Visualizer 22809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGE("Cannot retrieve int measurements, requested measurement mode 0x%x not set(0x%x)", 22909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi type, mMeasurementMode); 23009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return INVALID_OPERATION; 23109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 23209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi // only peak+RMS measurement supported 23309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if ((type != MEASUREMENT_MODE_PEAK_RMS) 23409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi // for peak+RMS measurement, the results are 2 int32_t values 23509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi || (number != 2)) { 23609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGE("Cannot retrieve int measurements, MEASUREMENT_MODE_PEAK_RMS returns 2 ints, not %d", 23709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi number); 23809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return BAD_VALUE; 23909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 24009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 24109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status_t status = NO_ERROR; 24209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if (mEnabled) { 24309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi uint32_t replySize = number * sizeof(int32_t); 24409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status = command(VISUALIZER_CMD_MEASURE, 24509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi sizeof(uint32_t) /*cmdSize*/, 24609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi &type /*cmdData*/, 24709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi &replySize, measurements); 24809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGV("getMeasurements() command returned %d", status); 24909647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi if ((status == NO_ERROR) && (replySize == 0)) { 25009647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi status = NOT_ENOUGH_DATA; 25109647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 25209647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } else { 25309647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi ALOGV("getMeasurements() disabled"); 25409647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return INVALID_OPERATION; 25509647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi } 25609647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi return status; 25709647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi} 25809647d29eaf429ce88c9c9709ff63dee62f2147aJean-Michel Trivi 259da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::getWaveForm(uint8_t *waveform) 260da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 261da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (waveform == NULL) { 262da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 263da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 264da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureSize == 0) { 265da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_INIT; 266da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 267da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 268da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = NO_ERROR; 269da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 27025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t replySize = mCaptureSize; 2716d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform); 2723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getWaveForm() command returned %d", status); 273af7d8189f91c45ab919a6c9ac386b268c8d91168John Grossman if ((status == NO_ERROR) && (replySize == 0)) { 274da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = NOT_ENOUGH_DATA; 275da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 276da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 2773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getWaveForm() disabled"); 278da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent memset(waveform, 0x80, mCaptureSize); 279da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 280da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 281da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 282da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 283da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::getFft(uint8_t *fft) 284da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 285da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (fft == NULL) { 286da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return BAD_VALUE; 287da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 288da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureSize == 0) { 289da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_INIT; 290da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 291da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 292da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = NO_ERROR; 293da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mEnabled) { 294da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t buf[mCaptureSize]; 2950fa449cc475580d995e9d56756c3da5507d2b6f6Eric Laurent status = getWaveForm(buf); 296da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 297da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = doFft(fft, buf); 298da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 299da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } else { 300da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent memset(fft, 0, mCaptureSize); 301da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 302da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return status; 303da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 304da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 305da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform) 306da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 307dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh int32_t workspace[mCaptureSize >> 1]; 308dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh int32_t nonzero = 0; 309dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 310dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh for (uint32_t i = 0; i < mCaptureSize; i += 2) { 3116b6a736ec71c692c165952fe653a7766075e94bbChia-chi Yeh workspace[i >> 1] = 3126b6a736ec71c692c165952fe653a7766075e94bbChia-chi Yeh ((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8); 313dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh nonzero |= workspace[i >> 1]; 314da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 315da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 316dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh if (nonzero) { 317dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh fixed_fft_real(mCaptureSize >> 1, workspace); 318da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 319dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 320dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh for (uint32_t i = 0; i < mCaptureSize; i += 2) { 321209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen short tmp = workspace[i >> 1] >> 21; 322209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen while (tmp > 127 || tmp < -128) tmp >>= 1; 323209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen fft[i] = tmp; 324209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen tmp = workspace[i >> 1]; 325209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen tmp >>= 5; 326209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen while (tmp > 127 || tmp < -128) tmp >>= 1; 327209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen fft[i + 1] = tmp; 328da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 329dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh 330da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return NO_ERROR; 331da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 332da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 333da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentvoid Visualizer::periodicCapture() 334da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 335a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten Mutex::Autolock _l(mCaptureLock); 3363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("periodicCapture() %p mCaptureCallBack %p mCaptureFlags 0x%08x", 337da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent this, mCaptureCallBack, mCaptureFlags); 338da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureCallBack != NULL && 339da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent (mCaptureFlags & (CAPTURE_WAVEFORM|CAPTURE_FFT)) && 340da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize != 0) { 341da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t waveform[mCaptureSize]; 342da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = getWaveForm(waveform); 343da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status != NO_ERROR) { 344da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return; 345da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 346da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t fft[mCaptureSize]; 347da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_FFT) { 348da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = doFft(fft, waveform); 349da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 350da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status != NO_ERROR) { 351da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return; 352da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 353da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t *wavePtr = NULL; 354da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint8_t *fftPtr = NULL; 355da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t waveSize = 0; 356da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t fftSize = 0; 357da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_WAVEFORM) { 358da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent wavePtr = waveform; 359da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent waveSize = mCaptureSize; 360da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 361da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (mCaptureFlags & CAPTURE_FFT) { 362da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent fftPtr = fft; 363da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent fftSize = mCaptureSize; 364da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 365da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureCallBack(mCaptureCbkUser, waveSize, wavePtr, fftSize, fftPtr, mSampleRate); 366da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 367da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 368da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 369da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentuint32_t Visualizer::initCaptureSize() 370da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 371da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 372da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent effect_param_t *p = (effect_param_t *)buf32; 373da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 374da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->psize = sizeof(uint32_t); 375da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent p->vsize = sizeof(uint32_t); 3766d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE; 377da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status_t status = getParameter(p); 378da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 379da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 380da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent status = p->status; 381da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 382da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 383da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent uint32_t size = 0; 384da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent if (status == NO_ERROR) { 385da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent size = *((int32_t *)p->data + 1); 386da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 387da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mCaptureSize = size; 388da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 3893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("initCaptureSize size %d status %d", mCaptureSize, status); 390da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 391da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return size; 392da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 393da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 3943476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivivoid Visualizer::controlStatusChanged(bool controlGranted) { 3953476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi if (controlGranted) { 3963476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi // this Visualizer instance regained control of the effect, reset the scaling mode 3973476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi // and capture size as has been cached through it. 3983476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV("controlStatusChanged(true) causes effect parameter reset:"); 3993476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV(" scaling mode reset to %d", mScalingMode); 4003476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi setScalingMode(mScalingMode); 4013476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi ALOGV(" capture size reset to %d", mCaptureSize); 4023476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi setCaptureSize(mCaptureSize); 4033476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi } 4043476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi AudioEffect::controlStatusChanged(controlGranted); 4053476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi} 4063476de62fb10e76412452ef4c6bd71936c9f7db1Jean-Michel Trivi 407da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent//------------------------------------------------------------------------- 408da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 40985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn KastenVisualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, 41085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten bool bCanCallJava) 411da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent : Thread(bCanCallJava), mReceiver(receiver) 412da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 413da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mSleepTimeUs = 1000000000 / captureRate; 4143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread cstor %p captureRate %d mSleepTimeUs %d", this, captureRate, mSleepTimeUs); 415da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 416da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 417da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentbool Visualizer::CaptureThread::threadLoop() 418da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{ 4193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread %p enter", this); 420da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent while (!exitPending()) 421da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent { 422da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent usleep(mSleepTimeUs); 423da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent mReceiver.periodicCapture(); 424da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent } 4253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("CaptureThread %p exiting", this); 426da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent return false; 427da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent} 428da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent 42940bc906252974d0b389ae4a147232d0c9a97193fGlenn Kasten} // namespace android 430