AudioRecord.cpp revision 6100d2d60517ff33ed8eb35d0b7ea63cde0831c9
1/* 2** 3** Copyright 2008, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18//#define LOG_NDEBUG 0 19#define LOG_TAG "AudioRecord" 20 21#include <stdint.h> 22#include <sys/types.h> 23 24#include <sched.h> 25#include <sys/resource.h> 26 27#include <private/media/AudioTrackShared.h> 28 29#include <media/AudioSystem.h> 30#include <media/AudioRecord.h> 31#include <media/mediarecorder.h> 32 33#include <binder/IServiceManager.h> 34#include <utils/Log.h> 35#include <binder/MemoryDealer.h> 36#include <binder/Parcel.h> 37#include <binder/IPCThreadState.h> 38#include <utils/Timers.h> 39#include <cutils/atomic.h> 40 41#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) 42#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 43 44namespace android { 45 46// --------------------------------------------------------------------------- 47 48AudioRecord::AudioRecord() 49 : mStatus(NO_INIT) 50{ 51} 52 53AudioRecord::AudioRecord( 54 int inputSource, 55 uint32_t sampleRate, 56 int format, 57 uint32_t channels, 58 int frameCount, 59 uint32_t flags, 60 callback_t cbf, 61 void* user, 62 int notificationFrames) 63 : mStatus(NO_INIT) 64{ 65 mStatus = set(inputSource, sampleRate, format, channels, 66 frameCount, flags, cbf, user, notificationFrames); 67} 68 69AudioRecord::~AudioRecord() 70{ 71 if (mStatus == NO_ERROR) { 72 // Make sure that callback function exits in the case where 73 // it is looping on buffer empty condition in obtainBuffer(). 74 // Otherwise the callback thread will never exit. 75 stop(); 76 if (mClientRecordThread != 0) { 77 mClientRecordThread->requestExitAndWait(); 78 mClientRecordThread.clear(); 79 } 80 mAudioRecord.clear(); 81 IPCThreadState::self()->flushCommands(); 82 } 83} 84 85status_t AudioRecord::set( 86 int inputSource, 87 uint32_t sampleRate, 88 int format, 89 uint32_t channels, 90 int frameCount, 91 uint32_t flags, 92 callback_t cbf, 93 void* user, 94 int notificationFrames, 95 bool threadCanCallJava) 96{ 97 98 LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount); 99 if (mAudioRecord != 0) { 100 return INVALID_OPERATION; 101 } 102 103 if (inputSource == AUDIO_SOURCE_DEFAULT) { 104 inputSource = AUDIO_SOURCE_MIC; 105 } 106 107 if (sampleRate == 0) { 108 sampleRate = DEFAULT_SAMPLE_RATE; 109 } 110 // these below should probably come from the audioFlinger too... 111 if (format == 0) { 112 format = AudioSystem::PCM_16_BIT; 113 } 114 // validate parameters 115 if (!AudioSystem::isValidFormat(format)) { 116 LOGE("Invalid format"); 117 return BAD_VALUE; 118 } 119 120 if (!AudioSystem::isInputChannel(channels)) { 121 return BAD_VALUE; 122 } 123 int channelCount = AudioSystem::popCount(channels); 124 125 audio_io_handle_t input = AudioSystem::getInput(inputSource, 126 sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags); 127 if (input == 0) { 128 LOGE("Could not get audio output for stream type %d", inputSource); 129 return BAD_VALUE; 130 } 131 132 // validate framecount 133 size_t inputBuffSizeInBytes = -1; 134 if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes) 135 != NO_ERROR) { 136 LOGE("AudioSystem could not query the input buffer size."); 137 return NO_INIT; 138 } 139 140 if (inputBuffSizeInBytes == 0) { 141 LOGE("Recording parameters are not supported: sampleRate %d, channelCount %d, format %d", 142 sampleRate, channelCount, format); 143 return BAD_VALUE; 144 } 145 146 int frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1); 147 if (AudioSystem::isLinearPCM(format)) { 148 frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? sizeof(int16_t) : sizeof(int8_t)); 149 } else { 150 frameSizeInBytes = sizeof(int8_t); 151 } 152 153 154 // We use 2* size of input buffer for ping pong use of record buffer. 155 int minFrameCount = 2 * inputBuffSizeInBytes / frameSizeInBytes; 156 LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 157 158 if (frameCount == 0) { 159 frameCount = minFrameCount; 160 } else if (frameCount < minFrameCount) { 161 return BAD_VALUE; 162 } 163 164 if (notificationFrames == 0) { 165 notificationFrames = frameCount/2; 166 } 167 168 // create the IAudioRecord 169 status_t status = openRecord(sampleRate, format, channelCount, 170 frameCount, flags, input); 171 172 if (status != NO_ERROR) { 173 return status; 174 } 175 176 if (cbf != 0) { 177 mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); 178 if (mClientRecordThread == 0) { 179 return NO_INIT; 180 } 181 } 182 183 mStatus = NO_ERROR; 184 185 mFormat = format; 186 // Update buffer size in case it has been limited by AudioFlinger during track creation 187 mFrameCount = mCblk->frameCount; 188 mChannelCount = (uint8_t)channelCount; 189 mChannels = channels; 190 mActive = 0; 191 mCbf = cbf; 192 mNotificationFrames = notificationFrames; 193 mRemainingFrames = notificationFrames; 194 mUserData = user; 195 // TODO: add audio hardware input latency here 196 mLatency = (1000*mFrameCount) / sampleRate; 197 mMarkerPosition = 0; 198 mMarkerReached = false; 199 mNewPosition = 0; 200 mUpdatePeriod = 0; 201 mInputSource = (uint8_t)inputSource; 202 mFlags = flags; 203 204 return NO_ERROR; 205} 206 207status_t AudioRecord::initCheck() const 208{ 209 return mStatus; 210} 211 212// ------------------------------------------------------------------------- 213 214uint32_t AudioRecord::latency() const 215{ 216 return mLatency; 217} 218 219int AudioRecord::format() const 220{ 221 return mFormat; 222} 223 224int AudioRecord::channelCount() const 225{ 226 return mChannelCount; 227} 228 229uint32_t AudioRecord::frameCount() const 230{ 231 return mFrameCount; 232} 233 234int AudioRecord::frameSize() const 235{ 236 if (AudioSystem::isLinearPCM(mFormat)) { 237 return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); 238 } else { 239 return sizeof(uint8_t); 240 } 241} 242 243int AudioRecord::inputSource() const 244{ 245 return (int)mInputSource; 246} 247 248// ------------------------------------------------------------------------- 249 250status_t AudioRecord::start() 251{ 252 status_t ret = NO_ERROR; 253 sp<ClientRecordThread> t = mClientRecordThread; 254 255 LOGV("start"); 256 257 if (t != 0) { 258 if (t->exitPending()) { 259 if (t->requestExitAndWait() == WOULD_BLOCK) { 260 LOGE("AudioRecord::start called from thread"); 261 return WOULD_BLOCK; 262 } 263 } 264 t->mLock.lock(); 265 } 266 267 if (android_atomic_or(1, &mActive) == 0) { 268 ret = mAudioRecord->start(); 269 if (ret == DEAD_OBJECT) { 270 LOGV("start() dead IAudioRecord: creating a new one"); 271 ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount, 272 mFrameCount, mFlags, getInput()); 273 if (ret == NO_ERROR) { 274 ret = mAudioRecord->start(); 275 } 276 } 277 if (ret == NO_ERROR) { 278 mNewPosition = mCblk->user + mUpdatePeriod; 279 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 280 mCblk->waitTimeMs = 0; 281 if (t != 0) { 282 t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT); 283 } else { 284 setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); 285 } 286 } else { 287 LOGV("start() failed"); 288 android_atomic_and(~1, &mActive); 289 } 290 } 291 292 if (t != 0) { 293 t->mLock.unlock(); 294 } 295 296 return ret; 297} 298 299status_t AudioRecord::stop() 300{ 301 sp<ClientRecordThread> t = mClientRecordThread; 302 303 LOGV("stop"); 304 305 if (t != 0) { 306 t->mLock.lock(); 307 } 308 309 if (android_atomic_and(~1, &mActive) == 1) { 310 mCblk->cv.signal(); 311 mAudioRecord->stop(); 312 // the record head position will reset to 0, so if a marker is set, we need 313 // to activate it again 314 mMarkerReached = false; 315 if (t != 0) { 316 t->requestExit(); 317 } else { 318 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 319 } 320 } 321 322 if (t != 0) { 323 t->mLock.unlock(); 324 } 325 326 return NO_ERROR; 327} 328 329bool AudioRecord::stopped() const 330{ 331 return !mActive; 332} 333 334uint32_t AudioRecord::getSampleRate() 335{ 336 return mCblk->sampleRate; 337} 338 339status_t AudioRecord::setMarkerPosition(uint32_t marker) 340{ 341 if (mCbf == 0) return INVALID_OPERATION; 342 343 mMarkerPosition = marker; 344 mMarkerReached = false; 345 346 return NO_ERROR; 347} 348 349status_t AudioRecord::getMarkerPosition(uint32_t *marker) 350{ 351 if (marker == 0) return BAD_VALUE; 352 353 *marker = mMarkerPosition; 354 355 return NO_ERROR; 356} 357 358status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 359{ 360 if (mCbf == 0) return INVALID_OPERATION; 361 362 uint32_t curPosition; 363 getPosition(&curPosition); 364 mNewPosition = curPosition + updatePeriod; 365 mUpdatePeriod = updatePeriod; 366 367 return NO_ERROR; 368} 369 370status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) 371{ 372 if (updatePeriod == 0) return BAD_VALUE; 373 374 *updatePeriod = mUpdatePeriod; 375 376 return NO_ERROR; 377} 378 379status_t AudioRecord::getPosition(uint32_t *position) 380{ 381 if (position == 0) return BAD_VALUE; 382 383 *position = mCblk->user; 384 385 return NO_ERROR; 386} 387 388 389// ------------------------------------------------------------------------- 390 391status_t AudioRecord::openRecord( 392 uint32_t sampleRate, 393 int format, 394 int channelCount, 395 int frameCount, 396 uint32_t flags, 397 audio_io_handle_t input) 398{ 399 status_t status; 400 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 401 if (audioFlinger == 0) { 402 return NO_INIT; 403 } 404 405 sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 406 sampleRate, format, 407 channelCount, 408 frameCount, 409 ((uint16_t)flags) << 16, 410 &status); 411 if (record == 0) { 412 LOGE("AudioFlinger could not create record track, status: %d", status); 413 return status; 414 } 415 sp<IMemory> cblk = record->getCblk(); 416 if (cblk == 0) { 417 LOGE("Could not get control block"); 418 return NO_INIT; 419 } 420 mAudioRecord.clear(); 421 mAudioRecord = record; 422 mCblkMemory.clear(); 423 mCblkMemory = cblk; 424 mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 425 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 426 mCblk->out = 0; 427 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 428 mCblk->waitTimeMs = 0; 429 return NO_ERROR; 430} 431 432status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 433{ 434 int active; 435 status_t result; 436 audio_track_cblk_t* cblk = mCblk; 437 uint32_t framesReq = audioBuffer->frameCount; 438 uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 439 440 audioBuffer->frameCount = 0; 441 audioBuffer->size = 0; 442 443 uint32_t framesReady = cblk->framesReady(); 444 445 if (framesReady == 0) { 446 cblk->lock.lock(); 447 goto start_loop_here; 448 while (framesReady == 0) { 449 active = mActive; 450 if (UNLIKELY(!active)) { 451 cblk->lock.unlock(); 452 return NO_MORE_BUFFERS; 453 } 454 if (UNLIKELY(!waitCount)) { 455 cblk->lock.unlock(); 456 return WOULD_BLOCK; 457 } 458 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 459 if (__builtin_expect(result!=NO_ERROR, false)) { 460 cblk->waitTimeMs += waitTimeMs; 461 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 462 LOGW( "obtainBuffer timed out (is the CPU pegged?) " 463 "user=%08x, server=%08x", cblk->user, cblk->server); 464 cblk->lock.unlock(); 465 result = mAudioRecord->start(); 466 if (result == DEAD_OBJECT) { 467 LOGW("obtainBuffer() dead IAudioRecord: creating a new one"); 468 result = openRecord(cblk->sampleRate, mFormat, mChannelCount, 469 mFrameCount, mFlags, getInput()); 470 if (result == NO_ERROR) { 471 cblk = mCblk; 472 mAudioRecord->start(); 473 } 474 } 475 cblk->lock.lock(); 476 cblk->waitTimeMs = 0; 477 } 478 if (--waitCount == 0) { 479 cblk->lock.unlock(); 480 return TIMED_OUT; 481 } 482 } 483 // read the server count again 484 start_loop_here: 485 framesReady = cblk->framesReady(); 486 } 487 cblk->lock.unlock(); 488 } 489 490 cblk->waitTimeMs = 0; 491 492 if (framesReq > framesReady) { 493 framesReq = framesReady; 494 } 495 496 uint32_t u = cblk->user; 497 uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 498 499 if (u + framesReq > bufferEnd) { 500 framesReq = bufferEnd - u; 501 } 502 503 audioBuffer->flags = 0; 504 audioBuffer->channelCount= mChannelCount; 505 audioBuffer->format = mFormat; 506 audioBuffer->frameCount = framesReq; 507 audioBuffer->size = framesReq*cblk->frameSize; 508 audioBuffer->raw = (int8_t*)cblk->buffer(u); 509 active = mActive; 510 return active ? status_t(NO_ERROR) : status_t(STOPPED); 511} 512 513void AudioRecord::releaseBuffer(Buffer* audioBuffer) 514{ 515 audio_track_cblk_t* cblk = mCblk; 516 cblk->stepUser(audioBuffer->frameCount); 517} 518 519audio_io_handle_t AudioRecord::getInput() 520{ 521 return AudioSystem::getInput(mInputSource, 522 mCblk->sampleRate, 523 mFormat, mChannels, 524 (AudioSystem::audio_in_acoustics)mFlags); 525} 526 527// ------------------------------------------------------------------------- 528 529ssize_t AudioRecord::read(void* buffer, size_t userSize) 530{ 531 ssize_t read = 0; 532 Buffer audioBuffer; 533 int8_t *dst = static_cast<int8_t*>(buffer); 534 535 if (ssize_t(userSize) < 0) { 536 // sanity-check. user is most-likely passing an error code. 537 LOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 538 buffer, userSize, userSize); 539 return BAD_VALUE; 540 } 541 542 LOGV("read size: %d", userSize); 543 544 do { 545 546 audioBuffer.frameCount = userSize/frameSize(); 547 548 // Calling obtainBuffer() with a negative wait count causes 549 // an (almost) infinite wait time. 550 status_t err = obtainBuffer(&audioBuffer, -1); 551 if (err < 0) { 552 // out of buffers, return #bytes written 553 if (err == status_t(NO_MORE_BUFFERS)) 554 break; 555 return ssize_t(err); 556 } 557 558 size_t bytesRead = audioBuffer.size; 559 memcpy(dst, audioBuffer.i8, bytesRead); 560 561 dst += bytesRead; 562 userSize -= bytesRead; 563 read += bytesRead; 564 565 releaseBuffer(&audioBuffer); 566 } while (userSize); 567 568 return read; 569} 570 571// ------------------------------------------------------------------------- 572 573bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) 574{ 575 Buffer audioBuffer; 576 uint32_t frames = mRemainingFrames; 577 size_t readSize; 578 579 // Manage marker callback 580 if (!mMarkerReached && (mMarkerPosition > 0)) { 581 if (mCblk->user >= mMarkerPosition) { 582 mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 583 mMarkerReached = true; 584 } 585 } 586 587 // Manage new position callback 588 if (mUpdatePeriod > 0) { 589 while (mCblk->user >= mNewPosition) { 590 mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 591 mNewPosition += mUpdatePeriod; 592 } 593 } 594 595 do { 596 audioBuffer.frameCount = frames; 597 // Calling obtainBuffer() with a wait count of 1 598 // limits wait time to WAIT_PERIOD_MS. This prevents from being 599 // stuck here not being able to handle timed events (position, markers). 600 status_t err = obtainBuffer(&audioBuffer, 1); 601 if (err < NO_ERROR) { 602 if (err != TIMED_OUT) { 603 LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 604 return false; 605 } 606 break; 607 } 608 if (err == status_t(STOPPED)) return false; 609 610 size_t reqSize = audioBuffer.size; 611 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 612 readSize = audioBuffer.size; 613 614 // Sanity check on returned size 615 if (ssize_t(readSize) <= 0) { 616 // The callback is done filling buffers 617 // Keep this thread going to handle timed events and 618 // still try to get more data in intervals of WAIT_PERIOD_MS 619 // but don't just loop and block the CPU, so wait 620 usleep(WAIT_PERIOD_MS*1000); 621 break; 622 } 623 if (readSize > reqSize) readSize = reqSize; 624 625 audioBuffer.size = readSize; 626 audioBuffer.frameCount = readSize/frameSize(); 627 frames -= audioBuffer.frameCount; 628 629 releaseBuffer(&audioBuffer); 630 631 } while (frames); 632 633 634 // Manage overrun callback 635 if (mActive && (mCblk->framesAvailable_l() == 0)) { 636 LOGV("Overrun user: %x, server: %x, flowControlFlag %d", mCblk->user, mCblk->server, mCblk->flowControlFlag); 637 if (mCblk->flowControlFlag == 0) { 638 mCbf(EVENT_OVERRUN, mUserData, 0); 639 mCblk->flowControlFlag = 1; 640 } 641 } 642 643 if (frames == 0) { 644 mRemainingFrames = mNotificationFrames; 645 } else { 646 mRemainingFrames = frames; 647 } 648 return true; 649} 650 651// ========================================================================= 652 653AudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) 654 : Thread(bCanCallJava), mReceiver(receiver) 655{ 656} 657 658bool AudioRecord::ClientRecordThread::threadLoop() 659{ 660 return mReceiver.processAudioBuffer(this); 661} 662 663// ------------------------------------------------------------------------- 664 665}; // namespace android 666 667