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