Merge pull request #25316 from peppy/metronome-always-play-tick

Decouple metronome tick playback from pendulum movement
This commit is contained in:
Bartłomiej Dach 2023-10-31 09:37:29 +01:00 committed by GitHub
commit 850866e7f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 50 additions and 24 deletions

View File

@ -34,16 +34,18 @@ public partial class MetronomeDisplay : BeatSyncedContainer
private IAdjustableClock metronomeClock = null!;
private Sample? sampleTick;
private Sample? sampleTickDownbeat;
private Sample? sampleLatch;
private ScheduledDelegate? tickPlaybackDelegate;
private readonly MetronomeTick metronomeTick = new MetronomeTick();
[Resolved]
private OverlayColourProvider overlayColourProvider { get; set; } = null!;
public bool EnableClicking { get; set; } = true;
public bool EnableClicking
{
get => metronomeTick.EnableClicking;
set => metronomeTick.EnableClicking = value;
}
public MetronomeDisplay()
{
@ -53,8 +55,6 @@ public MetronomeDisplay()
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
sampleTick = audio.Samples.Get(@"UI/metronome-tick");
sampleTickDownbeat = audio.Samples.Get(@"UI/metronome-tick-downbeat");
sampleLatch = audio.Samples.Get(@"UI/metronome-latch");
const float taper = 25;
@ -67,8 +67,11 @@ private void load(AudioManager audio)
AutoSizeAxes = Axes.Both;
metronomeTick.Ticked = onTickPlayed;
InternalChildren = new Drawable[]
{
metronomeTick,
new Container
{
Name = @"Taper adjust",
@ -265,9 +268,6 @@ protected override void Update()
isSwinging = false;
tickPlaybackDelegate?.Cancel();
tickPlaybackDelegate = null;
// instantly latch if pendulum arm is close enough to center (to prevent awkward delayed playback of latch sound)
if (Precision.AlmostEquals(swing.Rotation, 0, 1))
{
@ -306,27 +306,53 @@ protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint,
float targetAngle = currentAngle > 0 ? -angle : angle;
swing.RotateTo(targetAngle, beatLength, Easing.InOutQuad);
}
if (currentAngle != 0 && Math.Abs(currentAngle - targetAngle) > angle * 1.8f && isSwinging)
private void onTickPlayed()
{
// Originally, this flash only occurred when the pendulum correctly passess the centre.
// Mappers weren't happy with the metronome tick not playing immediately after starting playback
// so now this matches the actual tick sample.
stick.FlashColour(overlayColourProvider.Content1, beatLength, Easing.OutQuint);
}
private partial class MetronomeTick : BeatSyncedContainer
{
public bool EnableClicking;
private Sample? sampleTick;
private Sample? sampleTickDownbeat;
public Action? Ticked;
public MetronomeTick()
{
using (BeginDelayedSequence(beatLength / 2))
{
stick.FlashColour(overlayColourProvider.Content1, beatLength, Easing.OutQuint);
AllowMistimedEventFiring = false;
}
tickPlaybackDelegate = Schedule(() =>
{
if (!EnableClicking)
return;
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
sampleTick = audio.Samples.Get(@"UI/metronome-tick");
sampleTickDownbeat = audio.Samples.Get(@"UI/metronome-tick-downbeat");
}
var channel = beatIndex % timingPoint.TimeSignature.Numerator == 0 ? sampleTickDownbeat?.GetChannel() : sampleTick?.GetChannel();
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
{
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
if (channel == null)
return;
if (!IsBeatSyncedWithTrack || !EnableClicking)
return;
channel.Frequency.Value = RNG.NextDouble(0.98f, 1.02f);
channel.Play();
});
}
var channel = beatIndex % timingPoint.TimeSignature.Numerator == 0 ? sampleTickDownbeat?.GetChannel() : sampleTick?.GetChannel();
if (channel == null)
return;
channel.Frequency.Value = RNG.NextDouble(0.98f, 1.02f);
channel.Play();
Ticked?.Invoke();
}
}
}