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