Take R128 header (not) into account while calculating replay gain.

This commit is contained in:
Adrian Ulrich 2019-05-01 18:15:31 +02:00
parent 8bb3395b0b
commit c57d256a1c
2 changed files with 30 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2013-2016 Adrian Ulrich <adrian@blinkenlights.ch> * Copyright (C) 2013-2019 Adrian Ulrich <adrian@blinkenlights.ch>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -33,6 +33,7 @@ public class BastpUtil {
public class GainValues { public class GainValues {
public float album; public float album;
public float track; public float track;
public boolean found;
} }
/** /**
* LRU cache for ReplayGain values * LRU cache for ReplayGain values
@ -45,7 +46,7 @@ public class BastpUtil {
public BastpUtil() { public BastpUtil() {
rgCache = new RGLruCache(64); /* Cache up to 64 entries */ rgCache = new RGLruCache(64);
} }
/** /**
@ -75,25 +76,34 @@ public class BastpUtil {
// normal replay gain // normal replay gain
if(tags.containsKey("REPLAYGAIN_TRACK_GAIN")) { if(tags.containsKey("REPLAYGAIN_TRACK_GAIN")) {
gv.track = getFloatFromString((String)((ArrayList)tags.get("REPLAYGAIN_TRACK_GAIN")).get(0)); gv.track = getFloatFromString((String)((ArrayList)tags.get("REPLAYGAIN_TRACK_GAIN")).get(0));
gv.found = true;
} }
if(tags.containsKey("REPLAYGAIN_ALBUM_GAIN")) { if(tags.containsKey("REPLAYGAIN_ALBUM_GAIN")) {
gv.album = getFloatFromString((String)((ArrayList)tags.get("REPLAYGAIN_ALBUM_GAIN")).get(0)); gv.album = getFloatFromString((String)((ArrayList)tags.get("REPLAYGAIN_ALBUM_GAIN")).get(0));
gv.found = true;
} }
// R128 replay gain // R128 replay gain
boolean r128 = false; boolean r128 = false;
if(tags.containsKey("R128_BASTP_BASE_GAIN")) { if(tags.containsKey("R128_BASTP_BASE_GAIN")) {
// This is the gain found in the opus header which automatically gets applied by the media framework.
// We therefore do not need to include it in our calculation, but we set the 'found' bit and reset
// both album and track gain information as an opus file should only ever contain r128 gain infos.
float base = getFloatFromString((String)((ArrayList)tags.get("R128_BASTP_BASE_GAIN")).get(0)) / 256.0f; float base = getFloatFromString((String)((ArrayList)tags.get("R128_BASTP_BASE_GAIN")).get(0)) / 256.0f;
gv.track = base; if (base != 0.0f) {
gv.album = base; gv.track = 0;
r128 = true; gv.album = 0;
gv.found = true;
}
} }
if(tags.containsKey("R128_TRACK_GAIN")) { if(tags.containsKey("R128_TRACK_GAIN")) {
gv.track += getFloatFromString((String)((ArrayList)tags.get("R128_TRACK_GAIN")).get(0)) / 256.0f; gv.track += getFloatFromString((String)((ArrayList)tags.get("R128_TRACK_GAIN")).get(0)) / 256.0f;
gv.found = true;
r128 = true; r128 = true;
} }
if(tags.containsKey("R128_ALBUM_GAIN")) { if(tags.containsKey("R128_ALBUM_GAIN")) {
gv.album += getFloatFromString((String)((ArrayList)tags.get("R128_ALBUM_GAIN")).get(0)) / 256.0f; gv.album += getFloatFromString((String)((ArrayList)tags.get("R128_ALBUM_GAIN")).get(0)) / 256.0f;
gv.found = true;
r128 = true; r128 = true;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2012-2018 Adrian Ulrich <adrian@blinkenlights.ch> * Copyright (C) 2012-2019 Adrian Ulrich <adrian@blinkenlights.ch>
* Copyright (C) 2010, 2011 Christopher Eby <kreed@kreed.org> * Copyright (C) 2010, 2011 Christopher Eby <kreed@kreed.org>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
@ -735,33 +735,33 @@ public final class PlaybackService extends Service
float adjust = 0f; float adjust = 0f;
if (mReplayGainAlbumEnabled) { if (mReplayGainAlbumEnabled) {
adjust = (rg.track != 0 ? rg.track : adjust); /* do we have track adjustment ? */ adjust = (rg.track != 0 ? rg.track : adjust); // Album gain enabled, but we use the track gain as a backup.
adjust = (rg.album != 0 ? rg.album : adjust); /* ..or, even better, album adj? */ adjust = (rg.album != 0 ? rg.album : adjust); // If album gain is present, we will prefer it.
} }
if (mReplayGainTrackEnabled || (mReplayGainAlbumEnabled && adjust == 0)) { if (mReplayGainTrackEnabled || (mReplayGainAlbumEnabled && adjust == 0)) {
adjust = (rg.album != 0 ? rg.album : adjust); /* do we have album adjustment ? */ adjust = (rg.album != 0 ? rg.album : adjust); // Track gain enabled, but we use the album gain as a backup.
adjust = (rg.track != 0 ? rg.track : adjust); /* ..or, even better, track adj? */ adjust = (rg.track != 0 ? rg.track : adjust); // If track gain is present, we will prefer it.
} }
if(adjust == 0) { if (!rg.found) {
/* No RG value found: decrease volume for untagged song if requested by user */ // No replay gain information found: adjust volume if requested by user.
adjust = (mReplayGainUntaggedDeBump-150)/10f; adjust = (mReplayGainUntaggedDeBump-150)/10f;
} else { } else {
/* This song has some replay gain info, we are now going to apply the 'bump' value // This song has some replay gain info, we are now going to apply the 'bump' value
** The preferences stores the raw value of the seekbar, that's 0-150 // The preferences stores the raw value of the seekbar, that's 0-150
** But we want -15 <-> +15, so 75 shall be zero */ // But we want -15 <-> +15, so 75 shall be zero.
adjust += 2*(mReplayGainBump-75)/10f; /* 2* -> we want +-15, not +-7.5 */ adjust += 2*(mReplayGainBump-75)/10f; // 2* -> we want +-15, not +-7.5
} }
if(mReplayGainAlbumEnabled == false && mReplayGainTrackEnabled == false) { if(mReplayGainAlbumEnabled == false && mReplayGainTrackEnabled == false) {
/* Feature is disabled: Make sure that we are going to 100% volume */ // Feature is disabled: Make sure that we are going to 100% volume.
adjust = 0f; adjust = 0f;
} }
float rg_result = ((float)Math.pow(10, (adjust/20) ))*mFadeOut; float rg_result = ((float)Math.pow(10, (adjust/20) ))*mFadeOut;
if(rg_result > 1.0f) { if(rg_result > 1.0f) {
rg_result = 1.0f; /* android would IGNORE the change if this is > 1 and we would end up with the wrong volume */ rg_result = 1.0f; // Android would IGNORE the change if this is > 1 and we would end up with the wrong volume.
} else if (rg_result < 0.0f) { } else if (rg_result < 0.0f) {
rg_result = 0.0f; rg_result = 0.0f;
} }