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
AudioOutput(const char * alsa_name,enum pcm_format alsa_pcm_format)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
~AudioOutput()78 AudioOutput::~AudioOutput() {
79 cleanupResources();
80 free(mStagingBuf);
81 free(mSilenceBuf);
82 }
83
initCheck()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
setupInternal()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
primeOutput(bool hasActiveOutputs)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
adjustDelay(int32_t nFrames)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
pushSilence(uint32_t nFrames)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
cleanupResources()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
openPCMDevice()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
getNextWriteTimestamp(int64_t * timestamp,bool * discon)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
getLastNextWriteTSValid() const317 bool AudioOutput::getLastNextWriteTSValid() const {
318 return mLastNextWriteTimeValid;
319 }
320
getLastNextWriteTS() const321 int64_t AudioOutput::getLastNextWriteTS() const {
322 return mLastNextWriteTime;
323 }
324
getExternalDelay_uSec() const325 uint32_t AudioOutput::getExternalDelay_uSec() const {
326 return mExternalDelayUSec;
327 }
328
setExternalDelay_uSec(uint32_t delay_usec)329 void AudioOutput::setExternalDelay_uSec(uint32_t delay_usec) {
330 mExternalDelayUSec = delay_usec;
331 }
332
reset()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
getDMAStartData(int64_t * dma_start_time,int64_t * frames_queued_to_driver)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
processOneChunk(const uint8_t * data,size_t len,bool hasActiveOutputs,audio_format_t format)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
doPCMWrite(const uint8_t * data,size_t len,audio_format_t format)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
setVolume(float vol)480 void AudioOutput::setVolume(float vol) {
481 Mutex::Autolock _l(mVolumeLock);
482 if (mVolume != vol) {
483 mVolume = vol;
484 mVolParamsDirty = true;
485 }
486 }
487
setMute(bool mute)488 void AudioOutput::setMute(bool mute) {
489 Mutex::Autolock _l(mVolumeLock);
490 if (mMute != mute) {
491 mMute = mute;
492 mVolParamsDirty = true;
493 }
494 }
495
setOutputIsFixed(bool fixed)496 void AudioOutput::setOutputIsFixed(bool fixed) {
497 Mutex::Autolock _l(mVolumeLock);
498 if (mOutputFixed != fixed) {
499 mOutputFixed = fixed;
500 mVolParamsDirty = true;
501 }
502 }
503
setFixedOutputLevel(float level)504 void AudioOutput::setFixedOutputLevel(float level) {
505 Mutex::Autolock _l(mVolumeLock);
506 if (mFixedLvl != level) {
507 mFixedLvl = level;
508 mVolParamsDirty = true;
509 }
510 }
511
getHardwareTimestamp(size_t * pAvail,struct timespec * pTimestamp)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