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 IAdjustableClock metronomeClock = null!;
private Sample? sampleTick;
private Sample? sampleTickDownbeat;
private Sample? sampleLatch; private Sample? sampleLatch;
private ScheduledDelegate? tickPlaybackDelegate; private readonly MetronomeTick metronomeTick = new MetronomeTick();
[Resolved] [Resolved]
private OverlayColourProvider overlayColourProvider { get; set; } = null!; private OverlayColourProvider overlayColourProvider { get; set; } = null!;
public bool EnableClicking { get; set; } = true; public bool EnableClicking
{
get => metronomeTick.EnableClicking;
set => metronomeTick.EnableClicking = value;
}
public MetronomeDisplay() public MetronomeDisplay()
{ {
@ -53,8 +55,6 @@ public MetronomeDisplay()
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audio) 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"); sampleLatch = audio.Samples.Get(@"UI/metronome-latch");
const float taper = 25; const float taper = 25;
@ -67,8 +67,11 @@ private void load(AudioManager audio)
AutoSizeAxes = Axes.Both; AutoSizeAxes = Axes.Both;
metronomeTick.Ticked = onTickPlayed;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
metronomeTick,
new Container new Container
{ {
Name = @"Taper adjust", Name = @"Taper adjust",
@ -265,9 +268,6 @@ protected override void Update()
isSwinging = false; isSwinging = false;
tickPlaybackDelegate?.Cancel();
tickPlaybackDelegate = null;
// instantly latch if pendulum arm is close enough to center (to prevent awkward delayed playback of latch sound) // 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)) 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; float targetAngle = currentAngle > 0 ? -angle : angle;
swing.RotateTo(targetAngle, beatLength, Easing.InOutQuad); 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)) AllowMistimedEventFiring = false;
{ }
stick.FlashColour(overlayColourProvider.Content1, beatLength, Easing.OutQuint);
tickPlaybackDelegate = Schedule(() => [BackgroundDependencyLoader]
{ private void load(AudioManager audio)
if (!EnableClicking) {
return; 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) if (!IsBeatSyncedWithTrack || !EnableClicking)
return; return;
channel.Frequency.Value = RNG.NextDouble(0.98f, 1.02f); var channel = beatIndex % timingPoint.TimeSignature.Numerator == 0 ? sampleTickDownbeat?.GetChannel() : sampleTick?.GetChannel();
channel.Play();
}); if (channel == null)
} return;
channel.Frequency.Value = RNG.NextDouble(0.98f, 1.02f);
channel.Play();
Ticked?.Invoke();
} }
} }
} }