- start_threshold = PARA_MIN(pad->buffer_frames,
- (snd_pcm_uframes_t)pad->samplerate);
- if (snd_pcm_sw_params_set_start_threshold(pad->handle, swparams,
- start_threshold) < 0)
- return -E_START_THRESHOLD;
- stop_threshold = pad->buffer_frames;
- 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");
- 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 private_alsa_write_data *pad = para_calloc(sizeof(*pad));
-
- wn->private_data = pad;
- return 1;
-}
-static int alsa_open(struct writer_node *wn)
-{
- if (wn->btrn)
- return alsa_open_btr(wn);
- return alsa_open_nobtr(wn);
-}
-
-static int alsa_write_pre_select(struct sched *s, struct writer_node *wn)
-{
- struct private_alsa_write_data *pad = wn->private_data;
- struct writer_node_group *wng = wn->wng;
- struct timeval tv;
- snd_pcm_sframes_t avail, underrun;
-
- if (!pad->handle)
- return 1;
- if (wn->btrn) {
- int ret = btr_node_status(wn->btrn, wn->min_iqs, BTR_NT_LEAF);
- if (ret == 0)
- return 1;
- if (ret < 0) {
- sched_request_timeout_ms(20, s);
- return 42;
+ start_threshold = PARA_MIN(buffer_size,
+ (snd_pcm_uframes_t)pad->sample_rate);
+ msg = "could not set start threshold";
+ ret = snd_pcm_sw_params_set_start_threshold(pad->handle, swparams,
+ start_threshold);
+ if (ret < 0)
+ goto fail;
+ stop_threshold = buffer_size;
+ 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;
+ PARA_INFO_LOG("dumping alsa configuration\n");
+ snd_pcm_dump(pad->handle, output_log);
+ snd_output_buffer_string(output_log, &buf);
+ for (;;) {
+ char *p = strchr(buf, '\n');
+ if (!p) /* omit last output line, it's empty */
+ break;
+ *p = '\0';
+ PARA_INFO_LOG("%s\n", buf);
+ buf = p + 1;