aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-09-18 00:12:47 -0300
committerGitHub <noreply@github.com>2018-09-18 00:12:47 -0300
commitbec95cacc1061f91373a1e3a1411981af7fe2e4e (patch)
tree5c8d57e2aeb1d70e167440b3da4a8fddd9618b39
parentc7387be0d296f54a6ad5678d25e2c0d4910b7da4 (diff)
Ensure that buffers are available after a signal when GetReleasedBuffers is called (#369)
-rw-r--r--Ryujinx.Audio/OpenAL/OpenALAudioOut.cs135
1 files changed, 57 insertions, 78 deletions
diff --git a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs
index 80a070c9..d7a2a777 100644
--- a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs
+++ b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs
@@ -28,16 +28,12 @@ namespace Ryujinx.Audio.OpenAL
public PlaybackState State { get; set; }
- private bool ShouldCallReleaseCallback;
-
private ConcurrentDictionary<long, int> Buffers;
private Queue<long> QueuedTagsQueue;
private Queue<long> ReleasedTagsQueue;
- private int LastReleasedCount;
-
private bool Disposed;
public Track(int SampleRate, ALFormat Format, ReleaseCallback Callback)
@@ -59,8 +55,6 @@ namespace Ryujinx.Audio.OpenAL
public bool ContainsBuffer(long Tag)
{
- SyncQueuedTags();
-
foreach (long QueuedTag in QueuedTagsQueue)
{
if (QueuedTag == Tag)
@@ -72,20 +66,29 @@ namespace Ryujinx.Audio.OpenAL
return false;
}
- public long[] GetReleasedBuffers(int MaxCount)
+ public long[] GetReleasedBuffers(int Count)
{
- ClearReleased();
+ AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount);
+
+ ReleasedCount += ReleasedTagsQueue.Count;
+
+ if (Count > ReleasedCount)
+ {
+ Count = ReleasedCount;
+ }
List<long> Tags = new List<long>();
- HashSet<long> Unique = new HashSet<long>();
+ while (Count-- > 0 && ReleasedTagsQueue.TryDequeue(out long Tag))
+ {
+ Tags.Add(Tag);
+ }
- while (MaxCount-- > 0 && ReleasedTagsQueue.TryDequeue(out long Tag))
+ while (Count-- > 0 && QueuedTagsQueue.TryDequeue(out long Tag))
{
- if (Unique.Add(Tag))
- {
- Tags.Add(Tag);
- }
+ AL.SourceUnqueueBuffers(SourceId, 1);
+
+ Tags.Add(Tag);
}
return Tags.ToArray();
@@ -112,67 +115,27 @@ namespace Ryujinx.Audio.OpenAL
return Id;
}
- public void ClearReleased()
+ public void CallReleaseCallbackIfNeeded()
{
- SyncQueuedTags();
-
AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount);
- CheckReleaseChanges(ReleasedCount);
-
if (ReleasedCount > 0)
{
- AL.SourceUnqueueBuffers(SourceId, ReleasedCount);
- }
- }
-
- public void CallReleaseCallbackIfNeeded()
- {
- CheckReleaseChanges();
+ //If we signal, then we also need to have released buffers available
+ //to return when GetReleasedBuffers is called.
+ //If playback needs to be re-started due to all buffers being processed,
+ //then OpenAL zeros the counts (ReleasedCount), so we keep it on the queue.
+ while (ReleasedCount-- > 0 && QueuedTagsQueue.TryDequeue(out long Tag))
+ {
+ AL.SourceUnqueueBuffers(SourceId, 1);
- if (ShouldCallReleaseCallback)
- {
- ShouldCallReleaseCallback = false;
+ ReleasedTagsQueue.Enqueue(Tag);
+ }
Callback();
}
}
- private void CheckReleaseChanges()
- {
- AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount);
-
- CheckReleaseChanges(ReleasedCount);
- }
-
- private void CheckReleaseChanges(int NewReleasedCount)
- {
- if (LastReleasedCount != NewReleasedCount)
- {
- LastReleasedCount = NewReleasedCount;
-
- ShouldCallReleaseCallback = true;
- }
- }
-
- private void SyncQueuedTags()
- {
- AL.GetSource(SourceId, ALGetSourcei.BuffersQueued, out int QueuedCount);
- AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount);
-
- QueuedCount -= ReleasedCount;
-
- while (QueuedTagsQueue.Count > QueuedCount)
- {
- ReleasedTagsQueue.Enqueue(QueuedTagsQueue.Dequeue());
- }
-
- while (ReleasedTagsQueue.Count > MaxReleased)
- {
- ReleasedTagsQueue.Dequeue();
- }
- }
-
public void Dispose()
{
Dispose(true);
@@ -266,7 +229,10 @@ namespace Ryujinx.Audio.OpenAL
{
if (Tracks.TryRemove(Track, out Track Td))
{
- Td.Dispose();
+ lock (Td)
+ {
+ Td.Dispose();
+ }
}
}
@@ -274,7 +240,10 @@ namespace Ryujinx.Audio.OpenAL
{
if (Tracks.TryGetValue(Track, out Track Td))
{
- return Td.ContainsBuffer(Tag);
+ lock (Td)
+ {
+ return Td.ContainsBuffer(Tag);
+ }
}
return false;
@@ -284,7 +253,10 @@ namespace Ryujinx.Audio.OpenAL
{
if (Tracks.TryGetValue(Track, out Track Td))
{
- return Td.GetReleasedBuffers(MaxCount);
+ lock (Td)
+ {
+ return Td.GetReleasedBuffers(MaxCount);
+ }
}
return null;
@@ -294,15 +266,18 @@ namespace Ryujinx.Audio.OpenAL
{
if (Tracks.TryGetValue(Track, out Track Td))
{
- int BufferId = Td.AppendBuffer(Tag);
+ lock (Td)
+ {
+ int BufferId = Td.AppendBuffer(Tag);
- int Size = Buffer.Length * Marshal.SizeOf<T>();
+ int Size = Buffer.Length * Marshal.SizeOf<T>();
- AL.BufferData<T>(BufferId, Td.Format, Buffer, Size, Td.SampleRate);
+ AL.BufferData<T>(BufferId, Td.Format, Buffer, Size, Td.SampleRate);
- AL.SourceQueueBuffer(Td.SourceId, BufferId);
+ AL.SourceQueueBuffer(Td.SourceId, BufferId);
- StartPlaybackIfNeeded(Td);
+ StartPlaybackIfNeeded(Td);
+ }
}
}
@@ -310,9 +285,12 @@ namespace Ryujinx.Audio.OpenAL
{
if (Tracks.TryGetValue(Track, out Track Td))
{
- Td.State = PlaybackState.Playing;
+ lock (Td)
+ {
+ Td.State = PlaybackState.Playing;
- StartPlaybackIfNeeded(Td);
+ StartPlaybackIfNeeded(Td);
+ }
}
}
@@ -324,8 +302,6 @@ namespace Ryujinx.Audio.OpenAL
if (State != ALSourceState.Playing && Td.State == PlaybackState.Playing)
{
- Td.ClearReleased();
-
AL.SourcePlay(Td.SourceId);
}
}
@@ -334,9 +310,12 @@ namespace Ryujinx.Audio.OpenAL
{
if (Tracks.TryGetValue(Track, out Track Td))
{
- Td.State = PlaybackState.Stopped;
+ lock (Td)
+ {
+ Td.State = PlaybackState.Stopped;
- AL.SourceStop(Td.SourceId);
+ AL.SourceStop(Td.SourceId);
+ }
}
}