mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Fixed looped audio playback position calculation (#6325)
* fix: looped audio position calculation * refactor: tiny clean up * move comment * fix: review changes * remove ` * rerun tests * Remove unecessary formatting changes --------- Co-authored-by: PJB3005 <pieterjan.briers+git@gmail.com>
This commit is contained in:
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Numerics;
|
||||
using JetBrains.Annotations;
|
||||
using OpenTK.Audio.OpenAL;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
@@ -17,7 +16,6 @@ using Robust.Shared.Exceptions;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
@@ -182,14 +180,16 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
}
|
||||
|
||||
// If playback position changed then update it.
|
||||
var position = (float) ((entity.Comp.PauseTime ?? Timing.CurTime) - entity.Comp.AudioStart).TotalSeconds;
|
||||
var totalLen = GetAudioLengthImpl(entity.Comp.FileName).TotalSeconds;
|
||||
var position = CalculateAudioPosition(entity, (float) totalLen);
|
||||
|
||||
var currentPosition = entity.Comp.Source.PlaybackPosition;
|
||||
var diff = Math.Abs(position - currentPosition);
|
||||
|
||||
// Don't try to set the audio too far ahead.
|
||||
if (!string.IsNullOrEmpty(entity.Comp.FileName))
|
||||
{
|
||||
if (position > GetAudioLengthImpl(entity.Comp.FileName).TotalSeconds - _audioEndBuffer)
|
||||
if (position > totalLen - _audioEndBuffer)
|
||||
{
|
||||
entity.Comp.StopPlaying();
|
||||
return;
|
||||
@@ -251,7 +251,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
length ??= GetAudioLength(component.FileName);
|
||||
|
||||
// If audio came into range then start playback at the correct position.
|
||||
var offset = ((entity.Comp.PauseTime ?? Timing.CurTime) - component.AudioStart).TotalSeconds;
|
||||
var offset = CalculateAudioPosition(entity, (float) length.Value.TotalSeconds);
|
||||
|
||||
if (TryAudioLimit(component.FileName))
|
||||
{
|
||||
@@ -289,7 +289,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
|
||||
if (offset > 0)
|
||||
{
|
||||
component.PlaybackPosition = (float) offset;
|
||||
component.PlaybackPosition = offset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -755,10 +755,7 @@ public sealed partial class AudioSystem : SharedAudioSystem
|
||||
var comp = entity.Comp;
|
||||
var source = comp.Source;
|
||||
|
||||
// TODO clamp the offset inside of SetPlaybackPosition() itself.
|
||||
var offset = audioP.PlayOffsetSeconds;
|
||||
var maxOffset = Math.Max((float) stream.Length.TotalSeconds - 0.01f, 0f);
|
||||
offset = Math.Clamp(offset, 0f, maxOffset);
|
||||
var offset = CalculateAudioPosition(entity, (float)stream.Length.TotalSeconds, audioP.PlayOffsetSeconds);
|
||||
source.PlaybackPosition = offset;
|
||||
|
||||
source.StartPlaying();
|
||||
|
||||
@@ -75,6 +75,7 @@ public abstract partial class SharedAudioSystem : EntitySystem
|
||||
return;
|
||||
|
||||
var audioLength = GetAudioLength(entity.Comp.FileName);
|
||||
position = CalculateAudioPosition(entity!, (float)audioLength.TotalSeconds, position);
|
||||
|
||||
if (audioLength.TotalSeconds < position)
|
||||
{
|
||||
@@ -86,12 +87,6 @@ public abstract partial class SharedAudioSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (position < 0f)
|
||||
{
|
||||
Log.Error($"Tried to set playback position for {ToPrettyString(entity.Owner)} / {entity.Comp.FileName} outside of bounds");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're paused then the current position is <pause time - start time>, else it's <cur time - start time>
|
||||
var currentPos = (entity.Comp.PauseTime ?? Timing.CurTime) - entity.Comp.AudioStart;
|
||||
var timeOffset = TimeSpan.FromSeconds(position - currentPos.TotalSeconds);
|
||||
@@ -315,6 +310,36 @@ public abstract partial class SharedAudioSystem : EntitySystem
|
||||
return GetAudioPath(resolved);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the current playback position of an audio entity
|
||||
/// and clamps it to the range from 0 to (length - 0.01f).
|
||||
/// </summary>
|
||||
/// <param name="ent">The audio entity.</param>
|
||||
/// <param name="length">
|
||||
/// The total length of the audio file.
|
||||
/// If null, the method retrieves the length using <see cref="GetAudioLength"/>.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A precomputed playback position.
|
||||
/// If provided, it will be added to the calculation.
|
||||
/// </param>
|
||||
/// <returns>The playback position as a float.</returns>
|
||||
protected float CalculateAudioPosition(Entity<AudioComponent> ent, float? length = null, float? position = null)
|
||||
{
|
||||
position ??= (float) ((ent.Comp.PauseTime ?? Timing.CurTime) - ent.Comp.AudioStart).TotalSeconds;
|
||||
length ??= (float) GetAudioLength(ent.Comp.FileName).TotalSeconds;
|
||||
|
||||
// Looped audio has no conceptual start or end.
|
||||
if (ent.Comp.Params.Loop)
|
||||
position %= length;
|
||||
|
||||
// TODO clamp the offset inside of AudioSource.SetPlaybackPosition() itself.
|
||||
var maxOffset = Math.Max((float) length - 0.01f, 0f);
|
||||
position = Math.Clamp(position.Value, 0f, maxOffset);
|
||||
|
||||
return position.Value;
|
||||
}
|
||||
|
||||
#region AudioParams
|
||||
|
||||
[return: NotNullIfNotNull(nameof(specifier))]
|
||||
|
||||
Reference in New Issue
Block a user