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