A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Miika Pekkarinen
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#ifdef HAVE_TAGCACHE
22#ifndef _TAGCACHE_H
23#define _TAGCACHE_H
24
25#include "config.h"
26#include "system.h"
27#include "metadata.h"
28#include "settings.h"
29
30/**
31 Note: When adding new tags, make sure to update index_entry_ec and tags_str in
32 tagcache.c and bump up the header version too.
33 */
34enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
35 tag_filename, tag_composer, tag_comment, tag_albumartist, tag_grouping, tag_year,
36 tag_discnumber, tag_tracknumber, tag_virt_canonicalartist, tag_bitrate, tag_length,
37 tag_playcount, tag_rating, tag_playtime, tag_lastplayed, tag_commitid, tag_mtime,
38 tag_lastelapsed, tag_lastoffset,
39 /* Real tags end here, count them. */
40 TAG_COUNT,
41 /* Virtual tags */
42 tag_virt_basename=TAG_COUNT,
43 tag_virt_length_min, tag_virt_length_sec,
44 tag_virt_playtime_min, tag_virt_playtime_sec,
45 tag_virt_entryage, tag_virt_autoscore,
46 TAG_COUNT_ALL};
47
48/* How many entries to fetch to the seek table at once while searching. */
49#define SEEK_LIST_SIZE 32
50
51#define TAGCACHE_MAX_FILTERS 4
52#define TAGCACHE_MAX_CLAUSES 32
53
54/* Tag to be used on untagged files. */
55#define UNTAGGED "<Untagged>"
56/* Maximum length of a single tag. */
57#define TAG_MAXLEN (MAX_PATH*2)
58/* buffer size for all the (stack allocated & static) buffers handling tc data */
59#define TAGCACHE_BUFSZ (TAG_MAXLEN+32)
60
61/* Numeric tags (we can use these tags with conditional clauses). */
62#define TAGCACHE_NUMERIC_TAGS ((1LU << tag_year) | (1LU << tag_discnumber) | \
63 (1LU << tag_tracknumber) | (1LU << tag_length) | (1LU << tag_bitrate) | \
64 (1LU << tag_playcount) | (1LU << tag_rating) | (1LU << tag_playtime) | \
65 (1LU << tag_lastplayed) | (1LU << tag_commitid) | (1LU << tag_mtime) | \
66 (1LU << tag_lastelapsed) | (1LU << tag_lastoffset) | \
67 (1LU << tag_virt_length_min) | (1LU << tag_virt_length_sec) | \
68 (1LU << tag_virt_playtime_min) | (1LU << tag_virt_playtime_sec) | \
69 (1LU << tag_virt_entryage) | (1LU << tag_virt_autoscore))
70
71#define TAGCACHE_IS_NUMERIC(tag) (BIT_N(tag) & TAGCACHE_NUMERIC_TAGS)
72
73enum clause { clause_none, clause_is, clause_is_not, clause_gt, clause_gteq,
74 clause_lt, clause_lteq, clause_contains, clause_not_contains,
75 clause_begins_with, clause_not_begins_with, clause_ends_with,
76 clause_not_ends_with, clause_oneof,
77 clause_begins_oneof, clause_ends_oneof, clause_not_oneof,
78 clause_not_begins_oneof, clause_not_ends_oneof,
79 clause_logical_or };
80
81struct tagcache_stat {
82 char db_path[MAX_PATHNAME+1]; /* Path to DB root directory */
83
84 bool initialized; /* Is tagcache currently busy? */
85 bool readyvalid; /* Has tagcache ready status been ascertained */
86 bool ready; /* Is tagcache ready to be used? */
87 bool ramcache; /* Is tagcache loaded in ram? */
88 bool commit_delayed; /* Has commit been delayed until next reboot? */
89 bool econ; /* Is endianess correction enabled? */
90 volatile bool syncscreen;/* Synchronous operation with debug screen? */
91 volatile const char
92 *curentry; /* Path of the current entry being scanned. */
93
94 int commit_step; /* Commit progress */
95 int ramcache_allocated; /* Has ram been allocated for ramcache? */
96 int ramcache_used; /* How much ram has been really used */
97 int progress; /* Current progress of disk scan */
98 int processed_entries; /* Scanned disk entries so far */
99 int total_entries; /* Total entries in tagcache */
100 int queue_length; /* Command queue length */
101
102 //const char *uimessage; /* Pending error message. Implement soon. */
103};
104
105enum source_type {source_constant,
106 source_runtime,
107 source_current_path /* dont add items after this.
108 it is used as an index
109 into id3_to_search_mapping */
110 };
111
112struct tagcache_search_clause
113{
114 int tag;
115 int type;
116 bool numeric;
117 int source;
118 long numeric_data;
119 char *str;
120};
121
122struct tagcache_seeklist_entry {
123 int32_t seek;
124 int32_t flag;
125 int32_t idx_id;
126};
127
128struct tagcache_search {
129 /* For internal use only. */
130 int fd, masterfd;
131 int idxfd[TAG_COUNT];
132 struct tagcache_seeklist_entry seeklist[SEEK_LIST_SIZE];
133 int seek_list_count;
134 int32_t filter_tag[TAGCACHE_MAX_FILTERS];
135 int32_t filter_seek[TAGCACHE_MAX_FILTERS];
136 int filter_count;
137 struct tagcache_search_clause *clause[TAGCACHE_MAX_CLAUSES];
138 int clause_count;
139 int list_position;
140 int seek_pos;
141 long position;
142 int entry_count;
143 bool valid;
144 bool initialized;
145 uint32_t *unique_list;
146 int unique_list_capacity;
147 int unique_list_count;
148
149 /* Exported variables. */
150 bool ramsearch; /* Is ram copy of the tagcache being used. */
151 bool ramresult; /* False if result is not static, and must be copied.
152 Currently always false since ramresult buffer is
153 movable */
154 int type; /* The tag type to be searched. Only nonvirtual tags */
155 char *result; /* The result data for all tags. */
156 int result_len; /* Length of the result including \0 */
157 int32_t result_seek; /* Current position in the tag data. */
158 int32_t idx_id; /* Entry number in the master index. */
159};
160
161#ifdef __PCTOOL__
162void tagcache_reverse_scan(void);
163/* call this directly instead of tagcache_build in order to not pull
164 * on global_settings */
165void do_tagcache_build(const char *path[]);
166#endif
167
168const char* tagcache_tag_to_str(int tag);
169
170bool tagcache_find_index(struct tagcache_search *tcs, const char *filename);
171bool tagcache_check_clauses(struct tagcache_search *tcs,
172 struct tagcache_search_clause **clause, int count);
173bool tagcache_search(struct tagcache_search *tcs, int tag);
174void tagcache_search_set_uniqbuf(struct tagcache_search *tcs,
175 void *buffer, long length);
176bool tagcache_search_add_filter(struct tagcache_search *tcs,
177 int tag, int seek);
178bool tagcache_search_add_clause(struct tagcache_search *tcs,
179 struct tagcache_search_clause *clause);
180bool tagcache_get_next(struct tagcache_search *tcs, char *buf, long size);
181bool tagcache_retrieve(struct tagcache_search *tcs, int idxid,
182 int tag, char *buf, long size);
183void tagcache_search_finish(struct tagcache_search *tcs);
184long tagcache_get_numeric(const struct tagcache_search *tcs, int tag);
185long tagcache_increase_serial(void);
186bool tagcache_import_changelog(void);
187bool tagcache_create_changelog(struct tagcache_search *tcs);
188void tagcache_update_numeric(int idx_id, int tag, long data);
189bool tagcache_modify_numeric_entry(struct tagcache_search *tcs,
190 int tag, long data);
191
192struct tagcache_stat* tagcache_get_stat(void);
193int tagcache_get_commit_step(void);
194bool tagcache_prepare_shutdown(void);
195void tagcache_shutdown(void);
196void tagcache_remove_statefile(void);
197
198void tagcache_screensync_event(void);
199void tagcache_screensync_enable(bool state);
200
201#ifdef HAVE_TC_RAMCACHE
202bool tagcache_is_in_ram(void);
203#ifdef HAVE_DIRCACHE
204bool tagcache_fill_tags(struct mp3entry *id3, const char *filename);
205#endif
206void tagcache_unload_ramcache(void);
207#endif
208void tagcache_commit_finalize(void);
209void tagcache_init(void) INIT_ATTR;
210bool tagcache_is_initialized(void);
211bool tagcache_is_fully_initialized(void);
212bool tagcache_is_usable(void);
213void tagcache_start_scan(void);
214void tagcache_stop_scan(void);
215bool tagcache_update(void);
216bool tagcache_rebuild(void);
217int tagcache_get_max_commit_step(void);
218#endif
219#endif