X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=mood.c;h=fe8ee8ad9915cdc3db089a8f8584883537963111;hp=ae71dab0863c5a8e1c552333bf73f5ae57a78277;hb=d96c06ff93493c125b9f4d36655e77d7029ca309;hpb=9242741b62d726e7b673a3b10c62bbc8509a75ef diff --git a/mood.c b/mood.c index ae71dab0..fe8ee8ad 100644 --- a/mood.c +++ b/mood.c @@ -35,7 +35,7 @@ struct afs_statistics { /** Number of admissible files */ unsigned num; }; -struct afs_statistics statistics; +static struct afs_statistics statistics; /** * Each line of the current mood corresponds to a mood_item. @@ -107,60 +107,74 @@ static uint64_t int_sqrt(uint64_t x) return res; } -/* returns 1 if row matches score item, negative otherwise */ -static int add_item_score(const struct osl_row *row, struct mood_item *item, long *score, +/* returns 1 if row matches score item, 0 if not. */ +static int get_item_score(struct mood_item *item, const struct afs_info *afsi, + const struct afh_info *afhi, const char *path, long *score, long *score_arg_sum) { - struct afs_info afsi; - struct afh_info afhi; - char *path; - int ret; + int ret, match = 1; *score_arg_sum += item->random_score? 100 : PARA_ABS(item->score_arg); ret = 100; if (item->method) { - ret = get_afsi_of_row(row, &afsi); - if (ret< 0) - return ret; - ret = get_afhi_of_row(row, &afhi); - if (ret< 0) - return ret; - ret = get_audio_file_path_of_row(row, &path); - if (ret< 0) - return ret; - ret = item->method->score_function(path, &afsi, &afhi, + ret = item->method->score_function(path, afsi, afhi, item->parser_data); if ((ret < 0 && !item->logical_not) || (ret >= 0 && item->logical_not)) - return -1; /* no match */ + match = 0; /* no match */ } if (item->random_score) - *score += PARA_ABS(ret) * para_random(100); + *score = PARA_ABS(ret) * para_random(100); else - *score += PARA_ABS(ret) * item->score_arg; - return 1; + *score = PARA_ABS(ret) * item->score_arg; + return match; } +/* returns 1 if row admissible, 0 if not, negative on errors */ static int compute_mood_score(const struct osl_row *aft_row, struct mood *m, long *result) { struct mood_item *item; - int match = 0; - long score_arg_sum = 0, score = 0; + int ret, match = 0; + long score_arg_sum = 0, score = 0, item_score; + struct afs_info afsi; + struct afh_info afhi; + char *path; if (!m) return -E_NO_MOOD; + ret = get_afsi_of_row(aft_row, &afsi); + if (ret< 0) + return ret; + ret = get_afhi_of_row(aft_row, &afhi); + if (ret< 0) + return ret; + ret = get_audio_file_path_of_row(aft_row, &path); + if (ret< 0) + return ret; /* reject audio file if it matches any entry in the deny list */ - list_for_each_entry(item, &m->deny_list, mood_item_node) - if (add_item_score(aft_row, item, &score, &score_arg_sum) > 0) - return -E_NOT_ADMISSIBLE; - list_for_each_entry(item, &m->accept_list, mood_item_node) - if (add_item_score(aft_row, item, &score, &score_arg_sum) > 0) - match = 1; + list_for_each_entry(item, &m->deny_list, mood_item_node) { + ret = get_item_score(item, &afsi, &afhi, path, &item_score, + &score_arg_sum); + if (ret > 0) /* not admissible */ + return 0; + score += item_score; + } + list_for_each_entry(item, &m->accept_list, mood_item_node) { + ret = get_item_score(item, &afsi, &afhi, path, &item_score, + &score_arg_sum); + if (ret == 0) + continue; + match = 1; + score += item_score; + } /* reject if there is no matching entry in the accept list */ if (!match && !list_empty(&m->accept_list)) - return -E_NOT_ADMISSIBLE; - list_for_each_entry(item, &m->score_list, mood_item_node) - add_item_score(aft_row, item, &score, &score_arg_sum); + return 0; + list_for_each_entry(item, &m->score_list, mood_item_node) { + ret = get_item_score(item, &afsi, &afhi, path, &item_score, + &score_arg_sum); + score += item_score; + } if (score_arg_sum) score /= score_arg_sum; *result = score; @@ -570,7 +584,7 @@ struct admissible_array { * \param aft_row The audio file to be added. * \param private_data Pointer to a struct admissible_file_info. * - * \return Negative on errors, positive on success. + * \return 1 if row admissible, 0 if not, negative on errors. */ static int add_if_admissible(struct osl_row *aft_row, void *data) { @@ -579,8 +593,8 @@ static int add_if_admissible(struct osl_row *aft_row, void *data) long score = 0; ret = compute_mood_score(aft_row, aa->m, &score); - if (ret < 0) - return (ret == -E_NOT_ADMISSIBLE)? 1 : ret; + if (ret <= 0) + return ret; if (statistics.num >= aa->size) { aa->size *= 2; aa->size += 100; @@ -718,6 +732,8 @@ static int mood_update_audio_file(const struct osl_row *aft_row, return ret; was_admissible = ret; ret = compute_mood_score(aft_row, current_mood, &score); + if (ret < 0) + return ret; is_admissible = (ret > 0); if (!was_admissible && !is_admissible) return 1; @@ -877,7 +893,9 @@ int reload_current_mood(void) int moods_event_handler(enum afs_events event, __a_unused struct para_buffer *pb, void *data) { - switch(event) { + if (!current_mood) + return 0; + switch (event) { /* * The three blob events might change the set of admissible files, * so we must reload the score list.