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