AudioSource.cpp revision 4f998cdef97b9c027f145b2da5c48278e19c3d33
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,
54        uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
55        uid_t uid, pid_t pid)
56    : mStarted(false),
57      mSampleRate(sampleRate),
58      mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate),
59      mTrackMaxAmplitude(false),
60      mStartTimeUs(0),
61      mMaxAmplitude(0),
62      mPrevSampleTimeUs(0),
63      mInitialReadTimeUs(0),
64      mNumFramesReceived(0),
65      mNumFramesSkipped(0),
66      mNumFramesLost(0),
67      mNumClientOwnedBuffers(0) {
68    ALOGV("sampleRate: %u, outSampleRate: %u, channelCount: %u",
69            sampleRate, outSampleRate, channelCount);
70    CHECK(channelCount == 1 || channelCount == 2);
71    CHECK(sampleRate > 0);
72
73    size_t minFrameCount;
74    status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
75                                           sampleRate,
76                                           AUDIO_FORMAT_PCM_16_BIT,
77                                           audio_channel_in_mask_from_count(channelCount));
78    if (status == OK) {
79        // make sure that the AudioRecord callback never returns more than the maximum
80        // buffer size
81        uint32_t frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount;
82
83        // make sure that the AudioRecord total buffer size is large enough
84        size_t bufCount = 2;
85        while ((bufCount * frameCount) < minFrameCount) {
86            bufCount++;
87        }
88
89        mRecord = new AudioRecord(
90                    inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
91                    audio_channel_in_mask_from_count(channelCount),
92                    opPackageName,
93                    (size_t) (bufCount * frameCount),
94                    AudioRecordCallbackFunction,
95                    this,
96                    frameCount /*notificationFrames*/,
97                    AUDIO_SESSION_ALLOCATE,
98                    AudioRecord::TRANSFER_DEFAULT,
99                    AUDIO_INPUT_FLAG_NONE,
100                    uid,
101                    pid);
102        mInitCheck = mRecord->initCheck();
103        if (mInitCheck != OK) {
104            mRecord.clear();
105        }
106    } else {
107        mInitCheck = status;
108    }
109}
110
111AudioSource::~AudioSource() {
112    if (mStarted) {
113        reset();
114    }
115}
116
117status_t AudioSource::initCheck() const {
118    return mInitCheck;
119}
120
121status_t AudioSource::start(MetaData *params) {
122    Mutex::Autolock autoLock(mLock);
123    if (mStarted) {
124        return UNKNOWN_ERROR;
125    }
126
127    if (mInitCheck != OK) {
128        return NO_INIT;
129    }
130
131    mTrackMaxAmplitude = false;
132    mMaxAmplitude = 0;
133    mInitialReadTimeUs = 0;
134    mStartTimeUs = 0;
135    int64_t startTimeUs;
136    if (params && params->findInt64(kKeyTime, &startTimeUs)) {
137        mStartTimeUs = startTimeUs;
138    }
139    status_t err = mRecord->start();
140    if (err == OK) {
141        mStarted = true;
142    } else {
143        mRecord.clear();
144    }
145
146
147    return err;
148}
149
150void AudioSource::releaseQueuedFrames_l() {
151    ALOGV("releaseQueuedFrames_l");
152    List<MediaBuffer *>::iterator it;
153    while (!mBuffersReceived.empty()) {
154        it = mBuffersReceived.begin();
155        (*it)->release();
156        mBuffersReceived.erase(it);
157    }
158}
159
160void AudioSource::waitOutstandingEncodingFrames_l() {
161    ALOGV("waitOutstandingEncodingFrames_l: %" PRId64, mNumClientOwnedBuffers);
162    while (mNumClientOwnedBuffers > 0) {
163        mFrameEncodingCompletionCondition.wait(mLock);
164    }
165}
166
167status_t AudioSource::reset() {
168    Mutex::Autolock autoLock(mLock);
169    if (!mStarted) {
170        return UNKNOWN_ERROR;
171    }
172
173    if (mInitCheck != OK) {
174        return NO_INIT;
175    }
176
177    mStarted = false;
178    mFrameAvailableCondition.signal();
179
180    mRecord->stop();
181    waitOutstandingEncodingFrames_l();
182    releaseQueuedFrames_l();
183
184    return OK;
185}
186
187sp<MetaData> AudioSource::getFormat() {
188    Mutex::Autolock autoLock(mLock);
189    if (mInitCheck != OK) {
190        return 0;
191    }
192
193    sp<MetaData> meta = new MetaData;
194    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
195    meta->setInt32(kKeySampleRate, mSampleRate);
196    meta->setInt32(kKeyChannelCount, mRecord->channelCount());
197    meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
198    meta->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
199
200    return meta;
201}
202
203void AudioSource::rampVolume(
204        int32_t startFrame, int32_t rampDurationFrames,
205        uint8_t *data,   size_t bytes) {
206
207    const int32_t kShift = 14;
208    int32_t fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
209    const int32_t nChannels = mRecord->channelCount();
210    int32_t stopFrame = startFrame + bytes / sizeof(int16_t);
211    int16_t *frame = (int16_t *) data;
212    if (stopFrame > rampDurationFrames) {
213        stopFrame = rampDurationFrames;
214    }
215
216    while (startFrame < stopFrame) {
217        if (nChannels == 1) {  // mono
218            frame[0] = (frame[0] * fixedMultiplier) >> kShift;
219            ++frame;
220            ++startFrame;
221        } else {               // stereo
222            frame[0] = (frame[0] * fixedMultiplier) >> kShift;
223            frame[1] = (frame[1] * fixedMultiplier) >> kShift;
224            frame += 2;
225            startFrame += 2;
226        }
227
228        // Update the multiplier every 4 frames
229        if ((startFrame & 3) == 0) {
230            fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
231        }
232    }
233}
234
235status_t AudioSource::read(
236        MediaBuffer **out, const ReadOptions * /* options */) {
237    Mutex::Autolock autoLock(mLock);
238    *out = NULL;
239
240    if (mInitCheck != OK) {
241        return NO_INIT;
242    }
243
244    while (mStarted && mBuffersReceived.empty()) {
245        mFrameAvailableCondition.wait(mLock);
246    }
247    if (!mStarted) {
248        return OK;
249    }
250    MediaBuffer *buffer = *mBuffersReceived.begin();
251    mBuffersReceived.erase(mBuffersReceived.begin());
252    ++mNumClientOwnedBuffers;
253    buffer->setObserver(this);
254    buffer->add_ref();
255
256    // Mute/suppress the recording sound
257    int64_t timeUs;
258    CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
259    int64_t elapsedTimeUs = timeUs - mStartTimeUs;
260    if (elapsedTimeUs < kAutoRampStartUs) {
261        memset((uint8_t *) buffer->data(), 0, buffer->range_length());
262    } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
263        int32_t autoRampDurationFrames =
264                    ((int64_t)kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting
265
266        int32_t autoRampStartFrames =
267                    ((int64_t)kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting
268
269        int32_t nFrames = mNumFramesReceived - autoRampStartFrames;
270        rampVolume(nFrames, autoRampDurationFrames,
271                (uint8_t *) buffer->data(), buffer->range_length());
272    }
273
274    // Track the max recording signal amplitude.
275    if (mTrackMaxAmplitude) {
276        trackMaxAmplitude(
277            (int16_t *) buffer->data(), buffer->range_length() >> 1);
278    }
279
280    if (mSampleRate != mOutSampleRate) {
281            timeUs *= (int64_t)mSampleRate / (int64_t)mOutSampleRate;
282            buffer->meta_data()->setInt64(kKeyTime, timeUs);
283    }
284
285    *out = buffer;
286    return OK;
287}
288
289void AudioSource::signalBufferReturned(MediaBuffer *buffer) {
290    ALOGV("signalBufferReturned: %p", buffer->data());
291    Mutex::Autolock autoLock(mLock);
292    --mNumClientOwnedBuffers;
293    buffer->setObserver(0);
294    buffer->release();
295    mFrameEncodingCompletionCondition.signal();
296    return;
297}
298
299status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
300    int64_t timeUs, position, timeNs;
301    ExtendedTimestamp ts;
302    ExtendedTimestamp::Location location;
303    const int32_t usPerSec = 1000000;
304
305    if (mRecord->getTimestamp(&ts) == OK &&
306            ts.getBestTimestamp(&position, &timeNs, ExtendedTimestamp::TIMEBASE_MONOTONIC,
307            &location) == OK) {
308        // Use audio timestamp.
309        timeUs = timeNs / 1000 -
310                (position - mNumFramesSkipped -
311                mNumFramesReceived + mNumFramesLost) * usPerSec / mSampleRate;
312    } else {
313        // This should not happen in normal case.
314        ALOGW("Failed to get audio timestamp, fallback to use systemclock");
315        timeUs = systemTime() / 1000ll;
316        // Estimate the real sampling time of the 1st sample in this buffer
317        // from AudioRecord's latency. (Apply this adjustment first so that
318        // the start time logic is not affected.)
319        timeUs -= mRecord->latency() * 1000LL;
320    }
321
322    ALOGV("dataCallbackTimestamp: %" PRId64 " us", timeUs);
323    Mutex::Autolock autoLock(mLock);
324    if (!mStarted) {
325        ALOGW("Spurious callback from AudioRecord. Drop the audio data.");
326        return OK;
327    }
328
329    const size_t bufferSize = audioBuffer.size;
330
331    // Drop retrieved and previously lost audio data.
332    if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
333        (void) mRecord->getInputFramesLost();
334        int64_t receievedFrames = bufferSize / mRecord->frameSize();
335        ALOGV("Drop audio data(%" PRId64 " frames) at %" PRId64 "/%" PRId64 " us",
336                receievedFrames, timeUs, mStartTimeUs);
337        mNumFramesSkipped += receievedFrames;
338        return OK;
339    }
340
341    if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
342        mInitialReadTimeUs = timeUs;
343        // Initial delay
344        if (mStartTimeUs > 0) {
345            mStartTimeUs = timeUs - mStartTimeUs;
346        }
347        mPrevSampleTimeUs = mStartTimeUs;
348    }
349
350    size_t numLostBytes = 0;
351    if (mNumFramesReceived > 0) {  // Ignore earlier frame lost
352        // getInputFramesLost() returns the number of lost frames.
353        // Convert number of frames lost to number of bytes lost.
354        numLostBytes = mRecord->getInputFramesLost() * mRecord->frameSize();
355    }
356
357    CHECK_EQ(numLostBytes & 1, 0u);
358    CHECK_EQ(audioBuffer.size & 1, 0u);
359    if (numLostBytes > 0) {
360        // Loss of audio frames should happen rarely; thus the LOGW should
361        // not cause a logging spam
362        ALOGW("Lost audio record data: %zu bytes", numLostBytes);
363    }
364
365    while (numLostBytes > 0) {
366        size_t bufferSize = numLostBytes;
367        if (numLostBytes > kMaxBufferSize) {
368            numLostBytes -= kMaxBufferSize;
369            bufferSize = kMaxBufferSize;
370        } else {
371            numLostBytes = 0;
372        }
373        MediaBuffer *lostAudioBuffer = new MediaBuffer(bufferSize);
374        memset(lostAudioBuffer->data(), 0, bufferSize);
375        lostAudioBuffer->set_range(0, bufferSize);
376        mNumFramesLost += bufferSize / mRecord->frameSize();
377        queueInputBuffer_l(lostAudioBuffer, timeUs);
378    }
379
380    if (audioBuffer.size == 0) {
381        ALOGW("Nothing is available from AudioRecord callback buffer");
382        return OK;
383    }
384
385    MediaBuffer *buffer = new MediaBuffer(bufferSize);
386    memcpy((uint8_t *) buffer->data(),
387            audioBuffer.i16, audioBuffer.size);
388    buffer->set_range(0, bufferSize);
389    queueInputBuffer_l(buffer, timeUs);
390    return OK;
391}
392
393void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
394    const size_t bufferSize = buffer->range_length();
395    const size_t frameSize = mRecord->frameSize();
396    const int64_t timestampUs =
397                mPrevSampleTimeUs +
398                    ((1000000LL * (bufferSize / frameSize)) +
399                        (mSampleRate >> 1)) / mSampleRate;
400
401    if (mNumFramesReceived == 0) {
402        buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
403    }
404
405    buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
406    buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
407    mPrevSampleTimeUs = timestampUs;
408    mNumFramesReceived += bufferSize / frameSize;
409    mBuffersReceived.push_back(buffer);
410    mFrameAvailableCondition.signal();
411}
412
413void AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) {
414    for (int i = nSamples; i > 0; --i) {
415        int16_t value = *data++;
416        if (value < 0) {
417            value = -value;
418        }
419        if (mMaxAmplitude < value) {
420            mMaxAmplitude = value;
421        }
422    }
423}
424
425int16_t AudioSource::getMaxAmplitude() {
426    // First call activates the tracking.
427    if (!mTrackMaxAmplitude) {
428        mTrackMaxAmplitude = true;
429    }
430    int16_t value = mMaxAmplitude;
431    mMaxAmplitude = 0;
432    ALOGV("max amplitude since last call: %d", value);
433    return value;
434}
435
436}  // namespace android
437