diff --git a/src/output/alsa_output_plugin.c b/src/output/alsa_output_plugin.c index cf3370d01..5107d0a94 100644 --- a/src/output/alsa_output_plugin.c +++ b/src/output/alsa_output_plugin.c @@ -674,9 +674,7 @@ alsa_open(struct audio_output *ao, struct audio_format *audio_format, GError **e } ad->in_frame_size = audio_format_frame_size(audio_format); - ad->out_frame_size = ad->export.pack24 - ? (size_t)(audio_format->channels * 3) - : ad->in_frame_size; + ad->out_frame_size = pcm_export_frame_size(&ad->export, audio_format); return true; } diff --git a/src/pcm_export.c b/src/pcm_export.c index e586b51d2..824b41b18 100644 --- a/src/pcm_export.c +++ b/src/pcm_export.c @@ -70,6 +70,27 @@ pcm_export_open(struct pcm_export_state *state, } } +size_t +pcm_export_frame_size(const struct pcm_export_state *state, + const struct audio_format *audio_format) +{ + assert(state != NULL); + assert(audio_format != NULL); + + if (state->pack24) + /* packed 24 bit samples (3 bytes per sample) */ + return audio_format->channels * 3; + + if (state->dsd_usb) + /* the DSD-over-USB draft says that DSD 1-bit samples + are enclosed within 24 bit samples, and MPD's + representation of 24 bit is padded to 32 bit (4 + bytes per sample) */ + return audio_format->channels * 4; + + return audio_format_frame_size(audio_format); +} + const void * pcm_export(struct pcm_export_state *state, const void *data, size_t size, size_t *dest_size_r) diff --git a/src/pcm_export.h b/src/pcm_export.h index 418dcdfa3..a7e7c3f68 100644 --- a/src/pcm_export.h +++ b/src/pcm_export.h @@ -114,6 +114,14 @@ pcm_export_open(struct pcm_export_state *state, enum sample_format sample_format, unsigned channels, bool dsd_usb, bool shift8, bool pack, bool reverse_endian); +/** + * Calculate the size of one output frame. + */ +G_GNUC_PURE +size_t +pcm_export_frame_size(const struct pcm_export_state *state, + const struct audio_format *audio_format); + /** * Export a PCM buffer. *