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