Commit d6e28c42 authored by Max Kellermann's avatar Max Kellermann

ReplayGainInfo: refactor to a class

parent 6d475c40
......@@ -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;
};
struct ReplayGainInfo {
ReplayGainTuple tuples[2];
};
void Clear() {
gain = INFINITY;
peak = 0.0;
}
static inline void
replay_gain_tuple_init(ReplayGainTuple *tuple)
{
tuple->gain = INFINITY;
tuple->peak = 0.0;
}
gcc_pure
bool IsDefined() const {
return !std::isinf(gain);
}
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]);
}
gcc_pure
float CalculateScale(float preamp, float missing_preamp,
bool peak_limit) const;
};
static inline bool
replay_gain_tuple_defined(const ReplayGainTuple *tuple)
{
return !std::isinf(tuple->gain);
}
struct ReplayGainInfo {
ReplayGainTuple tuples[2];
float
replay_gain_tuple_scale(const ReplayGainTuple *tuple, float preamp, float missing_preamp, bool peak_limit);
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.
/**
* Attempt to auto-complete missing data. In particular, if
* album information is missing, track gain is used.
*/
void
replay_gain_info_complete(ReplayGainInfo &info);
void Complete();
};
#endif
......@@ -64,10 +64,9 @@ bool
flac_parse_replay_gain(ReplayGainInfo &rgi,
const FLAC__StreamMetadata *block)
{
bool found = false;
replay_gain_info_init(&rgi);
rgi.Clear();
bool found = false;
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)
{
bool found = false;
replay_gain_info_init(&rgi);
rgi.Clear();
bool found = false;
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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment