annotate foosdk/sdk/foobar2000/SDK/replaygain_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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #ifdef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include <pfc/fpu.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #define RG_FPU() fpu_control_roundnearest bah;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 #define RG_FPU()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 bool replaygain_info::g_format_gain(float p_value,char p_buffer[text_buffer_size])
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 RG_FPU();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 if (p_value == gain_invalid)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 p_buffer[0] = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 pfc::float_to_string(p_buffer,text_buffer_size - 4,p_value,2,true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 #ifdef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 strcat_s(p_buffer, text_buffer_size, " dB");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 strcat(p_buffer, " dB");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 return true;
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 bool replaygain_info::g_format_peak_db(float p_value, char p_buffer[text_buffer_size]) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 const float lo = 1.0 / (float)(1 << 24);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 if ( p_value == peak_invalid || p_value < lo ) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 return g_format_gain((float)audio_math::scale_to_gain(p_value), p_buffer);
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 bool replaygain_info::g_format_peak(float p_value,char p_buffer[text_buffer_size])
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 RG_FPU();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 if (p_value == peak_invalid)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 p_buffer[0] = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 return false;
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 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 pfc::float_to_string(p_buffer,text_buffer_size,p_value,6,false);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 return true;
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 void replaygain_info::reset()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 *this = replaygain_info();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 }
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 #define meta_album_gain "replaygain_album_gain"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 #define meta_album_peak "replaygain_album_peak"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 #define meta_track_gain "replaygain_track_gain"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 #define meta_track_peak "replaygain_track_peak"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 bool replaygain_info::g_is_meta_replaygain(const char * p_name,t_size p_name_len)
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 stricmp_utf8_ex(p_name,p_name_len,meta_album_gain,SIZE_MAX) == 0 ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 stricmp_utf8_ex(p_name,p_name_len,meta_album_peak,SIZE_MAX) == 0 ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 stricmp_utf8_ex(p_name,p_name_len,meta_track_gain,SIZE_MAX) == 0 ||
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 stricmp_utf8_ex(p_name,p_name_len,meta_track_peak,SIZE_MAX) == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 }
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 bool replaygain_info::set_from_meta_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
72 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 RG_FPU();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 if (stricmp_utf8_ex(p_name,p_name_len,meta_album_gain,SIZE_MAX) == 0)
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 m_album_gain = (float)pfc::string_to_float(p_value,p_value_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 return true;
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 else if (stricmp_utf8_ex(p_name,p_name_len,meta_album_peak,SIZE_MAX) == 0)
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 m_album_peak = (float)pfc::string_to_float(p_value,p_value_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 if (m_album_peak < 0) m_album_peak = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 else if (stricmp_utf8_ex(p_name,p_name_len,meta_track_gain,SIZE_MAX) == 0)
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 m_track_gain = (float)pfc::string_to_float(p_value,p_value_len);
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 if (stricmp_utf8_ex(p_name,p_name_len,meta_track_peak,SIZE_MAX) == 0)
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 m_track_peak = (float)pfc::string_to_float(p_value,p_value_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 if (m_track_peak < 0) m_track_peak = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 else return false;
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 t_size replaygain_info::get_value_count()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 t_size ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 if (is_album_gain_present()) ret++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 if (is_album_peak_present()) ret++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 if (is_track_gain_present()) ret++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 if (is_track_peak_present()) ret++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 return ret;
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 float replaygain_info::anyGain(bool bPreferAlbum) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 if ( bPreferAlbum ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 if ( this->is_album_gain_present() ) return this->m_album_gain;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 return this->m_track_gain;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 if ( this->is_track_gain_present() ) return this->m_track_gain;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 return this->m_album_gain;
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 }
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 float replaygain_info::g_parse_gain_text(const char * p_text, t_size p_text_len) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 RG_FPU();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 if (p_text != 0 && p_text_len > 0 && *p_text != 0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 return (float)pfc::string_to_float(p_text, p_text_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 return gain_invalid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 }
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 void replaygain_info::set_album_gain_text(const char * p_text,t_size p_text_len) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 m_album_gain = g_parse_gain_text(p_text, p_text_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 }
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 void replaygain_info::set_track_gain_text(const char * p_text,t_size p_text_len)
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 m_track_gain = g_parse_gain_text(p_text, p_text_len);
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 void replaygain_info::set_album_peak_text(const char * p_text,t_size p_text_len)
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 RG_FPU();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 if (p_text != 0 && p_text_len > 0 && *p_text != 0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 m_album_peak = (float)pfc::string_to_float(p_text,p_text_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 remove_album_peak();
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 replaygain_info::set_track_peak_text(const char * p_text,t_size p_text_len)
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 RG_FPU();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 if (p_text != 0 && p_text_len > 0 && *p_text != 0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 m_track_peak = (float)pfc::string_to_float(p_text,p_text_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 remove_track_peak();
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 replaygain_info replaygain_info::g_merge(replaygain_info r1,replaygain_info r2)
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 replaygain_info ret = r1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 if (!ret.is_album_gain_present()) ret.m_album_gain = r2.m_album_gain;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 if (!ret.is_album_peak_present()) ret.m_album_peak = r2.m_album_peak;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 if (!ret.is_track_gain_present()) ret.m_track_gain = r2.m_track_gain;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 if (!ret.is_track_peak_present()) ret.m_track_peak = r2.m_track_peak;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 }
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 void replaygain_info::for_each(for_each_t f) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 t_text_buffer buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 if (format_track_gain(buffer)) f(meta_track_gain, buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 if (format_track_peak(buffer)) f(meta_track_peak, buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 if (format_album_gain(buffer)) f(meta_album_gain, buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 if (format_album_peak(buffer)) f(meta_album_peak, buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 }