X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=alsa_write.c;h=75fe6fae90bb6282b199ef3a659576ad152f0c42;hp=8b56f31a4e9c71443205f7c681a5ba0c2799f031;hb=49c897ce4cffb9ab355540043cd85d22d9a78299;hpb=015055963d095abd0e153832f5b3f0fda3ac8306 diff --git a/alsa_write.c b/alsa_write.c index 8b56f31a..75fe6fae 100644 --- a/alsa_write.c +++ b/alsa_write.c @@ -66,6 +66,7 @@ static int alsa_init(struct private_alsa_write_data *pad, snd_pcm_uframes_t period_size; int err; + PARA_INFO_LOG("opening %s\n", conf->device_arg); err = snd_pcm_open(&pad->handle, conf->device_arg, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (err < 0) @@ -152,7 +153,6 @@ static int alsa_open_btr(struct writer_node *wn) { struct private_alsa_write_data *pad = para_calloc(sizeof(*pad)); - sprintf(wn->task.status, "alsa writer"); wn->private_data = pad; return 1; } @@ -173,12 +173,12 @@ static int alsa_write_pre_select(struct sched *s, struct writer_node *wn) if (!pad->handle) return 1; if (wn->btrn) { - size_t sz = btr_get_input_queue_size(wn->btrn); - if (sz < pad->bytes_per_frame) { - if (!btr_no_parent(wn->btrn)) - return 1; - underrun = 10; - goto timeout; + 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; } } else { if (*wng->loaded - wn->written < pad->bytes_per_frame) @@ -202,7 +202,6 @@ static int alsa_write_pre_select(struct sched *s, struct writer_node *wn) if (underrun < 50) underrun = 50; underrun -= 50; -timeout: ms2tv(underrun, &tv); if (tv_diff(&s->timeout, &tv, NULL) > 0) s->timeout = tv; @@ -213,7 +212,7 @@ timeout: static void alsa_write_pre_select_btr(struct sched *s, struct task *t) { struct writer_node *wn = container_of(t, struct writer_node, task); - t->error = alsa_write_pre_select(s, wn); + alsa_write_pre_select(s, wn); } static void xrun(snd_pcm_t *handle) @@ -307,11 +306,12 @@ static void alsa_write_post_select_btr(__a_unused struct sched *s, again: t->error = 0; - ret = prepare_writer_node(wn); + ret = btr_node_status(btrn, wn->min_iqs, BTR_NT_LEAF); if (ret == 0) return; + btr_merge(btrn, wn->min_iqs); bytes = btr_next_buffer(btrn, &data); - if (bytes < pad->bytes_per_frame) { /* eof */ + if (ret < 0 || bytes < pad->bytes_per_frame) { /* eof */ assert(btr_no_parent(btrn)); ret = -E_ALSA_EOF; if (!pad->handle) @@ -320,44 +320,25 @@ again: avail = snd_pcm_avail_update(pad->handle); if (avail + 1000 > pad->buffer_frames) goto err; + PARA_DEBUG_LOG("waiting for device to drain\n"); return; } if (!pad->handle) { - char *buf; struct alsa_write_args_info *conf = wn->conf; if (bytes == 0) /* no data available */ return; - PARA_CRIT_LOG("alsa init\n"); /* defaults */ pad->samplerate = conf->samplerate_arg; pad->channels = conf->channels_arg; if (!conf->samplerate_given) { /* config option trumps btr_exec */ - /* ask parent btr nodes */ - buf = NULL; - ret = btr_exec_up(btrn, "samplerate", &buf); - PARA_CRIT_LOG("ret: %d\n", ret); - if (ret >= 0) { - int32_t rate; - - ret = para_atoi32(buf, &rate); - free(buf); - if (ret < 0) /* should not happen */ - goto err; + int32_t rate; + if (get_btr_samplerate(btrn, &rate) >= 0) pad->samplerate = rate; - } } if (!conf->channels_given) { - buf = NULL; - ret = btr_exec_up(btrn, "channels", &buf); - if (ret >= 0) { - int32_t ch; - - ret = para_atoi32(buf, &ch); - freep(&buf); - if (ret < 0) - goto err; + int32_t ch; + if (get_btr_channels(btrn, &ch) >= 0) pad->channels = ch; - } } PARA_INFO_LOG("%d channel(s), %dHz\n", pad->channels, pad->samplerate); ret = 1; @@ -367,11 +348,6 @@ again: wn->min_iqs = pad->bytes_per_frame; } frames = bytes / pad->bytes_per_frame; - avail = snd_pcm_avail_update(pad->handle); - if (avail <= 0) - return; - frames = PARA_MIN(frames, avail); - //PARA_CRIT_LOG("writing %ld frames\n", frames); frames = snd_pcm_writei(pad->handle, data, frames); if (frames >= 0) { btr_consume(btrn, frames * pad->bytes_per_frame); @@ -382,14 +358,13 @@ again: snd_pcm_prepare(pad->handle); return; } - PARA_WARNING_LOG("%s\n", snd_strerror(-frames)); if (frames == -EAGAIN) return; + PARA_WARNING_LOG("%s\n", snd_strerror(-frames)); ret = -E_ALSA_WRITE; err: assert(ret < 0); - btr_del_node(btrn); - alsa_close(wn); + btr_remove_node(btrn); t->error = ret; } @@ -410,12 +385,17 @@ err_out: return NULL; } +static void alsa_free_config(void *conf) +{ + alsa_cmdline_parser_free(conf); +} + /** - * the init function of the alsa writer + * The init function of the alsa writer. * - * \param w pointer to the writer to initialize + * \param w Pointer to the writer to initialize. * - * \sa struct writer + * \sa \ref struct writer. */ void alsa_write_init(struct writer *w) { @@ -430,6 +410,7 @@ void alsa_write_init(struct writer *w) w->post_select_btr = alsa_write_post_select_btr; w->parse_config = alsa_parse_config; w->shutdown = NULL; /* nothing to do */ + w->free_config = alsa_free_config; w->help = (struct ggo_help) { .short_help = alsa_write_args_info_help, .detailed_help = alsa_write_args_info_detailed_help