diff --git a/NEWS b/NEWS index ab7465171..2e86cc75e 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ ver 0.21 (not yet released) - "find" and "search" can sort * tags - new tag "OriginalDate" +* decoder + - pcm: support audio/L24 (RFC 3190) * output - alsa: non-blocking mode diff --git a/src/decoder/plugins/PcmDecoderPlugin.cxx b/src/decoder/plugins/PcmDecoderPlugin.cxx index 421fc3a81..22e34c193 100644 --- a/src/decoder/plugins/PcmDecoderPlugin.cxx +++ b/src/decoder/plugins/PcmDecoderPlugin.cxx @@ -21,6 +21,7 @@ #include "PcmDecoderPlugin.hxx" #include "../DecoderAPI.hxx" #include "CheckAudioFormat.hxx" +#include "pcm/PcmPack.hxx" #include "input/InputStream.hxx" #include "system/ByteOrder.hxx" #include "util/Domain.hxx" @@ -67,13 +68,18 @@ pcm_stream_decode(DecoderClient &client, InputStream &is) const bool l16 = mime != nullptr && GetMimeTypeBase(mime) == "audio/L16"; + const bool l24 = mime != nullptr && + GetMimeTypeBase(mime) == "audio/L24"; const bool is_float = mime != nullptr && GetMimeTypeBase(mime) == "audio/x-mpd-float"; - if (l16 || is_float) { + if (l16 || l24 || is_float) { audio_format.sample_rate = 0; audio_format.channels = 1; } + if (l24) + audio_format.format = SampleFormat::S24_P32; + const bool reverse_endian = (l16 && IsLittleEndian()) || (mime != nullptr && strcmp(mime, "audio/x-mpd-cdda-pcm-reverse") == 0); @@ -149,6 +155,10 @@ pcm_stream_decode(DecoderClient &client, InputStream &is) StaticFifoBuffer buffer; + /* a buffer for pcm_unpack_24be() large enough to hold the + results for a full source buffer */ + int32_t unpack_buffer[buffer.GetCapacity() / 3]; + DecoderCommand cmd; do { if (!FillBuffer(client, is, buffer)) @@ -166,6 +176,14 @@ pcm_stream_decode(DecoderClient &client, InputStream &is) reverse_bytes_16((uint16_t *)r.data, (uint16_t *)r.data, (uint16_t *)(r.data + r.size)); + else if (l24) { + /* convert big-endian packed 24 bit + (audio/L24) to native-endian 24 bit (in 32 + bit integers) */ + pcm_unpack_24be(unpack_buffer, r.begin(), r.end()); + r.data = (uint8_t *)&unpack_buffer[0]; + r.size = (r.size / 3) * 4; + } cmd = !r.IsEmpty() ? client.SubmitData(is, r.data, r.size, 0) @@ -192,6 +210,9 @@ static const char *const pcm_mime_types[] = { /* RFC 2586 */ "audio/L16", + /* RFC 3190 */ + "audio/L24", + /* MPD-specific: float32 native-endian */ "audio/x-mpd-float",