1 /*
2  * Copyright 2008-2013 Various Authors
3  * Copyright 2004-2005 Timo Hirvonen
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef CMUS_TRACK_INFO_H
20 #define CMUS_TRACK_INFO_H
21 
22 #include <time.h>
23 #include <stddef.h>
24 #include <stdint.h>
25 #include <stdbool.h>
26 
27 struct track_info {
28 	uint64_t uid;
29 	struct keyval *comments;
30 
31 	// next track_info in the hash table (cache.c)
32 	struct track_info *next;
33 
34 	time_t mtime;
35 	int duration;
36 	long bitrate;
37 	char *codec;
38 	char *codec_profile;
39 	char *filename;
40 
41 	int tracknumber;
42 	int discnumber;
43 	int date;
44 	int originaldate;
45 	double rg_track_gain;
46 	double rg_track_peak;
47 	double rg_album_gain;
48 	double rg_album_peak;
49 	const char *artist;
50 	const char *album;
51 	const char *title;
52 	const char *genre;
53 	const char *comment;
54 	const char *albumartist;
55 	const char *artistsort;
56 	const char *albumsort;
57 	const char *media;
58 
59 	char *collkey_artist;
60 	char *collkey_album;
61 	char *collkey_title;
62 	char *collkey_genre;
63 	char *collkey_comment;
64 	char *collkey_albumartist;
65 
66 	unsigned int play_count;
67 
68 	int is_va_compilation : 1;
69 	int bpm;
70 };
71 
72 typedef size_t sort_key_t;
73 
74 #define SORT_INVALID            ((sort_key_t) (-1))
75 #define SORT_ARTIST        	offsetof(struct track_info, collkey_artist)
76 #define SORT_ALBUM         	offsetof(struct track_info, collkey_album)
77 #define SORT_TITLE         	offsetof(struct track_info, collkey_title)
78 #define SORT_TRACKNUMBER   	offsetof(struct track_info, tracknumber)
79 #define SORT_DISCNUMBER    	offsetof(struct track_info, discnumber)
80 #define SORT_DATE          	offsetof(struct track_info, date)
81 #define SORT_ORIGINALDATE  	offsetof(struct track_info, originaldate)
82 #define SORT_RG_TRACK_GAIN 	offsetof(struct track_info, rg_track_gain)
83 #define SORT_RG_TRACK_PEAK 	offsetof(struct track_info, rg_track_peak)
84 #define SORT_RG_ALBUM_GAIN 	offsetof(struct track_info, rg_album_gain)
85 #define SORT_RG_ALBUM_PEAK 	offsetof(struct track_info, rg_album_peak)
86 #define SORT_GENRE         	offsetof(struct track_info, collkey_genre)
87 #define SORT_COMMENT       	offsetof(struct track_info, collkey_comment)
88 #define SORT_ALBUMARTIST   	offsetof(struct track_info, collkey_albumartist)
89 #define SORT_PLAY_COUNT   	offsetof(struct track_info, play_count)
90 #define SORT_FILENAME      	offsetof(struct track_info, filename)
91 #define SORT_FILEMTIME     	offsetof(struct track_info, mtime)
92 #define SORT_BITRATE       	offsetof(struct track_info, bitrate)
93 #define SORT_CODEC         	offsetof(struct track_info, codec)
94 #define SORT_CODEC_PROFILE 	offsetof(struct track_info, codec_profile)
95 #define SORT_MEDIA		offsetof(struct track_info, media)
96 #define SORT_BPM		offsetof(struct track_info, bpm)
97 #define REV_SORT__START		sizeof(struct track_info)
98 #define REV_SORT_ARTIST		(REV_SORT__START + offsetof(struct track_info, collkey_artist))
99 #define REV_SORT_ALBUM          (REV_SORT__START + offsetof(struct track_info, collkey_album))
100 #define REV_SORT_TITLE          (REV_SORT__START + offsetof(struct track_info, collkey_title))
101 #define REV_SORT_PLAY_COUNT   	(REV_SORT__START + offsetof(struct track_info, play_count))
102 #define REV_SORT_TRACKNUMBER    (REV_SORT__START + offsetof(struct track_info, tracknumber))
103 #define REV_SORT_DISCNUMBER     (REV_SORT__START + offsetof(struct track_info, discnumber))
104 #define REV_SORT_DATE           (REV_SORT__START + offsetof(struct track_info, date))
105 #define REV_SORT_ORIGINALDATE   (REV_SORT__START + offsetof(struct track_info, originaldate))
106 #define REV_SORT_RG_TRACK_GAIN  (REV_SORT__START + offsetof(struct track_info, rg_track_gain))
107 #define REV_SORT_RG_TRACK_PEAK  (REV_SORT__START + offsetof(struct track_info, rg_track_peak))
108 #define REV_SORT_RG_ALBUM_GAIN  (REV_SORT__START + offsetof(struct track_info, rg_album_gain))
109 #define REV_SORT_RG_ALBUM_PEAK  (REV_SORT__START + offsetof(struct track_info, rg_album_peak))
110 #define REV_SORT_GENRE          (REV_SORT__START + offsetof(struct track_info, collkey_genre))
111 #define REV_SORT_COMMENT        (REV_SORT__START + offsetof(struct track_info, collkey_comment))
112 #define REV_SORT_ALBUMARTIST    (REV_SORT__START + offsetof(struct track_info, collkey_albumartist))
113 #define REV_SORT_FILENAME       (REV_SORT__START + offsetof(struct track_info, filename))
114 #define REV_SORT_FILEMTIME      (REV_SORT__START + offsetof(struct track_info, mtime))
115 #define REV_SORT_BITRATE        (REV_SORT__START + offsetof(struct track_info, bitrate))
116 #define REV_SORT_CODEC          (REV_SORT__START + offsetof(struct track_info, codec))
117 #define REV_SORT_CODEC_PROFILE  (REV_SORT__START + offsetof(struct track_info, codec_profile))
118 #define REV_SORT_MEDIA          (REV_SORT__START + offsetof(struct track_info, media))
119 #define REV_SORT_BPM            (REV_SORT__START + offsetof(struct track_info, bpm))
120 
121 #define TI_MATCH_ARTIST       (1 << 0)
122 #define TI_MATCH_ALBUM        (1 << 1)
123 #define TI_MATCH_TITLE        (1 << 2)
124 #define TI_MATCH_ALBUMARTIST  (1 << 3)
125 #define TI_MATCH_ALL          (~0)
126 
127 /* initializes only filename and ref */
128 struct track_info *track_info_new(const char *filename);
129 void track_info_set_comments(struct track_info *ti, struct keyval *comments);
130 
131 void track_info_ref(struct track_info *ti);
132 void track_info_unref(struct track_info *ti);
133 bool track_info_unique_ref(struct track_info *ti);
134 
135 /*
136  * returns: 1 if @ti has any of the following tags: artist, album, title
137  *          0 otherwise
138  */
139 int track_info_has_tag(const struct track_info *ti);
140 
141 /*
142  * @flags  fields to search in (TI_MATCH_*)
143  *
144  * returns: 1 if all words in @text are found to match defined fields (@flags) in @ti
145  *          0 otherwise
146  */
147 int track_info_matches(const struct track_info *ti, const char *text, unsigned int flags);
148 
149 /*
150  * @flags            fields to search in (TI_MATCH_*)
151  * @exclude_flags    fields which must not match (TI_MATCH_*)
152  * @match_all_words  if true, all words must be found in @ti
153  *
154  * returns: 1 if all/any words in @text are found to match defined fields (@flags) in @ti
155  *          0 otherwise
156  */
157 int track_info_matches_full(const struct track_info *ti, const char *text, unsigned int flags,
158 		unsigned int exclude_flags, int match_all_words);
159 
160 int track_info_cmp(const struct track_info *a, const struct track_info *b, const sort_key_t *keys);
161 
162 sort_key_t *parse_sort_keys(const char *value);
163 const char *sort_key_to_str(sort_key_t key);
164 void sort_keys_to_str(const sort_key_t *keys, char *buf, size_t bufsize);
165 
166 #endif
167