diff --git a/mythtv/libs/libmyth/audio/audiooutputalsa.cpp b/mythtv/libs/libmyth/audio/audiooutputalsa.cpp
index f8bc384..ff15bbc 100644
a
|
b
|
AudioOutputALSA::AudioOutputALSA(const AudioSettings &settings) : |
34 | 34 | m_pbufsize(-1), |
35 | 35 | m_card(-1), |
36 | 36 | m_device(-1), |
37 | | m_subdevice(-1) |
| 37 | m_subdevice(-1), |
| 38 | m_s24_3bytes(false) |
38 | 39 | { |
39 | 40 | m_mixer.handle = NULL; |
40 | 41 | m_mixer.elem = NULL; |
… |
… |
AudioOutputSettings* AudioOutputALSA::GetOutputSettings(bool passthrough) |
382 | 383 | default: continue; |
383 | 384 | } |
384 | 385 | if (snd_pcm_hw_params_test_format(pcm_handle, params, afmt) >= 0) |
| 386 | { |
385 | 387 | settings->AddSupportedFormat(fmt); |
| 388 | m_s24_3bytes = true; |
| 389 | } |
| 390 | else if (fmt == FORMAT_S24LSB) |
| 391 | { |
| 392 | #if HAVE_BIGENDIAN |
| 393 | afmt = SND_PCM_FORMAT_S24_3BE; |
| 394 | #else |
| 395 | afmt = SND_PCM_FORMAT_S24_3LE; |
| 396 | #endif |
| 397 | if (snd_pcm_hw_params_test_format(pcm_handle, params, afmt) >= 0) |
| 398 | { |
| 399 | settings->AddSupportedFormat(fmt); |
| 400 | m_s24_3bytes = true; |
| 401 | VBAUDIO("S24 3 bytes format supported"); |
| 402 | } |
| 403 | else |
| 404 | { |
| 405 | m_s24_3bytes = false; |
| 406 | } |
| 407 | } |
386 | 408 | } |
387 | 409 | |
388 | 410 | for (uint channels = CHANNELS_MIN; channels <= CHANNELS_MAX; channels++) |
… |
… |
bool AudioOutputALSA::OpenDevice() |
470 | 492 | { |
471 | 493 | case FORMAT_U8: format = SND_PCM_FORMAT_U8; break; |
472 | 494 | case FORMAT_S16: format = SND_PCM_FORMAT_S16; break; |
473 | | case FORMAT_S24LSB: format = SND_PCM_FORMAT_S24; break; |
| 495 | case FORMAT_S24LSB: |
| 496 | if (m_s24_3bytes) |
| 497 | { |
| 498 | #if HAVE_BIGENDIAN |
| 499 | format = SND_PCM_FORMAT_S24_3BE; |
| 500 | #else |
| 501 | format = SND_PCM_FORMAT_S24_3LE; |
| 502 | #endif |
| 503 | } |
| 504 | else |
| 505 | { |
| 506 | format = SND_PCM_FORMAT_S24; |
| 507 | } |
| 508 | break; |
474 | 509 | case FORMAT_S24: format = SND_PCM_FORMAT_S32; break; |
475 | 510 | case FORMAT_S32: format = SND_PCM_FORMAT_S32; break; |
476 | 511 | case FORMAT_FLT: format = SND_PCM_FORMAT_FLOAT; break; |
… |
… |
static inline void ReorderSmpteToAlsa(void *buf, uint frames, |
543 | 578 | } |
544 | 579 | } |
545 | 580 | |
| 581 | static inline void ConvertS24To3Bytes(uchar *buf, uint samples) |
| 582 | { |
| 583 | int *bufi = (int *)buf; |
| 584 | |
| 585 | for (uint i = 0; i < samples; i++) |
| 586 | { |
| 587 | int *tmpi = (int *)buf; |
| 588 | |
| 589 | *tmpi = *bufi; |
| 590 | bufi++; |
| 591 | buf += 3; |
| 592 | } |
| 593 | } |
| 594 | |
546 | 595 | void AudioOutputALSA::WriteAudio(uchar *aubuf, int size) |
547 | 596 | { |
548 | 597 | uchar *tmpbuf = aubuf; |
549 | 598 | uint frames = size / output_bytes_per_frame; |
550 | 599 | int err, lw = 0; |
| 600 | bool s243bytes = false; |
551 | 601 | |
552 | 602 | if (pcm_handle == NULL) |
553 | 603 | { |
… |
… |
void AudioOutputALSA::WriteAudio(uchar *aubuf, int size) |
561 | 611 | ReorderSmpteToAlsa(aubuf, frames, output_format, channels - 6); |
562 | 612 | } |
563 | 613 | |
| 614 | if (output_format == FORMAT_S24LSB && m_s24_3bytes) |
| 615 | { |
| 616 | // Handle special format where ALSA expects |
| 617 | s243bytes = true; |
| 618 | ConvertS24To3Bytes(aubuf, frames * channels); |
| 619 | } |
| 620 | |
564 | 621 | LOG(VB_AUDIO | VB_TIMESTAMP, LOG_INFO, |
565 | 622 | QString("WriteAudio: Preparing %1 bytes (%2 frames)") |
566 | 623 | .arg(size).arg(frames)); |
… |
… |
void AudioOutputALSA::WriteAudio(uchar *aubuf, int size) |
576 | 633 | .arg(lw * output_bytes_per_frame)); |
577 | 634 | |
578 | 635 | frames -= lw; |
579 | | tmpbuf += lw * output_bytes_per_frame; // bytes |
| 636 | tmpbuf += |
| 637 | lw * (s243bytes ? channels * 3 : output_bytes_per_frame); // bytes |
580 | 638 | continue; |
581 | 639 | } |
582 | 640 | |
diff --git a/mythtv/libs/libmyth/audio/audiooutputalsa.h b/mythtv/libs/libmyth/audio/audiooutputalsa.h
index b9ec580..b8536f7 100644
a
|
b
|
class AudioOutputALSA : public AudioOutputBase |
58 | 58 | long volrange; |
59 | 59 | } m_mixer; |
60 | 60 | |
| 61 | bool m_s24_3bytes; |
61 | 62 | }; |
62 | 63 | #endif |