foobar2000 SDK  2015-01-14
replaygain.cpp
Go to the documentation of this file.
1 #include "foobar2000.h"
2 
4 {
9 }
10 
12 {
13  return query_scale(info.get_replaygain());
14 }
15 
17  const audio_sample peak_margin = 1.0;//used to be 0.999 but it must not trigger on lossless
18 
19  audio_sample peak = peak_margin;
20  audio_sample gain = 0;
21 
22  bool have_rg_gain = false, have_rg_peak = false;
23 
25  {
26  float gain_select = replaygain_info::gain_invalid, peak_select = replaygain_info::peak_invalid;
28  {
29  if (info.is_track_gain_present()) {gain = info.m_track_gain; have_rg_gain = true; }
30  else if (info.is_album_gain_present()) {gain = info.m_album_gain; have_rg_gain = true; }
31  if (info.is_track_peak_present()) {peak = info.m_track_peak; have_rg_peak = true; }
32  else if (info.is_album_peak_present()) {peak = info.m_album_peak; have_rg_peak = true; }
33  }
34  else
35  {
36  if (info.is_album_gain_present()) {gain = info.m_album_gain; have_rg_gain = true; }
37  else if (info.is_track_gain_present()) {gain = info.m_track_gain; have_rg_gain = true; }
38  if (info.is_album_peak_present()) {peak = info.m_album_peak; have_rg_peak = true; }
39  else if (info.is_track_peak_present()) {peak = info.m_track_peak; have_rg_peak = true; }
40  }
41  }
42 
43  gain += have_rg_gain ? m_preamp_with_rg : m_preamp_without_rg;
44 
45  audio_sample scale = 1.0;
46 
48  {
49  scale *= audio_math::gain_to_scale(gain);
50  }
51 
53  {
54  if (scale * peak > peak_margin)
55  scale = (audio_sample)(peak_margin / peak);
56  }
57 
58  return scale;
59 }
60 
62 {
63  return query_scale(p_object->get_async_info_ref()->info());
64 }
65 
67 {
69  get_core_settings(temp);
70  return temp.query_scale(p_info);
71 }
72 
74 {
76  get_core_settings(temp);
77  return temp.query_scale(info);
78 }
79 
80 //enum t_source_mode {source_mode_none,source_mode_track,source_mode_album};
81 //enum t_processing_mode {processing_mode_none,processing_mode_gain,processing_mode_gain_and_peak,processing_mode_peak};
82 namespace {
83 class format_dbdelta
84 {
85 public:
86  format_dbdelta(double p_val);
87  operator const char*() const {return m_buffer;}
88 private:
89  pfc::string_fixed_t<128> m_buffer;
90 };
91 static const char * querysign(int val) {
92  return val<0 ? "-" : val>0 ? "+" : "\xc2\xb1";
93 }
94 
95 format_dbdelta::format_dbdelta(double p_val) {
96  int val = (int)(p_val * 10);
97  m_buffer << querysign(val) << (abs(val)/10) << "." << (abs(val)%10) << "dB";
98 }
99 }
101 {
102  switch(m_processing_mode)
103  {
105  p_out = "None.";
106  break;
108  switch(m_source_mode)
109  {
110  case source_mode_none:
111  if (m_preamp_without_rg == 0) p_out = "None.";
112  else p_out = PFC_string_formatter() << "Preamp : " << format_dbdelta(m_preamp_without_rg);
113  break;
114  case source_mode_track:
115  {
117  fmt << "Apply track gain";
118  if (m_preamp_without_rg != 0 || m_preamp_with_rg != 0) fmt << ", with preamp";
119  fmt << ".";
120  p_out = fmt;
121  }
122  break;
123  case source_mode_album:
124  {
126  fmt << "Apply album gain";
127  if (m_preamp_without_rg != 0 || m_preamp_with_rg != 0) fmt << ", with preamp";
128  fmt << ".";
129  p_out = fmt;
130  }
131  break;
132  };
133  break;
135  switch(m_source_mode)
136  {
137  case source_mode_none:
138  if (m_preamp_without_rg >= 0) p_out = "None.";
139  else p_out = PFC_string_formatter() << "Preamp : " << format_dbdelta(m_preamp_without_rg);
140  break;
141  case source_mode_track:
142  {
144  fmt << "Apply track gain";
145  if (m_preamp_without_rg != 0 || m_preamp_with_rg != 0) fmt << ", with preamp";
146  fmt << ", prevent clipping according to track peak.";
147  p_out = fmt;
148  }
149  break;
150  case source_mode_album:
151  {
153  fmt << "Apply album gain";
154  if (m_preamp_without_rg != 0 || m_preamp_with_rg != 0) fmt << ", with preamp";
155  fmt << ", prevent clipping according to album peak.";
156  p_out = fmt;
157  }
158  break;
159  };
160  break;
162  switch(m_source_mode)
163  {
164  case source_mode_none:
165  p_out = "None.";
166  break;
167  case source_mode_track:
168  p_out = "Prevent clipping according to track peak.";
169  break;
170  case source_mode_album:
171  p_out = "Prevent clipping according to album peak.";
172  break;
173  };
174  break;
175  }
176 }
177 
179 {
180  switch(m_processing_mode)
181  {
183  return false;
185  switch(m_source_mode)
186  {
187  case source_mode_none:
188  return m_preamp_without_rg != 0;
189  case source_mode_track:
190  return true;
191  case source_mode_album:
192  return true;
193  };
194  return false;
196  switch(m_source_mode)
197  {
198  case source_mode_none:
199  return m_preamp_without_rg < 0;
200  case source_mode_track:
201  return true;
202  case source_mode_album:
203  return true;
204  };
205  return false;
207  switch(m_source_mode)
208  {
209  case source_mode_none:
210  return false;
211  case source_mode_track:
212  return true;
213  case source_mode_album:
214  return true;
215  };
216  return false;
217  default:
218  return false;
219  }
220 }
virtual void get_core_settings(t_replaygain_config &p_out)=0
Retrieves playback ReplayGain settings.
bool is_track_peak_present() const
Definition: file_info.h:32
float m_track_gain
Definition: file_info.h:4
void format_name(pfc::string_base &p_out) const
Definition: replaygain.cpp:100
t_source_mode m_source_mode
Definition: replaygain.h:13
void info(const char *p_message)
Definition: console.cpp:4
float m_album_peak
Definition: file_info.h:5
float m_preamp_without_rg
Definition: replaygain.h:15
bool is_active() const
Definition: replaygain.cpp:178
Structure containing ReplayGain scan results from some playable object, also providing various helper...
Definition: file_info.h:2
Main interface class for information about some playable object.
Definition: file_info.h:73
Structure storing ReplayGain configuration: album/track source data modes, gain/peak processing modes...
Definition: replaygain.h:2
string8_fastalloc string_formatter
Definition: string_base.h:614
audio_sample query_scale(const file_info &info) const
Definition: replaygain.cpp:11
void SHARED_EXPORT scale(const audio_sample *p_source, t_size p_count, audio_sample *p_output, audio_sample p_scale)
p_source/p_output can point to same buffer
Definition: audio_math.cpp:63
audio_sample core_settings_query_scale(const file_info &p_info)
Helper; queries scale value for specified item according to core playback settings.
Definition: replaygain.cpp:66
float audio_sample
Definition: audio_sample.h:6
bool is_album_peak_present() const
Definition: file_info.h:31
bool is_track_gain_present() const
Definition: file_info.h:30
float m_album_gain
Definition: file_info.h:4
bool is_album_gain_present() const
Definition: file_info.h:29
virtual replaygain_info get_replaygain() const =0
Retrieves ReplayGain information.
float m_track_peak
Definition: file_info.h:5
t_processing_mode m_processing_mode
Definition: replaygain.h:14
audio_sample gain_to_scale(double p_gain)
Definition: audio_sample.h:71