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