From c5fe75ac10d83b071187ee17dabf7df5d4bf0709 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Tue, 8 Mar 2022 18:46:07 +0100 Subject: [PATCH] Clean up and rename change_current_mood(). Move the code which destroys the current mood to the end of the function so that we can still return to the old mood if something goes awry. To make this work, various functions need to be adjusted to no longer refer to to afs statistics via the global current_mood pointer. Pass a pointer to the statistics structure to those. Also get rid of the local mood pointer variable in favor of ->m of struct admissible_array. Rename the function because it is public and deserves the mood_ prefix. --- afs.c | 4 ++-- mood.c | 70 +++++++++++++++++++++++++--------------------------------- mood.h | 2 +- mp.c | 2 +- 4 files changed, 34 insertions(+), 44 deletions(-) diff --git a/afs.c b/afs.c index 72e7accc..4d473dc1 100644 --- a/afs.c +++ b/afs.c @@ -430,7 +430,7 @@ static int activate_mood_or_playlist(const char *arg, int *num_admissible, if (!arg) { mode = PLAY_MODE_MOOD; - ret = change_current_mood(NULL, errmsg); + ret = mood_switch(NULL, errmsg); if (ret < 0) { if (num_admissible) *num_admissible = 0; @@ -441,7 +441,7 @@ static int activate_mood_or_playlist(const char *arg, int *num_admissible, ret = playlist_open(arg + 2, errmsg); mode = PLAY_MODE_PLAYLIST; } else if (!strncmp(arg, "m/", 2)) { - ret = change_current_mood(arg + 2, errmsg); + ret = mood_switch(arg + 2, errmsg); mode = PLAY_MODE_MOOD; } else { if (errmsg) diff --git a/mood.c b/mood.c index 5b0ddfdd..db0dfaee 100644 --- a/mood.c +++ b/mood.c @@ -259,9 +259,9 @@ static int64_t normalized_value(int64_t x, int64_t n, int64_t sum, int64_t qd) return 100 * (n * x - sum) / (int64_t)int_sqrt(n) / (int64_t)int_sqrt(qd); } -static long compute_score(struct afs_info *afsi) +static long compute_score(struct afs_info *afsi, + const struct afs_statistics *stats) { - const struct afs_statistics *stats = ¤t_mood->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, @@ -269,12 +269,12 @@ static long compute_score(struct afs_info *afsi) return score / 2; } -static int add_afs_statistics(const struct osl_row *row) +static int add_afs_statistics(const struct osl_row *row, + struct afs_statistics *stats) { uint64_t n, x, s, q; struct afs_info afsi; int ret; - struct afs_statistics *stats = ¤t_mood->stats; ret = get_afsi_of_row(row, &afsi); if (ret < 0) @@ -360,8 +360,8 @@ struct admissible_array { */ static int add_if_admissible(struct osl_row *aft_row, void *data) { - const struct afs_statistics *stats = ¤t_mood->stats; struct admissible_array *aa = data; + struct afs_statistics *stats = &aa->m->stats; if (!mp_eval_row(aft_row, aa->m->parser_context)) return 0; @@ -372,7 +372,7 @@ static int add_if_admissible(struct osl_row *aft_row, void *data) sizeof(struct osl_row *)); } aa->array[stats->num] = aft_row; - return add_afs_statistics(aft_row); + return add_afs_statistics(aft_row, stats); } /** @@ -434,7 +434,8 @@ static void update_afs_statistics(struct afs_info *old_afsi, stats->num_played_sum += new_afsi->num_played - old_afsi->num_played; } -static int add_to_score_table(const struct osl_row *aft_row) +static int add_to_score_table(const struct osl_row *aft_row, + const struct afs_statistics *stats) { long score; struct afs_info afsi; @@ -442,7 +443,7 @@ static int add_to_score_table(const struct osl_row *aft_row) if (ret < 0) return ret; - score = compute_score(&afsi); + score = compute_score(&afsi, stats); return score_add(aft_row, score); } @@ -507,10 +508,10 @@ static int mood_update_audio_file(const struct osl_row *aft_row, if (was_admissible && !is_admissible) return delete_from_statistics_and_score_table(aft_row); if (!was_admissible && is_admissible) { - ret = add_afs_statistics(aft_row); + ret = add_afs_statistics(aft_row, ¤t_mood->stats); if (ret < 0) return ret; - return add_to_score_table(aft_row); + return add_to_score_table(aft_row, ¤t_mood->stats); } /* update score */ ret = get_afsi_of_row(aft_row, &afsi); @@ -518,7 +519,7 @@ static int mood_update_audio_file(const struct osl_row *aft_row, return ret; if (old_afsi) update_afs_statistics(old_afsi, &afsi); - score = compute_score(&afsi); + score = compute_score(&afsi, ¤t_mood->stats); PARA_DEBUG_LOG("score: %li\n", score); percent = (score + 100) / 3; if (percent > 100) @@ -530,15 +531,11 @@ static int mood_update_audio_file(const struct osl_row *aft_row, } /* sse: seconds since epoch. */ -static void log_statistics(int64_t sse) +static void log_statistics(struct afs_statistics *stats, int64_t sse) { - const struct afs_statistics *stats = ¤t_mood->stats; unsigned n = stats->num; int mean_days, sigma_days; - assert(current_mood); - PARA_NOTICE_LOG("loaded mood %s\n", current_mood->name? - current_mood->name : "(dummy)"); if (!n) { PARA_WARNING_LOG("no admissible files\n"); return; @@ -569,10 +566,8 @@ void close_current_mood(void) current_mood = NULL; } -static void compute_correction_factors(int64_t sse) +static void compute_correction_factors(int64_t sse, struct afs_statistics *s) { - struct afs_statistics *s = ¤t_mood->stats; - if (s->num > 0) { s->normalization_divisor = int_sqrt(s->last_played_qd) * int_sqrt(s->num_played_qd) / s->num / 100; @@ -605,13 +600,10 @@ static void compute_correction_factors(int64_t sse) * * \sa struct \ref afs_info::last_played, \ref mp_eval_row(). */ -int change_current_mood(const char *mood_name, char **errmsg) +int mood_switch(const char *mood_name, char **errmsg) { int i, ret; - struct admissible_array aa = { - .size = 0, - .array = NULL - }; + struct admissible_array aa = {.size = 0}; /* * We can not use the "now" pointer from sched.c here because we are * called before schedule(), which initializes "now". @@ -619,17 +611,11 @@ int change_current_mood(const char *mood_name, char **errmsg) struct timeval rnow; if (mood_name) { - struct mood *m; - ret = init_mood_parser(mood_name, &m, errmsg); + ret = init_mood_parser(mood_name, &aa.m, errmsg); if (ret < 0) return ret; - close_current_mood(); - current_mood = m; - } else { /* load dummy mood */ - close_current_mood(); - current_mood = alloc_new_mood(NULL); - } - aa.m = current_mood; + } else /* load dummy mood */ + aa.m = alloc_new_mood(NULL); PARA_NOTICE_LOG("computing statistics of admissible files\n"); ret = audio_file_loop(&aa, add_if_admissible); if (ret < 0) { @@ -638,10 +624,10 @@ int change_current_mood(const char *mood_name, char **errmsg) goto out; } clock_get_realtime(&rnow); - compute_correction_factors(rnow.tv_sec); - log_statistics(rnow.tv_sec); - for (i = 0; i < current_mood->stats.num; i++) { - ret = add_to_score_table(aa.array[i]); + compute_correction_factors(rnow.tv_sec, &aa.m->stats); + log_statistics(&aa.m->stats, rnow.tv_sec); + for (i = 0; i < aa.m->stats.num; i++) { + ret = add_to_score_table(aa.array[i], &aa.m->stats); if (ret < 0) { if (errmsg) *errmsg = make_message( @@ -649,11 +635,15 @@ int change_current_mood(const char *mood_name, char **errmsg) goto out; } } - ret = current_mood->stats.num; + /* success */ + close_current_mood(); + current_mood = aa.m; + PARA_NOTICE_LOG("loaded mood %s\n", mood_name? mood_name : "(dummy)"); + ret = aa.m->stats.num; out: free(aa.array); if (ret < 0) - close_current_mood(); + destroy_mood(aa.m); return ret; } @@ -678,7 +668,7 @@ static int reload_current_mood(void) if (current_mood->name) mood_name = para_strdup(current_mood->name); close_current_mood(); - ret = change_current_mood(mood_name, NULL); + ret = mood_switch(mood_name, NULL); free(mood_name); return ret; } diff --git a/mood.h b/mood.h index fcfe1efc..a4b262b4 100644 --- a/mood.h +++ b/mood.h @@ -2,6 +2,6 @@ /** \file mood.h Public functions of mood.c. */ -int change_current_mood(const char *mood_name, char **errmsg); +int mood_switch(const char *mood_name, char **errmsg); void close_current_mood(void); int mood_check_callback(struct afs_callback_arg *aca); diff --git a/mp.c b/mp.c index fb5a0c07..df030ead 100644 --- a/mp.c +++ b/mp.c @@ -557,7 +557,7 @@ int mp_init(const char *definition, int nbytes, struct mp_context **result, * function returns true (without looking at the audio file metadata) to * indicate that the given audio file should be considered admissible. * - * \sa \ref change_current_mood(), \ref mp_eval_ast(). + * \sa \ref mood_switch(), \ref mp_eval_ast(). */ bool mp_eval_row(const struct osl_row *aft_row, struct mp_context *ctx) { -- 2.39.5