X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=f0ce62587d9c6fc995fe7c99440fa1238e706b49;hp=295c37553be11c9b72f2e9052f8fd77ab08e2296;hb=74943155276117fe23d94180b5fc12cd8749ac22;hpb=a8e9ce1067c40f01d50e58d760c099ac98e9b12f diff --git a/audiod.c b/audiod.c index 295c3755..f0ce6258 100644 --- a/audiod.c +++ b/audiod.c @@ -7,6 +7,7 @@ /** \file audiod.c the paraslash's audio daemon */ #include #include +#include #include "para.h" #include "error.h" @@ -65,6 +66,9 @@ struct audio_format_info { struct slot_info slot[MAX_STREAM_SLOTS]; +/** The array of status items sent by para_server. */ +char *stat_item_values[NUM_STAT_ITEMS] = {NULL}; + /** * the current mode of operation of which can be changed by the on/off/cycle * commands. It is either, AUDIOD_OFF, AUDIOD_ON or AUDIOD_STANDBY. @@ -90,7 +94,7 @@ static struct status_task status_task_struct; * * \sa struct status_task */ -struct status_task *stat_task = &status_task_struct; +static struct status_task *stat_task = &status_task_struct; static struct timeval initial_delay_barrier; /** @@ -127,6 +131,55 @@ int get_audio_format_num(char *name) return -E_UNSUPPORTED_AUDIO_FORMAT; } +char *get_time_string(struct timeval *newest_stime) +{ + struct timeval diff, adj_stream_start, tmp; + int total = 0, use_server_time = 1, + length_seconds = stat_task->length_seconds; + + if (!stat_task->playing) { + if (length_seconds) + return NULL; + return make_message("%s:\n", status_item_list[SI_PLAY_TIME]); + } + if (audiod_status == AUDIOD_OFF) + goto out; + if (stat_task->sa_time_diff_sign > 0) + tv_diff(&stat_task->server_stream_start, &stat_task->sa_time_diff, + &adj_stream_start); + else + tv_add(&stat_task->server_stream_start, &stat_task->sa_time_diff, + &adj_stream_start); + tmp = adj_stream_start; + if (newest_stime && audiod_status == AUDIOD_ON) { + tv_diff(newest_stime, &adj_stream_start, &diff); + if (tv2ms(&diff) < 5000) { + tmp = *newest_stime; + use_server_time = 0; + } + } + tv_diff(now, &tmp, &diff); + total = diff.tv_sec + stat_task->offset_seconds; + if (total > length_seconds) + total = length_seconds; + if (total < 0) + total = 0; +out: + return make_message( + "%s: %s%d:%02d [%d:%02d] (%d%%/%d:%02d)\n", + status_item_list[SI_PLAY_TIME], + use_server_time? "~" : "", + total / 60, + total % 60, + (length_seconds - total) / 60, + (length_seconds - total) % 60, + length_seconds? (total * 100 + length_seconds / 2) / + length_seconds : 0, + length_seconds / 60, + length_seconds % 60 + ); +} + /** * the log function of para_audiod * @@ -274,7 +327,7 @@ static void open_filters(int slot_num) return; PARA_INFO_LOG("opening %s filters\n", audio_formats[s->format]); s->fc = para_calloc(sizeof(struct filter_chain)); - s->fc->filter_nodes = para_malloc(nf * sizeof(struct filter_chain)); + s->fc->filter_nodes = para_malloc(nf * sizeof(struct filter_node)); s->fc->inbuf = s->receiver_node->buf; s->fc->in_loaded = &s->receiver_node->loaded; s->fc->input_error = &s->receiver_node->task.error; @@ -294,7 +347,7 @@ static void open_filters(int slot_num) INIT_LIST_HEAD(&fn->callbacks); f->open(fn); PARA_NOTICE_LOG("%s filter %d/%d (%s) started in slot %d\n", - audio_formats[s->format], i + 1, nf, f->name, slot_num); + audio_formats[s->format], i, nf, f->name, slot_num); s->fc->outbuf = fn->buf; s->fc->out_loaded = &fn->loaded; } @@ -382,8 +435,7 @@ static int receiver_running(int format) FOR_EACH_SLOT(i) { struct slot_info *s = &slot[i]; - if (s->format == format && s->receiver_node - && s->receiver_node->task.error >= 0) + if (s->format == format && s->receiver_node) return 1; } return 0; @@ -467,8 +519,8 @@ static int check_stat_line(char *line, __a_unused void *data) tmp = make_message("%s\n", line); stat_client_write(tmp, itemnum); free(tmp); - free(stat_task->stat_item_values[itemnum]); - stat_task->stat_item_values[itemnum] = para_strdup(line); + free(stat_item_values[itemnum]); + stat_item_values[itemnum] = para_strdup(line); ilen = strlen(status_item_list[itemnum]); switch (itemnum) { case SI_STATUS: @@ -539,7 +591,7 @@ static int add_filter(int format, char *cmdline) return filter_num; a->filter_nums[nf] = filter_num; a->num_filters++; - PARA_INFO_LOG("%s filter %d: %s\n", audio_formats[format], nf + 1, + PARA_INFO_LOG("%s filter %d: %s\n", audio_formats[format], nf, filters[filter_num].name); return filter_num; } @@ -756,13 +808,12 @@ static void signal_pre_select(struct sched *s, struct task *t) static void signal_post_select(struct sched *s, struct task *t) { struct signal_task *st = container_of(t, struct signal_task, task); - int signum; if (!FD_ISSET(st->fd, &s->rfds)) return; - signum = para_next_signal(); - switch (signum) { + st->signum = para_next_signal(); + switch (st->signum) { case SIGINT: case SIGTERM: case SIGHUP: @@ -815,18 +866,18 @@ static void close_stat_pipe(void) client_close(stat_task->ct); stat_task->ct = NULL; FOR_EACH_STATUS_ITEM(i) { - free(stat_task->stat_item_values[i]); - stat_task->stat_item_values[i] = NULL; + free(stat_item_values[i]); + stat_item_values[i] = NULL; } dump_empty_status(); stat_task->length_seconds = 0; stat_task->offset_seconds = 0; audiod_status_dump(); stat_task->playing = 0; - stat_task->stat_item_values[SI_BASENAME] = make_message( + stat_item_values[SI_BASENAME] = make_message( "%s: no connection to para_server\n", status_item_list[SI_BASENAME]); - stat_client_write(stat_task->stat_item_values[SI_BASENAME], + stat_client_write(stat_item_values[SI_BASENAME], SI_BASENAME); } @@ -1030,22 +1081,27 @@ int main(int argc, char *argv[]) { char *config_file; int ret, i; - struct sched s; + static struct sched s; struct command_task command_task_struct, *cmd_task = &command_task_struct; + struct audiod_cmdline_parser_params params = { + .override = 0, + .initialize = 1, + .check_required = 0, + .check_ambiguity = 0, + .print_errors = 1 + }; valid_fd_012(); - audiod_cmdline_parser(argc, argv, &conf); + audiod_cmdline_parser_ext(argc, argv, &conf, ¶ms); HANDLE_VERSION_FLAG("audiod", conf); para_drop_privileges(conf.user_arg, conf.group_arg); config_file = configfile_exists(); if (config_file) { - struct audiod_cmdline_parser_params params = { - .override = 0, - .initialize = 0, - .check_required = 0, - .check_ambiguity = 0 - - }; + params.override = 0; + params.initialize = 0; + params.check_required = 1; + params.check_ambiguity = 0; + params.print_errors = 1; if (audiod_cmdline_parser_config_file(config_file, &conf, ¶ms)) { PARA_EMERG_LOG("parse error in config file\n"); exit(EXIT_FAILURE);