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