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