annotate foosdk/sdk/foobar2000/SDK/file_info.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "foobar2000-sdk-pch.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "file_info.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "console.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include "filesystem.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include <pfc/unicode-normalize.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 #ifndef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #define strcat_s strcat
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #define _atoi64 atoll
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 static constexpr char info_WAVEFORMATEXTENSIBLE_CHANNEL_MASK[] = "WAVEFORMATEXTENSIBLE_CHANNEL_MASK";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 t_size file_info::meta_find_ex(const char * p_name,t_size p_name_length) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 t_size n, m = meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 for(n=0;n<m;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 if (pfc::stricmp_ascii_ex(meta_enum_name(n),SIZE_MAX,p_name,p_name_length) == 0) return n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 return SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 bool file_info::meta_exists_ex(const char * p_name,t_size p_name_length) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 return meta_find_ex(p_name,p_name_length) != SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 void file_info::meta_remove_field_ex(const char * p_name,t_size p_name_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 auto index = meta_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 if (index!= SIZE_MAX) meta_remove_index(index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 void file_info::meta_remove_index(t_size p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 meta_remove_mask(pfc::bit_array_one(p_index));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 void file_info::meta_remove_all()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 meta_remove_mask(pfc::bit_array_true());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 void file_info::meta_remove_value(t_size p_index,t_size p_value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 meta_remove_values(p_index, pfc::bit_array_one(p_value));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 t_size file_info::meta_get_count_by_name_ex(const char * p_name,t_size p_name_length) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 auto index = meta_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 if (index == SIZE_MAX) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 return meta_enum_value_count(index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 t_size file_info::info_find_ex(const char * p_name,t_size p_name_length) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 t_size n, m = info_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 for(n=0;n<m;n++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 if (pfc::stricmp_ascii_ex(info_enum_name(n), SIZE_MAX,p_name,p_name_length) == 0) return n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 return SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 bool file_info::info_exists_ex(const char * p_name,t_size p_name_length) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 return info_find_ex(p_name,p_name_length) != SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 void file_info::info_remove_index(t_size p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 info_remove_mask(pfc::bit_array_one(p_index));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 void file_info::info_remove_all()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 info_remove_mask(pfc::bit_array_true());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 bool file_info::info_remove_ex(const char * p_name,t_size p_name_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 auto index = info_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 if (index != SIZE_MAX)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 info_remove_index(index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 else return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 void file_info::overwrite_meta(const file_info & p_source) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 const t_size total = p_source.meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 for(t_size walk = 0; walk < total; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 copy_meta_single(p_source, walk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 bool file_info::overwrite_meta_if_changed( const file_info & source ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 const t_size total = source.meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 bool changed = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 for(t_size walk = 0; walk < total; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 auto name = source.meta_enum_name(walk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 auto idx = this->meta_find(name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 if ( idx != SIZE_MAX ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 if (field_value_equals(*this, idx, source, walk)) continue;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 copy_meta_single(source, walk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 changed = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 return changed;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 void file_info::copy_meta_single(const file_info & p_source,t_size p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 copy_meta_single_rename(p_source,p_index,p_source.meta_enum_name(p_index));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 void file_info::copy_meta_single_nocheck(const file_info & p_source,t_size p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 const char * name = p_source.meta_enum_name(p_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 t_size n, m = p_source.meta_enum_value_count(p_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 t_size new_index = SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 for(n=0;n<m;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 const char * value = p_source.meta_enum_value(p_index,n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 if (n == 0) new_index = meta_set_nocheck(name,value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 else meta_add_value(new_index,value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 void file_info::copy_meta_single_by_name_ex(const file_info & p_source,const char * p_name,t_size p_name_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 auto index = p_source.meta_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 if (index != SIZE_MAX) copy_meta_single(p_source,index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 void file_info::copy_info_single_by_name_ex(const file_info & p_source,const char * p_name,t_size p_name_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 auto index = p_source.info_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 if (index != SIZE_MAX) copy_info_single(p_source,index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 void file_info::copy_meta_single_by_name_nocheck_ex(const file_info & p_source,const char * p_name,t_size p_name_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 auto index = p_source.meta_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 if (index != SIZE_MAX) copy_meta_single_nocheck(p_source,index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 void file_info::copy_info_single_by_name_nocheck_ex(const file_info & p_source,const char * p_name,t_size p_name_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 auto index = p_source.info_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 if (index != SIZE_MAX) copy_info_single_nocheck(p_source,index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 void file_info::copy_info_single(const file_info & p_source,t_size p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 info_set(p_source.info_enum_name(p_index),p_source.info_enum_value(p_index));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 void file_info::copy_info_single_nocheck(const file_info & p_source,t_size p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 info_set_nocheck(p_source.info_enum_name(p_index),p_source.info_enum_value(p_index));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 void file_info::copy_meta(const file_info & p_source)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 if (&p_source != this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 meta_remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 t_size n, m = p_source.meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 for(n=0;n<m;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 copy_meta_single_nocheck(p_source,n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 void file_info::copy_info(const file_info & p_source)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 if (&p_source != this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 info_remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 t_size n, m = p_source.info_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 for(n=0;n<m;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 copy_info_single_nocheck(p_source,n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 void file_info::copy(const file_info & p_source)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 if (&p_source != this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 copy_meta(p_source);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 copy_info(p_source);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 set_length(p_source.get_length());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 set_replaygain(p_source.get_replaygain());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 const char * file_info::meta_get_ex(const char * p_name,t_size p_name_length,t_size p_index) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 auto index = meta_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 if (index == SIZE_MAX) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 auto max = meta_enum_value_count(index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 if (p_index >= max) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 return meta_enum_value(index,p_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 const char * file_info::info_get_ex(const char * p_name,t_size p_name_length) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 auto index = info_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 if (index == SIZE_MAX) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 return info_enum_value(index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 t_int64 file_info::info_get_int(const char * name) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 PFC_ASSERT(pfc::is_valid_utf8(name));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 const char * val = info_get(name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 if (val==0) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 return _atoi64(val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 t_int64 file_info::info_get_length_samples() const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 t_int64 ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 double len = get_length();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 t_int64 srate = info_get_int("samplerate");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 if (srate>0 && len>0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 ret = audio_math::time_to_samples(len,(unsigned)srate);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 double file_info::info_get_float(const char * name) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 const char * ptr = info_get(name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 if (ptr) return pfc::string_to_float(ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 else return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 void file_info::info_set_int(const char * name,t_int64 value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 PFC_ASSERT(pfc::is_valid_utf8(name));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 info_set(name,pfc::format_int(value));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 void file_info::info_set_float(const char * name,double value,unsigned precision,bool force_sign,const char * unit)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 PFC_ASSERT(pfc::is_valid_utf8(name));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 PFC_ASSERT(unit==0 || strlen(unit) <= 64);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 char temp[128];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 pfc::float_to_string(temp,64,value,precision,force_sign);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 temp[63] = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 if (unit)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 strcat_s(temp," ");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 strcat_s(temp,unit);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 info_set(name,temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 void file_info::info_set_replaygain_album_gain(float value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 replaygain_info temp = get_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 temp.m_album_gain = value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 set_replaygain(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 void file_info::info_set_replaygain_album_peak(float value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 replaygain_info temp = get_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 temp.m_album_peak = value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 set_replaygain(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 void file_info::info_set_replaygain_track_gain(float value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 replaygain_info temp = get_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 temp.m_track_gain = value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 set_replaygain(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 void file_info::info_set_replaygain_track_peak(float value)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 replaygain_info temp = get_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 temp.m_track_peak = value;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 set_replaygain(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 static bool is_valid_bps(t_int64 val)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 return val>0 && val<=256;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 unsigned file_info::info_get_decoded_bps() const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 t_int64 val = info_get_int("decoded_bitspersample");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 if (is_valid_bps(val)) return (unsigned)val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 val = info_get_int("bitspersample");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 if (is_valid_bps(val)) return (unsigned)val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 bool file_info::info_get_codec_long(pfc::string_base& out, const char * delim) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 const char * codec;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 codec = this->info_get("codec_long");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 if (codec != nullptr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 out = codec; return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 codec = this->info_get("codec");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 if (codec != nullptr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 out = codec;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 const char * profile = this->info_get("codec_profile");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 if (profile != nullptr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 out << delim << profile;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 void file_info::reset()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 info_remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 meta_remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 set_length(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 reset_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 void file_info::reset_replaygain()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 replaygain_info temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 temp.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 set_replaygain(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 void file_info::copy_meta_single_rename_ex(const file_info & p_source,t_size p_index,const char * p_new_name,t_size p_new_name_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 t_size n, m = p_source.meta_enum_value_count(p_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 t_size new_index = SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 for(n=0;n<m;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 const char * value = p_source.meta_enum_value(p_index,n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 if (n == 0) new_index = meta_set_ex(p_new_name,p_new_name_length,value,SIZE_MAX);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 else meta_add_value(new_index,value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 t_size file_info::meta_add_ex(const char * p_name,t_size p_name_length,const char * p_value,t_size p_value_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 auto index = meta_find_ex(p_name,p_name_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 if (index == SIZE_MAX) return meta_set_nocheck_ex(p_name,p_name_length,p_value,p_value_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 meta_add_value_ex(index,p_value,p_value_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 return index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 void file_info::meta_add_value_ex(t_size p_index,const char * p_value,t_size p_value_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 meta_insert_value_ex(p_index,meta_enum_value_count(p_index),p_value,p_value_length);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 t_size file_info::meta_calc_total_value_count() const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 t_size n, m = meta_get_count(), ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 for(n=0;n<m;n++) ret += meta_enum_value_count(n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 bool file_info::info_set_replaygain_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 replaygain_info temp = get_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 if (temp.set_from_meta_ex(p_name,p_name_len,p_value,p_value_len))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 set_replaygain(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 else return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 void file_info::info_set_replaygain_auto_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 if (!info_set_replaygain_ex(p_name,p_name_len,p_value,p_value_len))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 info_set_ex(p_name,p_name_len,p_value,p_value_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 static bool _matchGain(float g1, float g2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 if (g1 == replaygain_info::gain_invalid && g2 == replaygain_info::gain_invalid) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 else if (g1 == replaygain_info::gain_invalid || g2 == replaygain_info::gain_invalid) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 else return fabs(g1-g2) < 0.1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 static bool _matchPeak(float p1, float p2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400 if (p1 == replaygain_info::peak_invalid && p2 == replaygain_info::peak_invalid) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 else if (p1 == replaygain_info::peak_invalid || p2 == replaygain_info::peak_invalid) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 else return fabs(p1-p2) < 0.01;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 bool replaygain_info::g_equalLoose( const replaygain_info & i1, const replaygain_info & i2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 return _matchGain(i1.m_track_gain, i2.m_track_gain) && _matchGain(i1.m_album_gain, i2.m_album_gain) && _matchPeak(i1.m_track_peak, i2.m_track_peak) && _matchPeak(i1.m_album_peak, i2.m_album_peak);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 bool replaygain_info::g_equal(const replaygain_info & item1,const replaygain_info & item2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 return item1.m_album_gain == item2.m_album_gain &&
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 item1.m_track_gain == item2.m_track_gain &&
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411 item1.m_album_peak == item2.m_album_peak &&
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 item1.m_track_peak == item2.m_track_peak;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 void replaygain_info::adjust(double deltaDB) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 if (this->is_album_gain_present()) this->m_album_gain -= (float)deltaDB;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 if (this->is_track_gain_present()) this->m_track_gain -= (float)deltaDB;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418 const auto scale = audio_math::gain_to_scale(deltaDB);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 if (this->is_album_peak_present()) this->m_album_peak *= (float)scale;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 if (this->is_track_peak_present()) this->m_track_peak *= (float)scale;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 bool file_info::are_meta_fields_identical(t_size p_index1,t_size p_index2) const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 const t_size count = meta_enum_value_count(p_index1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426 if (count != meta_enum_value_count(p_index2)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 for(n=0;n<count;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 if (strcmp(meta_enum_value(p_index1,n),meta_enum_value(p_index2,n))) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436 void file_info::meta_format_entry(t_size index, pfc::string_base & out, const char * separator) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 out.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 t_size val, count = meta_enum_value_count(index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 PFC_ASSERT( count > 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 for(val=0;val<count;val++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442 if (val > 0) out += separator;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443 out += meta_enum_value(index,val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 bool file_info::meta_format(const char * p_name,pfc::string_base & p_out, const char * separator) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 p_out.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 auto index = meta_find(p_name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450 if (index == SIZE_MAX) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 meta_format_entry(index, p_out, separator);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 void file_info::info_calculate_bitrate(uint64_t p_filesize,double p_length)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 unsigned b = audio_math::bitrate_kbps( p_filesize, p_length );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 if ( b > 0 ) info_set_bitrate(b);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461 void file_info::info_set_bitspersample(uint32_t val, bool isFloat) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462 // Bits per sample semantics
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463 // "bitspersample" is set to integer value of bits per sample
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464 // "bitspersample_extra" is used for bps of 32 or 64, either "floating-point" or "fixed-point"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 // bps other than 32 or 64 are implicitly fixed-point as floating-point for such makes no sense
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467 info_set_int("bitspersample", val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468 if ( isFloat || val == 32 || val == 64 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469 info_set("bitspersample_extra", isFloat ? "floating-point" : "fixed-point");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471 info_remove("bitspersample_extra");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 bool file_info::is_encoding_float() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476 auto bs = info_get_int("bitspersample");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 auto extra = info_get("bitspersample_extra");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 if (bs == 32 || bs == 64) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 if (extra == nullptr || strcmp(extra, "floating-point") == 0) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 bool file_info::is_encoding_overkill() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 #if audio_sample_size == 32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486 auto bs = info_get_int("bitspersample");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 auto extra = info_get("bitspersample_extra");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 if ( bs <= 24 ) return false; // fixedpoint up to 24bit, OK
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489 if ( bs > 32 ) return true; // fixed or float beyond 32bit, overkill
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 if ( extra != nullptr ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492 if (strcmp(extra, "fixed-point") == 0) return true; // int32, overkill
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
498 bool file_info::is_encoding_lossy() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
499 const char * encoding = info_get("encoding");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500 if (encoding != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501 if (pfc::stricmp_ascii(encoding,"lossy") == 0 /*|| pfc::stricmp_ascii(encoding,"hybrid") == 0*/) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 //the old way
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504 //disabled: don't whine if we're not sure what we're dealing with - might be a file with info not-yet-loaded in oddball cases or a mod file
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505 //if (info_get("bitspersample") == NULL) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
508 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
509
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 bool file_info::is_encoding_lossless() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511 const char* encoding = info_get("encoding");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512 return encoding != nullptr && pfc::stringEqualsI_ascii(encoding, "lossless");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
515 bool file_info::g_is_meta_equal(const file_info & p_item1,const file_info & p_item2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
516 const t_size count = p_item1.meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
517 if (count != p_item2.meta_get_count()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
518 //uDebugLog() << "meta count mismatch";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
519 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
520 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
521 pfc::map_t<const char*,t_size,field_name_comparator> item2_meta_map;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
522 for(t_size n=0; n<count; n++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
523 item2_meta_map.set(p_item2.meta_enum_name(n),n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
524 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
525 for(t_size n1=0; n1<count; n1++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
526 t_size n2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
527 if (!item2_meta_map.query(p_item1.meta_enum_name(n1),n2)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
528 //uDebugLog() << "item2 doesn't have " << p_item1.meta_enum_name(n1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
529 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
530 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
531 t_size value_count = p_item1.meta_enum_value_count(n1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
532 if (value_count != p_item2.meta_enum_value_count(n2)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
533 //uDebugLog() << "meta value count mismatch: " << p_item1.meta_enum_name(n1) << " : " << value_count << " vs " << p_item2.meta_enum_value_count(n2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
534 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
535 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
536 for(t_size v = 0; v < value_count; v++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
537 if (strcmp(p_item1.meta_enum_value(n1,v),p_item2.meta_enum_value(n2,v)) != 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
538 //uDebugLog() << "meta mismatch: " << p_item1.meta_enum_name(n1) << " : " << p_item1.meta_enum_value(n1,v) << " vs " << p_item2.meta_enum_value(n2,v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
539 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
540 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
541 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
542 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
543 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
544 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
545
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
546 bool file_info::g_is_meta_equal_debug(const file_info & p_item1,const file_info & p_item2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
547 const t_size count = p_item1.meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
548 if (count != p_item2.meta_get_count()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
549 FB2K_DebugLog() << "meta count mismatch";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
550 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
551 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
552 pfc::map_t<const char*,t_size,field_name_comparator> item2_meta_map;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
553 for(t_size n=0; n<count; n++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
554 item2_meta_map.set(p_item2.meta_enum_name(n),n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
555 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
556 for(t_size n1=0; n1<count; n1++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
557 t_size n2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
558 if (!item2_meta_map.query(p_item1.meta_enum_name(n1),n2)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
559 FB2K_DebugLog() << "item2 doesn't have " << p_item1.meta_enum_name(n1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
560 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
561 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
562 t_size value_count = p_item1.meta_enum_value_count(n1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
563 if (value_count != p_item2.meta_enum_value_count(n2)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
564 FB2K_DebugLog() << "meta value count mismatch: " << p_item1.meta_enum_name(n1) << " : " << (uint32_t)value_count << " vs " << (uint32_t)p_item2.meta_enum_value_count(n2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
565 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
566 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
567 for(t_size v = 0; v < value_count; v++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
568 if (strcmp(p_item1.meta_enum_value(n1,v),p_item2.meta_enum_value(n2,v)) != 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
569 FB2K_DebugLog() << "meta mismatch: " << p_item1.meta_enum_name(n1) << " : " << p_item1.meta_enum_value(n1,v) << " vs " << p_item2.meta_enum_value(n2,v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
570 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
571 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
572 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
573 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
574 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
575 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
576
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
577 bool file_info::g_is_info_equal(const file_info & p_item1,const file_info & p_item2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
578 t_size count = p_item1.info_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
579 if (count != p_item2.info_get_count()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
580 //uDebugLog() << "info count mismatch";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
581 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
582 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
583 for(t_size n1=0; n1<count; n1++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
584 t_size n2 = p_item2.info_find(p_item1.info_enum_name(n1));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
585 if (n2 == SIZE_MAX) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
586 //uDebugLog() << "item2 does not have " << p_item1.info_enum_name(n1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
587 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
588 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
589 if (strcmp(p_item1.info_enum_value(n1),p_item2.info_enum_value(n2)) != 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
590 //uDebugLog() << "value mismatch: " << p_item1.info_enum_name(n1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
591 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
592 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
593 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
594 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
595 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
596
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
597 bool file_info::g_is_meta_subset_debug(const file_info& superset, const file_info& subset) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
598 size_t total = subset.meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
599 bool rv = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
600 for (size_t walk = 0; walk < total; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
601 const char* name = subset.meta_enum_name(walk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
602 const size_t idx = superset.meta_find(name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
603 if (idx == SIZE_MAX) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
604 rv = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
605 FB2K_console_formatter() << "Field " << name << " missing";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
606 } else if (!field_value_equals(superset, idx, subset, walk)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
607 rv = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
608 FB2K_console_formatter() << "Field " << name << " mismatch";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
609 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
610 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
611 return rv;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
612 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
613
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
614 static bool is_valid_field_name_char(char p_char) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
615 return p_char >= 32 && p_char < 127 && p_char != '=' && p_char != '%' && p_char != '<' && p_char != '>';
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
616 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
617
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
618 bool file_info::g_is_valid_field_name(const char * p_name,t_size p_length) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
619 t_size walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
620 for(walk = 0; walk < p_length && p_name[walk] != 0; walk++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
621 if (!is_valid_field_name_char(p_name[walk])) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
622 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
623 return walk > 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
624 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
625
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
626 void file_info::to_formatter(pfc::string_formatter& out) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
627 out << "File info dump:\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
628 if (get_length() > 0) out<< "Duration: " << pfc::format_time_ex(get_length(), 6) << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
629 pfc::string_formatter temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
630 for(t_size metaWalk = 0; metaWalk < meta_get_count(); ++metaWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
631 meta_format_entry(metaWalk, temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
632 out << "Meta: " << meta_enum_name(metaWalk) << " = " << temp << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
633 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
634 for(t_size infoWalk = 0; infoWalk < info_get_count(); ++infoWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
635 out << "Info: " << info_enum_name(infoWalk) << " = " << info_enum_value(infoWalk) << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
636 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
637 auto rg = this->get_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
638 replaygain_info::t_text_buffer rgbuf;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
639 if (rg.format_track_gain(rgbuf)) out << "RG track gain: " << rgbuf << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
640 if (rg.format_track_peak(rgbuf)) out << "RG track peak: " << rgbuf << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
641 if (rg.format_album_gain(rgbuf)) out << "RG album gain: " << rgbuf << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
642 if (rg.format_album_peak(rgbuf)) out << "RG album peak: " << rgbuf << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
643 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
644
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
645 void file_info::to_console() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
646 FB2K_console_formatter1() << "File info dump:";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
647 if (get_length() > 0) FB2K_console_formatter() << "Duration: " << pfc::format_time_ex(get_length(), 6);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
648 pfc::string_formatter temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
649 const auto numMeta = meta_get_count(), numInfo = info_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
650 if (numMeta == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
651 FB2K_console_formatter() << "Meta is blank";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
652 } else for(t_size metaWalk = 0; metaWalk < numMeta; ++metaWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
653 const char * name = meta_enum_name( metaWalk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
654 const auto valCount = meta_enum_value_count( metaWalk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
655 for ( size_t valWalk = 0; valWalk < valCount; ++valWalk ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
656 FB2K_console_formatter() << "Meta: " << name << " = " << meta_enum_value( metaWalk, valWalk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
657 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
658
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
659 /*
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
660 meta_format_entry(metaWalk, temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
661 FB2K_console_formatter() << "Meta: " << meta_enum_name(metaWalk) << " = " << temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
662 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
663 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
664 if (numInfo == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
665 FB2K_console_formatter() << "Info is blank";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
666 } else for(t_size infoWalk = 0; infoWalk < numInfo; ++infoWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
667 FB2K_console_formatter() << "Info: " << info_enum_name(infoWalk) << " = " << info_enum_value(infoWalk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
668 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
669 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
670
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
671 void file_info::info_set_channels(uint32_t v) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
672 this->info_set_int("channels", v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
673 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
674
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
675 void file_info::info_set_channels_ex(uint32_t channels, uint32_t mask) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
676 info_set_channels(channels);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
677 info_set_wfx_chanMask(mask);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
678 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
679
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
680 static bool parse_wfx_chanMask(const char* str, uint32_t& out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
681 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
682 if (pfc::strcmp_partial(str, "0x") != 0) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
683 out = pfc::atohex<uint32_t>(str + 2, strlen(str + 2));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
684 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
685 } catch (...) { return false; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
686 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
687
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
688 void file_info::info_tidy_channels() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
689 const char * info = this->info_get(info_WAVEFORMATEXTENSIBLE_CHANNEL_MASK);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
690 if (info != nullptr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
691 bool keep = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
692 uint32_t v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
693 if (parse_wfx_chanMask(info, v)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
694 if (v != 0 && v != 3 && v != 4) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
695 // valid, not mono, not stereo
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
696 keep = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
697 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
698 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
699 if (!keep) this->info_remove(info_WAVEFORMATEXTENSIBLE_CHANNEL_MASK);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
700 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
701 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
702
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
703 void file_info::info_set_wfx_chanMask(uint32_t val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
704 switch(val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
705 case 0:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
706 case 4:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
707 case 3:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
708 this->info_remove(info_WAVEFORMATEXTENSIBLE_CHANNEL_MASK);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
709 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
710 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
711 info_set (info_WAVEFORMATEXTENSIBLE_CHANNEL_MASK, pfc::format("0x", pfc::format_hex(val) ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
712 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
713 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
714 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
715
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
716 uint32_t file_info::info_get_wfx_chanMask() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
717 const char * str = this->info_get(info_WAVEFORMATEXTENSIBLE_CHANNEL_MASK);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
718 if (str == NULL) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
719 uint32_t ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
720 if (parse_wfx_chanMask(str, ret)) return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
721 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
722 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
723
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
724 bool file_info::field_is_person(const char * fieldName) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
725 return field_name_equals(fieldName, "artist") ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
726 field_name_equals(fieldName, "album artist") ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
727 field_name_equals(fieldName, "composer") ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
728 field_name_equals(fieldName, "performer") ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
729 field_name_equals(fieldName, "conductor") ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
730 field_name_equals(fieldName, "orchestra") ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
731 field_name_equals(fieldName, "ensemble") ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
732 field_name_equals(fieldName, "engineer");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
733 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
734
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
735 bool file_info::field_is_title(const char * fieldName) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
736 return field_name_equals(fieldName, "title") || field_name_equals(fieldName, "album");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
737 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
738
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
739
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
740 void file_info::to_stream( stream_writer * stream, abort_callback & abort ) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
741 stream_writer_formatter<> out(* stream, abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
742
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
743 out << this->get_length();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
744
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
745 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
746 const auto rg = this->get_replaygain();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
747 out << rg.m_track_gain << rg.m_album_gain << rg.m_track_peak << rg.m_album_peak;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
748 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
749
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
750
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
751 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
752 const uint32_t metaCount = pfc::downcast_guarded<uint32_t>( this->meta_get_count() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
753 for(uint32_t metaWalk = 0; metaWalk < metaCount; ++metaWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
754 const char * name = this->meta_enum_name( metaWalk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
755 if (*name) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
756 out.write_string_nullterm( this->meta_enum_name( metaWalk ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
757 const size_t valCount = this->meta_enum_value_count( metaWalk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
758 for(size_t valWalk = 0; valWalk < valCount; ++valWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
759 const char * value = this->meta_enum_value( metaWalk, valWalk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
760 if (*value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
761 out.write_string_nullterm( value );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
762 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
763 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
764 out.write_int<char>(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
765 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
766 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
767 out.write_int<char>(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
768 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
769
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
770 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
771 const uint32_t infoCount = pfc::downcast_guarded<uint32_t>( this->info_get_count() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
772 for(uint32_t infoWalk = 0; infoWalk < infoCount; ++infoWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
773 const char * name = this->info_enum_name( infoWalk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
774 const char * value = this->info_enum_value( infoWalk );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
775 if (*name && *value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
776 out.write_string_nullterm(name); out.write_string_nullterm(value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
777 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
778 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
779 out.write_int<char>(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
780 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
781 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
782
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
783 void file_info::from_stream( stream_reader * stream, abort_callback & abort ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
784 stream_reader_formatter<> in( *stream, abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
785 pfc::string_formatter tempName, tempValue;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
786 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
787 double len; in >> len; this->set_length( len );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
788 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
789 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
790 replaygain_info rg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
791 in >> rg.m_track_gain >> rg.m_album_gain >> rg.m_track_peak >> rg.m_album_peak;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
792 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
793
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
794 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
795 this->meta_remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
796 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
797 in.read_string_nullterm( tempName );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
798 if (tempName.length() == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
799 size_t metaIndex = SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
800 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
801 in.read_string_nullterm( tempValue );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
802 if (tempValue.length() == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
803 if (metaIndex == SIZE_MAX) metaIndex = this->meta_add( tempName, tempValue );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
804 else this->meta_add_value( metaIndex, tempValue );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
805 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
806 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
807 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
808 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
809 this->info_remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
810 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
811 in.read_string_nullterm( tempName );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
812 if (tempName.length() == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
813 in.read_string_nullterm( tempValue );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
814 this->info_set( tempName, tempValue );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
815 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
816 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
817 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
818
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
819 static const char * _readString( const uint8_t * & ptr, size_t & remaining ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
820 const char * rv = (const char*)ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
821 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
822 if (remaining == 0) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
823 uint8_t byte = *ptr++; --remaining;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
824 if (byte == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
825 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
826 return rv;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
827 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
828
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
829 template<typename int_t> void _readInt( int_t & out, const uint8_t * &ptr, size_t & remaining) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
830 if (remaining < sizeof(out)) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
831 pfc::decode_little_endian( out, ptr ); ptr += sizeof(out); remaining -= sizeof(out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
832 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
833
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
834 template<typename float_t> static void _readFloat(float_t & out, const uint8_t * &ptr, size_t & remaining) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
835 union {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
836 typename pfc::sized_int_t<sizeof(float_t)>::t_unsigned i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
837 float_t f;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
838 } u;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
839 _readInt(u.i, ptr, remaining);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
840 out = u.f;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
841 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
842
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
843 void file_info::from_mem( const void * memPtr, size_t memSize ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
844 size_t remaining = memSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
845 const uint8_t * walk = (const uint8_t*) memPtr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
846
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
847 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
848 double len; _readFloat(len, walk, remaining);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
849 this->set_length( len );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
850 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
851
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
852 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
853 replaygain_info rg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
854 _readFloat(rg.m_track_gain, walk, remaining );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
855 _readFloat(rg.m_album_gain, walk, remaining );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
856 _readFloat(rg.m_track_peak, walk, remaining );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
857 _readFloat(rg.m_album_peak, walk, remaining );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
858 this->set_replaygain( rg );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
859 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
860
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
861 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
862 this->meta_remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
863 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
864 const char * metaName = _readString( walk, remaining );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
865 if (*metaName == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
866 size_t metaIndex = SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
867 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
868 const char * metaValue = _readString( walk, remaining );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
869 if (*metaValue == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
870 if (metaIndex == SIZE_MAX) metaIndex = this->meta_add( metaName, metaValue );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
871 else this->meta_add_value( metaIndex, metaName );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
872 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
873 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
874 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
875 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
876 this->info_remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
877 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
878 const char * infoName = _readString( walk, remaining );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
879 if (*infoName == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
880 const char * infoValue = _readString( walk, remaining );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
881 this->info_set( infoName, infoValue );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
882 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
883 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
884 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
885
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
886 void file_info::set_audio_chunk_spec(audio_chunk::spec_t s) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
887 this->info_set_int("samplerate", s.sampleRate);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
888 this->info_set_int("channels", s.chanCount);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
889 uint32_t mask = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
890 if (audio_chunk::g_count_channels(s.chanMask) == s.chanCount) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
891 mask = s.chanMask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
892 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
893 this->info_set_wfx_chanMask(mask); // clears if zero or one of trivial values
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
894 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
895
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
896 audio_chunk::spec_t file_info::audio_chunk_spec() const
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
897 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
898 audio_chunk::spec_t rv = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
899 rv.sampleRate = (uint32_t)this->info_get_int("samplerate");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
900 rv.chanCount = (uint32_t)this->info_get_int("channels");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
901 rv.chanMask = (uint32_t)this->info_get_wfx_chanMask();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
902 if (audio_chunk::g_count_channels( rv.chanMask ) != rv.chanCount ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
903 rv.chanMask = audio_chunk::g_guess_channel_config( rv.chanCount );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
904 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
905 return rv;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
906 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
907
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
908 bool file_info::field_value_equals(const file_info& i1, size_t meta1, const file_info& i2, size_t meta2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
909 const size_t c = i1.meta_enum_value_count(meta1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
910 if (c != i2.meta_enum_value_count(meta2)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
911 for (size_t walk = 0; walk < c; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
912 if (strcmp(i1.meta_enum_value(meta1, walk), i2.meta_enum_value(meta2, walk)) != 0) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
913 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
914 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
915 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
916
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
917 bool file_info::unicode_normalize_C() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
918 const size_t total = this->meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
919 bool changed = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
920 for (size_t mwalk = 0; mwalk < total; ++mwalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
921 const size_t totalV = this->meta_enum_value_count(mwalk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
922 for (size_t vwalk = 0; vwalk < totalV; ++vwalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
923 const char* val = this->meta_enum_value(mwalk, vwalk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
924 if (pfc::stringContainsFormD(val)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
925 auto norm = pfc::unicodeNormalizeC(val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
926 if (strcmp(norm, val) != 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
927 this->meta_modify_value(mwalk, vwalk, norm);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
928 changed = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
929 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
930 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
931 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
932 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
933 return changed;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
934 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
935
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
936 void file_info::meta_enumerate(meta_enumerate_t cb) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
937 const size_t nMeta = this->meta_get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
938 for (size_t metaWalk = 0; metaWalk < nMeta; ++metaWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
939 const char* name = this->meta_enum_name(metaWalk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
940 const size_t nValue = this->meta_enum_value_count(metaWalk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
941 for (size_t valueWalk = 0; valueWalk < nValue; ++valueWalk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
942 const char* value = this->meta_enum_value(metaWalk, valueWalk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
943 cb(name, value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
944 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
945 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
946 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
947
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
948 bool file_info::meta_value_exists( const char * name, const char * findValue, bool insensitive ) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
949 const auto idx = this->meta_find(name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
950 if ( idx != SIZE_MAX ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
951 const auto count = this->meta_enum_value_count(idx);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
952 for( size_t walk = 0; walk < count; ++ walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
953 auto value = this->meta_enum_value(idx, walk);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
954 if ( insensitive ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
955 if (pfc::stringEqualsI_utf8(value, findValue)) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
956 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
957 if ( strcmp(value, findValue) == 0 ) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
958 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
959 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
960 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
961 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
962 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
963
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
964 const char * file_info::meta_get_title( const char * fallback) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
965 auto ret = meta_get("title", 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
966 return ret?ret:fallback;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
967 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
968
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
969 #ifdef FOOBAR2000_MOBILE
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
970 #include "album_art.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
971 #include "hasher_md5.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
972
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
973 void file_info::info_set_pictures( const GUID * guids, size_t size ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
974 this->info_set("pictures", album_art_ids::ids_to_string(guids, size) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
975 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
976
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
977 pfc::array_t<GUID> file_info::info_get_pictures( ) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
978 return album_art_ids::string_to_ids( this->info_get( "pictures" ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
979 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
980
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
981 bool file_info::info_have_picture( const GUID & arg ) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
982 for( auto & walk : info_get_pictures() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
983 if ( walk == arg ) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
984 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
985 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
986 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
987
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
988 uint64_t file_info::makeMetaHash() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
989 pfc::string_formatter temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
990
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
991 auto doMeta = [&] ( const char * meta ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
992 const char * p = meta_get(meta, 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
993 if (p != nullptr) temp << p;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
994 temp << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
995 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
996 auto doMetaInt = [&] ( const char * meta ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
997 const char * p = meta_get(meta, 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
998 if (p != nullptr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
999 auto s = strchr(p, '/' ); if ( s != nullptr ) p = s+1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1000 while(*p == '0') ++p;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1001 temp << p;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1002 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1003 temp << "\n";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1004 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1005 doMeta("title");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1006 doMeta("artist");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1007 doMeta("album");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1008 doMetaInt("tracknumber");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1009 doMetaInt("discnumber");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1010
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1011 if (temp.length() == 5) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1012
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1013 return hasher_md5::get()->process_single( temp.c_str(), temp.length( ) ).xorHalve();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1014 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1015
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1016 #endif // FOOBAR2000_MOBILE