X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=alsa_writer.c;h=7d7d36bfbdab04bf91ab0bc932b69c9b129d2a28;hp=5c3290731dd3aff35ddc9b4a9929236e9b0df36e;hb=b829b61f516298a0de3907cd4c30aef189dd8dd4;hpb=eedc9eafd60b670dd2b90fcbcc380f3f9a333f93 diff --git a/alsa_writer.c b/alsa_writer.c index 5c329073..7d7d36bf 100644 --- a/alsa_writer.c +++ b/alsa_writer.c @@ -83,7 +83,7 @@ static int alsa_open(struct writer_node *w) w->private_data = pad; snd_pcm_info_alloca(&info); err = snd_pcm_open(&pad->handle, conf->device_arg, - SND_PCM_STREAM_PLAYBACK, 0); + SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (err < 0) return -E_PCM_OPEN; if ((err = snd_pcm_info(pad->handle, info)) < 0) @@ -146,66 +146,65 @@ static int alsa_open(struct writer_node *w) PARA_ERROR_LOG("%s\n", "failed to set nonblock mode"); return period_size * pad->bytes_per_frame; } -static void alsa_write_pre_select(struct sched *s, struct task *t) + +static int alsa_write_pre_select(struct sched *s, struct writer_node *wn) { - struct writer_node *wn = t->private_data; struct private_alsa_data *pad = wn->private_data; struct writer_node_group *wng = wn->wng; struct timeval diff; - t->ret = 1; - if (*wng->input_eof && *wng->loaded < pad->bytes_per_frame) - return; - if (tv_diff(&s->now, &pad->next_chunk, &diff) < 0) { + if (*wng->loaded < pad->bytes_per_frame) + return 1; + if (tv_diff(now, &pad->next_chunk, &diff) < 0) { if (tv_diff(&s->timeout, &diff, NULL) > 0) s->timeout = diff; } else { s->timeout.tv_sec = 0; - s->timeout.tv_usec = 1000; + s->timeout.tv_usec = 1; } + return 1; // PARA_INFO_LOG("timeout: %lu\n", tv2ms(&s->timeout)); } -static void alsa_write_post_select(struct sched *s, struct task *t) +static int alsa_write_post_select(__a_unused struct sched *s, + struct writer_node *wn) { - struct writer_node *wn = t->private_data; struct private_alsa_data *pad = wn->private_data; struct writer_node_group *wng = wn->wng; - size_t frames = *wng->loaded / pad->bytes_per_frame; + size_t frames = (*wng->loaded - wn->written) / pad->bytes_per_frame; snd_pcm_sframes_t ret; - unsigned char *data = (unsigned char*)wng->buf; + unsigned char *data = (unsigned char*)wng->buf + wn->written; struct timeval tv; - t->ret = 0; // PARA_INFO_LOG("%zd frames\n", frames); if (!frames) { if (*wng->input_eof) - t->ret = *wng->loaded; - return; + wn->written = *wng->loaded; + return 1; } - if (tv_diff(&s->now, &pad->next_chunk, NULL) < 0) - return; + if (tv_diff(now, &pad->next_chunk, NULL) < 0) + return 1; ret = snd_pcm_writei(pad->handle, data, frames); if (ret == -EPIPE) { PARA_WARNING_LOG("%s", "EPIPE\n"); snd_pcm_prepare(pad->handle); - return; + return 1; } if (ret < 0) { PARA_WARNING_LOG("%s", "ALSA ERROR\n"); - t->ret = -E_ALSA_WRITE; - return; + return -E_ALSA_WRITE; } ms2tv(pad->buffer_time / 4000, &tv); // ms2tv(1, &tv); - tv_add(&s->now, &tv, &pad->next_chunk); - t->ret = ret * pad->bytes_per_frame; -// PARA_INFO_LOG("ret: %d, frames: %zd\n", t->ret, frames); + tv_add(now, &tv, &pad->next_chunk); + wn->written += ret * pad->bytes_per_frame; + return 1; } static void alsa_close(struct writer_node *wn) { struct private_alsa_data *pad = wn->private_data; + PARA_INFO_LOG("closing writer node %p\n", wn); snd_pcm_drain(pad->handle); snd_pcm_close(pad->handle); snd_config_update_free_global();