aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-03-19 15:58:46 -0300
committerGitHub <noreply@github.com>2018-03-19 15:58:46 -0300
commit4314a8f3e5b76bbf2143f701c06e9354de712027 (patch)
treeacded3e24125e54bc791f322f0be869f1d379c19 /Ryujinx.Audio/OpenAL/OpenALAudioOut.cs
parent4940cf0ea58c77c8666d76abdfc35c6380efed4c (diff)
[WIP] Add support for events (#60)
* Add support for events, move concept of domains to IpcService * Support waiting for KThread, remove some test code, other tweaks * Use move handle on NIFM since I can't test that now, it's better to leave it how it was
Diffstat (limited to 'Ryujinx.Audio/OpenAL/OpenALAudioOut.cs')
-rw-r--r--Ryujinx.Audio/OpenAL/OpenALAudioOut.cs75
1 files changed, 72 insertions, 3 deletions
diff --git a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs
index 48dcd199..f574b46f 100644
--- a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs
+++ b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs
@@ -3,6 +3,7 @@ using OpenTK.Audio.OpenAL;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Threading;
namespace Ryujinx.Audio.OpenAL
{
@@ -22,20 +23,27 @@ namespace Ryujinx.Audio.OpenAL
public ALFormat Format { get; private set; }
+ private ReleaseCallback Callback;
+
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)
+ public Track(int SampleRate, ALFormat Format, ReleaseCallback Callback)
{
this.SampleRate = SampleRate;
this.Format = Format;
+ this.Callback = Callback;
State = PlaybackState.Stopped;
@@ -109,11 +117,42 @@ namespace Ryujinx.Audio.OpenAL
AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount);
+ CheckReleaseChanges(ReleasedCount);
+
if (ReleasedCount > 0)
{
AL.SourceUnqueueBuffers(SourceId, ReleasedCount);
}
}
+
+ public void CallReleaseCallbackIfNeeded()
+ {
+ CheckReleaseChanges();
+
+ if (ShouldCallReleaseCallback)
+ {
+ ShouldCallReleaseCallback = false;
+
+ 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()
{
@@ -156,18 +195,46 @@ namespace Ryujinx.Audio.OpenAL
private ConcurrentDictionary<int, Track> Tracks;
+ private Thread AudioPollerThread;
+
+ private bool KeepPolling;
+
public OpenALAudioOut()
{
Context = new AudioContext();
Tracks = new ConcurrentDictionary<int, Track>();
+
+ KeepPolling = true;
+
+ AudioPollerThread = new Thread(AudioPollerWork);
+
+ AudioPollerThread.Start();
+ }
+
+ private void AudioPollerWork()
+ {
+ do
+ {
+ foreach (Track Td in Tracks.Values)
+ {
+ Td.CallReleaseCallbackIfNeeded();
+ }
+
+ Thread.Yield();
+ }
+ while (KeepPolling);
}
- public int OpenTrack(int SampleRate, int Channels, out AudioFormat Format)
+ public int OpenTrack(
+ int SampleRate,
+ int Channels,
+ ReleaseCallback Callback,
+ out AudioFormat Format)
{
Format = AudioFormat.PcmInt16;
- Track Td = new Track(SampleRate, GetALFormat(Channels, Format));
+ Track Td = new Track(SampleRate, GetALFormat(Channels, Format), Callback);
for (int Id = 0; Id < MaxTracks; Id++)
{
@@ -292,5 +359,7 @@ namespace Ryujinx.Audio.OpenAL
return PlaybackState.Stopped;
}
+
+
}
} \ No newline at end of file