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