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
Show file tree
Hide file tree
Changes from all commits
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
13 changes: 13 additions & 0 deletions Assets/Scenes/PersistantScene.unity
Original file line number Diff line number Diff line change
Expand Up @@ -1861,6 +1861,7 @@ GameObject:
m_Component:
- component: {fileID: 788257160}
- component: {fileID: 788257161}
- component: {fileID: 788257162}
m_Layer: 0
m_Name: Game Manager
m_TagString: Untagged
Expand Down Expand Up @@ -1896,6 +1897,18 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
<SettingsMenu>k__BackingField: {fileID: 0}
--- !u!114 &788257162
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 788257159}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 9528aed6905f440386374733309d1614, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &826511794
GameObject:
m_ObjectHideFlags: 0
Expand Down
22 changes: 22 additions & 0 deletions Assets/Script/Audio/Bass/BassAudioManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down
12 changes: 9 additions & 3 deletions Assets/Script/Audio/Bass/BassStemMixer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
}
Expand Down
6 changes: 6 additions & 0 deletions Assets/Script/Audio/Interfaces/IAudioManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

namespace YARG.Audio {
public interface IAudioManager {

public delegate void SongEndCallback();

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

Expand Down Expand Up @@ -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);

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

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

public double GetLengthInSeconds();

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

namespace YARG.Audio {
public interface IStemMixer : IDisposable {
Expand All @@ -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
Expand Up @@ -329,6 +329,8 @@ private IEnumerator StartAudio() {
}

GameManager.AudioManager.Play();

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

Expand Down Expand Up @@ -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() {
Expand Down
24 changes: 24 additions & 0 deletions Assets/Script/UnityMainThreadCallback.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace YARG {
public class UnityMainThreadCallback : MonoBehaviour {

private static readonly Queue<Action> CallbackQueue = new();

private void Update() {
lock (CallbackQueue) {
while (CallbackQueue.Count > 0) {
CallbackQueue.Dequeue().Invoke();
}
}
}

public static void QueueEvent(Action action) {
lock (CallbackQueue) {
CallbackQueue.Enqueue(action);
}
}
}
}
3 changes: 3 additions & 0 deletions Assets/Script/UnityMainThreadCallback.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.