- if (snd_pcm_sw_params_set_stop_threshold(pad->handle, swparams,
- stop_threshold) < 0)
- 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->channels / 8;
- if (pad->bytes_per_frame <= 0)
- return -E_PHYSICAL_WIDTH;
- PARA_INFO_LOG("bytes per frame: %d\n", pad->bytes_per_frame);
- if (snd_pcm_nonblock(pad->handle, 1))
- PARA_ERROR_LOG("failed to set nonblock mode\n");
- pad->buffer_frames = 1000 * pad->buffer_time / pad->samplerate;
- PARA_INFO_LOG("max buffered frames: %d\n", pad->buffer_frames);
- return 1;
-}
-
-/* Open an instance of the alsa writer. */
-static int alsa_open_nobtr(struct writer_node *wn)
-{
- struct alsa_write_args_info *conf = wn->conf;
- struct writer_node_group *wng = wn->wng;
- struct private_alsa_write_data *pad = para_calloc(sizeof(*pad));
-
- wn->private_data = pad;
- if (!conf->samplerate_given && wng->samplerate)
- pad->samplerate = *wng->samplerate;
- else
- pad->samplerate = conf->samplerate_arg;
- if (!conf->channels_given && wng->channels)
- pad->channels = *wng->channels;
- else
- pad->channels = conf->channels_arg;
- PARA_INFO_LOG("%d channel(s), %dHz\n", pad->channels, pad->samplerate);
- return 1;
-}
-
-static int alsa_open_btr(struct writer_node *wn)
-{
- struct alsa_write_args_info *conf = wn->conf;
- struct private_alsa_write_data *pad = para_calloc(sizeof(*pad));
- int ret;
- char *buf = NULL;
-
- sprintf(wn->task.status, "alsa writer");
- wn->private_data = pad;
-
- /* defaults */
- pad->samplerate = conf->samplerate_arg;
- pad->channels = conf->channels_arg;
-
- if (!conf->samplerate_given) { /* config option trumps btr_exec */
- /* ask parent btr nodes */
- ret = btr_exec_up(wn->btrn, "samplerate", &buf);
- if (ret >= 0) {
- int32_t rate;
- ret = para_atoi32(buf, &rate);
- if (ret < 0) /* should not happen */
- goto out;
- pad->samplerate = rate;
- }
- freep(&buf);
- }
-
- if (!conf->channels_given) {
- ret = btr_exec_up(wn->btrn, "channels", &buf);
- if (ret >= 0) {
- int32_t ch;
- ret = para_atoi32(buf, &ch);
- if (ret < 0)
- goto out;
- pad->channels = ch;
+ msg = "could not set stop threshold";
+ ret = snd_pcm_sw_params_set_stop_threshold(pad->handle, swparams,
+ stop_threshold);
+ if (ret < 0)
+ goto fail;
+ msg = "unable to install sw params";
+ ret = snd_pcm_sw_params(pad->handle, swparams);
+ if (ret < 0)
+ goto fail;
+ msg = "unable to determine bytes per frame";
+ ret = snd_pcm_format_physical_width(pad->sample_format);
+ if (ret <= 0)
+ goto fail;
+ pad->bytes_per_frame = ret * pad->channels / 8;
+ msg = "failed to set alsa handle to nonblock mode";
+ ret = snd_pcm_nonblock(pad->handle, 1);
+ if (ret < 0)
+ goto fail;
+ ret = snd_output_buffer_open(&output_log);
+ if (ret == 0) {
+ char *buf, *p;
+ size_t sz;
+ PARA_INFO_LOG("dumping alsa configuration\n");
+ snd_pcm_dump(pad->handle, output_log);
+ sz = snd_output_buffer_string(output_log, &buf);
+ for (p = buf; p < buf + sz;) {
+ char *q = memchr(p, '\n', buf + sz - p);
+ if (!q)
+ break;
+ *q = '\0';
+ PARA_INFO_LOG("%s\n", p);
+ p = q + 1;