X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;ds=sidebyside;f=mood.c;h=9cdfd011a6ef4f2ab9fb180892f6412247eb68fe;hb=ac03b19b1693fbb7b1d558989ac81c79ed1284ae;hp=9c2571aa054287859ca4f041f2384900999be33b;hpb=b0a87fd7b5aeb8007afd3ac25d8548543d42080c;p=paraslash.git diff --git a/mood.c b/mood.c index 9c2571aa..9cdfd011 100644 --- a/mood.c +++ b/mood.c @@ -48,9 +48,9 @@ struct afs_statistics { }; /** - * Stores an instance of an open mood (parser and statistics). + * Stores an instance of a loaded mood (parser and statistics). * - * A structure of this type is allocated and initialized at mood open time. + * A structure of this type is allocated and initialized when a mood is loaded. */ struct mood_instance { /** NULL means that this is the "dummy" mood. */ @@ -62,8 +62,8 @@ struct mood_instance { }; /* - * If current_mood is NULL then no mood is currently open. If - * current_mood->name is NULL, the dummy mood is currently open. + * If current_mood is NULL then no mood is currently loaded. If + * current_mood->name is NULL, the current mood is the dummy mood. * * The statistics are adjusted dynamically through this pointer as files are * added, removed or played. @@ -164,7 +164,7 @@ static int init_mood_parser(const char *mood_name, struct mood_instance **m, return ret; } *m = alloc_new_mood(mood_name); - PARA_INFO_LOG("opening mood %s\n", mood_name); + PARA_INFO_LOG("loading mood %s\n", mood_name); ret = mp_init(mood_def.data, mood_def.size, &(*m)->parser_context, err); osl_close_disk_object(&mood_def); if (ret < 0) @@ -174,14 +174,14 @@ static int init_mood_parser(const char *mood_name, struct mood_instance **m, static int check_mood(struct osl_row *mood_row, void *data) { - struct para_buffer *pb = data; + struct afs_callback_arg *aca = data; char *mood_name, *errmsg; struct osl_object mood_def; struct mood_instance *m; int ret = mood_get_name_and_def_by_row(mood_row, &mood_name, &mood_def); if (ret < 0) { - para_printf(pb, "cannot read mood\n"); + afs_error(aca, "cannot read mood\n"); return ret; } if (!*mood_name) /* ignore dummy row */ @@ -190,9 +190,9 @@ static int check_mood(struct osl_row *mood_row, void *data) ret = mp_init(mood_def.data, mood_def.size, &m->parser_context, &errmsg); if (ret < 0) { - para_printf(pb, "%s: %s\n", mood_name, errmsg); + afs_error(aca, "%s: %s\n%s\n", mood_name, errmsg, + para_strerror(-ret)); free(errmsg); - para_printf(pb, "%s\n", para_strerror(-ret)); } else destroy_mood(m); ret = 1; /* don't fail the loop on invalid mood definitions */ @@ -204,7 +204,7 @@ out: /** * Check all moods for syntax errors. * - * \param aca Only ->pbout is used for diagnostics. + * \param aca Output goes to ->pbout, errors to ->fd on the error band. * * \return Negative on fatal errors. Inconsistent mood definitions are not * considered an error. @@ -212,8 +212,7 @@ out: int mood_check_callback(struct afs_callback_arg *aca) { para_printf(&aca->pbout, "checking moods...\n"); - return osl(osl_rbtree_loop(moods_table, BLOBCOL_ID, &aca->pbout, - check_mood)); + return osl(osl_rbtree_loop(moods_table, BLOBCOL_ID, aca, check_mood)); } /* @@ -253,21 +252,23 @@ int mood_check_callback(struct afs_callback_arg *aca) * overflows and rounding errors we store the common divisor of the * correction factors separately. */ -static int64_t normalized_value(int64_t x, int64_t n, int64_t sum, int64_t qd) -{ - if (!n || !qd) - return 0; - return 100 * (n * x - sum) / (int64_t)int_sqrt(n) / (int64_t)int_sqrt(qd); -} - static long compute_score(struct afs_info *afsi, const struct afs_statistics *stats) { - long score = -normalized_value(afsi->num_played, stats->num, - stats->num_played_sum, stats->num_played_qd); - score -= normalized_value(afsi->last_played, stats->num, - stats->last_played_sum, stats->last_played_qd); - return score / 2; + int64_t mean_n, mean_l,score_n, score_l; + + assert(stats->normalization_divisor > 0); + assert(stats->num > 0); + mean_n = stats->num_played_sum / stats->num; + mean_l = stats->last_played_sum / stats->num; + + score_n = -((int64_t)afsi->num_played - mean_n) + * stats->num_played_correction + / stats->normalization_divisor; + score_l = -((int64_t)afsi->last_played - mean_l) + * stats->last_played_correction + / stats->normalization_divisor; + return (score_n + score_l) / 2; } static int add_afs_statistics(const struct osl_row *row, @@ -338,7 +339,7 @@ static int del_afs_statistics(const struct osl_row *row) } /* - * At mood open time we determine the set of admissible files for the given + * At mood load time we determine the set of admissible files for the given * mood where each file is identified by a pointer to a row of the audio file * table. In the first pass the pointers are added to a temporary array and * statistics are computed. When all admissible files have been processed in @@ -543,12 +544,8 @@ static char *get_statistics(struct mood_instance *m, int64_t sse) ); } -/** - * Close the current mood. - * - * Frees all resources of the current mood. - */ -void close_current_mood(void) +/** Free all resources of the current mood, if any. */ +void mood_unload(void) { destroy_mood(current_mood); current_mood = NULL; @@ -573,9 +570,7 @@ static void compute_correction_factors(int64_t sse, struct afs_statistics *s) /** * Change the current mood. * - * If there is already an open mood, it will be closed first. - * - * \param mood_name The name of the mood to open. + * \param mood_name The name of the mood to load. * \param msg Error message or mood info is returned here. * * If \a mood_name is \a NULL, load the dummy mood that accepts every audio file @@ -589,7 +584,7 @@ static void compute_correction_factors(int64_t sse, struct afs_statistics *s) * * \sa struct \ref afs_info::last_played, \ref mp_eval_row(). */ -int mood_switch(const char *mood_name, char **msg) +int mood_load(const char *mood_name, char **msg) { int i, ret; struct admissible_array aa = {.size = 0}; @@ -633,7 +628,7 @@ int mood_switch(const char *mood_name, char **msg) if (msg) *msg = get_statistics(aa.m, rnow.tv_sec); ret = aa.m->stats.num; - close_current_mood(); + mood_unload(); current_mood = aa.m; out: free(aa.array); @@ -643,7 +638,7 @@ out: } /* - * Close and re-open the current mood. + * Empty the score table and start over. * * This function is called on events which render the current list of * admissible files useless, for example if an attribute is removed from the @@ -655,15 +650,13 @@ static int reload_current_mood(void) char *mood_name = NULL; assert(current_mood); - ret = clear_score_table(); - if (ret < 0) - return ret; + score_clear(); PARA_NOTICE_LOG("reloading %s\n", current_mood->name? current_mood->name : "(dummy)"); if (current_mood->name) mood_name = para_strdup(current_mood->name); - close_current_mood(); - ret = mood_switch(mood_name, NULL); + mood_unload(); + ret = mood_load(mood_name, NULL); free(mood_name); return ret; }