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