Improvements for audio normalization - #1
Conversation
|
I believe you did the hard work of merging master into my branch given the 182 hidden items and 12 participants, so I probably wont bother with that. I've already skimmed the code and it looks solid, so I'll probably merge after I do tests on it. |
|
Okay, after having looked through things.
|
49aa227 to
46f11c7
Compare
|
I guess it's now okay? I just fixed the xmldoc you mentioned, too, |
smallketchup82
left a comment
There was a problem hiding this comment.
I've tested and it works fine, apart from these I have no other gripes myself. I'll probably merge this once everything is addressed, then have smoogi re-review.
|
|
||
| /// <inheritdoc /> | ||
| public bool Equals(IAudioNormalization? other) => other is AudioNormalization audioNormalization && Equals(audioNormalization); | ||
| public float IntegratedLoudnessInVolumeOffset => IntegratedLoudness != null ? (float)Math.Pow(10, (TARGET_LEVEL - (double)IntegratedLoudness) / 20) : 0.8f; |
There was a problem hiding this comment.
I think it'd be better to lower the global volume reduction. In my testing, turning off normalization would blast your ears since 100% volume with 0.8 is much louder than 100% with -14 LUFS.
I'll probably do my own testing to find a proper value for it and consult with the core team & @nekodex about it. You can dismiss this message since its more of a note for myself. Though, nekodex, if you have any thoughts on this then do let me know
| beatmapHitsoundBind = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds); | ||
|
|
||
| normalizeSampleIfTrue(beatmapHitsoundBind.Value); |
There was a problem hiding this comment.
Why do we only retain the relationship between tracks and hitsounds if beatmap hitsounds are turned on? Unless I'm mistaken and this does something entirely different, I think we'd want the volume offset to apply to skin hitsounds, beatmap hitsounds, and all other gameplay samples (combo sound, slider tick, etc).
Though I want to mention @nekodex and get his opinion on this.
There was a problem hiding this comment.
I assumed that most players expect consistent hitsounds over maps if they don't have beatmap hitsounds enabled. I guess I should have discussed about this earlier..
|
Refactored the code a bit so that MusicController won't access the bindable directly, and applied your suggestions, too. Edit: There are some things I probably have missed, but it's 3am here... so I'll fix them later. |
|
So I've written a git diff which removes the In its place, I've written a barebones implementation of a configuration setting to toggle normalization on or off. Since it might be a little unclear, I created the There's definitely ways to improve it (and probably shuffle things around to remove the multiple if statement checks for the config value in I'll be honest and say that the main reason I wrote this was because the hitsounds can get really quiet depending on the skin, beatmap, etc. Some users might want to turn off normalization to make use of the higher volume ceiling. Although, maybe instead of allowing users to disable normalization, it could be wise to change this setting to be something like "Volume boost" which changes the target level from -14 to something louder, like -10, to give users a higher volume ceiling without needing to disable normalization. This is probably something I'd want @nekodex to give his opinion on as well. diff --git a/osu.Game/Audio/AudioNormalizationManager.cs b/osu.Game/Audio/AudioNormalizationManager.cs
index 5e6b7e5e4a..129e1d1cdb 100644
--- a/osu.Game/Audio/AudioNormalizationManager.cs
+++ b/osu.Game/Audio/AudioNormalizationManager.cs
@@ -21,7 +21,12 @@ public class AudioNormalizationManager
/// </summary>
public const double FALLBACK_VOLUME = 0.8;
- private readonly Bindable<bool> beatmapHitsoundBind;
+ private readonly Bindable<bool> audioNormalizationSetting;
+
+ /// <summary>
+ /// Store the volume before normalization is disabled to restore it later if needed.
+ /// </summary>
+ private double storedVolume;
/// <summary>
/// Default <see cref="ITrackStore"/> will bind to this bindable.
@@ -44,23 +49,22 @@ public AudioNormalizationManager(AudioManager audioManager, OsuConfigManager con
{
audioManager.Tracks.AddAdjustment(AdjustableProperty.Volume, TrackNormalizeVolume);
- beatmapHitsoundBind = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds);
-
- normalizeSampleIfTrue(beatmapHitsoundBind.Value);
- beatmapHitsoundBind.BindValueChanged(change => normalizeSampleIfTrue(change.NewValue));
- }
-
- private void normalizeSampleIfTrue(bool value)
- {
- if (value)
+ audioNormalizationSetting = config.GetBindable<bool>(OsuSetting.AudioNormalization);
+ audioNormalizationSetting.BindValueChanged(change =>
{
- SampleNormalizeVolume.BindTo(TrackNormalizeVolume);
- }
- else
- {
- SampleNormalizeVolume.UnbindFrom(TrackNormalizeVolume);
- SampleNormalizeVolume.Value = 1.0;
- }
+ if (change.NewValue)
+ {
+ TrackNormalizeVolume.Value = storedVolume;
+ SampleNormalizeVolume.BindTo(TrackNormalizeVolume);
+ }
+ else
+ {
+ storedVolume = TrackNormalizeVolume.Value;
+ TrackNormalizeVolume.Value = FALLBACK_VOLUME;
+ SampleNormalizeVolume.UnbindFrom(TrackNormalizeVolume);
+ SampleNormalizeVolume.Value = 1.0;
+ }
+ }, true);
}
/// <summary>
@@ -75,17 +79,21 @@ public void SetTrackNormalizationVolume(AudioNormalization? audioNormalization,
if (volume == null)
{
volume = FALLBACK_VOLUME;
- Logger.Log($"Normalization status: {Math.Round((double)volume * 100)}% (fallback)");
+ if (audioNormalizationSetting.Value) Logger.Log($"Normalization status: {Math.Round((double)volume * 100)}% (fallback)");
}
- else
- {
+ else if (audioNormalizationSetting.Value)
Logger.Log($"Normalization status: {Math.Round((double)volume * 100)}%");
- }
if (volume == TrackNormalizeVolume.Value)
return;
- action(TrackNormalizeVolume, (double)volume);
+ if (audioNormalizationSetting.Value)
+ action(TrackNormalizeVolume, (double)volume);
+ else
+ {
+ storedVolume = (double)volume;
+ action(TrackNormalizeVolume, FALLBACK_VOLUME);
+ }
}
}
}
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index f4a4c553d8..30aac469ff 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.cs
@@ -109,6 +109,8 @@ protected override void InitialiseDefaults()
SetDefault(OsuSetting.AudioOffset, 0, -500.0, 500.0, 1);
+ SetDefault(OsuSetting.AudioNormalization, true);
+
// Input
SetDefault(OsuSetting.MenuCursorSize, 1.0f, 0.5f, 2f, 0.01f);
SetDefault(OsuSetting.GameplayCursorSize, 1.0f, 0.1f, 2f, 0.01f);
@@ -360,6 +362,7 @@ public enum OsuSetting
/// This is added to the audio track's current time. Higher values will cause gameplay to occur earlier, relative to the audio track.
/// </summary>
AudioOffset,
+ AudioNormalization,
VolumeInactive,
MenuMusic,
diff --git a/osu.Game/Localisation/AudioSettingsStrings.cs b/osu.Game/Localisation/AudioSettingsStrings.cs
index 89db60d8a6..138970e38e 100644
--- a/osu.Game/Localisation/AudioSettingsStrings.cs
+++ b/osu.Game/Localisation/AudioSettingsStrings.cs
@@ -64,6 +64,11 @@ public static class AudioSettingsStrings
/// </summary>
public static LocalisableString AudioOffset => new TranslatableString(getKey(@"audio_offset"), @"Audio offset");
+ /// <summary>
+ /// "Normalize Audio"
+ /// </summary>
+ public static LocalisableString AudioNormalization => new TranslatableString(getKey(@"audio_normalization"), @"Normalize Audio");
+
/// <summary>
/// "Play a few beatmaps to receive a suggested offset!"
/// </summary>
diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs
index 2bb5fa983f..7d73dbd199 100644
--- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs
@@ -49,6 +49,11 @@ private void load(AudioManager audio, OsuConfigManager config)
KeyboardStep = 0.01f,
DisplayAsPercentage = true
},
+ new SettingsCheckbox
+ {
+ LabelText = AudioSettingsStrings.AudioNormalization,
+ Current = config.GetBindable<bool>(OsuSetting.AudioNormalization)
+ }
};
} |
Co-authored-by: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
|
Added 'Normalize Audio' setting with your diff, and I refactored it once again. I guess it's now in an acceptable state? |
|
The code itself looks fine to me now. I'll merge this since further review from me probably wouldn't be productive. Better to leave the rest to the core team. In regards to #1 (comment), it seems like the current implementation applies the normalization regardless of whether beatmap hitsounds are turned on or off. If the core team wants to change that, that can be addressed then. I'd like for you to be subscribed to the original PR, as having your input on things would be useful. |
This is a set of model changes which is supposed to facilitate support for custom sample sets to the beatmap editor that is on par with stable. It is the minimal set of changes. Because of this, it can probably be considered "ugly" or however else you want to put it - but before you say that, I want to try and pre-empt that criticism by explaining where the problems lie. Problem #1: duality in sample models --- There is currently a weird duality of what a `HitObject`'s samples will be. - If an object has just been placed in the editor, and not saved / decoded yet, it will use `HitSampleInfo`. - If an object has already been encoded to the beatmap at least once, it will use `ConvertHitObjectParser.LegacyHitSampleInfo`. As long as that state of affairs remains, `HitSampleInfo` must be able to represent anything that `LegacyHitSampleInfo` can, if feature parity is to be achieved. Problem 2: The 0 & 1 sample banks --- Custom sample banks of 2 and above are a pretty clean affair. They map to a suffix on the sample filename, and said samples are allowed to be looked up from the beatmap skin. `Suffix` already exists in `HitSampleInfo`. However, the 1 custom sample bank is evil. It uses *non-suffixed* samples, *allows lookups from the beatmap skins*, contrary to no bank / bank 0, which *also* uses non-suffixed samples, but *doesn't* allow them to be looked up from the beatmap skin. This is why `HitSampleInfo.UseBeatmapSamples` has been called to existence - without it there is no way to represent the ability of using or not using the beatmap skin assets. As has been stated previously in discussions about this feature, it's both a *mapping* and a *skinning* concern. There are many things you could do about either of these problems, but I am pretty sure tackling either one is going to take *many* more lines of code than this commit does. Which is why this is the starting point of negotiation.
You may want to merge master into your branch before reviewing this. I merged master into my branch because I didn't want to play with framework version..
Changes:
TrackLoudnessfrom osu!framework (requires Add TrackLoudness (BASSloud) ppy/osu-framework#6281)