]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - alsa_write.c
para.h: Fix typo in comment.
[paraslash.git] / alsa_write.c
index 09cca93f4a34783e16b2bc601408184591a32362..d115a52db0ae899be1ec003d4f7e060611b0ee94 100644 (file)
@@ -31,9 +31,6 @@
 #include "alsa_write.cmdline.h"
 #include "error.h"
 
-/** always use 16 bit little endian */
-#define FORMAT SND_PCM_FORMAT_S16_LE
-
 /** Data specific to the alsa writer. */
 struct private_alsa_write_data {
        /** The alsa handle */
@@ -49,6 +46,7 @@ struct private_alsa_write_data {
         * of the writer node group.
         */
        unsigned sample_rate;
+       snd_pcm_format_t sample_format;
        /**
         * The number of channels, given by command line option or the
         * decoder of the writer node group.
@@ -57,6 +55,19 @@ struct private_alsa_write_data {
        struct timeval drain_barrier;
 };
 
+static snd_pcm_format_t get_alsa_pcm_format(enum sample_format sf)
+{
+       switch (sf) {
+       case SF_S8: return SND_PCM_FORMAT_S8;
+       case SF_U8: return SND_PCM_FORMAT_U8;
+       case SF_S16_LE: return SND_PCM_FORMAT_S16_LE;
+       case SF_S16_BE: return SND_PCM_FORMAT_S16_BE;
+       case SF_U16_LE: return SND_PCM_FORMAT_U16_LE;
+       case SF_U16_BE: return SND_PCM_FORMAT_U16_BE;
+       default: return SND_PCM_FORMAT_S16_LE;
+       }
+}
+
 /* Install PCM software and hardware configuration. */
 static int alsa_init(struct private_alsa_write_data *pad,
                struct alsa_write_args_info *conf)
@@ -80,7 +91,8 @@ static int alsa_init(struct private_alsa_write_data *pad,
        if (snd_pcm_hw_params_set_access(pad->handle, hwparams,
                        SND_PCM_ACCESS_RW_INTERLEAVED) < 0)
                return -E_ACCESS_TYPE;
-       if (snd_pcm_hw_params_set_format(pad->handle, hwparams, FORMAT) < 0)
+       if (snd_pcm_hw_params_set_format(pad->handle, hwparams,
+                       pad->sample_format) < 0)
                return -E_SAMPLE_FORMAT;
        if (snd_pcm_hw_params_set_channels(pad->handle, hwparams,
                        pad->channels) < 0)
@@ -120,7 +132,7 @@ static int alsa_init(struct private_alsa_write_data *pad,
                return -E_STOP_THRESHOLD;
        if (snd_pcm_sw_params(pad->handle, swparams) < 0)
                PARA_WARNING_LOG("unable to install sw params\n");
-       pad->bytes_per_frame = snd_pcm_format_physical_width(FORMAT)
+       pad->bytes_per_frame = snd_pcm_format_physical_width(pad->sample_format)
                * pad->channels / 8;
        if (pad->bytes_per_frame <= 0)
                return -E_PHYSICAL_WIDTH;
@@ -229,18 +241,23 @@ again:
        }
        if (!pad->handle) {
                int32_t val;
+
                if (bytes == 0) /* no data available */
                        return;
                get_btr_sample_rate(btrn, &val);
                pad->sample_rate = val;
                get_btr_channels(btrn, &val);
                pad->channels = val;
+               get_btr_sample_format(btrn, &val);
+               pad->sample_format = get_alsa_pcm_format(val);
+
                PARA_INFO_LOG("%d channel(s), %dHz\n", pad->channels,
                        pad->sample_rate);
                ret = alsa_init(pad, wn->conf);
                if (ret < 0)
                        goto err;
                wn->min_iqs = pad->bytes_per_frame;
+               goto again;
        }
        frames = bytes / pad->bytes_per_frame;
        frames = snd_pcm_writei(pad->handle, data, frames);