ReplayGainInfo: refactor to a class

This commit is contained in:
Max Kellermann 2013-10-25 19:05:49 +02:00
parent 6d475c40de
commit d6e28c42e5
13 changed files with 65 additions and 68 deletions

View File

@ -518,11 +518,12 @@ decoder_replay_gain(Decoder &decoder,
if (rgm != REPLAY_GAIN_ALBUM) if (rgm != REPLAY_GAIN_ALBUM)
rgm = REPLAY_GAIN_TRACK; rgm = REPLAY_GAIN_TRACK;
decoder.dc.replay_gain_db = 20.0 * log10f( const auto &tuple = replay_gain_info->tuples[rgm];
replay_gain_tuple_scale( const auto scale =
&replay_gain_info->tuples[rgm], tuple.CalculateScale(replay_gain_preamp,
replay_gain_preamp, replay_gain_missing_preamp, replay_gain_missing_preamp,
replay_gain_limit)); replay_gain_limit);
decoder.dc.replay_gain_db = 20.0 * log10f(scale);
} }
decoder.replay_gain_info = *replay_gain_info; decoder.replay_gain_info = *replay_gain_info;

View File

@ -21,18 +21,19 @@
#include "ReplayGainInfo.hxx" #include "ReplayGainInfo.hxx"
float 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; float scale;
if (replay_gain_tuple_defined(tuple)) { if (IsDefined()) {
scale = pow(10.0, tuple->gain / 20.0); scale = pow(10.0, gain / 20.0);
scale *= preamp; scale *= preamp;
if (scale > 15.0) if (scale > 15.0)
scale = 15.0; scale = 15.0;
if (peak_limit && scale * tuple->peak > 1.0) if (peak_limit && scale * peak > 1.0)
scale = 1.0 / tuple->peak; scale = 1.0 / peak;
} else } else
scale = missing_preamp; scale = missing_preamp;
@ -40,9 +41,8 @@ replay_gain_tuple_scale(const ReplayGainTuple *tuple, float preamp, float missin
} }
void void
replay_gain_info_complete(ReplayGainInfo &info) ReplayGainInfo::Complete()
{ {
if (!replay_gain_tuple_defined(&info.tuples[REPLAY_GAIN_ALBUM])) if (!tuples[REPLAY_GAIN_ALBUM].IsDefined())
info.tuples[REPLAY_GAIN_ALBUM] = tuples[REPLAY_GAIN_ALBUM] = tuples[REPLAY_GAIN_TRACK];
info.tuples[REPLAY_GAIN_TRACK];
} }

View File

@ -21,6 +21,7 @@
#define MPD_REPLAY_GAIN_INFO_HXX #define MPD_REPLAY_GAIN_INFO_HXX
#include "check.h" #include "check.h"
#include "Compiler.h"
#include <cmath> #include <cmath>
@ -34,40 +35,35 @@ enum ReplayGainMode {
struct ReplayGainTuple { struct ReplayGainTuple {
float gain; float gain;
float peak; 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 { struct ReplayGainInfo {
ReplayGainTuple tuples[2]; ReplayGainTuple tuples[2];
};
static inline void void Clear() {
replay_gain_tuple_init(ReplayGainTuple *tuple) tuples[REPLAY_GAIN_ALBUM].Clear();
{ tuples[REPLAY_GAIN_TRACK].Clear();
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 * Attempt to auto-complete missing data. In particular, if
* information is missing, track gain is used. * album information is missing, track gain is used.
*/ */
void void Complete();
replay_gain_info_complete(ReplayGainInfo &info); };
#endif #endif

View File

@ -64,10 +64,9 @@ bool
flac_parse_replay_gain(ReplayGainInfo &rgi, flac_parse_replay_gain(ReplayGainInfo &rgi,
const FLAC__StreamMetadata *block) const FLAC__StreamMetadata *block)
{ {
rgi.Clear();
bool found = false; bool found = false;
replay_gain_info_init(&rgi);
if (flac_find_float_comment(block, "replaygain_album_gain", if (flac_find_float_comment(block, "replaygain_album_gain",
&rgi.tuples[REPLAY_GAIN_ALBUM].gain)) &rgi.tuples[REPLAY_GAIN_ALBUM].gain))
found = true; found = true;

View File

@ -260,7 +260,7 @@ parse_id3_replay_gain_info(ReplayGainInfo &rgi,
struct id3_frame *frame; struct id3_frame *frame;
bool found = false; bool found = false;
replay_gain_info_init(&rgi); rgi.Clear();
for (i = 0; (frame = id3_tag_findframe(tag, "TXXX", i)); i++) { for (i = 0; (frame = id3_tag_findframe(tag, "TXXX", i)); i++) {
if (frame->nfields < 3) if (frame->nfields < 3)
@ -872,7 +872,7 @@ MadDecoder::DecodeFirstFrame(Tag **tag)
if (decoder != nullptr && !found_replay_gain && if (decoder != nullptr && !found_replay_gain &&
lame.track_gain) { lame.track_gain) {
ReplayGainInfo rgi; ReplayGainInfo rgi;
replay_gain_info_init(&rgi); rgi.Clear();
rgi.tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain; rgi.tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain;
rgi.tuples[REPLAY_GAIN_TRACK].peak = lame.peak; rgi.tuples[REPLAY_GAIN_TRACK].peak = lame.peak;
decoder_replay_gain(*decoder, &rgi); decoder_replay_gain(*decoder, &rgi);

View File

@ -169,7 +169,7 @@ mpcdec_decode(Decoder &mpd_decoder, InputStream &is)
} }
ReplayGainInfo rgi; 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].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_ALBUM].peak = pow(10, info.peak_album / 256. / 20) / 32767;
rgi.tuples[REPLAY_GAIN_TRACK].gain = MPC_OLD_GAIN_REF - (info.gain_title / 256.); rgi.tuples[REPLAY_GAIN_TRACK].gain = MPC_OLD_GAIN_REF - (info.gain_title / 256.);

View File

@ -283,7 +283,7 @@ inline DecoderCommand
MPDOpusDecoder::HandleTags(const ogg_packet &packet) MPDOpusDecoder::HandleTags(const ogg_packet &packet)
{ {
ReplayGainInfo rgi; ReplayGainInfo rgi;
replay_gain_info_init(&rgi); rgi.Clear();
TagBuilder tag_builder; TagBuilder tag_builder;

View File

@ -49,11 +49,11 @@ vorbis_comment_value(const char *comment, const char *needle)
bool bool
vorbis_comments_to_replay_gain(ReplayGainInfo &rgi, char **comments) vorbis_comments_to_replay_gain(ReplayGainInfo &rgi, char **comments)
{ {
rgi.Clear();
const char *temp; const char *temp;
bool found = false; bool found = false;
replay_gain_info_init(&rgi);
while (*comments) { while (*comments) {
if ((temp = if ((temp =
vorbis_comment_value(*comments, "replaygain_track_gain"))) { vorbis_comment_value(*comments, "replaygain_track_gain"))) {

View File

@ -224,10 +224,9 @@ static bool
wavpack_replaygain(ReplayGainInfo &rgi, wavpack_replaygain(ReplayGainInfo &rgi,
WavpackContext *wpc) WavpackContext *wpc)
{ {
rgi.Clear();
bool found = false; bool found = false;
replay_gain_info_init(&rgi);
found |= wavpack_tag_float(wpc, "replaygain_track_gain", found |= wavpack_tag_float(wpc, "replaygain_track_gain",
&rgi.tuples[REPLAY_GAIN_TRACK].gain); &rgi.tuples[REPLAY_GAIN_TRACK].gain);
found |= wavpack_tag_float(wpc, "replaygain_track_peak", found |= wavpack_tag_float(wpc, "replaygain_track_peak",

View File

@ -76,7 +76,7 @@ public:
ReplayGainFilter() ReplayGainFilter()
:mixer(nullptr), mode(REPLAY_GAIN_OFF), :mixer(nullptr), mode(REPLAY_GAIN_OFF),
volume(PCM_VOLUME_1) { volume(PCM_VOLUME_1) {
replay_gain_info_init(&info); info.Clear();
} }
void SetMixer(Mixer *_mixer, unsigned _base) { void SetMixer(Mixer *_mixer, unsigned _base) {
@ -91,9 +91,9 @@ public:
void SetInfo(const ReplayGainInfo *_info) { void SetInfo(const ReplayGainInfo *_info) {
if (_info != NULL) { if (_info != NULL) {
info = *_info; info = *_info;
replay_gain_info_complete(info); info.Complete();
} else } else
replay_gain_info_init(&info); info.Clear();
Update(); Update();
} }
@ -126,8 +126,10 @@ void
ReplayGainFilter::Update() ReplayGainFilter::Update()
{ {
if (mode != REPLAY_GAIN_OFF) { if (mode != REPLAY_GAIN_OFF) {
float scale = replay_gain_tuple_scale(&info.tuples[mode], const auto &tuple = info.tuples[mode];
replay_gain_preamp, replay_gain_missing_preamp, replay_gain_limit); float scale = tuple.CalculateScale(replay_gain_preamp,
replay_gain_missing_preamp,
replay_gain_limit);
FormatDebug(replay_gain_domain, FormatDebug(replay_gain_domain,
"scale=%f\n", (double)scale); "scale=%f\n", (double)scale);

View File

@ -120,12 +120,12 @@ decoder_replay_gain(gcc_unused Decoder &decoder,
const ReplayGainInfo *rgi) const ReplayGainInfo *rgi)
{ {
const ReplayGainTuple *tuple = &rgi->tuples[REPLAY_GAIN_ALBUM]; 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", g_printerr("replay_gain[album]: gain=%f peak=%f\n",
tuple->gain, tuple->peak); tuple->gain, tuple->peak);
tuple = &rgi->tuples[REPLAY_GAIN_TRACK]; 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", g_printerr("replay_gain[track]: gain=%f peak=%f\n",
tuple->gain, tuple->peak); tuple->gain, tuple->peak);
} }

View File

@ -67,7 +67,7 @@ int main(int argc, char **argv)
} }
ReplayGainInfo replay_gain; ReplayGainInfo replay_gain;
replay_gain_info_init(&replay_gain); replay_gain.Clear();
bool success = tag_rva2_parse(tag, replay_gain); bool success = tag_rva2_parse(tag, replay_gain);
id3_tag_delete(tag); id3_tag_delete(tag);
@ -78,12 +78,12 @@ int main(int argc, char **argv)
} }
const ReplayGainTuple *tuple = &replay_gain.tuples[REPLAY_GAIN_ALBUM]; 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", g_printerr("replay_gain[album]: gain=%f peak=%f\n",
tuple->gain, tuple->peak); tuple->gain, tuple->peak);
tuple = &replay_gain.tuples[REPLAY_GAIN_TRACK]; 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", g_printerr("replay_gain[track]: gain=%f peak=%f\n",
tuple->gain, tuple->peak); tuple->gain, tuple->peak);

View File

@ -130,12 +130,12 @@ decoder_replay_gain(gcc_unused Decoder &decoder,
const ReplayGainInfo *rgi) const ReplayGainInfo *rgi)
{ {
const ReplayGainTuple *tuple = &rgi->tuples[REPLAY_GAIN_ALBUM]; 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", g_printerr("replay_gain[album]: gain=%f peak=%f\n",
tuple->gain, tuple->peak); tuple->gain, tuple->peak);
tuple = &rgi->tuples[REPLAY_GAIN_TRACK]; 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", g_printerr("replay_gain[track]: gain=%f peak=%f\n",
tuple->gain, tuple->peak); tuple->gain, tuple->peak);
} }