AudioSource.cpp revision b44c9d2bdc0d5b9cb03254022a58e017b516e9e6
1e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber/* 2e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * Copyright (C) 2010 The Android Open Source Project 3e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * 4e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * you may not use this file except in compliance with the License. 6e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * You may obtain a copy of the License at 7e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * 8e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * 10e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * Unless required by applicable law or agreed to in writing, software 11e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * See the License for the specific language governing permissions and 14e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber * limitations under the License. 15e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber */ 16e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 17050b28a593350047845a45a14cc5026221ac1620James Dong//#define LOG_NDEBUG 0 18050b28a593350047845a45a14cc5026221ac1620James Dong#define LOG_TAG "AudioSource" 19050b28a593350047845a45a14cc5026221ac1620James Dong#include <utils/Log.h> 20050b28a593350047845a45a14cc5026221ac1620James Dong 21e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/AudioRecord.h> 226b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong#include <media/stagefright/AudioSource.h> 236b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong#include <media/stagefright/MediaBuffer.h> 24e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MediaDefs.h> 25e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber#include <media/stagefright/MetaData.h> 266b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong#include <media/stagefright/foundation/ADebug.h> 27365a963142093a1cd8efdcea76b5f65096a5b115James Dong#include <cutils/properties.h> 2846292fb347d72a314d985e34e5e3743d846cb9b6James Dong#include <stdlib.h> 29e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 30e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubernamespace android { 31e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 326b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongstatic void AudioRecordCallbackFunction(int event, void *user, void *info) { 336b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong AudioSource *source = (AudioSource *) user; 346b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong switch (event) { 356b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong case AudioRecord::EVENT_MORE_DATA: { 366b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong source->dataCallbackTimestamp(*((AudioRecord::Buffer *) info), systemTime() / 1000); 376b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong break; 386b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 396b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong case AudioRecord::EVENT_OVERRUN: { 405ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("AudioRecord reported overrun!"); 416b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong break; 426b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 436b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong default: 446b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong // does nothing 456b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong break; 466b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 476b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong} 486b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong 49e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAudioSource::AudioSource( 50eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten audio_source_t inputSource, uint32_t sampleRate, uint32_t channels) 51be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong : mStarted(false), 526b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mSampleRate(sampleRate), 5346292fb347d72a314d985e34e5e3743d846cb9b6James Dong mPrevSampleTimeUs(0), 546b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mNumFramesReceived(0), 556b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mNumClientOwnedBuffers(0) { 56be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong 573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("sampleRate: %d, channels: %d", sampleRate, channels); 58f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong CHECK(channels == 1 || channels == 2); 59be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong uint32_t flags = AudioRecord::RECORD_AGC_ENABLE | 60be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong AudioRecord::RECORD_NS_ENABLE | 61be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong AudioRecord::RECORD_IIR_ENABLE; 62be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong mRecord = new AudioRecord( 63fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT, 64fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin channels > 1? AUDIO_CHANNEL_IN_STEREO: AUDIO_CHANNEL_IN_MONO, 65be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong 4 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */ 666b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong flags, 676b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong AudioRecordCallbackFunction, 686b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong this); 69be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong 70be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong mInitCheck = mRecord->initCheck(); 71e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 72e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 73e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAudioSource::~AudioSource() { 74e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mStarted) { 75b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong reset(); 76e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 77e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 78e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber delete mRecord; 79e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mRecord = NULL; 80e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 81e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 82e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AudioSource::initCheck() const { 83e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return mInitCheck; 84e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 85e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 86e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AudioSource::start(MetaData *params) { 876b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong Mutex::Autolock autoLock(mLock); 88e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (mStarted) { 89e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 90e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 91e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 926e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong if (mInitCheck != OK) { 936e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong return NO_INIT; 946e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong } 956e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong 96d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mTrackMaxAmplitude = false; 97d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mMaxAmplitude = 0; 98d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong mInitialReadTimeUs = 0; 99f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = 0; 100f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t startTimeUs; 101f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (params && params->findInt64(kKeyTime, &startTimeUs)) { 102f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = startTimeUs; 103f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 104e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber status_t err = mRecord->start(); 105e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (err == OK) { 106e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = true; 107eaae38445a340c4857c1c5569475879a728e63b7James Dong } else { 108eaae38445a340c4857c1c5569475879a728e63b7James Dong delete mRecord; 109eaae38445a340c4857c1c5569475879a728e63b7James Dong mRecord = NULL; 110e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 111e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 112eaae38445a340c4857c1c5569475879a728e63b7James Dong 113e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return err; 114e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 115e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1166b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongvoid AudioSource::releaseQueuedFrames_l() { 1173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseQueuedFrames_l"); 1186b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong List<MediaBuffer *>::iterator it; 1196b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong while (!mBuffersReceived.empty()) { 1206b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong it = mBuffersReceived.begin(); 1216b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong (*it)->release(); 1226b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mBuffersReceived.erase(it); 1236b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 1246b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong} 1256b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong 1266b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongvoid AudioSource::waitOutstandingEncodingFrames_l() { 1273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("waitOutstandingEncodingFrames_l: %lld", mNumClientOwnedBuffers); 1286b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong while (mNumClientOwnedBuffers > 0) { 1296b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mFrameEncodingCompletionCondition.wait(mLock); 1306b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 1316b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong} 1326b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong 133b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dongstatus_t AudioSource::reset() { 1346b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong Mutex::Autolock autoLock(mLock); 135e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber if (!mStarted) { 136e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return UNKNOWN_ERROR; 137e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber } 138e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 1396e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong if (mInitCheck != OK) { 1406e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong return NO_INIT; 1416e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong } 1426e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong 143e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber mStarted = false; 1446b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mRecord->stop(); 1456b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong waitOutstandingEncodingFrames_l(); 1466b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong releaseQueuedFrames_l(); 147365a963142093a1cd8efdcea76b5f65096a5b115James Dong 148e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 149e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 150e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 151e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubersp<MetaData> AudioSource::getFormat() { 1526b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong Mutex::Autolock autoLock(mLock); 1536e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong if (mInitCheck != OK) { 1546e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong return 0; 1556e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong } 1566e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong 157e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber sp<MetaData> meta = new MetaData; 158e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 1596b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong meta->setInt32(kKeySampleRate, mSampleRate); 160e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber meta->setInt32(kKeyChannelCount, mRecord->channelCount()); 161e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber meta->setInt32(kKeyMaxInputSize, kMaxBufferSize); 162e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 163e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return meta; 164e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 165e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 166f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dongvoid AudioSource::rampVolume( 167f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong int32_t startFrame, int32_t rampDurationFrames, 168f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong uint8_t *data, size_t bytes) { 169f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong 170f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong const int32_t kShift = 14; 171f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong int32_t fixedMultiplier = (startFrame << kShift) / rampDurationFrames; 172f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong const int32_t nChannels = mRecord->channelCount(); 173f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong int32_t stopFrame = startFrame + bytes / sizeof(int16_t); 174f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong int16_t *frame = (int16_t *) data; 175f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong if (stopFrame > rampDurationFrames) { 176f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong stopFrame = rampDurationFrames; 177f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong } 178f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong 179f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong while (startFrame < stopFrame) { 180f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong if (nChannels == 1) { // mono 181f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong frame[0] = (frame[0] * fixedMultiplier) >> kShift; 182f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong ++frame; 183f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong ++startFrame; 184f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong } else { // stereo 185f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong frame[0] = (frame[0] * fixedMultiplier) >> kShift; 186f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong frame[1] = (frame[1] * fixedMultiplier) >> kShift; 187f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong frame += 2; 188f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong startFrame += 2; 189f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong } 190f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong 191f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong // Update the multiplier every 4 frames 192f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong if ((startFrame & 3) == 0) { 193f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong fixedMultiplier = (startFrame << kShift) / rampDurationFrames; 194f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong } 195f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong } 196f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong} 197f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong 198e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AudioSource::read( 199e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber MediaBuffer **out, const ReadOptions *options) { 2006b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong Mutex::Autolock autoLock(mLock); 2016b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong *out = NULL; 2026e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong 2036e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong if (mInitCheck != OK) { 2046e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong return NO_INIT; 2056e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong } 2066e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong 2076b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong while (mStarted && mBuffersReceived.empty()) { 2086b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mFrameAvailableCondition.wait(mLock); 2096b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 2106b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (!mStarted) { 2116b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong return OK; 2126b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 2136b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong MediaBuffer *buffer = *mBuffersReceived.begin(); 2146b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mBuffersReceived.erase(mBuffersReceived.begin()); 2156b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong ++mNumClientOwnedBuffers; 2166b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong buffer->setObserver(this); 2176b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong buffer->add_ref(); 2186b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong 2196b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong // Mute/suppress the recording sound 2206b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong int64_t timeUs; 2216b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); 2226b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong int64_t elapsedTimeUs = timeUs - mStartTimeUs; 2236b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (elapsedTimeUs < kAutoRampStartUs) { 2246b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong memset((uint8_t *) buffer->data(), 0, buffer->range_length()); 2256b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) { 2266b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong int32_t autoRampDurationFrames = 2276b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong (kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL; 2286b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong 2296b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong int32_t autoRampStartFrames = 2306b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong (kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL; 2316b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong 2326b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong int32_t nFrames = mNumFramesReceived - autoRampStartFrames; 2336b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong rampVolume(nFrames, autoRampDurationFrames, 2346b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong (uint8_t *) buffer->data(), buffer->range_length()); 2356b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 236542db5d438988360d491a5add1040a2df9aa90c9James Dong 2376b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong // Track the max recording signal amplitude. 2386b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (mTrackMaxAmplitude) { 2396b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong trackMaxAmplitude( 2406b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong (int16_t *) buffer->data(), buffer->range_length() >> 1); 2416b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 242542db5d438988360d491a5add1040a2df9aa90c9James Dong 2436b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong *out = buffer; 2446b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong return OK; 2456b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong} 246542db5d438988360d491a5add1040a2df9aa90c9James Dong 2476b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongvoid AudioSource::signalBufferReturned(MediaBuffer *buffer) { 2483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("signalBufferReturned: %p", buffer->data()); 2496b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong Mutex::Autolock autoLock(mLock); 2506b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong --mNumClientOwnedBuffers; 2516b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong buffer->setObserver(0); 2526b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong buffer->release(); 2536b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mFrameEncodingCompletionCondition.signal(); 2546b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong return; 2556b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong} 25646292fb347d72a314d985e34e5e3743d846cb9b6James Dong 2576b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongstatus_t AudioSource::dataCallbackTimestamp( 2586b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong const AudioRecord::Buffer& audioBuffer, int64_t timeUs) { 2593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dataCallbackTimestamp: %lld us", timeUs); 2606b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong Mutex::Autolock autoLock(mLock); 2616b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (!mStarted) { 2625ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Spurious callback from AudioRecord. Drop the audio data."); 2636b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong return OK; 2646b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 26546292fb347d72a314d985e34e5e3743d846cb9b6James Dong 266a472613aec322e25891abf5c77bf3f7e3c244920James Dong // Drop retrieved and previously lost audio data. 267a472613aec322e25891abf5c77bf3f7e3c244920James Dong if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) { 268a472613aec322e25891abf5c77bf3f7e3c244920James Dong mRecord->getInputFramesLost(); 2693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Drop audio data at %lld/%lld us", timeUs, mStartTimeUs); 270a472613aec322e25891abf5c77bf3f7e3c244920James Dong return OK; 271a472613aec322e25891abf5c77bf3f7e3c244920James Dong } 272a472613aec322e25891abf5c77bf3f7e3c244920James Dong 2736b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) { 2746b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mInitialReadTimeUs = timeUs; 2756b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong // Initial delay 2766b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (mStartTimeUs > 0) { 2776b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mStartTimeUs = timeUs - mStartTimeUs; 2786b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } else { 2796b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong // Assume latency is constant. 2806b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mStartTimeUs += mRecord->latency() * 1000; 281f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 2826b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mPrevSampleTimeUs = mStartTimeUs; 2836b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 284e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 2856b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong int64_t timestampUs = mPrevSampleTimeUs; 2866b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong 287a472613aec322e25891abf5c77bf3f7e3c244920James Dong size_t numLostBytes = 0; 288a472613aec322e25891abf5c77bf3f7e3c244920James Dong if (mNumFramesReceived > 0) { // Ignore earlier frame lost 289a472613aec322e25891abf5c77bf3f7e3c244920James Dong // getInputFramesLost() returns the number of lost frames. 290a472613aec322e25891abf5c77bf3f7e3c244920James Dong // Convert number of frames lost to number of bytes lost. 291a472613aec322e25891abf5c77bf3f7e3c244920James Dong numLostBytes = mRecord->getInputFramesLost() * mRecord->frameSize(); 292a472613aec322e25891abf5c77bf3f7e3c244920James Dong } 293a472613aec322e25891abf5c77bf3f7e3c244920James Dong 2946b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong CHECK_EQ(numLostBytes & 1, 0u); 2956b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong CHECK_EQ(audioBuffer.size & 1, 0u); 2966b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong size_t bufferSize = numLostBytes + audioBuffer.size; 2976b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong MediaBuffer *buffer = new MediaBuffer(bufferSize); 2986b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (numLostBytes > 0) { 2996b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong memset(buffer->data(), 0, numLostBytes); 3006b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong memcpy((uint8_t *) buffer->data() + numLostBytes, 3016b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong audioBuffer.i16, audioBuffer.size); 3026b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } else { 3036b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (audioBuffer.size == 0) { 3045ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Nothing is available from AudioRecord callback buffer"); 305542db5d438988360d491a5add1040a2df9aa90c9James Dong buffer->release(); 3066b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong return OK; 307d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong } 3086b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong memcpy((uint8_t *) buffer->data(), 3096b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong audioBuffer.i16, audioBuffer.size); 3106b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong } 3113c3763d2ee1cd1fba7fe522fbaf0faca315d8c2aJames Dong 3126b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong buffer->set_range(0, bufferSize); 3136b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong timestampUs += ((1000000LL * (bufferSize >> 1)) + 3146b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong (mSampleRate >> 1)) / mSampleRate; 315e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 3166b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong if (mNumFramesReceived == 0) { 3176b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs); 318542db5d438988360d491a5add1040a2df9aa90c9James Dong } 3196b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs); 3206b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs); 3216b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mPrevSampleTimeUs = timestampUs; 3226b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mNumFramesReceived += buffer->range_length() / sizeof(int16_t); 3236b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mBuffersReceived.push_back(buffer); 3246b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong mFrameAvailableCondition.signal(); 325e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 326e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber return OK; 327e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} 328e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber 329d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dongvoid AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) { 330d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong for (int i = nSamples; i > 0; --i) { 331d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong int16_t value = *data++; 332d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong if (value < 0) { 333d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong value = -value; 334d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong } 335d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong if (mMaxAmplitude < value) { 336d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mMaxAmplitude = value; 337d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong } 338d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong } 339d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong} 340d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong 341d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dongint16_t AudioSource::getMaxAmplitude() { 342d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong // First call activates the tracking. 343d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong if (!mTrackMaxAmplitude) { 344d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mTrackMaxAmplitude = true; 345d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong } 346d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong int16_t value = mMaxAmplitude; 347d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong mMaxAmplitude = 0; 3483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("max amplitude since last call: %d", value); 349d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong return value; 350d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong} 351d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong 352e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber} // namespace android 353