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