AudioSource.cpp revision d411b4ca2945cd8974a3a78199fce94646950128
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "AudioSource"
19#include <utils/Log.h>
20
21#include <media/AudioRecord.h>
22#include <media/stagefright/AudioSource.h>
23#include <media/stagefright/MediaBuffer.h>
24#include <media/stagefright/MediaDefs.h>
25#include <media/stagefright/MetaData.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/foundation/ALooper.h>
28#include <cutils/properties.h>
29#include <stdlib.h>
30
31namespace android {
32
33static void AudioRecordCallbackFunction(int event, void *user, void *info) {
34    AudioSource *source = (AudioSource *) user;
35    switch (event) {
36        case AudioRecord::EVENT_MORE_DATA: {
37            source->dataCallback(*((AudioRecord::Buffer *) info));
38            break;
39        }
40        case AudioRecord::EVENT_OVERRUN: {
41            ALOGW("AudioRecord reported overrun!");
42            break;
43        }
44        default:
45            // does nothing
46            break;
47    }
48}
49
50AudioSource::AudioSource(
51        audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount)
52    : mStarted(false),
53      mSampleRate(sampleRate),
54      mPrevSampleTimeUs(0),
55      mNumFramesReceived(0),
56      mNumClientOwnedBuffers(0) {
57    ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount);
58    CHECK(channelCount == 1 || channelCount == 2);
59
60    size_t minFrameCount;
61    status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
62                                           sampleRate,
63                                           AUDIO_FORMAT_PCM_16_BIT,
64                                           audio_channel_in_mask_from_count(channelCount));
65    if (status == OK) {
66        // make sure that the AudioRecord callback never returns more than the maximum
67        // buffer size
68        int frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount;
69
70        // make sure that the AudioRecord total buffer size is large enough
71        size_t bufCount = 2;
72        while ((bufCount * frameCount) < minFrameCount) {
73            bufCount++;
74        }
75
76        mRecord = new AudioRecord(
77                    inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
78                    audio_channel_in_mask_from_count(channelCount),
79                    bufCount * frameCount,
80                    AudioRecordCallbackFunction,
81                    this,
82                    frameCount);
83        mInitCheck = mRecord->initCheck();
84    } else {
85        mInitCheck = status;
86    }
87}
88
89AudioSource::~AudioSource() {
90    if (mStarted) {
91        reset();
92    }
93}
94
95status_t AudioSource::initCheck() const {
96    return mInitCheck;
97}
98
99status_t AudioSource::start(MetaData *params) {
100    Mutex::Autolock autoLock(mLock);
101    if (mStarted) {
102        return UNKNOWN_ERROR;
103    }
104
105    if (mInitCheck != OK) {
106        return NO_INIT;
107    }
108
109    mTrackMaxAmplitude = false;
110    mMaxAmplitude = 0;
111    mInitialReadTimeUs = 0;
112    mStartTimeUs = 0;
113    int64_t startTimeUs;
114    if (params && params->findInt64(kKeyTime, &startTimeUs)) {
115        mStartTimeUs = startTimeUs;
116    }
117    status_t err = mRecord->start();
118    if (err == OK) {
119        mStarted = true;
120    } else {
121        mRecord.clear();
122    }
123
124
125    return err;
126}
127
128void AudioSource::releaseQueuedFrames_l() {
129    ALOGV("releaseQueuedFrames_l");
130    List<MediaBuffer *>::iterator it;
131    while (!mBuffersReceived.empty()) {
132        it = mBuffersReceived.begin();
133        (*it)->release();
134        mBuffersReceived.erase(it);
135    }
136}
137
138void AudioSource::waitOutstandingEncodingFrames_l() {
139    ALOGV("waitOutstandingEncodingFrames_l: %lld", mNumClientOwnedBuffers);
140    while (mNumClientOwnedBuffers > 0) {
141        mFrameEncodingCompletionCondition.wait(mLock);
142    }
143}
144
145status_t AudioSource::reset() {
146    Mutex::Autolock autoLock(mLock);
147    if (!mStarted) {
148        return UNKNOWN_ERROR;
149    }
150
151    if (mInitCheck != OK) {
152        return NO_INIT;
153    }
154
155    mStarted = false;
156    mRecord->stop();
157    waitOutstandingEncodingFrames_l();
158    releaseQueuedFrames_l();
159
160    return OK;
161}
162
163sp<MetaData> AudioSource::getFormat() {
164    Mutex::Autolock autoLock(mLock);
165    if (mInitCheck != OK) {
166        return 0;
167    }
168
169    sp<MetaData> meta = new MetaData;
170    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
171    meta->setInt32(kKeySampleRate, mSampleRate);
172    meta->setInt32(kKeyChannelCount, mRecord->channelCount());
173    meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
174
175    return meta;
176}
177
178void AudioSource::rampVolume(
179        int32_t startFrame, int32_t rampDurationFrames,
180        uint8_t *data,   size_t bytes) {
181
182    const int32_t kShift = 14;
183    int32_t fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
184    const int32_t nChannels = mRecord->channelCount();
185    int32_t stopFrame = startFrame + bytes / sizeof(int16_t);
186    int16_t *frame = (int16_t *) data;
187    if (stopFrame > rampDurationFrames) {
188        stopFrame = rampDurationFrames;
189    }
190
191    while (startFrame < stopFrame) {
192        if (nChannels == 1) {  // mono
193            frame[0] = (frame[0] * fixedMultiplier) >> kShift;
194            ++frame;
195            ++startFrame;
196        } else {               // stereo
197            frame[0] = (frame[0] * fixedMultiplier) >> kShift;
198            frame[1] = (frame[1] * fixedMultiplier) >> kShift;
199            frame += 2;
200            startFrame += 2;
201        }
202
203        // Update the multiplier every 4 frames
204        if ((startFrame & 3) == 0) {
205            fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
206        }
207    }
208}
209
210status_t AudioSource::read(
211        MediaBuffer **out, const ReadOptions * /* options */) {
212    Mutex::Autolock autoLock(mLock);
213    *out = NULL;
214
215    if (mInitCheck != OK) {
216        return NO_INIT;
217    }
218
219    while (mStarted && mBuffersReceived.empty()) {
220        mFrameAvailableCondition.wait(mLock);
221    }
222    if (!mStarted) {
223        return OK;
224    }
225    MediaBuffer *buffer = *mBuffersReceived.begin();
226    mBuffersReceived.erase(mBuffersReceived.begin());
227    ++mNumClientOwnedBuffers;
228    buffer->setObserver(this);
229    buffer->add_ref();
230
231    // Mute/suppress the recording sound
232    int64_t timeUs;
233    CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
234    int64_t elapsedTimeUs = timeUs - mStartTimeUs;
235    if (elapsedTimeUs < kAutoRampStartUs) {
236        memset((uint8_t *) buffer->data(), 0, buffer->range_length());
237    } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
238        int32_t autoRampDurationFrames =
239                    ((int64_t)kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting
240
241        int32_t autoRampStartFrames =
242                    ((int64_t)kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting
243
244        int32_t nFrames = mNumFramesReceived - autoRampStartFrames;
245        rampVolume(nFrames, autoRampDurationFrames,
246                (uint8_t *) buffer->data(), buffer->range_length());
247    }
248
249    // Track the max recording signal amplitude.
250    if (mTrackMaxAmplitude) {
251        trackMaxAmplitude(
252            (int16_t *) buffer->data(), buffer->range_length() >> 1);
253    }
254
255    *out = buffer;
256    return OK;
257}
258
259void AudioSource::signalBufferReturned(MediaBuffer *buffer) {
260    ALOGV("signalBufferReturned: %p", buffer->data());
261    Mutex::Autolock autoLock(mLock);
262    --mNumClientOwnedBuffers;
263    buffer->setObserver(0);
264    buffer->release();
265    mFrameEncodingCompletionCondition.signal();
266    return;
267}
268
269status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
270    int64_t timeUs = systemTime() / 1000ll;
271
272    ALOGV("dataCallbackTimestamp: %lld us", timeUs);
273    Mutex::Autolock autoLock(mLock);
274    if (!mStarted) {
275        ALOGW("Spurious callback from AudioRecord. Drop the audio data.");
276        return OK;
277    }
278
279    // Drop retrieved and previously lost audio data.
280    if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
281        mRecord->getInputFramesLost();
282        ALOGV("Drop audio data at %lld/%lld us", timeUs, mStartTimeUs);
283        return OK;
284    }
285
286    if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
287        mInitialReadTimeUs = timeUs;
288        // Initial delay
289        if (mStartTimeUs > 0) {
290            mStartTimeUs = timeUs - mStartTimeUs;
291        } else {
292            // Assume latency is constant.
293            mStartTimeUs += mRecord->latency() * 1000;
294        }
295
296        mPrevSampleTimeUs = mStartTimeUs;
297    }
298
299    size_t numLostBytes = 0;
300    if (mNumFramesReceived > 0) {  // Ignore earlier frame lost
301        // getInputFramesLost() returns the number of lost frames.
302        // Convert number of frames lost to number of bytes lost.
303        numLostBytes = mRecord->getInputFramesLost() * mRecord->frameSize();
304    }
305
306    CHECK_EQ(numLostBytes & 1, 0u);
307    CHECK_EQ(audioBuffer.size & 1, 0u);
308    if (numLostBytes > 0) {
309        // Loss of audio frames should happen rarely; thus the LOGW should
310        // not cause a logging spam
311        ALOGW("Lost audio record data: %zu bytes", numLostBytes);
312    }
313
314    while (numLostBytes > 0) {
315        size_t bufferSize = numLostBytes;
316        if (numLostBytes > kMaxBufferSize) {
317            numLostBytes -= kMaxBufferSize;
318            bufferSize = kMaxBufferSize;
319        } else {
320            numLostBytes = 0;
321        }
322        MediaBuffer *lostAudioBuffer = new MediaBuffer(bufferSize);
323        memset(lostAudioBuffer->data(), 0, bufferSize);
324        lostAudioBuffer->set_range(0, bufferSize);
325        queueInputBuffer_l(lostAudioBuffer, timeUs);
326    }
327
328    if (audioBuffer.size == 0) {
329        ALOGW("Nothing is available from AudioRecord callback buffer");
330        return OK;
331    }
332
333    const size_t bufferSize = audioBuffer.size;
334    MediaBuffer *buffer = new MediaBuffer(bufferSize);
335    memcpy((uint8_t *) buffer->data(),
336            audioBuffer.i16, audioBuffer.size);
337    buffer->set_range(0, bufferSize);
338    queueInputBuffer_l(buffer, timeUs);
339    return OK;
340}
341
342void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
343    const size_t bufferSize = buffer->range_length();
344    const size_t frameSize = mRecord->frameSize();
345    const int64_t timestampUs =
346                mPrevSampleTimeUs +
347                    ((1000000LL * (bufferSize / frameSize)) +
348                        (mSampleRate >> 1)) / mSampleRate;
349
350    if (mNumFramesReceived == 0) {
351        buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
352    }
353
354    buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
355    buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
356    mPrevSampleTimeUs = timestampUs;
357    mNumFramesReceived += bufferSize / frameSize;
358    mBuffersReceived.push_back(buffer);
359    mFrameAvailableCondition.signal();
360}
361
362void AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) {
363    for (int i = nSamples; i > 0; --i) {
364        int16_t value = *data++;
365        if (value < 0) {
366            value = -value;
367        }
368        if (mMaxAmplitude < value) {
369            mMaxAmplitude = value;
370        }
371    }
372}
373
374int16_t AudioSource::getMaxAmplitude() {
375    // First call activates the tracking.
376    if (!mTrackMaxAmplitude) {
377        mTrackMaxAmplitude = true;
378    }
379    int16_t value = mMaxAmplitude;
380    mMaxAmplitude = 0;
381    ALOGV("max amplitude since last call: %d", value);
382    return value;
383}
384
385}  // namespace android
386