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