output/alsa: split the frame_size attribute

Make it in_frame_size and out_frame_size, to account for packing.
This commit is contained in:
Max Kellermann 2012-03-22 01:01:11 +01:00
parent b99ecb4dc9
commit 725fbe946b

View File

@ -74,8 +74,15 @@ struct alsa_data {
*/ */
alsa_writei_t *writei; 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. * 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; 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; return true;
} }
@ -645,7 +653,7 @@ alsa_drain(struct audio_output *ao)
period */ period */
snd_pcm_uframes_t nframes = snd_pcm_uframes_t nframes =
ad->period_frames - ad->period_position; 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); void *buffer = g_malloc(nbytes);
snd_pcm_hw_params_t *params; snd_pcm_hw_params_t *params;
snd_pcm_format_t format; 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; struct alsa_data *ad = (struct alsa_data *)ao;
assert(size % ad->in_frame_size == 0);
chunk = pcm_export(&ad->export, chunk, size, &size); 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) { while (true) {
snd_pcm_sframes_t ret = ad->writei(ad->pcm, chunk, size); snd_pcm_sframes_t ret = ad->writei(ad->pcm, chunk, size);
if (ret > 0) { if (ret > 0) {
ad->period_position = (ad->period_position + ret) ad->period_position = (ad->period_position + ret)
% ad->period_frames; % ad->period_frames;
return ret * ad->frame_size; return ret * ad->in_frame_size;
} }
if (ret < 0 && ret != -EAGAIN && ret != -EINTR && if (ret < 0 && ret != -EAGAIN && ret != -EINTR &&