ReplayGainInfo: refactor to a class
This commit is contained in:
parent
6d475c40de
commit
d6e28c42e5
|
@ -518,11 +518,12 @@ decoder_replay_gain(Decoder &decoder,
|
|||
if (rgm != REPLAY_GAIN_ALBUM)
|
||||
rgm = REPLAY_GAIN_TRACK;
|
||||
|
||||
decoder.dc.replay_gain_db = 20.0 * log10f(
|
||||
replay_gain_tuple_scale(
|
||||
&replay_gain_info->tuples[rgm],
|
||||
replay_gain_preamp, replay_gain_missing_preamp,
|
||||
replay_gain_limit));
|
||||
const auto &tuple = replay_gain_info->tuples[rgm];
|
||||
const auto scale =
|
||||
tuple.CalculateScale(replay_gain_preamp,
|
||||
replay_gain_missing_preamp,
|
||||
replay_gain_limit);
|
||||
decoder.dc.replay_gain_db = 20.0 * log10f(scale);
|
||||
}
|
||||
|
||||
decoder.replay_gain_info = *replay_gain_info;
|
||||
|
|
|
@ -21,18 +21,19 @@
|
|||
#include "ReplayGainInfo.hxx"
|
||||
|
||||
float
|
||||
replay_gain_tuple_scale(const ReplayGainTuple *tuple, float preamp, float missing_preamp, bool peak_limit)
|
||||
ReplayGainTuple::CalculateScale(float preamp, float missing_preamp,
|
||||
bool peak_limit) const
|
||||
{
|
||||
float scale;
|
||||
|
||||
if (replay_gain_tuple_defined(tuple)) {
|
||||
scale = pow(10.0, tuple->gain / 20.0);
|
||||
if (IsDefined()) {
|
||||
scale = pow(10.0, gain / 20.0);
|
||||
scale *= preamp;
|
||||
if (scale > 15.0)
|
||||
scale = 15.0;
|
||||
|
||||
if (peak_limit && scale * tuple->peak > 1.0)
|
||||
scale = 1.0 / tuple->peak;
|
||||
if (peak_limit && scale * peak > 1.0)
|
||||
scale = 1.0 / peak;
|
||||
} else
|
||||
scale = missing_preamp;
|
||||
|
||||
|
@ -40,9 +41,8 @@ replay_gain_tuple_scale(const ReplayGainTuple *tuple, float preamp, float missin
|
|||
}
|
||||
|
||||
void
|
||||
replay_gain_info_complete(ReplayGainInfo &info)
|
||||
ReplayGainInfo::Complete()
|
||||
{
|
||||
if (!replay_gain_tuple_defined(&info.tuples[REPLAY_GAIN_ALBUM]))
|
||||
info.tuples[REPLAY_GAIN_ALBUM] =
|
||||
info.tuples[REPLAY_GAIN_TRACK];
|
||||
if (!tuples[REPLAY_GAIN_ALBUM].IsDefined())
|
||||
tuples[REPLAY_GAIN_ALBUM] = tuples[REPLAY_GAIN_TRACK];
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define MPD_REPLAY_GAIN_INFO_HXX
|
||||
|
||||
#include "check.h"
|
||||
#include "Compiler.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
@ -34,40 +35,35 @@ enum ReplayGainMode {
|
|||
struct ReplayGainTuple {
|
||||
float gain;
|
||||
float peak;
|
||||
|
||||
void Clear() {
|
||||
gain = INFINITY;
|
||||
peak = 0.0;
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool IsDefined() const {
|
||||
return !std::isinf(gain);
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
float CalculateScale(float preamp, float missing_preamp,
|
||||
bool peak_limit) const;
|
||||
};
|
||||
|
||||
struct ReplayGainInfo {
|
||||
ReplayGainTuple tuples[2];
|
||||
|
||||
void Clear() {
|
||||
tuples[REPLAY_GAIN_ALBUM].Clear();
|
||||
tuples[REPLAY_GAIN_TRACK].Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to auto-complete missing data. In particular, if
|
||||
* album information is missing, track gain is used.
|
||||
*/
|
||||
void Complete();
|
||||
};
|
||||
|
||||
static inline void
|
||||
replay_gain_tuple_init(ReplayGainTuple *tuple)
|
||||
{
|
||||
tuple->gain = INFINITY;
|
||||
tuple->peak = 0.0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
replay_gain_info_init(struct ReplayGainInfo *info)
|
||||
{
|
||||
replay_gain_tuple_init(&info->tuples[REPLAY_GAIN_ALBUM]);
|
||||
replay_gain_tuple_init(&info->tuples[REPLAY_GAIN_TRACK]);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
replay_gain_tuple_defined(const ReplayGainTuple *tuple)
|
||||
{
|
||||
return !std::isinf(tuple->gain);
|
||||
}
|
||||
|
||||
float
|
||||
replay_gain_tuple_scale(const ReplayGainTuple *tuple, float preamp, float missing_preamp, bool peak_limit);
|
||||
|
||||
/**
|
||||
* Attempt to auto-complete missing data. In particular, if album
|
||||
* information is missing, track gain is used.
|
||||
*/
|
||||
void
|
||||
replay_gain_info_complete(ReplayGainInfo &info);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -64,10 +64,9 @@ bool
|
|||
flac_parse_replay_gain(ReplayGainInfo &rgi,
|
||||
const FLAC__StreamMetadata *block)
|
||||
{
|
||||
rgi.Clear();
|
||||
|
||||
bool found = false;
|
||||
|
||||
replay_gain_info_init(&rgi);
|
||||
|
||||
if (flac_find_float_comment(block, "replaygain_album_gain",
|
||||
&rgi.tuples[REPLAY_GAIN_ALBUM].gain))
|
||||
found = true;
|
||||
|
|
|
@ -260,7 +260,7 @@ parse_id3_replay_gain_info(ReplayGainInfo &rgi,
|
|||
struct id3_frame *frame;
|
||||
bool found = false;
|
||||
|
||||
replay_gain_info_init(&rgi);
|
||||
rgi.Clear();
|
||||
|
||||
for (i = 0; (frame = id3_tag_findframe(tag, "TXXX", i)); i++) {
|
||||
if (frame->nfields < 3)
|
||||
|
@ -872,7 +872,7 @@ MadDecoder::DecodeFirstFrame(Tag **tag)
|
|||
if (decoder != nullptr && !found_replay_gain &&
|
||||
lame.track_gain) {
|
||||
ReplayGainInfo rgi;
|
||||
replay_gain_info_init(&rgi);
|
||||
rgi.Clear();
|
||||
rgi.tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain;
|
||||
rgi.tuples[REPLAY_GAIN_TRACK].peak = lame.peak;
|
||||
decoder_replay_gain(*decoder, &rgi);
|
||||
|
|
|
@ -169,7 +169,7 @@ mpcdec_decode(Decoder &mpd_decoder, InputStream &is)
|
|||
}
|
||||
|
||||
ReplayGainInfo rgi;
|
||||
replay_gain_info_init(&rgi);
|
||||
rgi.Clear();
|
||||
rgi.tuples[REPLAY_GAIN_ALBUM].gain = MPC_OLD_GAIN_REF - (info.gain_album / 256.);
|
||||
rgi.tuples[REPLAY_GAIN_ALBUM].peak = pow(10, info.peak_album / 256. / 20) / 32767;
|
||||
rgi.tuples[REPLAY_GAIN_TRACK].gain = MPC_OLD_GAIN_REF - (info.gain_title / 256.);
|
||||
|
|
|
@ -283,7 +283,7 @@ inline DecoderCommand
|
|||
MPDOpusDecoder::HandleTags(const ogg_packet &packet)
|
||||
{
|
||||
ReplayGainInfo rgi;
|
||||
replay_gain_info_init(&rgi);
|
||||
rgi.Clear();
|
||||
|
||||
TagBuilder tag_builder;
|
||||
|
||||
|
|
|
@ -49,11 +49,11 @@ vorbis_comment_value(const char *comment, const char *needle)
|
|||
bool
|
||||
vorbis_comments_to_replay_gain(ReplayGainInfo &rgi, char **comments)
|
||||
{
|
||||
rgi.Clear();
|
||||
|
||||
const char *temp;
|
||||
bool found = false;
|
||||
|
||||
replay_gain_info_init(&rgi);
|
||||
|
||||
while (*comments) {
|
||||
if ((temp =
|
||||
vorbis_comment_value(*comments, "replaygain_track_gain"))) {
|
||||
|
|
|
@ -224,10 +224,9 @@ static bool
|
|||
wavpack_replaygain(ReplayGainInfo &rgi,
|
||||
WavpackContext *wpc)
|
||||
{
|
||||
rgi.Clear();
|
||||
|
||||
bool found = false;
|
||||
|
||||
replay_gain_info_init(&rgi);
|
||||
|
||||
found |= wavpack_tag_float(wpc, "replaygain_track_gain",
|
||||
&rgi.tuples[REPLAY_GAIN_TRACK].gain);
|
||||
found |= wavpack_tag_float(wpc, "replaygain_track_peak",
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
ReplayGainFilter()
|
||||
:mixer(nullptr), mode(REPLAY_GAIN_OFF),
|
||||
volume(PCM_VOLUME_1) {
|
||||
replay_gain_info_init(&info);
|
||||
info.Clear();
|
||||
}
|
||||
|
||||
void SetMixer(Mixer *_mixer, unsigned _base) {
|
||||
|
@ -91,9 +91,9 @@ public:
|
|||
void SetInfo(const ReplayGainInfo *_info) {
|
||||
if (_info != NULL) {
|
||||
info = *_info;
|
||||
replay_gain_info_complete(info);
|
||||
info.Complete();
|
||||
} else
|
||||
replay_gain_info_init(&info);
|
||||
info.Clear();
|
||||
|
||||
Update();
|
||||
}
|
||||
|
@ -126,8 +126,10 @@ void
|
|||
ReplayGainFilter::Update()
|
||||
{
|
||||
if (mode != REPLAY_GAIN_OFF) {
|
||||
float scale = replay_gain_tuple_scale(&info.tuples[mode],
|
||||
replay_gain_preamp, replay_gain_missing_preamp, replay_gain_limit);
|
||||
const auto &tuple = info.tuples[mode];
|
||||
float scale = tuple.CalculateScale(replay_gain_preamp,
|
||||
replay_gain_missing_preamp,
|
||||
replay_gain_limit);
|
||||
FormatDebug(replay_gain_domain,
|
||||
"scale=%f\n", (double)scale);
|
||||
|
||||
|
|
|
@ -120,12 +120,12 @@ decoder_replay_gain(gcc_unused Decoder &decoder,
|
|||
const ReplayGainInfo *rgi)
|
||||
{
|
||||
const ReplayGainTuple *tuple = &rgi->tuples[REPLAY_GAIN_ALBUM];
|
||||
if (replay_gain_tuple_defined(tuple))
|
||||
if (tuple->IsDefined())
|
||||
g_printerr("replay_gain[album]: gain=%f peak=%f\n",
|
||||
tuple->gain, tuple->peak);
|
||||
|
||||
tuple = &rgi->tuples[REPLAY_GAIN_TRACK];
|
||||
if (replay_gain_tuple_defined(tuple))
|
||||
if (tuple->IsDefined())
|
||||
g_printerr("replay_gain[track]: gain=%f peak=%f\n",
|
||||
tuple->gain, tuple->peak);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
ReplayGainInfo replay_gain;
|
||||
replay_gain_info_init(&replay_gain);
|
||||
replay_gain.Clear();
|
||||
|
||||
bool success = tag_rva2_parse(tag, replay_gain);
|
||||
id3_tag_delete(tag);
|
||||
|
@ -78,12 +78,12 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
const ReplayGainTuple *tuple = &replay_gain.tuples[REPLAY_GAIN_ALBUM];
|
||||
if (replay_gain_tuple_defined(tuple))
|
||||
if (tuple->IsDefined())
|
||||
g_printerr("replay_gain[album]: gain=%f peak=%f\n",
|
||||
tuple->gain, tuple->peak);
|
||||
|
||||
tuple = &replay_gain.tuples[REPLAY_GAIN_TRACK];
|
||||
if (replay_gain_tuple_defined(tuple))
|
||||
if (tuple->IsDefined())
|
||||
g_printerr("replay_gain[track]: gain=%f peak=%f\n",
|
||||
tuple->gain, tuple->peak);
|
||||
|
||||
|
|
|
@ -130,12 +130,12 @@ decoder_replay_gain(gcc_unused Decoder &decoder,
|
|||
const ReplayGainInfo *rgi)
|
||||
{
|
||||
const ReplayGainTuple *tuple = &rgi->tuples[REPLAY_GAIN_ALBUM];
|
||||
if (replay_gain_tuple_defined(tuple))
|
||||
if (tuple->IsDefined())
|
||||
g_printerr("replay_gain[album]: gain=%f peak=%f\n",
|
||||
tuple->gain, tuple->peak);
|
||||
|
||||
tuple = &rgi->tuples[REPLAY_GAIN_TRACK];
|
||||
if (replay_gain_tuple_defined(tuple))
|
||||
if (tuple->IsDefined())
|
||||
g_printerr("replay_gain[track]: gain=%f peak=%f\n",
|
||||
tuple->gain, tuple->peak);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue