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