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