1 /* 2 ** 3 ** Copyright 2011, 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_TAG "AudioHAL:AudioOutput" 19 // #define LOG_NDEBUG 0 20 21 #include <utils/Log.h> 22 23 #include <assert.h> 24 #include <limits.h> 25 #include <semaphore.h> 26 #include <sys/ioctl.h> 27 28 #include <audio_utils/primitives.h> 29 #include <common_time/local_clock.h> 30 31 #define __DO_FUNCTION_IMPL__ 32 #include "alsa_utils.h" 33 #undef __DO_FUNCTION_IMPL__ 34 #include "AudioOutput.h" 35 36 // TODO: Consider using system/media/alsa_utils for the future. 37 38 namespace android { 39 40 const uint32_t AudioOutput::kMaxDelayCompensationMSec = 300; 41 const uint32_t AudioOutput::kPrimeTimeoutChunks = 10; // 100ms 42 43 AudioOutput::AudioOutput(const char* alsa_name, 44 enum pcm_format alsa_pcm_format) 45 : mState(OUT_OF_SYNC) 46 , mFramesPerChunk(0) 47 , mFramesPerSec(0) 48 , mBufferChunks(0) 49 , mChannelCnt(0) 50 , mALSAName(alsa_name) 51 , mALSAFormat(alsa_pcm_format) 52 , mBytesPerSample(0) 53 , mBytesPerFrame(0) 54 , mBytesPerChunk(0) 55 , mStagingSize(0) 56 , mStagingBuf(NULL) 57 , mSilenceSize(0) 58 , mSilenceBuf(NULL) 59 , mPrimeTimeoutChunks(0) 60 , mReportedWriteFail(false) 61 , mVolume(0.0) 62 , mFixedLvl(0.0) 63 , mMute(false) 64 , mOutputFixed(false) 65 , mVolParamsDirty(true) 66 { 67 mLastNextWriteTimeValid = false; 68 69 mMaxDelayCompFrames = 0; 70 mExternalDelayUSec = 0; 71 72 mDevice = NULL; 73 mDeviceExtFd = -1; 74 mALSACardID = -1; 75 mFramesQueuedToDriver = 0; 76 } 77 78 AudioOutput::~AudioOutput() { 79 cleanupResources(); 80 free(mStagingBuf); 81 free(mSilenceBuf); 82 } 83 84 status_t AudioOutput::initCheck() { 85 if (!mDevice) { 86 ALOGE("Unable to open PCM device for %s output.", getOutputName()); 87 return NO_INIT; 88 } 89 if (!pcm_is_ready(mDevice)) { 90 ALOGE("PCM device %s is not ready.", getOutputName()); 91 ALOGE("PCM error: %s", pcm_get_error(mDevice)); 92 return NO_INIT; 93 } 94 95 return OK; 96 } 97 98 void AudioOutput::setupInternal() { 99 LocalClock lc; 100 101 mMaxDelayCompFrames = kMaxDelayCompensationMSec * mFramesPerSec / 1000; 102 103 switch (mALSAFormat) { 104 case PCM_FORMAT_S16_LE: 105 mBytesPerSample = 2; 106 break; 107 case PCM_FORMAT_S24_3LE: 108 mBytesPerSample = 3; 109 break; 110 case PCM_FORMAT_S24_LE: // fall through 111 case PCM_FORMAT_S32_LE: 112 mBytesPerSample = 4; 113 break; 114 default: 115 LOG_ALWAYS_FATAL("Unexpected alsa format %d", mALSAFormat); 116 break; 117 } 118 119 mBytesPerFrame = mBytesPerSample * mChannelCnt; 120 mBytesPerChunk = mBytesPerFrame * mFramesPerChunk; 121 122 memset(&mFramesToLocalTime, 0, sizeof(mFramesToLocalTime)); 123 mFramesToLocalTime.a_to_b_numer = lc.getLocalFreq(); 124 mFramesToLocalTime.a_to_b_denom = mFramesPerSec ? mFramesPerSec : 1; 125 LinearTransform::reduce( 126 &mFramesToLocalTime.a_to_b_numer, 127 &mFramesToLocalTime.a_to_b_denom); 128 129 openPCMDevice(); 130 } 131 132 void AudioOutput::primeOutput(bool hasActiveOutputs) { 133 ALOGI("primeOutput %s", getOutputName()); 134 135 if (hasFatalError()) 136 return; 137 138 // See comments in AudioStreamOut::write for the reasons behind the 139 // different priming levels. 140 uint32_t primeAmt = mFramesPerChunk * mBufferChunks; 141 if (hasActiveOutputs) 142 primeAmt /= 2; 143 144 pushSilence(primeAmt); 145 mPrimeTimeoutChunks = 0; 146 mState = PRIMED; 147 } 148 149 void AudioOutput::adjustDelay(int32_t nFrames) { 150 if (hasFatalError()) 151 return; 152 153 if (nFrames >= 0) { 154 ALOGI("adjustDelay %s %d", getOutputName(), nFrames); 155 pushSilence(nFrames); 156 mState = ACTIVE; 157 } else { 158 ALOGW("adjustDelay %s %d, ignoring negative adjustment", 159 getOutputName(), nFrames); 160 } 161 } 162 163 void AudioOutput::pushSilence(uint32_t nFrames) 164 { 165 if (nFrames == 0 || hasFatalError()) 166 return; 167 // choose 8_24_BIT instead of 16_BIT as it is native to Fugu 168 const audio_format_t format = AUDIO_FORMAT_PCM_8_24_BIT; 169 const size_t frameSize = audio_bytes_per_sample(format) * mChannelCnt; 170 const size_t writeSize = nFrames * frameSize; 171 if (mSilenceSize < writeSize) { 172 // for zero initialized memory calloc is much faster than malloc or realloc. 173 void *sbuf = calloc(nFrames, frameSize); 174 if (sbuf == NULL) return; 175 free(mSilenceBuf); 176 mSilenceBuf = sbuf; 177 mSilenceSize = writeSize; 178 } 179 doPCMWrite((const uint8_t*)mSilenceBuf, writeSize, format); 180 mFramesQueuedToDriver += nFrames; 181 } 182 183 void AudioOutput::cleanupResources() { 184 185 Mutex::Autolock _l(mDeviceLock); 186 187 if (NULL != mDevice) 188 pcm_close(mDevice); 189 190 mDevice = NULL; 191 mDeviceExtFd = -1; 192 mALSACardID = -1; 193 } 194 195 void AudioOutput::openPCMDevice() { 196 197 Mutex::Autolock _l(mDeviceLock); 198 if (NULL == mDevice) { 199 struct pcm_config config; 200 int dev_id = 0; 201 int retry = 0; 202 static const int MAX_RETRY_COUNT = 3; 203 204 mALSACardID = find_alsa_card_by_name(mALSAName); 205 if (mALSACardID < 0) 206 return; 207 208 memset(&config, 0, sizeof(config)); 209 config.channels = mChannelCnt; 210 config.rate = mFramesPerSec; 211 config.period_size = mFramesPerChunk; 212 config.period_count = mBufferChunks; 213 config.format = mALSAFormat; 214 // start_threshold is in audio frames. The default behavior 215 // is to fill period_size*period_count frames before outputing 216 // audio. Setting to 1 will start the DMA immediately. Our first 217 // write is a full chunk, so we have 10ms to get back with the next 218 // chunk before we underflow. This number could be increased if 219 // problems arise. 220 config.start_threshold = 1; 221 222 ALOGI("calling pcm_open() for output, mALSACardID = %d, dev_id %d, rate = %u, " 223 "%d channels, framesPerChunk = %d, alsaFormat = %d", 224 mALSACardID, dev_id, config.rate, config.channels, config.period_size, config.format); 225 while (1) { 226 // Use PCM_MONOTONIC clock for get_presentation_position. 227 mDevice = pcm_open(mALSACardID, dev_id, 228 PCM_OUT | PCM_NORESTART | PCM_MONOTONIC, &config); 229 if (initCheck() == OK) 230 break; 231 if (retry++ >= MAX_RETRY_COUNT) { 232 ALOGI("out of retries, giving up"); 233 break; 234 } 235 /* try again after a delay. on hotplug, there appears to 236 * be a race where the pcm device node isn't available on 237 * first open try. 238 */ 239 pcm_close(mDevice); 240 mDevice = NULL; 241 sleep(1); 242 ALOGI("retrying pcm_open() after delay"); 243 } 244 mDeviceExtFd = mDevice 245 ? *(reinterpret_cast<int*>(mDevice)) 246 : -1; 247 mState = OUT_OF_SYNC; 248 } 249 } 250 251 status_t AudioOutput::getNextWriteTimestamp(int64_t* timestamp, 252 bool* discon) { 253 int64_t dma_start_time; 254 int64_t frames_queued_to_driver; 255 status_t ret; 256 257 *discon = false; 258 if (hasFatalError()) 259 return UNKNOWN_ERROR; 260 261 ret = getDMAStartData(&dma_start_time, 262 &frames_queued_to_driver); 263 if (OK != ret) { 264 if (mLastNextWriteTimeValid) { 265 if (!hasFatalError()) 266 ALOGE("Underflow detected for output \"%s\"", getOutputName()); 267 *discon = true; 268 } 269 270 goto bailout; 271 } 272 273 if (mLastNextWriteTimeValid && (mLastDMAStartTime != dma_start_time)) { 274 *discon = true; 275 ret = UNKNOWN_ERROR; 276 277 ALOGE("Discontinuous DMA start time detected for output \"%s\"." 278 "DMA start time is %lld, but last DMA start time was %lld.", 279 getOutputName(), dma_start_time, mLastDMAStartTime); 280 281 goto bailout; 282 } 283 284 mLastDMAStartTime = dma_start_time; 285 286 mFramesToLocalTime.a_zero = 0; 287 mFramesToLocalTime.b_zero = dma_start_time; 288 289 if (!mFramesToLocalTime.doForwardTransform(frames_queued_to_driver, 290 timestamp)) { 291 ALOGE("Overflow when attempting to compute next write time for output" 292 " \"%s\". Frames Queued To Driver = %lld, DMA Start Time = %lld", 293 getOutputName(), frames_queued_to_driver, dma_start_time); 294 ret = UNKNOWN_ERROR; 295 goto bailout; 296 } 297 298 mLastNextWriteTime = *timestamp; 299 mLastNextWriteTimeValid = true; 300 301 // If we have a valuid timestamp, DMA has started so advance the state. 302 if (mState == PRIMED) 303 mState = DMA_START; 304 305 return OK; 306 307 bailout: 308 mLastNextWriteTimeValid = false; 309 // If we underflow, reset this output now. 310 if (mState > PRIMED) { 311 reset(); 312 } 313 314 return ret; 315 } 316 317 bool AudioOutput::getLastNextWriteTSValid() const { 318 return mLastNextWriteTimeValid; 319 } 320 321 int64_t AudioOutput::getLastNextWriteTS() const { 322 return mLastNextWriteTime; 323 } 324 325 uint32_t AudioOutput::getExternalDelay_uSec() const { 326 return mExternalDelayUSec; 327 } 328 329 void AudioOutput::setExternalDelay_uSec(uint32_t delay_usec) { 330 mExternalDelayUSec = delay_usec; 331 } 332 333 void AudioOutput::reset() { 334 if (hasFatalError()) 335 return; 336 337 // Flush the driver level. 338 cleanupResources(); 339 openPCMDevice(); 340 mFramesQueuedToDriver = 0; 341 mLastNextWriteTimeValid = false; 342 343 if (OK == initCheck()) { 344 ALOGE("Reset %s", mALSAName); 345 } else { 346 ALOGE("Reset for %s failed, device is a zombie pending cleanup.", mALSAName); 347 cleanupResources(); 348 mState = FATAL; 349 } 350 } 351 352 status_t AudioOutput::getDMAStartData( 353 int64_t* dma_start_time, 354 int64_t* frames_queued_to_driver) { 355 int ret; 356 #if 1 /* not implemented in driver yet, just fake it */ 357 *dma_start_time = mLastDMAStartTime; 358 ret = 0; 359 #endif 360 361 // If the get start time ioctl fails with an error of EBADFD, then our 362 // underlying audio device is in the DISCONNECTED state. The only reason 363 // this should happen is that HDMI was unplugged while we were running, and 364 // the audio driver needed to immediately shut down the driver without 365 // involving the application level. We should enter the fatal state, and 366 // wait until the app level catches up to our view of the world (at which 367 // point in time we will go through a plug/unplug cycle which should clean 368 // things up). 369 if (ret < 0) { 370 if (EBADFD == errno) { 371 ALOGI("Failed to ioctl to %s, output is probably disconnected." 372 " Going into zombie state to await cleanup.", mALSAName); 373 cleanupResources(); 374 mState = FATAL; 375 } 376 377 return UNKNOWN_ERROR; 378 } 379 380 *frames_queued_to_driver = mFramesQueuedToDriver; 381 return OK; 382 } 383 384 void AudioOutput::processOneChunk(const uint8_t* data, size_t len, 385 bool hasActiveOutputs, audio_format_t format) { 386 switch (mState) { 387 case OUT_OF_SYNC: 388 primeOutput(hasActiveOutputs); 389 break; 390 case PRIMED: 391 if (mPrimeTimeoutChunks < kPrimeTimeoutChunks) 392 mPrimeTimeoutChunks++; 393 else 394 // Uh-oh, DMA didn't start. Reset and try again. 395 reset(); 396 397 break; 398 case DMA_START: 399 // Don't push data when primed and waiting for buffer alignment. 400 // We need to align the ALSA buffers first. 401 break; 402 case ACTIVE: { 403 doPCMWrite(data, len, format); 404 // we use input frame size here (mBytesPerFrame is alsa device frame size) 405 const size_t frameSize = mChannelCnt * audio_bytes_per_sample(format); 406 mFramesQueuedToDriver += len / frameSize; 407 } break; 408 default: 409 // Do nothing. 410 break; 411 } 412 413 } 414 415 void AudioOutput::doPCMWrite(const uint8_t* data, size_t len, audio_format_t format) { 416 if (len == 0 || hasFatalError()) 417 return; 418 419 // If write fails with an error of EBADFD, then our underlying audio 420 // device is in a pretty bad state. This common cause of this is 421 // that HDMI was unplugged while we were running, and the audio 422 // driver needed to immediately shut down the driver without 423 // involving the application level. When this happens, the HDMI 424 // audio device is put into the DISCONNECTED state, and calls to 425 // write will return EBADFD. 426 #if 1 427 /* Intel HDMI appears to be locked at 24bit PCM, but Android 428 * will send data in the format specified in adev_open_output_stream(). 429 */ 430 LOG_ALWAYS_FATAL_IF(mALSAFormat != PCM_FORMAT_S24_LE, 431 "Fugu alsa device format(%d) must be PCM_FORMAT_S24_LE", mALSAFormat); 432 433 int err = BAD_VALUE; 434 switch(format) { 435 case AUDIO_FORMAT_PCM_16_BIT: { 436 const size_t outputSize = len * 2; 437 if (outputSize > mStagingSize) { 438 void *buf = realloc(mStagingBuf, outputSize); 439 if (buf == NULL) { 440 ALOGE("%s: memory allocation for conversion buffer failed", __func__); 441 return; 442 } 443 mStagingBuf = buf; 444 mStagingSize = outputSize; 445 } 446 memcpy_to_q8_23_from_i16((int32_t*)mStagingBuf, (const int16_t*)data, len >> 1); 447 err = pcm_write(mDevice, mStagingBuf, outputSize); 448 } break; 449 case AUDIO_FORMAT_PCM_8_24_BIT: 450 err = pcm_write(mDevice, data, len); 451 break; 452 default: 453 LOG_ALWAYS_FATAL("Fugu input format(%#x) should be 16 bit or 8_24 bit pcm", format); 454 break; 455 } 456 457 #else 458 459 int err = pcm_write(mDevice, data, len); 460 #endif 461 if ((err < 0) && (EBADFD == errno)) { 462 ALOGI("Failed to write to %s, output is probably disconnected." 463 " Going into zombie state to await cleanup.", mALSAName); 464 cleanupResources(); 465 mState = FATAL; 466 } 467 else if (err < 0) { 468 ALOGW_IF(!mReportedWriteFail, "pcm_write failed err %d", err); 469 mReportedWriteFail = true; 470 } 471 else { 472 mReportedWriteFail = false; 473 #if 1 /* not implemented in driver yet, just fake it */ 474 LocalClock lc; 475 mLastDMAStartTime = lc.getLocalTime(); 476 #endif 477 } 478 } 479 480 void AudioOutput::setVolume(float vol) { 481 Mutex::Autolock _l(mVolumeLock); 482 if (mVolume != vol) { 483 mVolume = vol; 484 mVolParamsDirty = true; 485 } 486 } 487 488 void AudioOutput::setMute(bool mute) { 489 Mutex::Autolock _l(mVolumeLock); 490 if (mMute != mute) { 491 mMute = mute; 492 mVolParamsDirty = true; 493 } 494 } 495 496 void AudioOutput::setOutputIsFixed(bool fixed) { 497 Mutex::Autolock _l(mVolumeLock); 498 if (mOutputFixed != fixed) { 499 mOutputFixed = fixed; 500 mVolParamsDirty = true; 501 } 502 } 503 504 void AudioOutput::setFixedOutputLevel(float level) { 505 Mutex::Autolock _l(mVolumeLock); 506 if (mFixedLvl != level) { 507 mFixedLvl = level; 508 mVolParamsDirty = true; 509 } 510 } 511 512 int AudioOutput::getHardwareTimestamp(size_t *pAvail, 513 struct timespec *pTimestamp) 514 { 515 Mutex::Autolock _l(mDeviceLock); 516 if (!mDevice) { 517 ALOGW("pcm device unavailable - reinitialize timestamp"); 518 return -1; 519 } 520 return pcm_get_htimestamp(mDevice, pAvail, pTimestamp); 521 } 522 523 } // namespace android 524