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
AudioOutput(const char * alsa_name,enum pcm_format alsa_pcm_format)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
~AudioOutput()69 AudioOutput::~AudioOutput() {
70 cleanupResources();
71 delete[] mStagingBuf;
72 }
73
initCheck()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
setupInternal()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
primeOutput(bool hasActiveOutputs)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
adjustDelay(int32_t nFrames)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
pushSilence(uint32_t nFrames)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
stageChunk(const uint8_t * chunkData,uint8_t * sbuf,uint32_t inBytesPerSample,uint32_t nSamples)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
cleanupResources()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
openPCMDevice()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
getNextWriteTimestamp(int64_t * timestamp,bool * discon)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
getLastNextWriteTSValid() const322 bool AudioOutput::getLastNextWriteTSValid() const {
323 return mLastNextWriteTimeValid;
324 }
325
getLastNextWriteTS() const326 int64_t AudioOutput::getLastNextWriteTS() const {
327 return mLastNextWriteTime;
328 }
329
getExternalDelay_uSec() const330 uint32_t AudioOutput::getExternalDelay_uSec() const {
331 return mExternalDelayUSec;
332 }
333
setExternalDelay_uSec(uint32_t delay_usec)334 void AudioOutput::setExternalDelay_uSec(uint32_t delay_usec) {
335 mExternalDelayUSec = delay_usec;
336 }
337
reset()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
getDMAStartData(int64_t * dma_start_time,int64_t * frames_queued_to_driver)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
processOneChunk(const uint8_t * data,size_t len,bool hasActiveOutputs)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
convert_16PCM_to_24PCM(const void * input,void * output,int ipbytes)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
doPCMWrite(const uint8_t * data,size_t len)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
setVolume(float vol)492 void AudioOutput::setVolume(float vol) {
493 Mutex::Autolock _l(mVolumeLock);
494 if (mVolume != vol) {
495 mVolume = vol;
496 mVolParamsDirty = true;
497 }
498 }
499
setMute(bool mute)500 void AudioOutput::setMute(bool mute) {
501 Mutex::Autolock _l(mVolumeLock);
502 if (mMute != mute) {
503 mMute = mute;
504 mVolParamsDirty = true;
505 }
506 }
507
setOutputIsFixed(bool fixed)508 void AudioOutput::setOutputIsFixed(bool fixed) {
509 Mutex::Autolock _l(mVolumeLock);
510 if (mOutputFixed != fixed) {
511 mOutputFixed = fixed;
512 mVolParamsDirty = true;
513 }
514 }
515
setFixedOutputLevel(float level)516 void AudioOutput::setFixedOutputLevel(float level) {
517 Mutex::Autolock _l(mVolumeLock);
518 if (mFixedLvl != level) {
519 mFixedLvl = level;
520 mVolParamsDirty = true;
521 }
522 }
523
getHardwareTimestamp(size_t * pAvail,struct timespec * pTimestamp)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