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>
27082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber#include <media/stagefright/foundation/ALooper.h>
28365a963142093a1cd8efdcea76b5f65096a5b115James Dong#include <cutils/properties.h>
2946292fb347d72a314d985e34e5e3743d846cb9b6James Dong#include <stdlib.h>
30e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
31e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubernamespace android {
32e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
336b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongstatic void AudioRecordCallbackFunction(int event, void *user, void *info) {
346b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    AudioSource *source = (AudioSource *) user;
356b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    switch (event) {
366b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        case AudioRecord::EVENT_MORE_DATA: {
37082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber            source->dataCallback(*((AudioRecord::Buffer *) info));
386b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong            break;
396b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        }
406b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        case AudioRecord::EVENT_OVERRUN: {
415ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("AudioRecord reported overrun!");
426b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong            break;
436b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        }
446b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        default:
456b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong            // does nothing
466b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong            break;
476b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
486b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong}
496b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong
50e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAudioSource::AudioSource(
51ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten        audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount)
52a0108697f86d8625eb7ad3f13e422427fe7573caJames Dong    : mRecord(NULL),
53a0108697f86d8625eb7ad3f13e422427fe7573caJames Dong      mStarted(false),
546b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong      mSampleRate(sampleRate),
5546292fb347d72a314d985e34e5e3743d846cb9b6James Dong      mPrevSampleTimeUs(0),
566b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong      mNumFramesReceived(0),
57af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber      mNumClientOwnedBuffers(0) {
58ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten    ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount);
59ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten    CHECK(channelCount == 1 || channelCount == 2);
60be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7James Dong
61e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent    int minFrameCount;
62e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent    status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
63e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent                                           sampleRate,
64e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent                                           AUDIO_FORMAT_PCM_16_BIT,
65dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten                                           audio_channel_in_mask_from_count(channelCount));
66e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent    if (status == OK) {
67e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        // make sure that the AudioRecord callback never returns more than the maximum
68e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        // buffer size
69e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        int frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount;
70e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent
71e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        // make sure that the AudioRecord total buffer size is large enough
72e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        int bufCount = 2;
73e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        while ((bufCount * frameCount) < minFrameCount) {
74e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent            bufCount++;
75e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        }
76e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent
77e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        mRecord = new AudioRecord(
78e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent                    inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
79e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent                    audio_channel_in_mask_from_count(channelCount),
80e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent                    bufCount * frameCount,
81e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent                    AudioRecordCallbackFunction,
82e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent                    this,
83e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent                    frameCount);
84e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        mInitCheck = mRecord->initCheck();
85e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent    } else {
86e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent        mInitCheck = status;
87e49f2b424318aa8e830e7a1338e5e32ab82992f9Eric Laurent    }
88e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber}
89e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
90e7c9cb48fec02697227bd847cd2e69432659adfdAndreas HuberAudioSource::~AudioSource() {
91e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    if (mStarted) {
92b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong        reset();
93e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    }
94e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
95e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    delete mRecord;
96e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    mRecord = NULL;
97e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber}
98e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
99e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AudioSource::initCheck() const {
100e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    return mInitCheck;
101e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber}
102e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
103e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AudioSource::start(MetaData *params) {
1046b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    Mutex::Autolock autoLock(mLock);
105e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    if (mStarted) {
106e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber        return UNKNOWN_ERROR;
107e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    }
108e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
1096e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong    if (mInitCheck != OK) {
1106e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong        return NO_INIT;
1116e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong    }
1126e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong
113d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    mTrackMaxAmplitude = false;
114d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    mMaxAmplitude = 0;
115d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    mInitialReadTimeUs = 0;
116f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    mStartTimeUs = 0;
117f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    int64_t startTimeUs;
118f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    if (params && params->findInt64(kKeyTime, &startTimeUs)) {
119f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        mStartTimeUs = startTimeUs;
120f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    }
121e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    status_t err = mRecord->start();
122e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    if (err == OK) {
123e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber        mStarted = true;
124eaae38445a340c4857c1c5569475879a728e63b7James Dong    } else {
125eaae38445a340c4857c1c5569475879a728e63b7James Dong        delete mRecord;
126eaae38445a340c4857c1c5569475879a728e63b7James Dong        mRecord = NULL;
127e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    }
128e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
129eaae38445a340c4857c1c5569475879a728e63b7James Dong
130e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    return err;
131e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber}
132e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
1336b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongvoid AudioSource::releaseQueuedFrames_l() {
1343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("releaseQueuedFrames_l");
1356b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    List<MediaBuffer *>::iterator it;
1366b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    while (!mBuffersReceived.empty()) {
1376b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        it = mBuffersReceived.begin();
1386b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        (*it)->release();
1396b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        mBuffersReceived.erase(it);
1406b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
1416b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong}
1426b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong
1436b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongvoid AudioSource::waitOutstandingEncodingFrames_l() {
1443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("waitOutstandingEncodingFrames_l: %lld", mNumClientOwnedBuffers);
1456b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    while (mNumClientOwnedBuffers > 0) {
1466b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        mFrameEncodingCompletionCondition.wait(mLock);
1476b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
1486b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong}
1496b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong
150b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dongstatus_t AudioSource::reset() {
1516b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    Mutex::Autolock autoLock(mLock);
152e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    if (!mStarted) {
153e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber        return UNKNOWN_ERROR;
154e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    }
155e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
1566e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong    if (mInitCheck != OK) {
1576e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong        return NO_INIT;
1586e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong    }
1596e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong
160e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    mStarted = false;
1616b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    mRecord->stop();
1626b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    waitOutstandingEncodingFrames_l();
1636b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    releaseQueuedFrames_l();
164365a963142093a1cd8efdcea76b5f65096a5b115James Dong
165e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    return OK;
166e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber}
167e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
168e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Hubersp<MetaData> AudioSource::getFormat() {
1696b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    Mutex::Autolock autoLock(mLock);
1706e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong    if (mInitCheck != OK) {
1716e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong        return 0;
1726e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong    }
1736e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong
174e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    sp<MetaData> meta = new MetaData;
175e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
1766b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    meta->setInt32(kKeySampleRate, mSampleRate);
177e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    meta->setInt32(kKeyChannelCount, mRecord->channelCount());
178e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
179e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
180e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber    return meta;
181e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber}
182e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
183f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dongvoid AudioSource::rampVolume(
184f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        int32_t startFrame, int32_t rampDurationFrames,
185f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        uint8_t *data,   size_t bytes) {
186f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong
187f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    const int32_t kShift = 14;
188f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    int32_t fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
189f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    const int32_t nChannels = mRecord->channelCount();
190f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    int32_t stopFrame = startFrame + bytes / sizeof(int16_t);
191f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    int16_t *frame = (int16_t *) data;
192f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    if (stopFrame > rampDurationFrames) {
193f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        stopFrame = rampDurationFrames;
194f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    }
195f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong
196f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    while (startFrame < stopFrame) {
197f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        if (nChannels == 1) {  // mono
198f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong            frame[0] = (frame[0] * fixedMultiplier) >> kShift;
199f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong            ++frame;
200f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong            ++startFrame;
201f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        } else {               // stereo
202f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong            frame[0] = (frame[0] * fixedMultiplier) >> kShift;
203f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong            frame[1] = (frame[1] * fixedMultiplier) >> kShift;
204f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong            frame += 2;
205f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong            startFrame += 2;
206f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        }
207f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong
208f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        // Update the multiplier every 4 frames
209f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        if ((startFrame & 3) == 0) {
210f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong            fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
211f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong        }
212f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong    }
213f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong}
214f1ae1963f5028a670573b50a9c1cfb504fc426b4James Dong
215e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huberstatus_t AudioSource::read(
216e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber        MediaBuffer **out, const ReadOptions *options) {
2176b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    Mutex::Autolock autoLock(mLock);
2186b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    *out = NULL;
2196e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong
2206e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong    if (mInitCheck != OK) {
2216e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong        return NO_INIT;
2226e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong    }
2236e20bdf799a6f4efa6c42121a958634ea32ed5ccJames Dong
2246b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    while (mStarted && mBuffersReceived.empty()) {
2256b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        mFrameAvailableCondition.wait(mLock);
2266b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
2276b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    if (!mStarted) {
2286b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        return OK;
2296b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
2306b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    MediaBuffer *buffer = *mBuffersReceived.begin();
2316b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    mBuffersReceived.erase(mBuffersReceived.begin());
2326b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    ++mNumClientOwnedBuffers;
2336b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    buffer->setObserver(this);
2346b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    buffer->add_ref();
2356b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong
2366b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    // Mute/suppress the recording sound
2376b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    int64_t timeUs;
2386b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
2396b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    int64_t elapsedTimeUs = timeUs - mStartTimeUs;
2406b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    if (elapsedTimeUs < kAutoRampStartUs) {
2416b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        memset((uint8_t *) buffer->data(), 0, buffer->range_length());
2426b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
2436b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        int32_t autoRampDurationFrames =
2446b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong                    (kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL;
2456b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong
2466b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        int32_t autoRampStartFrames =
2476b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong                    (kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL;
2486b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong
2496b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        int32_t nFrames = mNumFramesReceived - autoRampStartFrames;
2506b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        rampVolume(nFrames, autoRampDurationFrames,
2516b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong                (uint8_t *) buffer->data(), buffer->range_length());
2526b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
253542db5d438988360d491a5add1040a2df9aa90c9James Dong
2546b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    // Track the max recording signal amplitude.
2556b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    if (mTrackMaxAmplitude) {
2566b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        trackMaxAmplitude(
2576b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong            (int16_t *) buffer->data(), buffer->range_length() >> 1);
2586b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
259542db5d438988360d491a5add1040a2df9aa90c9James Dong
2606b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    *out = buffer;
2616b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    return OK;
2626b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong}
263542db5d438988360d491a5add1040a2df9aa90c9James Dong
2646b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dongvoid AudioSource::signalBufferReturned(MediaBuffer *buffer) {
2653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("signalBufferReturned: %p", buffer->data());
2666b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    Mutex::Autolock autoLock(mLock);
2676b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    --mNumClientOwnedBuffers;
2686b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    buffer->setObserver(0);
2696b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    buffer->release();
2706b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    mFrameEncodingCompletionCondition.signal();
2716b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    return;
2726b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong}
27346292fb347d72a314d985e34e5e3743d846cb9b6James Dong
274082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huberstatus_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
275af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber    int64_t timeUs = systemTime() / 1000ll;
276082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
2773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("dataCallbackTimestamp: %lld us", timeUs);
2786b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    Mutex::Autolock autoLock(mLock);
2796b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    if (!mStarted) {
2805ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Spurious callback from AudioRecord. Drop the audio data.");
2816b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        return OK;
2826b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
28346292fb347d72a314d985e34e5e3743d846cb9b6James Dong
284a472613aec322e25891abf5c77bf3f7e3c244920James Dong    // Drop retrieved and previously lost audio data.
285a472613aec322e25891abf5c77bf3f7e3c244920James Dong    if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
286a472613aec322e25891abf5c77bf3f7e3c244920James Dong        mRecord->getInputFramesLost();
2873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Drop audio data at %lld/%lld us", timeUs, mStartTimeUs);
288a472613aec322e25891abf5c77bf3f7e3c244920James Dong        return OK;
289a472613aec322e25891abf5c77bf3f7e3c244920James Dong    }
290a472613aec322e25891abf5c77bf3f7e3c244920James Dong
2916b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
2926b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        mInitialReadTimeUs = timeUs;
2936b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        // Initial delay
294af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber        if (mStartTimeUs > 0) {
2956b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong            mStartTimeUs = timeUs - mStartTimeUs;
2966b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        } else {
2976b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong            // Assume latency is constant.
2986b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong            mStartTimeUs += mRecord->latency() * 1000;
299f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        }
300082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
3016b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        mPrevSampleTimeUs = mStartTimeUs;
3026b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
303e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
304a472613aec322e25891abf5c77bf3f7e3c244920James Dong    size_t numLostBytes = 0;
305a472613aec322e25891abf5c77bf3f7e3c244920James Dong    if (mNumFramesReceived > 0) {  // Ignore earlier frame lost
306a472613aec322e25891abf5c77bf3f7e3c244920James Dong        // getInputFramesLost() returns the number of lost frames.
307a472613aec322e25891abf5c77bf3f7e3c244920James Dong        // Convert number of frames lost to number of bytes lost.
308a472613aec322e25891abf5c77bf3f7e3c244920James Dong        numLostBytes = mRecord->getInputFramesLost() * mRecord->frameSize();
309a472613aec322e25891abf5c77bf3f7e3c244920James Dong    }
310a472613aec322e25891abf5c77bf3f7e3c244920James Dong
3116b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    CHECK_EQ(numLostBytes & 1, 0u);
3126b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    CHECK_EQ(audioBuffer.size & 1, 0u);
3136b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    if (numLostBytes > 0) {
314b575ddce78d266fa218006f90306158dda5c8f56James Dong        // Loss of audio frames should happen rarely; thus the LOGW should
315b575ddce78d266fa218006f90306158dda5c8f56James Dong        // not cause a logging spam
316b575ddce78d266fa218006f90306158dda5c8f56James Dong        ALOGW("Lost audio record data: %d bytes", numLostBytes);
317b575ddce78d266fa218006f90306158dda5c8f56James Dong    }
318b575ddce78d266fa218006f90306158dda5c8f56James Dong
319b575ddce78d266fa218006f90306158dda5c8f56James Dong    while (numLostBytes > 0) {
320b575ddce78d266fa218006f90306158dda5c8f56James Dong        size_t bufferSize = numLostBytes;
321b575ddce78d266fa218006f90306158dda5c8f56James Dong        if (numLostBytes > kMaxBufferSize) {
322b575ddce78d266fa218006f90306158dda5c8f56James Dong            numLostBytes -= kMaxBufferSize;
323b575ddce78d266fa218006f90306158dda5c8f56James Dong            bufferSize = kMaxBufferSize;
324b575ddce78d266fa218006f90306158dda5c8f56James Dong        } else {
325b575ddce78d266fa218006f90306158dda5c8f56James Dong            numLostBytes = 0;
326d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong        }
327b575ddce78d266fa218006f90306158dda5c8f56James Dong        MediaBuffer *lostAudioBuffer = new MediaBuffer(bufferSize);
328b575ddce78d266fa218006f90306158dda5c8f56James Dong        memset(lostAudioBuffer->data(), 0, bufferSize);
329b575ddce78d266fa218006f90306158dda5c8f56James Dong        lostAudioBuffer->set_range(0, bufferSize);
330b575ddce78d266fa218006f90306158dda5c8f56James Dong        queueInputBuffer_l(lostAudioBuffer, timeUs);
331b575ddce78d266fa218006f90306158dda5c8f56James Dong    }
332b575ddce78d266fa218006f90306158dda5c8f56James Dong
333b575ddce78d266fa218006f90306158dda5c8f56James Dong    if (audioBuffer.size == 0) {
334b575ddce78d266fa218006f90306158dda5c8f56James Dong        ALOGW("Nothing is available from AudioRecord callback buffer");
335b575ddce78d266fa218006f90306158dda5c8f56James Dong        return OK;
3366b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    }
3373c3763d2ee1cd1fba7fe522fbaf0faca315d8c2aJames Dong
338b575ddce78d266fa218006f90306158dda5c8f56James Dong    const size_t bufferSize = audioBuffer.size;
339b575ddce78d266fa218006f90306158dda5c8f56James Dong    MediaBuffer *buffer = new MediaBuffer(bufferSize);
340b575ddce78d266fa218006f90306158dda5c8f56James Dong    memcpy((uint8_t *) buffer->data(),
341b575ddce78d266fa218006f90306158dda5c8f56James Dong            audioBuffer.i16, audioBuffer.size);
3426b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    buffer->set_range(0, bufferSize);
343b575ddce78d266fa218006f90306158dda5c8f56James Dong    queueInputBuffer_l(buffer, timeUs);
344b575ddce78d266fa218006f90306158dda5c8f56James Dong    return OK;
345b575ddce78d266fa218006f90306158dda5c8f56James Dong}
346b575ddce78d266fa218006f90306158dda5c8f56James Dong
347b575ddce78d266fa218006f90306158dda5c8f56James Dongvoid AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
348b575ddce78d266fa218006f90306158dda5c8f56James Dong    const size_t bufferSize = buffer->range_length();
349b575ddce78d266fa218006f90306158dda5c8f56James Dong    const size_t frameSize = mRecord->frameSize();
350b575ddce78d266fa218006f90306158dda5c8f56James Dong    const int64_t timestampUs =
351b575ddce78d266fa218006f90306158dda5c8f56James Dong                mPrevSampleTimeUs +
352b575ddce78d266fa218006f90306158dda5c8f56James Dong                    ((1000000LL * (bufferSize / frameSize)) +
353b575ddce78d266fa218006f90306158dda5c8f56James Dong                        (mSampleRate >> 1)) / mSampleRate;
354e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
3556b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    if (mNumFramesReceived == 0) {
3566b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong        buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
357542db5d438988360d491a5add1040a2df9aa90c9James Dong    }
358b575ddce78d266fa218006f90306158dda5c8f56James Dong
3596b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
3606b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
3616b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    mPrevSampleTimeUs = timestampUs;
362b575ddce78d266fa218006f90306158dda5c8f56James Dong    mNumFramesReceived += bufferSize / frameSize;
3636b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    mBuffersReceived.push_back(buffer);
3646b61f4355db1974cd0f0dfaa4effdd7117b9f09bJames Dong    mFrameAvailableCondition.signal();
365e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber}
366e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber
367d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dongvoid AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) {
368d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    for (int i = nSamples; i > 0; --i) {
369d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong        int16_t value = *data++;
370d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong        if (value < 0) {
371d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong            value = -value;
372d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong        }
373d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong        if (mMaxAmplitude < value) {
374d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong            mMaxAmplitude = value;
375d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong        }
376d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    }
377d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong}
378d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong
379d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dongint16_t AudioSource::getMaxAmplitude() {
380d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    // First call activates the tracking.
381d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    if (!mTrackMaxAmplitude) {
382d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong        mTrackMaxAmplitude = true;
383d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    }
384d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    int16_t value = mMaxAmplitude;
385d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    mMaxAmplitude = 0;
3863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("max amplitude since last call: %d", value);
387d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong    return value;
388d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong}
389d3d4e5069e1af0437c4f5a7b4ba344bda5b937afJames Dong
390e7c9cb48fec02697227bd847cd2e69432659adfdAndreas Huber}  // namespace android
391