Visualizer.cpp revision af7d8189f91c45ab919a6c9ac386b268c8d91168
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),
44da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        mCaptureCallBack(NULL),
45da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        mCaptureCbkUser(NULL)
46da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
47da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    initCaptureSize();
48da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
49da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
50da7581b7b61b84f15e8d671c86fd117c322b009eEric LaurentVisualizer::~Visualizer()
51da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
52da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
53da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
54da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setEnabled(bool enabled)
55da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
56a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten    Mutex::Autolock _l(mCaptureLock);
57da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
58da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    sp<CaptureThread> t = mCaptureThread;
59da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (t != 0) {
60da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        if (enabled) {
61da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            if (t->exitPending()) {
62da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent                if (t->requestExitAndWait() == WOULD_BLOCK) {
6329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Visualizer::enable() called from thread");
64da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent                    return INVALID_OPERATION;
65da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent                }
66da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            }
67da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
68da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        t->mLock.lock();
69da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent     }
70da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
71da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    status_t status = AudioEffect::setEnabled(enabled);
72da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
73da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (status == NO_ERROR) {
74da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        if (t != 0) {
75da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            if (enabled) {
769096f3471434d7f0d2419ac0ee2a618045489718Glenn Kasten                t->run("Visualizer");
77da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            } else {
78da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent                t->requestExit();
79da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            }
80da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
81da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
82da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
83da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (t != 0) {
84da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        t->mLock.unlock();
85da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
86da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
87da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return status;
88da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
89da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
90da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate)
91da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
92da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (rate > CAPTURE_RATE_MAX) {
93da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        return BAD_VALUE;
94da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
95a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten    Mutex::Autolock _l(mCaptureLock);
96da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
97da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (mEnabled) {
98da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        return INVALID_OPERATION;
99da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
100da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
101da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    sp<CaptureThread> t = mCaptureThread;
102da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (t != 0) {
103da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        t->mLock.lock();
104da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
105da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    mCaptureThread.clear();
106da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    mCaptureCallBack = cbk;
107da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    mCaptureCbkUser = user;
108da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    mCaptureFlags = flags;
109da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    mCaptureRate = rate;
110da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
111da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (t != 0) {
112da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        t->mLock.unlock();
113da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
114da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
115da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (cbk != NULL) {
116da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        mCaptureThread = new CaptureThread(*this, rate, ((flags & CAPTURE_CALL_JAVA) != 0));
117da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
1183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x",
119da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            rate, mCaptureThread.get(), mCaptureFlags);
120da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return NO_ERROR;
121da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
122da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
123da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::setCaptureSize(uint32_t size)
124da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
125da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (size > VISUALIZER_CAPTURE_SIZE_MAX ||
126da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        size < VISUALIZER_CAPTURE_SIZE_MIN ||
127fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        popcount(size) != 1) {
128da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        return BAD_VALUE;
129da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
130da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
131a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten    Mutex::Autolock _l(mCaptureLock);
132da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (mEnabled) {
133da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        return INVALID_OPERATION;
134da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
135da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
136da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
137da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    effect_param_t *p = (effect_param_t *)buf32;
138da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
139da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    p->psize = sizeof(uint32_t);
140da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    p->vsize = sizeof(uint32_t);
1416d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent    *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
142da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    *((int32_t *)p->data + 1)= size;
143da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    status_t status = setParameter(p);
144da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
1453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setCaptureSize size %d  status %d p->status %d", size, status, p->status);
146da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
147da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (status == NO_ERROR) {
148da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        status = p->status;
149da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
150da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (status == NO_ERROR) {
151da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        mCaptureSize = size;
152da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
153da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
154da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return status;
155da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
156da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
157da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::getWaveForm(uint8_t *waveform)
158da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
159da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (waveform == NULL) {
160da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        return BAD_VALUE;
161da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
162da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (mCaptureSize == 0) {
163da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        return NO_INIT;
164da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
165da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
166da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    status_t status = NO_ERROR;
167da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (mEnabled) {
16825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent        uint32_t replySize = mCaptureSize;
1696d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent        status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform);
1703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("getWaveForm() command returned %d", status);
171af7d8189f91c45ab919a6c9ac386b268c8d91168John Grossman        if ((status == NO_ERROR) && (replySize == 0)) {
172da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            status = NOT_ENOUGH_DATA;
173da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
174da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    } else {
1753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("getWaveForm() disabled");
176da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        memset(waveform, 0x80, mCaptureSize);
177da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
178da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return status;
179da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
180da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
181da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::getFft(uint8_t *fft)
182da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
183da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (fft == NULL) {
184da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        return BAD_VALUE;
185da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
186da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (mCaptureSize == 0) {
187da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        return NO_INIT;
188da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
189da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
190da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    status_t status = NO_ERROR;
191da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (mEnabled) {
192da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        uint8_t buf[mCaptureSize];
1930fa449cc475580d995e9d56756c3da5507d2b6f6Eric Laurent        status = getWaveForm(buf);
194da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        if (status == NO_ERROR) {
195da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            status = doFft(fft, buf);
196da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
197da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    } else {
198da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        memset(fft, 0, mCaptureSize);
199da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
200da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return status;
201da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
202da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
203da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform)
204da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
205dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh    int32_t workspace[mCaptureSize >> 1];
206dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh    int32_t nonzero = 0;
207dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh
208dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh    for (uint32_t i = 0; i < mCaptureSize; i += 2) {
2096b6a736ec71c692c165952fe653a7766075e94bbChia-chi Yeh        workspace[i >> 1] =
2106b6a736ec71c692c165952fe653a7766075e94bbChia-chi Yeh                ((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8);
211dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh        nonzero |= workspace[i >> 1];
212da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
213da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
214dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh    if (nonzero) {
215dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh        fixed_fft_real(mCaptureSize >> 1, workspace);
216da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
217dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh
218dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh    for (uint32_t i = 0; i < mCaptureSize; i += 2) {
219209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen        short tmp = workspace[i >> 1] >> 21;
220209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen        while (tmp > 127 || tmp < -128) tmp >>= 1;
221209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen        fft[i] = tmp;
222209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen        tmp = workspace[i >> 1];
223209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen        tmp >>= 5;
224209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen        while (tmp > 127 || tmp < -128) tmp >>= 1;
225209821c7b7ead3ac58743d0a6d21dd05a2e77708Marco Nelissen        fft[i + 1] = tmp;
226da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
227dbd2b7e4ebfe7a586b1db4459cf6aa032a7f8719Chia-chi Yeh
228da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return NO_ERROR;
229da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
230da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
231da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentvoid Visualizer::periodicCapture()
232da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
233a9b21c5a7c24fe14d20372263c0bf5faf3d3e348Glenn Kasten    Mutex::Autolock _l(mCaptureLock);
2343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("periodicCapture() %p mCaptureCallBack %p mCaptureFlags 0x%08x",
235da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            this, mCaptureCallBack, mCaptureFlags);
236da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (mCaptureCallBack != NULL &&
237da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        (mCaptureFlags & (CAPTURE_WAVEFORM|CAPTURE_FFT)) &&
238da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        mCaptureSize != 0) {
239da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        uint8_t waveform[mCaptureSize];
240da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        status_t status = getWaveForm(waveform);
241da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        if (status != NO_ERROR) {
242da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            return;
243da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
244da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        uint8_t fft[mCaptureSize];
245da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        if (mCaptureFlags & CAPTURE_FFT) {
246da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            status = doFft(fft, waveform);
247da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
248da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        if (status != NO_ERROR) {
249da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            return;
250da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
251da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        uint8_t *wavePtr = NULL;
252da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        uint8_t *fftPtr = NULL;
253da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        uint32_t waveSize = 0;
254da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        uint32_t fftSize = 0;
255da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        if (mCaptureFlags & CAPTURE_WAVEFORM) {
256da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            wavePtr = waveform;
257da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            waveSize = mCaptureSize;
258da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
259da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        if (mCaptureFlags & CAPTURE_FFT) {
260da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            fftPtr = fft;
261da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent            fftSize = mCaptureSize;
262da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        }
263da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        mCaptureCallBack(mCaptureCbkUser, waveSize, wavePtr, fftSize, fftPtr, mSampleRate);
264da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
265da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
266da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
267da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentuint32_t Visualizer::initCaptureSize()
268da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
269da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
270da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    effect_param_t *p = (effect_param_t *)buf32;
271da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
272da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    p->psize = sizeof(uint32_t);
273da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    p->vsize = sizeof(uint32_t);
2746d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent    *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
275da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    status_t status = getParameter(p);
276da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
277da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (status == NO_ERROR) {
278da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        status = p->status;
279da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
280da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
281da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    uint32_t size = 0;
282da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    if (status == NO_ERROR) {
283da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        size = *((int32_t *)p->data + 1);
284da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
285da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    mCaptureSize = size;
286da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
2873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("initCaptureSize size %d status %d", mCaptureSize, status);
288da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
289da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return size;
290da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
291da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
292da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent//-------------------------------------------------------------------------
293da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
294da7581b7b61b84f15e8d671c86fd117c322b009eEric LaurentVisualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava)
295da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    : Thread(bCanCallJava), mReceiver(receiver)
296da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
297da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    mSleepTimeUs = 1000000000 / captureRate;
2983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("CaptureThread cstor %p captureRate %d mSleepTimeUs %d", this, captureRate, mSleepTimeUs);
299da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
300da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
301da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentbool Visualizer::CaptureThread::threadLoop()
302da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
3033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("CaptureThread %p enter", this);
304da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    while (!exitPending())
305da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    {
306da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        usleep(mSleepTimeUs);
307da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent        mReceiver.periodicCapture();
308da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    }
3093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("CaptureThread %p exiting", this);
310da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return false;
311da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
312da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
313da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentstatus_t Visualizer::CaptureThread::readyToRun()
314da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
315da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent    return NO_ERROR;
316da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
317da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
318da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurentvoid Visualizer::CaptureThread::onFirstRef()
319da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent{
320da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}
321da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
322da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent}; // namespace android
323da7581b7b61b84f15e8d671c86fd117c322b009eEric Laurent
324