X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=mood.c;h=a63d4d2af5d10d7b64c319d915e00b9b7ea62e89;hp=584c46b8fa375f24d2f87492d44f67ac902fa98b;hb=62f16302b6cdb35de8b33894858cec81b34639be;hpb=3d3a2f50a05501cf27f1155629799953f952bd4b diff --git a/mood.c b/mood.c index 584c46b8..a63d4d2a 100644 --- a/mood.c +++ b/mood.c @@ -1,8 +1,4 @@ -/* - * Copyright (C) 2007 Andre Noll - * - * Licensed under the GPL v2. For licencing details see COPYING. - */ +/* Copyright (C) 2007 Andre Noll , see file COPYING. */ /** \file mood.c Paraslash's mood handling functions. */ @@ -93,32 +89,60 @@ struct mood { */ static struct mood *current_mood; -/** - * Rough approximation to sqrt. +/* + * Find the position of the most-significant set bit. * - * \param x Integer of which to calculate the sqrt. + * Copied and slightly adapted from the linux source tree, version 4.9.39 + * (2017-07). + */ +__a_const static uint32_t fls64(uint64_t v) +{ + int n = 63; + const uint64_t ones = ~(uint64_t)0U; + + if ((v & (ones << 32)) == 0) { + n -= 32; + v <<= 32; + } + if ((v & (ones << (64 - 16))) == 0) { + n -= 16; + v <<= 16; + } + if ((v & (ones << (64 - 8))) == 0) { + n -= 8; + v <<= 8; + } + if ((v & (ones << (64 - 4))) == 0) { + n -= 4; + v <<= 4; + } + if ((v & (ones << (64 - 2))) == 0) { + n -= 2; + v <<= 2; + } + if ((v & (ones << (64 - 1))) == 0) + n -= 1; + return n; +} + +/* + * Compute the integer square root floor(sqrt(x)). * - * \return An integer res with res * res <= x. + * Taken 2007 from the linux source tree. */ __a_const static uint64_t int_sqrt(uint64_t x) { - uint64_t op, res, one = 1; - op = x; - res = 0; - - one = one << 62; - while (one > op) - one >>= 2; + uint64_t op = x, res = 0, one = 1; + one = one << (fls64(x) & ~one); while (one != 0) { if (op >= res + one) { op = op - (res + one); - res = res + 2 * one; + res = res + 2 * one; } res /= 2; one /= 4; } -// PARA_NOTICE_LOG("sqrt(%llu) = %llu\n", x, res); return res; } @@ -394,10 +418,13 @@ static int load_mood(const struct osl_row *mood_row, struct mood **m, *m = NULL; ret = mood_get_name_and_def_by_row(mood_row, &mood_name, &mood_def); - if (ret < 0) + if (ret < 0) { + if (errmsg) + *errmsg = make_message( + "could not read mood definition"); return ret; - if (!*mood_name) - return -E_DUMMY_ROW; + } + assert(*mood_name); mlpd.m = alloc_new_mood(mood_name); ret = for_each_line(FELF_READ_ONLY, mood_def.data, mood_def.size, parse_mood_line, &mlpd); @@ -852,7 +879,9 @@ int change_current_mood(const char *mood_name, char **errmsg) }; ret = osl(osl_get_row(moods_table, BLOBCOL_NAME, &obj, &row)); if (ret < 0) { - PARA_NOTICE_LOG("no such mood: %s\n", mood_name); + if (errmsg) + *errmsg = make_message("no such mood: %s", + mood_name); return ret; } ret = load_mood(row, &m, errmsg); @@ -867,13 +896,20 @@ int change_current_mood(const char *mood_name, char **errmsg) aa.m = current_mood; PARA_NOTICE_LOG("computing statistics of admissible files\n"); ret = audio_file_loop(&aa, add_if_admissible); - if (ret < 0) + if (ret < 0) { + if (errmsg) + *errmsg = make_message("audio file loop failed"); return ret; + } 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); - if (ret < 0) + if (ret < 0) { + if (errmsg) + *errmsg = make_message( + "could not add row to score table"); goto out; + } } log_statistics(); ret = statistics.num;