Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix songs not ending in rare cases #453

Merged
merged 3 commits into from
Jun 11, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix song not ending in rare cases
RileyTheFox committed Jun 10, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 82afe70ff34633f16f05d9dbc02d16e8e3261eec
22 changes: 22 additions & 0 deletions Assets/Script/Audio/Bass/BassAudioManager.cs
Original file line number Diff line number Diff line change
@@ -31,13 +31,16 @@ public class BassAudioManager : MonoBehaviour, IAudioManager {
public float CurrentPositionF => (float) GetPosition();
public float AudioLengthF { get; private set; }

private IAudioManager.SongEndCallback _songEndCallback;

private double[] _stemVolumes;
private ISampleChannel[] _sfxSamples;

private int _opusHandle;

private IStemMixer _mixer;


private void Awake() {
SupportedFormats = new[] {
".ogg",
@@ -72,7 +75,10 @@ public void Initialize() {
Bass.Configure(Configuration.UpdateThreads, 2);
Bass.Configure(Configuration.FloatDSP, true);

// Undocumented BASS_CONFIG_MP3_OLDGAPS config.
Bass.Configure((Configuration) 68, 1);

// Disable undocumented BASS_CONFIG_DEV_TIMEOUT config. Prevents pausing audio output if a device times out.
Bass.Configure((Configuration) 70, false);

int deviceCount = Bass.DeviceCount;
@@ -225,6 +231,10 @@ public void LoadSong(ICollection<string> stems, float speed, params SongStem[] i
AudioLengthD = _mixer.LeadChannel.LengthD;
AudioLengthF = (float) AudioLengthD;

_mixer.SetSync(SyncFlags.End, () => {
UnityMainThreadCallback.QueueEvent(_songEndCallback.Invoke);
});

IsAudioLoaded = true;
}

@@ -307,6 +317,10 @@ public void LoadMogg(ExtractedConSongEntry exConSong, float speed, params SongSt
AudioLengthD = _mixer.LeadChannel.LengthD;
AudioLengthF = (float) AudioLengthD;

_mixer.SetSync(SyncFlags.End, () => {
UnityMainThreadCallback.QueueEvent(_songEndCallback.Invoke);
});

IsAudioLoaded = true;
}

@@ -388,6 +402,14 @@ public void Pause() {
IsPlaying = _mixer.IsPlaying;
}

public void AddSongEndCallback(IAudioManager.SongEndCallback callback) {
_songEndCallback += callback;
}

public void RemoveSongEndCallback(IAudioManager.SongEndCallback callback) {
_songEndCallback -= callback;
}

public void FadeIn(float maxVolume) {
Play(true);
if (IsPlaying) {
12 changes: 9 additions & 3 deletions Assets/Script/Audio/Bass/BassStemMixer.cs
Original file line number Diff line number Diff line change
@@ -11,9 +11,9 @@ namespace YARG.Audio.BASS {
public class BassStemMixer : IStemMixer {

public int StemsLoaded { get; protected set; }

public bool IsPlaying { get; protected set; }

public IReadOnlyDictionary<SongStem, IStemChannel> Channels => _channels;

public IStemChannel LeadChannel { get; protected set; }
@@ -175,6 +175,12 @@ public IStemChannel GetChannel(SongStem stem) {
return !_channels.ContainsKey(stem) ? null : _channels[stem];
}

public void SetSync(SyncFlags sync, Action callback) {
BassMix.ChannelSetSync(((BassStemChannel) LeadChannel).StreamHandle, sync, 0, (_, _, _, _) => {
UnityMainThreadCallback.QueueEvent(callback);
}, IntPtr.Zero);
}

public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
@@ -206,7 +212,7 @@ protected virtual void ReleaseUnmanagedResources() {
if (!Bass.StreamFree(_mixerHandle)) {
Debug.LogError("Failed to free mixer stream. THIS WILL LEAK MEMORY!");
}

_mixerHandle = 0;
}
}
6 changes: 6 additions & 0 deletions Assets/Script/Audio/Interfaces/IAudioManager.cs
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@

namespace YARG.Audio {
public interface IAudioManager {

public delegate void SongEndCallback();

public bool UseStarpowerFx { get; set; }
public bool IsChipmunkSpeedup { get; set; }

@@ -38,6 +41,9 @@ public interface IAudioManager {
public void Play();
public void Pause();

public void AddSongEndCallback(SongEndCallback callback);
public void RemoveSongEndCallback(SongEndCallback callback);

public void FadeIn(float maxVolume);
public UniTask FadeOut(CancellationToken token = default);

2 changes: 1 addition & 1 deletion Assets/Script/Audio/Interfaces/IStemChannel.cs
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ public interface IStemChannel : IDisposable {

public double GetPosition();
public void SetPosition(double position);

public double GetLengthInSeconds();

}
5 changes: 4 additions & 1 deletion Assets/Script/Audio/Interfaces/IStemMixer.cs
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using ManagedBass;

namespace YARG.Audio {
public interface IStemMixer : IDisposable {
@@ -28,10 +29,12 @@ public interface IStemMixer : IDisposable {
public void SetPosition(double position);

public int AddChannel(IStemChannel channel);

public bool RemoveChannel(IStemChannel channel);

public IStemChannel GetChannel(SongStem stem);

public void SetSync(SyncFlags sync, Action callback);

}
}
11 changes: 6 additions & 5 deletions Assets/Script/PlayMode/Play.cs
Original file line number Diff line number Diff line change
@@ -329,6 +329,8 @@ private IEnumerator StartAudio() {
}

GameManager.AudioManager.Play();

GameManager.AudioManager.AddSongEndCallback(OnEndReached);
audioStarted = true;
}

@@ -431,12 +433,11 @@ private void Update() {
if (!playingVocals) {
UpdateGenericLyrics();
}
}

// End song
if (!endReached && realSongTime >= SongLength) {
endReached = true;
StartCoroutine(EndSong(true));
}
private void OnEndReached() {
endReached = true;
StartCoroutine(EndSong(true));
}

private void UpdateGenericLyrics() {