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