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