AudioSource.cpp revision 53d4e0d58e2d5c18f6e026c705af833b9bdd7aba
107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber/*
207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * Copyright (C) 2010 The Android Open Source Project
307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber *
407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * you may not use this file except in compliance with the License.
607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * You may obtain a copy of the License at
707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber *
807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber *
1007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * Unless required by applicable law or agreed to in writing, software
1107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * See the License for the specific language governing permissions and
1407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber * limitations under the License.
1507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber */
1607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
17abed93a51b6b476ecb23a2c22faa43a219eb60a7James Dong//#define LOG_NDEBUG 0
18abed93a51b6b476ecb23a2c22faa43a219eb60a7James Dong#define LOG_TAG "AudioSource"
19abed93a51b6b476ecb23a2c22faa43a219eb60a7James Dong#include <utils/Log.h>
20abed93a51b6b476ecb23a2c22faa43a219eb60a7James Dong
2107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/AudioSource.h>
2207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
2307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/AudioRecord.h>
2407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
2507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MediaDebug.h>
2607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MediaDefs.h>
2707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber#include <media/stagefright/MetaData.h>
28dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong#include <cutils/properties.h>
29dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong#include <sys/time.h>
30dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong#include <time.h>
3107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
3207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Hubernamespace android {
3307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
3407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas HuberAudioSource::AudioSource(
3507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber        int inputSource, uint32_t sampleRate, uint32_t channels)
36d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong    : mStarted(false),
37dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong      mCollectStats(false),
38dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong      mTotalReadTimeUs(0),
39dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong      mTotalReadBytes(0),
40dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong      mTotalReads(0),
4107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber      mGroup(NULL) {
42d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong
43d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong    LOGV("sampleRate: %d, channels: %d", sampleRate, channels);
44d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong    uint32_t flags = AudioRecord::RECORD_AGC_ENABLE |
45d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong                     AudioRecord::RECORD_NS_ENABLE  |
46d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong                     AudioRecord::RECORD_IIR_ENABLE;
47d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong
48d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong    mRecord = new AudioRecord(
49d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong                inputSource, sampleRate, AudioSystem::PCM_16_BIT,
50d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong                channels > 1? AudioSystem::CHANNEL_IN_STEREO: AudioSystem::CHANNEL_IN_MONO,
51d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong                4 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */
52d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong                flags);
53d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong
54d77d2a980c6fbdc00b7d62a34d9b799dcf8c9514James Dong    mInitCheck = mRecord->initCheck();
5507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber}
5607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
5707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas HuberAudioSource::~AudioSource() {
5807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    if (mStarted) {
5907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber        stop();
6007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    }
6107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
6207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    delete mRecord;
6307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    mRecord = NULL;
6407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber}
6507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
6607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huberstatus_t AudioSource::initCheck() const {
6707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    return mInitCheck;
6807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber}
6907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
7007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huberstatus_t AudioSource::start(MetaData *params) {
7107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    if (mStarted) {
7207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber        return UNKNOWN_ERROR;
7307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    }
7407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
75dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong    char value[PROPERTY_VALUE_MAX];
76dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong    if (property_get("media.stagefright.record-stats", value, NULL)
77dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
78dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong        mCollectStats = true;
79dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong    }
8036e573bf7db5888f92c52eda26e0771aaa2406e4James Dong
8157e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    mTrackMaxAmplitude = false;
8257e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    mMaxAmplitude = 0;
8336e573bf7db5888f92c52eda26e0771aaa2406e4James Dong    mStartTimeUs = 0;
8436e573bf7db5888f92c52eda26e0771aaa2406e4James Dong    int64_t startTimeUs;
8536e573bf7db5888f92c52eda26e0771aaa2406e4James Dong    if (params && params->findInt64(kKeyTime, &startTimeUs)) {
8636e573bf7db5888f92c52eda26e0771aaa2406e4James Dong        mStartTimeUs = startTimeUs;
8736e573bf7db5888f92c52eda26e0771aaa2406e4James Dong    }
8807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    status_t err = mRecord->start();
8907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
9007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    if (err == OK) {
9107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber        mGroup = new MediaBufferGroup;
9207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber        mGroup->add_buffer(new MediaBuffer(kMaxBufferSize));
9307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
9407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber        mStarted = true;
9507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    }
9607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
9707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    return err;
9807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber}
9907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
10007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huberstatus_t AudioSource::stop() {
10107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    if (!mStarted) {
10207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber        return UNKNOWN_ERROR;
10307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    }
10407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
10507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    mRecord->stop();
10607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
10707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    delete mGroup;
10807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    mGroup = NULL;
10907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
11007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    mStarted = false;
11107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
112dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong    if (mCollectStats) {
113dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong        LOGI("%lld reads: %.2f bps in %lld us",
114dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong                mTotalReads,
115dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong                (mTotalReadBytes * 8000000.0) / mTotalReadTimeUs,
116dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong                mTotalReadTimeUs);
117dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong    }
118dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong
11907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    return OK;
12007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber}
12107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
12207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Hubersp<MetaData> AudioSource::getFormat() {
12307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    sp<MetaData> meta = new MetaData;
12407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
12507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    meta->setInt32(kKeySampleRate, mRecord->getSampleRate());
12607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    meta->setInt32(kKeyChannelCount, mRecord->channelCount());
12707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
12807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
12907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    return meta;
13007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber}
13107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
13207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huberstatus_t AudioSource::read(
13307bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
13407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    *out = NULL;
135dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong    ++mTotalReads;
13607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
13707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    MediaBuffer *buffer;
13807bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    CHECK_EQ(mGroup->acquire_buffer(&buffer), OK);
13907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
14053d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong    while (mStarted) {
14153d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        uint32_t numFramesRecorded;
14253d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        mRecord->getPosition(&numFramesRecorded);
14353d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        int64_t latency = mRecord->latency() * 1000;
14453d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong
14553d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        int64_t readTime = systemTime() / 1000;
14653d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong
14753d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        if (numFramesRecorded == 0) {
14853d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            // Initial delay
14953d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            if (mStartTimeUs > 0) {
15053d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                mStartTimeUs = readTime - mStartTimeUs;
15153d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            } else {
15253d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                mStartTimeUs += latency;
15353d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            }
15453d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        }
15553d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong
15653d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        ssize_t n = 0;
15753d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        if (mCollectStats) {
15853d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            n = mRecord->read(buffer->data(), buffer->size());
15953d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            int64_t endTime = systemTime() / 1000;
16053d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            mTotalReadTimeUs += (endTime - readTime);
16153d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            if (n >= 0) {
16253d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                mTotalReadBytes += n;
16353d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            }
16436e573bf7db5888f92c52eda26e0771aaa2406e4James Dong        } else {
16553d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            n = mRecord->read(buffer->data(), buffer->size());
16636e573bf7db5888f92c52eda26e0771aaa2406e4James Dong        }
16707bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
16853d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        if (n < 0) {
16953d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            buffer->release();
17053d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            buffer = NULL;
17153d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong
17253d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            return (status_t)n;
173dae9fd31907c62712f7a96bb2a8e288b0cca57c2James Dong        }
17407bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
17553d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        uint32_t sampleRate = mRecord->getSampleRate();
17653d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        int64_t timestampUs = (1000000LL * numFramesRecorded) / sampleRate +
17753d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                                 mStartTimeUs;
17853d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        int64_t skipFrameUs;
17953d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        if (!options || !options->getSkipFrame(&skipFrameUs)) {
18053d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            skipFrameUs = timestampUs;  // Don't skip frame
18153d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        }
18207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
18353d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        if (skipFrameUs > timestampUs) {
18453d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            // Safe guard against the abuse of the kSkipFrame_Option.
18553d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            if (skipFrameUs - timestampUs >= 1E6) {
18653d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                LOGE("Frame skipping requested is way too long: %lld us",
18753d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                    skipFrameUs - timestampUs);
18853d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                buffer->release();
18953d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                return UNKNOWN_ERROR;
19053d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            }
19153d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            LOGV("skipFrame: %lld us > timestamp: %lld us, samples %d",
19253d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                skipFrameUs, timestampUs, numFramesRecorded);
19353d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            continue;
19453d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        }
19507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
19653d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        if (mTrackMaxAmplitude) {
19753d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong            trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
19853d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        }
19957e7f83c0336db3f03666f077bce4c2692a88cf6James Dong
20053d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        buffer->meta_data()->setInt64(kKeyTime, timestampUs);
20153d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
20253d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong                mStartTimeUs, sampleRate, timestampUs);
20336e573bf7db5888f92c52eda26e0771aaa2406e4James Dong
20453d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        buffer->set_range(0, n);
20507bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
20653d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        *out = buffer;
20753d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong        return OK;
20853d4e0d58e2d5c18f6e026c705af833b9bdd7abaJames Dong    }
20907bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
21007bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber    return OK;
21107bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber}
21207bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber
21357e7f83c0336db3f03666f077bce4c2692a88cf6James Dongvoid AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) {
21457e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    for (int i = nSamples; i > 0; --i) {
21557e7f83c0336db3f03666f077bce4c2692a88cf6James Dong        int16_t value = *data++;
21657e7f83c0336db3f03666f077bce4c2692a88cf6James Dong        if (value < 0) {
21757e7f83c0336db3f03666f077bce4c2692a88cf6James Dong            value = -value;
21857e7f83c0336db3f03666f077bce4c2692a88cf6James Dong        }
21957e7f83c0336db3f03666f077bce4c2692a88cf6James Dong        if (mMaxAmplitude < value) {
22057e7f83c0336db3f03666f077bce4c2692a88cf6James Dong            mMaxAmplitude = value;
22157e7f83c0336db3f03666f077bce4c2692a88cf6James Dong        }
22257e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    }
22357e7f83c0336db3f03666f077bce4c2692a88cf6James Dong}
22457e7f83c0336db3f03666f077bce4c2692a88cf6James Dong
22557e7f83c0336db3f03666f077bce4c2692a88cf6James Dongint16_t AudioSource::getMaxAmplitude() {
22657e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    // First call activates the tracking.
22757e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    if (!mTrackMaxAmplitude) {
22857e7f83c0336db3f03666f077bce4c2692a88cf6James Dong        mTrackMaxAmplitude = true;
22957e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    }
23057e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    int16_t value = mMaxAmplitude;
23157e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    mMaxAmplitude = 0;
23257e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    LOGV("max amplitude since last call: %d", value);
23357e7f83c0336db3f03666f077bce4c2692a88cf6James Dong    return value;
23457e7f83c0336db3f03666f077bce4c2692a88cf6James Dong}
23557e7f83c0336db3f03666f077bce4c2692a88cf6James Dong
23607bf09da4a365282fc35f800b62a83e0fa5533e2Andreas Huber}  // namespace android
237