From 36cef88d47b16887106cf13da9edea350ee208d2 Mon Sep 17 00:00:00 2001 From: Christian Soffke Date: Sun, 15 Jan 2023 13:31:31 +0100 Subject: PictureFlow: id3 functions refactoring - Move multiple-id3 functionality into lib - Extract retrieve_id3 function In preparation for using these functions from the Properties plugin. Change-Id: I7252581340680e32df763f1f4b41646a055fe19e --- apps/plugins/lib/mul_id3.c | 182 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 apps/plugins/lib/mul_id3.c (limited to 'apps/plugins/lib/mul_id3.c') diff --git a/apps/plugins/lib/mul_id3.c b/apps/plugins/lib/mul_id3.c new file mode 100644 index 0000000000..5c8f4d9d9c --- /dev/null +++ b/apps/plugins/lib/mul_id3.c @@ -0,0 +1,182 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2023 Christian Soffke + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "plugin.h" +#include "mul_id3.h" + +struct multiple_tracks_id3 { + unsigned long length; + unsigned long filesize; + unsigned long frequency; + unsigned int artist_hash; + unsigned int composer_hash; + unsigned int albumartist_hash; + unsigned int grouping_hash; + unsigned int comment_hash; + unsigned int album_hash; + unsigned int genre_hash; + unsigned int codectype; + unsigned int bitrate; + int year; + bool filesize_ovf; + bool length_ovf; + bool vbr; +}; + +static struct multiple_tracks_id3 mul_id3; + + +/* Calculate modified FNV hash of string + * has good avalanche behaviour and uniform distribution + * see http://home.comcast.net/~bretm/hash/ */ +static unsigned int mfnv(char *str) +{ + const unsigned int p = 16777619; + unsigned int hash = 0x811C9DC5; // 2166136261; + + if (!str) + return 0; + + while(*str) + hash = (hash ^ *str++) * p; + hash += hash << 13; + hash ^= hash >> 7; + hash += hash << 3; + hash ^= hash >> 17; + hash += hash << 5; + return hash; +} + +void init_mul_id3(void) +{ + mul_id3.artist_hash = 0; + mul_id3.album_hash = 0; + mul_id3.genre_hash = 0; + mul_id3.composer_hash = 0; + mul_id3.albumartist_hash = 0; + mul_id3.grouping_hash = 0; + mul_id3.comment_hash = 0; + mul_id3.codectype = 0; + mul_id3.vbr = false; + mul_id3.bitrate = 0; + mul_id3.frequency = 0; + mul_id3.length = 0; + mul_id3.filesize = 0; + mul_id3.year = 0; + mul_id3.length_ovf = false; + mul_id3.filesize_ovf = false; +} + +void collect_id3(struct mp3entry *id3, bool is_first_track) +{ + if (is_first_track) + { + mul_id3.artist_hash = mfnv(id3->artist); + mul_id3.album_hash = mfnv(id3->album); + mul_id3.genre_hash = mfnv(id3->genre_string); + mul_id3.composer_hash = mfnv(id3->composer); + mul_id3.albumartist_hash = mfnv(id3->albumartist); + mul_id3.grouping_hash = mfnv(id3->grouping); + mul_id3.comment_hash = mfnv(id3->comment); + mul_id3.codectype = id3->codectype; + mul_id3.vbr = id3->vbr; + mul_id3.bitrate = id3->bitrate; + mul_id3.frequency = id3->frequency; + mul_id3.year = id3->year; + } + else + { + if (mul_id3.artist_hash && (mfnv(id3->artist) != mul_id3.artist_hash)) + mul_id3.artist_hash = 0; + if (mul_id3.album_hash && (mfnv(id3->album) != mul_id3.album_hash)) + mul_id3.album_hash = 0; + if (mul_id3.genre_hash && (mfnv(id3->genre_string) != mul_id3.genre_hash)) + mul_id3.genre_hash = 0; + if (mul_id3.composer_hash && (mfnv(id3->composer) != mul_id3.composer_hash)) + mul_id3.composer_hash = 0; + if (mul_id3.albumartist_hash && (mfnv(id3->albumartist) != + mul_id3.albumartist_hash)) + mul_id3.albumartist_hash = 0; + if (mul_id3.grouping_hash && (mfnv(id3->grouping) != mul_id3.grouping_hash)) + mul_id3.grouping_hash = 0; + if (mul_id3.comment_hash && (mfnv(id3->comment) != mul_id3.comment_hash)) + mul_id3.comment_hash = 0; + + if (mul_id3.codectype && (id3->codectype != mul_id3.codectype)) + mul_id3.codectype = AFMT_UNKNOWN; + if (mul_id3.bitrate && (id3->bitrate != mul_id3.bitrate || + id3->vbr != mul_id3.vbr)) + mul_id3.bitrate = 0; + if (mul_id3.frequency && (id3->frequency != mul_id3.frequency)) + mul_id3.frequency = 0; + if (mul_id3.year && (id3->year != mul_id3.year)) + mul_id3.year = 0; + } + + if (ULONG_MAX - mul_id3.length < id3->length) + { + mul_id3.length_ovf = true; + mul_id3.length = 0; + } + else if (!mul_id3.length_ovf) + mul_id3.length += id3->length; + + if (INT_MAX - mul_id3.filesize < id3->filesize) /* output_dyn_value expects int */ + { + mul_id3.filesize_ovf = true; + mul_id3.filesize = 0; + } + else if (!mul_id3.filesize_ovf) + mul_id3.filesize += id3->filesize; +} + +void write_id3_mul_tracks(struct mp3entry *id3) +{ + id3->path[0] = '\0'; + id3->title = NULL; + if (!mul_id3.artist_hash) + id3->artist = NULL; + if (!mul_id3.album_hash) + id3->album = NULL; + if (!mul_id3.genre_hash) + id3->genre_string = NULL; + if (!mul_id3.composer_hash) + id3->composer = NULL; + if (!mul_id3.albumartist_hash) + id3->albumartist = NULL; + if (!mul_id3.grouping_hash) + id3->grouping = NULL; + if (!mul_id3.comment_hash) + id3->comment = NULL; + id3->disc_string = NULL; + id3->track_string = NULL; + id3->year_string = NULL; + id3->year = mul_id3.year; + id3->length = mul_id3.length; + id3->filesize = mul_id3.filesize; + id3->frequency = mul_id3.frequency; + id3->bitrate = mul_id3.bitrate; + id3->codectype = mul_id3.codectype; + id3->vbr = mul_id3.vbr; + id3->discnum = 0; + id3->tracknum = 0; + id3->track_level = 0; + id3->album_level = 0; +} -- cgit v1.2.3