diff options
Diffstat (limited to 'apps/plugins/lib')
-rw-r--r-- | apps/plugins/lib/SOURCES | 6 | ||||
-rw-r--r-- | apps/plugins/lib/id3.c | 46 | ||||
-rw-r--r-- | apps/plugins/lib/id3.h | 26 | ||||
-rw-r--r-- | apps/plugins/lib/mul_id3.c | 182 | ||||
-rw-r--r-- | apps/plugins/lib/mul_id3.h | 28 |
5 files changed, 288 insertions, 0 deletions
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index bff9017404..09a8b1c5ed 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES | |||
@@ -69,3 +69,9 @@ kbd_helper.c | |||
69 | #ifdef HAVE_TOUCHSCREEN | 69 | #ifdef HAVE_TOUCHSCREEN |
70 | pluginlib_touchscreen.c | 70 | pluginlib_touchscreen.c |
71 | #endif | 71 | #endif |
72 | |||
73 | id3.c | ||
74 | |||
75 | #ifdef HAVE_TAGCACHE | ||
76 | mul_id3.c | ||
77 | #endif | ||
diff --git a/apps/plugins/lib/id3.c b/apps/plugins/lib/id3.c new file mode 100644 index 0000000000..0ce1736ffe --- /dev/null +++ b/apps/plugins/lib/id3.c | |||
@@ -0,0 +1,46 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2023 Christian Soffke | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "plugin.h" | ||
22 | |||
23 | bool retrieve_id3(struct mp3entry *id3, const char* file, bool try_tagcache) | ||
24 | { | ||
25 | bool ret = false; | ||
26 | int fd; | ||
27 | |||
28 | #if defined (HAVE_TAGCACHE) && defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE) | ||
29 | if (try_tagcache && rb->tagcache_fill_tags(id3, file)) | ||
30 | { | ||
31 | rb->strlcpy(id3->path, file, sizeof(id3->path)); | ||
32 | return true; | ||
33 | } | ||
34 | #else | ||
35 | (void) try_tagcache; | ||
36 | #endif | ||
37 | |||
38 | fd = rb->open(file, O_RDONLY); | ||
39 | if (fd >= 0) | ||
40 | { | ||
41 | if (rb->get_metadata(id3, fd, file)) | ||
42 | ret = true; | ||
43 | rb->close(fd); | ||
44 | } | ||
45 | return ret; | ||
46 | } | ||
diff --git a/apps/plugins/lib/id3.h b/apps/plugins/lib/id3.h new file mode 100644 index 0000000000..292556d0c4 --- /dev/null +++ b/apps/plugins/lib/id3.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2023 Christian Soffke | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef ID3_H | ||
22 | #define ID3_H | ||
23 | |||
24 | bool retrieve_id3(struct mp3entry *id3, const char* file, bool try_tagcache); | ||
25 | |||
26 | #endif /* ID3_H */ \ No newline at end of file | ||
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2023 Christian Soffke | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "plugin.h" | ||
22 | #include "mul_id3.h" | ||
23 | |||
24 | struct multiple_tracks_id3 { | ||
25 | unsigned long length; | ||
26 | unsigned long filesize; | ||
27 | unsigned long frequency; | ||
28 | unsigned int artist_hash; | ||
29 | unsigned int composer_hash; | ||
30 | unsigned int albumartist_hash; | ||
31 | unsigned int grouping_hash; | ||
32 | unsigned int comment_hash; | ||
33 | unsigned int album_hash; | ||
34 | unsigned int genre_hash; | ||
35 | unsigned int codectype; | ||
36 | unsigned int bitrate; | ||
37 | int year; | ||
38 | bool filesize_ovf; | ||
39 | bool length_ovf; | ||
40 | bool vbr; | ||
41 | }; | ||
42 | |||
43 | static struct multiple_tracks_id3 mul_id3; | ||
44 | |||
45 | |||
46 | /* Calculate modified FNV hash of string | ||
47 | * has good avalanche behaviour and uniform distribution | ||
48 | * see http://home.comcast.net/~bretm/hash/ */ | ||
49 | static unsigned int mfnv(char *str) | ||
50 | { | ||
51 | const unsigned int p = 16777619; | ||
52 | unsigned int hash = 0x811C9DC5; // 2166136261; | ||
53 | |||
54 | if (!str) | ||
55 | return 0; | ||
56 | |||
57 | while(*str) | ||
58 | hash = (hash ^ *str++) * p; | ||
59 | hash += hash << 13; | ||
60 | hash ^= hash >> 7; | ||
61 | hash += hash << 3; | ||
62 | hash ^= hash >> 17; | ||
63 | hash += hash << 5; | ||
64 | return hash; | ||
65 | } | ||
66 | |||
67 | void init_mul_id3(void) | ||
68 | { | ||
69 | mul_id3.artist_hash = 0; | ||
70 | mul_id3.album_hash = 0; | ||
71 | mul_id3.genre_hash = 0; | ||
72 | mul_id3.composer_hash = 0; | ||
73 | mul_id3.albumartist_hash = 0; | ||
74 | mul_id3.grouping_hash = 0; | ||
75 | mul_id3.comment_hash = 0; | ||
76 | mul_id3.codectype = 0; | ||
77 | mul_id3.vbr = false; | ||
78 | mul_id3.bitrate = 0; | ||
79 | mul_id3.frequency = 0; | ||
80 | mul_id3.length = 0; | ||
81 | mul_id3.filesize = 0; | ||
82 | mul_id3.year = 0; | ||
83 | mul_id3.length_ovf = false; | ||
84 | mul_id3.filesize_ovf = false; | ||
85 | } | ||
86 | |||
87 | void collect_id3(struct mp3entry *id3, bool is_first_track) | ||
88 | { | ||
89 | if (is_first_track) | ||
90 | { | ||
91 | mul_id3.artist_hash = mfnv(id3->artist); | ||
92 | mul_id3.album_hash = mfnv(id3->album); | ||
93 | mul_id3.genre_hash = mfnv(id3->genre_string); | ||
94 | mul_id3.composer_hash = mfnv(id3->composer); | ||
95 | mul_id3.albumartist_hash = mfnv(id3->albumartist); | ||
96 | mul_id3.grouping_hash = mfnv(id3->grouping); | ||
97 | mul_id3.comment_hash = mfnv(id3->comment); | ||
98 | mul_id3.codectype = id3->codectype; | ||
99 | mul_id3.vbr = id3->vbr; | ||
100 | mul_id3.bitrate = id3->bitrate; | ||
101 | mul_id3.frequency = id3->frequency; | ||
102 | mul_id3.year = id3->year; | ||
103 | } | ||
104 | else | ||
105 | { | ||
106 | if (mul_id3.artist_hash && (mfnv(id3->artist) != mul_id3.artist_hash)) | ||
107 | mul_id3.artist_hash = 0; | ||
108 | if (mul_id3.album_hash && (mfnv(id3->album) != mul_id3.album_hash)) | ||
109 | mul_id3.album_hash = 0; | ||
110 | if (mul_id3.genre_hash && (mfnv(id3->genre_string) != mul_id3.genre_hash)) | ||
111 | mul_id3.genre_hash = 0; | ||
112 | if (mul_id3.composer_hash && (mfnv(id3->composer) != mul_id3.composer_hash)) | ||
113 | mul_id3.composer_hash = 0; | ||
114 | if (mul_id3.albumartist_hash && (mfnv(id3->albumartist) != | ||
115 | mul_id3.albumartist_hash)) | ||
116 | mul_id3.albumartist_hash = 0; | ||
117 | if (mul_id3.grouping_hash && (mfnv(id3->grouping) != mul_id3.grouping_hash)) | ||
118 | mul_id3.grouping_hash = 0; | ||
119 | if (mul_id3.comment_hash && (mfnv(id3->comment) != mul_id3.comment_hash)) | ||
120 | mul_id3.comment_hash = 0; | ||
121 | |||
122 | if (mul_id3.codectype && (id3->codectype != mul_id3.codectype)) | ||
123 | mul_id3.codectype = AFMT_UNKNOWN; | ||
124 | if (mul_id3.bitrate && (id3->bitrate != mul_id3.bitrate || | ||
125 | id3->vbr != mul_id3.vbr)) | ||
126 | mul_id3.bitrate = 0; | ||
127 | if (mul_id3.frequency && (id3->frequency != mul_id3.frequency)) | ||
128 | mul_id3.frequency = 0; | ||
129 | if (mul_id3.year && (id3->year != mul_id3.year)) | ||
130 | mul_id3.year = 0; | ||
131 | } | ||
132 | |||
133 | if (ULONG_MAX - mul_id3.length < id3->length) | ||
134 | { | ||
135 | mul_id3.length_ovf = true; | ||
136 | mul_id3.length = 0; | ||
137 | } | ||
138 | else if (!mul_id3.length_ovf) | ||
139 | mul_id3.length += id3->length; | ||
140 | |||
141 | if (INT_MAX - mul_id3.filesize < id3->filesize) /* output_dyn_value expects int */ | ||
142 | { | ||
143 | mul_id3.filesize_ovf = true; | ||
144 | mul_id3.filesize = 0; | ||
145 | } | ||
146 | else if (!mul_id3.filesize_ovf) | ||
147 | mul_id3.filesize += id3->filesize; | ||
148 | } | ||
149 | |||
150 | void write_id3_mul_tracks(struct mp3entry *id3) | ||
151 | { | ||
152 | id3->path[0] = '\0'; | ||
153 | id3->title = NULL; | ||
154 | if (!mul_id3.artist_hash) | ||
155 | id3->artist = NULL; | ||
156 | if (!mul_id3.album_hash) | ||
157 | id3->album = NULL; | ||
158 | if (!mul_id3.genre_hash) | ||
159 | id3->genre_string = NULL; | ||
160 | if (!mul_id3.composer_hash) | ||
161 | id3->composer = NULL; | ||
162 | if (!mul_id3.albumartist_hash) | ||
163 | id3->albumartist = NULL; | ||
164 | if (!mul_id3.grouping_hash) | ||
165 | id3->grouping = NULL; | ||
166 | if (!mul_id3.comment_hash) | ||
167 | id3->comment = NULL; | ||
168 | id3->disc_string = NULL; | ||
169 | id3->track_string = NULL; | ||
170 | id3->year_string = NULL; | ||
171 | id3->year = mul_id3.year; | ||
172 | id3->length = mul_id3.length; | ||
173 | id3->filesize = mul_id3.filesize; | ||
174 | id3->frequency = mul_id3.frequency; | ||
175 | id3->bitrate = mul_id3.bitrate; | ||
176 | id3->codectype = mul_id3.codectype; | ||
177 | id3->vbr = mul_id3.vbr; | ||
178 | id3->discnum = 0; | ||
179 | id3->tracknum = 0; | ||
180 | id3->track_level = 0; | ||
181 | id3->album_level = 0; | ||
182 | } | ||
diff --git a/apps/plugins/lib/mul_id3.h b/apps/plugins/lib/mul_id3.h new file mode 100644 index 0000000000..71da10e87e --- /dev/null +++ b/apps/plugins/lib/mul_id3.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2023 Christian Soffke | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef MUL_ID3_H | ||
22 | #define MUL_ID3_H | ||
23 | |||
24 | void init_mul_id3(void); | ||
25 | void collect_id3(struct mp3entry *id3, bool is_first_track); | ||
26 | void write_id3_mul_tracks(struct mp3entry *id3); | ||
27 | |||
28 | #endif /* MUL_ID3_H */ \ No newline at end of file | ||