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