X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=afs.c;h=2d4184d239e6d1f54ef6fb41bdbe1591e89c0195;hp=8e0a50aa90fd5547c80bf168236f76221f36e7bf;hb=b9f9601828dd1a103ec9315bd430d39b458d2b80;hpb=db34194eaab9819772bd55ea1ab08c719ed8f1c8 diff --git a/afs.c b/afs.c index 8e0a50aa..2d4184d2 100644 --- a/afs.c +++ b/afs.c @@ -26,6 +26,7 @@ #include /* gettimeofday */ #include "server.cmdline.h" #include "db.h" +#include "afh.h" #include "afs.h" #include "send.h" #include "error.h" @@ -36,29 +37,29 @@ extern const char *status_item_list[]; static struct timeval announce_tv; static struct timeval data_send_barrier; static struct timeval eof_barrier; +static struct timeval autoplay_barrier; extern struct misc_meta_data *mmd; extern struct audio_file_selector selectors[]; extern struct sender senders[]; -extern struct gengetopt_args_info conf; static FILE *audio_file = NULL; #if 1 - void mp3_init(void *); + void mp3_init(struct audio_format_handler *); #endif #ifdef HAVE_OGGVORBIS - void ogg_init(void *); + void ogg_init(struct audio_format_handler *); #endif #ifdef HAVE_FAAD - void aac_afh_init(void *); + void aac_afh_init(struct audio_format_handler *); #endif /** * the list of supported audio formats */ -struct audio_format_handler afl[] = { +static struct audio_format_handler afl[] = { #if 1 { .name = "mp3", @@ -81,7 +82,7 @@ struct audio_format_handler afl[] = { .name = NULL, } }; - +#define FOR_EACH_AUDIO_FORMAT(i) for (i = 0; afl[i].name; i++) /** * check if audio file sender is playing @@ -166,6 +167,14 @@ void afs_init(void) } free(hn); free(home); + if (conf.autoplay_given) { + struct timeval now, tmp; + mmd->afs_status_flags |= AFS_PLAYING; + mmd->new_afs_status_flags |= AFS_PLAYING; + gettimeofday(&now, NULL); + ms2tv(conf.autoplay_delay_arg, &tmp); + tv_add(&now, &tmp, &autoplay_barrier); + } } static int get_file_info(int i) @@ -174,25 +183,30 @@ static int get_file_info(int i) &mmd->chunks_total, &mmd->seconds_total); } -/* +/** * guess the audio format judging from filename + * * \param name the filename * * \return This function returns -1 if it has no idea what kind of audio * file this might be. Otherwise the (non-negative) number of the audio format * is returned. */ -static int guess_audio_format(const char *name) +int guess_audio_format(const char *name) { - - int i, len1 = strlen(name), len2; - - for (i = 0; afl[i].name; i++) { - len2 = strlen(afl[i].name); - if (len1 < len2) - continue; - if (!strncasecmp(name + (len1 - len2), afl[i].name, len2)) { - PARA_DEBUG_LOG("might be %s\n", afl[i].name); + int i,j, len = strlen(name); + + FOR_EACH_AUDIO_FORMAT(i) { + for (j = 0; afl[i].suffixes[j]; j++) { + const char *p = afl[i].suffixes[j]; + int plen = strlen(p); + if (len < plen + 1) + continue; + if (name[len - plen - 1] != '.') + continue; + if (strcasecmp(name + len - plen, p)) + continue; +// PARA_DEBUG_LOG("might be %s\n", audio_format_name(i)); return i; } } @@ -203,7 +217,7 @@ static int get_audio_format(int omit) { int i; - for (i = 0; afl[i].name; i++) { + FOR_EACH_AUDIO_FORMAT(i) { if (i == omit || !afl[i].get_file_info) continue; rewind(audio_file); @@ -283,14 +297,15 @@ free: } static int chk_barrier(const char *bname, const struct timeval *now, - const struct timeval *barrier, struct timeval *diff, int log) + const struct timeval *barrier, struct timeval *diff, + int print_log) { long ms; if (tv_diff(now, barrier, diff) > 0) return 1; ms = tv2ms(diff); - if (log && ms) + if (print_log && ms) PARA_DEBUG_LOG("%s barrier: %lims left\n", bname, ms); return -1; } @@ -319,6 +334,9 @@ static struct timeval *afs_compute_timeout(void) return &the_timeout; } gettimeofday(&now, NULL); + if (chk_barrier("autoplay_delay", &now, &autoplay_barrier, + &the_timeout, 1) < 0) + return &the_timeout; if (chk_barrier("eof", &now, &eof_barrier, &the_timeout, 1) < 0) return &the_timeout; if (chk_barrier("data send", &now, &data_send_barrier, @@ -369,6 +387,43 @@ static void afs_eof(struct audio_format_handler *af) mmd->events++; } +/** + * get the header and of the current audio file + * + * \param header_len the length of the header is stored here + * + * \return a pointer to a buffer containing the header, or NULL, if no audio + * file is selected or if the current audio format does not need special header + * treamtment. + * + */ +char *afs_get_header(int *header_len) +{ + *header_len = 0; + if (mmd->audio_format < 0) + return NULL; + if (!afl[mmd->audio_format].get_header_info) + return NULL; + return afl[mmd->audio_format].get_header_info(header_len); +} +const char *supported_audio_formats(void) +{ + return SUPPORTED_AUDIO_FORMATS; +} + +/** + * get the chunk time of the current audio file + * + * \return a pointer to a struct containing the chunk time, or NULL, + * if currently no audio file is selected. + */ +struct timeval *afs_chunk_time(void) +{ + if (mmd->audio_format < 0) + return NULL; + return &afl[mmd->audio_format].chunk_tv; +} + /** * compute the timeout for para_server's main select-loop * @@ -379,9 +434,9 @@ static void afs_eof(struct audio_format_handler *af) * and acted upon by calling appropriate functions from the lower layers. * Possible actions include * - * - request a new file list from the current dabase tool (audio file change) + * - request a new file list from the current audio file selector * - shutdown of all senders (stop/pause command) - * - repositioning of the stream (ff/jmp command) + * - reposition the stream (ff/jmp command) * * \return A pointer to a struct timeval containing the timeout for the next * chunk of data to be sent, or NULL if we're not sending right now. @@ -484,8 +539,7 @@ void afs_send_chunk(void) mmd->events++; } for (i = 0; senders[i].name; i++) - senders[i].send(af, mmd->current_chunk, - mmd->chunks_sent, buf, ret); + senders[i].send(mmd->current_chunk, mmd->chunks_sent, buf, ret); mmd->new_afs_status_flags |= AFS_PLAYING; mmd->chunks_sent++; mmd->current_chunk++;