diff options
author | Max Kellermann <max@duempel.org> | 2012-03-22 01:01:11 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2012-03-22 01:01:11 +0100 |
commit | 725fbe946b2466cbfb60ddedf50ae1ed968d36e5 (patch) | |
tree | d04017b754ba6071e4a52e9420030547b38674ab /src | |
parent | b99ecb4dc96f45c0e0ca4b47b82efea57a21f016 (diff) | |
download | mpd-725fbe946b2466cbfb60ddedf50ae1ed968d36e5.tar.gz mpd-725fbe946b2466cbfb60ddedf50ae1ed968d36e5.tar.xz mpd-725fbe946b2466cbfb60ddedf50ae1ed968d36e5.zip |
output/alsa: split the frame_size attribute
Make it in_frame_size and out_frame_size, to account for packing.
Diffstat (limited to 'src')
-rw-r--r-- | src/output/alsa_output_plugin.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/output/alsa_output_plugin.c b/src/output/alsa_output_plugin.c index 4825bce40..49b11c9b2 100644 --- a/src/output/alsa_output_plugin.c +++ b/src/output/alsa_output_plugin.c @@ -74,8 +74,15 @@ struct alsa_data { */ alsa_writei_t *writei; - /** the size of one audio frame */ - size_t frame_size; + /** + * The size of one audio frame passed to method play(). + */ + size_t in_frame_size; + + /** + * The size of one audio frame passed to libasound. + */ + size_t out_frame_size; /** * The size of one period, in number of frames. @@ -590,7 +597,8 @@ alsa_open(struct audio_output *ao, struct audio_format *audio_format, GError **e return false; } - ad->frame_size = audio_format_frame_size(audio_format); + ad->in_frame_size = audio_format_frame_size(audio_format); + ad->out_frame_size = ad->export.pack24 ? 3 : ad->in_frame_size; return true; } @@ -645,7 +653,7 @@ alsa_drain(struct audio_output *ao) period */ snd_pcm_uframes_t nframes = ad->period_frames - ad->period_position; - size_t nbytes = nframes * ad->frame_size; + size_t nbytes = nframes * ad->out_frame_size; void *buffer = g_malloc(nbytes); snd_pcm_hw_params_t *params; snd_pcm_format_t format; @@ -690,16 +698,20 @@ alsa_play(struct audio_output *ao, const void *chunk, size_t size, { struct alsa_data *ad = (struct alsa_data *)ao; + assert(size % ad->in_frame_size == 0); + chunk = pcm_export(&ad->export, chunk, size, &size); - size /= ad->frame_size; + assert(size % ad->out_frame_size == 0); + + size /= ad->out_frame_size; while (true) { snd_pcm_sframes_t ret = ad->writei(ad->pcm, chunk, size); if (ret > 0) { ad->period_position = (ad->period_position + ret) % ad->period_frames; - return ret * ad->frame_size; + return ret * ad->in_frame_size; } if (ret < 0 && ret != -EAGAIN && ret != -EINTR && |