From 5b61e077e0e3d84f17a410d7327e2a7a73613aad Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 21 Mar 2012 20:43:33 +0100 Subject: pcm_export: add option "pack" Converts padded 24 bit samples to packed 24 bit samples. Will replace the packed S24 sample format, which is not used internally. --- src/output/alsa_output_plugin.c | 2 +- src/output/oss_output_plugin.c | 1 + src/pcm_export.c | 26 ++++++++++++++++++++++++-- src/pcm_export.h | 14 +++++++++++++- 4 files changed, 39 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/output/alsa_output_plugin.c b/src/output/alsa_output_plugin.c index 3788ba0f2..f8c34093b 100644 --- a/src/output/alsa_output_plugin.c +++ b/src/output/alsa_output_plugin.c @@ -525,7 +525,7 @@ configure_hw: ad->period_position = 0; pcm_export_open(&ad->export, audio_format->format, - reverse_endian); + false, reverse_endian); return true; diff --git a/src/output/oss_output_plugin.c b/src/output/oss_output_plugin.c index c32fceade..154930b38 100644 --- a/src/output/oss_output_plugin.c +++ b/src/output/oss_output_plugin.c @@ -536,6 +536,7 @@ oss_probe_sample_format(int fd, enum sample_format sample_format, #ifdef AFMT_S24_PACKED pcm_export_open(export, sample_format, + false, oss_format == AFMT_S24_PACKED && G_BYTE_ORDER != G_LITTLE_ENDIAN); #endif diff --git a/src/pcm_export.c b/src/pcm_export.c index 68b94b10a..0535358fc 100644 --- a/src/pcm_export.c +++ b/src/pcm_export.c @@ -19,6 +19,7 @@ #include "config.h" #include "pcm_export.h" +#include "pcm_pack.h" #include "util/byte_reverse.h" void @@ -35,11 +36,15 @@ void pcm_export_deinit(struct pcm_export_state *state) void pcm_export_open(struct pcm_export_state *state, enum sample_format sample_format, - bool reverse_endian) + bool pack, bool reverse_endian) { + state->pack24 = pack && sample_format == SAMPLE_FORMAT_S24_P32; + state->reverse_endian = 0; if (reverse_endian) { - size_t sample_size = sample_format_size(sample_format); + size_t sample_size = state->pack24 + ? 3 + : sample_format_size(sample_format); assert(sample_size <= 0xff); if (sample_size > 1) @@ -51,6 +56,23 @@ const void * pcm_export(struct pcm_export_state *state, const void *data, size_t size, size_t *dest_size_r) { + if (state->pack24) { + assert(size % 4 == 0); + + const size_t num_samples = size / 4; + const size_t dest_size = num_samples * 3; + + const uint8_t *src8 = data, *src_end8 = src8 + size; + uint8_t *dest = pcm_buffer_get(&state->pack_buffer, dest_size); + assert(dest != NULL); + + pcm_pack_24(dest, (const int32_t *)src8, + (const int32_t *)src_end8); + + data = dest; + size = dest_size; + } + if (state->reverse_endian > 0) { assert(state->reverse_endian >= 2); diff --git a/src/pcm_export.h b/src/pcm_export.h index 570092eb9..7dc9f5f03 100644 --- a/src/pcm_export.h +++ b/src/pcm_export.h @@ -34,6 +34,13 @@ struct audio_format; * representation which are not supported by the pcm_convert library. */ struct pcm_export_state { + /** + * The buffer used to pack samples, removing padding. + * + * @see #reverse_endian + */ + struct pcm_buffer pack_buffer; + /** * The buffer used to reverse the byte order. * @@ -41,6 +48,11 @@ struct pcm_export_state { */ struct pcm_buffer reverse_buffer; + /** + * Pack 24 bit samples? + */ + bool pack24; + /** * Export the samples in reverse byte order? A non-zero value * means the option is enabled and represents the size of each @@ -72,7 +84,7 @@ pcm_export_deinit(struct pcm_export_state *state); void pcm_export_open(struct pcm_export_state *state, enum sample_format sample_format, - bool reverse_endian); + bool pack, bool reverse_endian); /** * Export a PCM buffer. -- cgit v1.2.3