decoder/pcm: support audio/L24

Closes #31
This commit is contained in:
Max Kellermann 2017-04-22 08:47:49 +02:00
parent 8b0269c264
commit b0ce551523
2 changed files with 24 additions and 1 deletions

2
NEWS
View File

@ -4,6 +4,8 @@ ver 0.21 (not yet released)
- "find" and "search" can sort - "find" and "search" can sort
* tags * tags
- new tag "OriginalDate" - new tag "OriginalDate"
* decoder
- pcm: support audio/L24 (RFC 3190)
* output * output
- alsa: non-blocking mode - alsa: non-blocking mode

View File

@ -21,6 +21,7 @@
#include "PcmDecoderPlugin.hxx" #include "PcmDecoderPlugin.hxx"
#include "../DecoderAPI.hxx" #include "../DecoderAPI.hxx"
#include "CheckAudioFormat.hxx" #include "CheckAudioFormat.hxx"
#include "pcm/PcmPack.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "system/ByteOrder.hxx" #include "system/ByteOrder.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
@ -67,13 +68,18 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
const bool l16 = mime != nullptr && const bool l16 = mime != nullptr &&
GetMimeTypeBase(mime) == "audio/L16"; GetMimeTypeBase(mime) == "audio/L16";
const bool l24 = mime != nullptr &&
GetMimeTypeBase(mime) == "audio/L24";
const bool is_float = mime != nullptr && const bool is_float = mime != nullptr &&
GetMimeTypeBase(mime) == "audio/x-mpd-float"; GetMimeTypeBase(mime) == "audio/x-mpd-float";
if (l16 || is_float) { if (l16 || l24 || is_float) {
audio_format.sample_rate = 0; audio_format.sample_rate = 0;
audio_format.channels = 1; audio_format.channels = 1;
} }
if (l24)
audio_format.format = SampleFormat::S24_P32;
const bool reverse_endian = (l16 && IsLittleEndian()) || const bool reverse_endian = (l16 && IsLittleEndian()) ||
(mime != nullptr && (mime != nullptr &&
strcmp(mime, "audio/x-mpd-cdda-pcm-reverse") == 0); strcmp(mime, "audio/x-mpd-cdda-pcm-reverse") == 0);
@ -149,6 +155,10 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
StaticFifoBuffer<uint8_t, 4096> buffer; StaticFifoBuffer<uint8_t, 4096> 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; DecoderCommand cmd;
do { do {
if (!FillBuffer(client, is, buffer)) if (!FillBuffer(client, is, buffer))
@ -166,6 +176,14 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
reverse_bytes_16((uint16_t *)r.data, reverse_bytes_16((uint16_t *)r.data,
(uint16_t *)r.data, (uint16_t *)r.data,
(uint16_t *)(r.data + r.size)); (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() cmd = !r.IsEmpty()
? client.SubmitData(is, r.data, r.size, 0) ? client.SubmitData(is, r.data, r.size, 0)
@ -192,6 +210,9 @@ static const char *const pcm_mime_types[] = {
/* RFC 2586 */ /* RFC 2586 */
"audio/L16", "audio/L16",
/* RFC 3190 */
"audio/L24",
/* MPD-specific: float32 native-endian */ /* MPD-specific: float32 native-endian */
"audio/x-mpd-float", "audio/x-mpd-float",