From: Andre Noll Date: Thu, 10 Feb 2022 15:34:19 +0000 (+0100) Subject: Merge branch 'refs/heads/t/rm_v1_moods' X-Git-Tag: v0.7.0~8 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=88bf6848d1c;p=paraslash.git Merge branch 'refs/heads/t/rm_v1_moods' A single commit which removes a long obsolete feature. Cooking for almost a year. * refs/heads/t/rm_v1_moods: Remove support for version 1 moods. --- 88bf6848d1c58ad0e0d9b62d7da2a81cea5bf0ff diff --cc NEWS.md index 320dfbd5,3e3e7abf..a31aeaf1 --- a/NEWS.md +++ b/NEWS.md @@@ -1,64 -1,6 +1,65 @@@ NEWS ==== +--------------------------------------- +0.7.0 (to be announced) "seismic orbit" +--------------------------------------- + +- The new "duration" keyword of the mood grammar makes it possible to + impose a constraint on the duration of the admissible files. ++- The long deprecated version 1 mood syntax is no longer supported. +- Paraslash writers handle early end-of-file more gracefully. +- The alsa writer no longer warns about spurious underruns. +- The score formula of the audio file selector has been reworked. +- Cleanups of the doubly linked lists code. +- New option for configure: --enable-ubsan to detect and report undefined + behaviour. +- The "tasks" server command has been removed. + +Downloads: +[tarball](./releases/paraslash-git.tar.xz) + +-------------------------------------- +0.6.4 (2021-11-04) "fuzzy calibration" +-------------------------------------- + +This point release contains a fair number of fixes but no new features. +This marks the end of the 0.6 development, although paraslash-0.6 will +still be supported for some time and subsequent maintenance releases +may follow. + +- The udp sender no longer crashes when empty chunks are encountered. +- Fix a double-free bug in the exit path of the server. +- The "jmp" command now errors out when given a negative percentage. +- A fix for a bug in para_afh which triggered on the attempt to modify + the tags of an invalid mp4 file. +- A memory leak in para_afh has been fixed. +- The udp sender no longer sends multiple EOF packets. +- Some gcc warnings have been silenced. +- Minor log level adjustments and documentation improvements. + +Downloads: +[tarball](./releases/paraslash-0.6.4.tar.xz), +[signature](./releases/paraslash-0.6.4.tar.xz.asc) + +--------------------------------------- +0.5.9 (2021-11-04) "reversed dimension" +--------------------------------------- + +This release contains a few important fixes which have accumulated in +the maint branch. The paraslash-0.5.x series has now reached its end +of life and will no longer be supported. All users should upgrade to +a more recent version at this point. + +- Fix an issue with the bash completion script. +- Initialize the random seed also when using libgrypt. +- Fix some compiler warnings in the resample filter +- Don't return spurious errors from the ff server command. + +Downloads: +[tarball](./releases/paraslash-0.5.9.tar.bz2), +[signature](./releases/paraslash-0.5.9.tar.bz2.asc) + ---------------------------------------- 0.6.3 (2021-02-18) "generalized activity" ----------------------------------------- diff --cc mood.c index bf3f39fa,ccc57a03..bbe84734 --- a/mood.c +++ b/mood.c @@@ -48,34 -41,8 +47,8 @@@ struct afs_statistics /** Number of admissible files */ unsigned num; }; -static struct afs_statistics statistics; +static struct afs_statistics statistics = {.normalization_divisor = 1}; - /** - * Each line of the current mood corresponds to a mood_item. - */ - struct mood_item { - /** The method this line is referring to. */ - const struct mood_method *method; - /** The data structure computed by the mood parser. */ - void *parser_data; - /** The given score value, or zero if none was given. */ - int32_t score_arg; - /** Non-zero if random scoring was requested. */ - int random_score; - /** Whether the "not" keyword was given in the mood line. */ - int logical_not; - /** The position in the list of items. */ - struct list_head mood_item_node; - }; - - /* - * Created from the mood definition by \ref change_current_mood(). - * - * When a mood is opened, each line of its definition is investigated, and a - * corresponding mood item is produced. Each mood line starts with accept, - * deny, or score which determines the type of the mood line. For each such - * type a linked list is maintained whose entries are the mood items. - */ struct mood { /** The name of this mood. */ char *name; @@@ -505,59 -204,20 +210,57 @@@ int mood_check_callback(struct afs_call check_mood)); } +/* + * The normalized num_played and last_played values are defined as + * + * nn := -(np - mean_n) / sigma_n and nl := -(lp - mean_l) / sigma_l + * + * For a (hypothetical) file with np = 0 and lp = now we thus have + * + * nn = mean_n / sigma_n =: hn > 0 + * nl = -(now - mean_l) / sigma_l =: hl < 0 + * + * We design the score function so that both contributions get the same + * weight. Define the np and lp score of an arbitrary file as + * + * sn := nn * -hl and sl := nl * hn + * + * Example: + * num_played mean/sigma: 87/14 + * last_played mean/sigma: 45/32 days + * + * We have hn = 87 / 14 = 6.21 and hl = -45 / 32 = -1.41. Multiplying + * nn of every file with the correction factor 1.41 and nl with + * 6.21 makes the weight of the two contributions equal. + * + * The total score s := sn + sl has the representation + * + * s = -cn * (np - mean_n) - cl * (lp - mean_l) + * + * with positive correction factors + * + * cn = (now - mean_l) / (sqrt(ql) * sqrt(qn) / n) + * cl = mean_n / (sqrt(ql) * sqrt(qn) / n) + * + * where ql and qn are the quadratic deviations stored in the statistics + * structure and n is the number of admissible files. To avoid integer + * overflows and rounding errors we store the common divisor of the + * correction factors separately. + */ - static long compute_score(struct afs_info *afsi, long mood_score) + 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) { - int64_t mean_n, mean_l,score_n, score_l; - - assert(statistics.normalization_divisor > 0); - assert(statistics.num > 0); - mean_n = statistics.num_played_sum / statistics.num; - mean_l = statistics.last_played_sum / statistics.num; - - score_n = -((int64_t)afsi->num_played - mean_n) - * statistics.num_played_correction - / statistics.normalization_divisor; - score_l = -((int64_t)afsi->last_played - mean_l) - * statistics.last_played_correction - / statistics.normalization_divisor; - return (mood_score + score_n + score_l) / 3; + long score = -normalized_value(afsi->num_played, statistics.num, + statistics.num_played_sum, statistics.num_played_qd); + score -= normalized_value(afsi->last_played, statistics.num, + statistics.last_played_sum, statistics.last_played_qd); + return score / 2; } static int add_afs_statistics(const struct osl_row *row) @@@ -972,12 -585,8 +654,11 @@@ int change_current_mood(const char *moo *errmsg = make_message("audio file loop failed"); return ret; } + clock_get_realtime(&rnow); + compute_correction_factors(rnow.tv_sec); + log_statistics(rnow.tv_sec); for (i = 0; i < statistics.num; i++) { - struct admissible_file_info *a = aa.array + i; - ret = add_to_score_table(a->aft_row, a->score); + ret = add_to_score_table(aa.array[i]); if (ret < 0) { if (errmsg) *errmsg = make_message(