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