mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 18:46:43 +00:00
Audio prototype lib
This commit is contained in:
parent
a298f1630f
commit
e0f3dc578b
2 changed files with 102 additions and 3 deletions
|
@ -1,5 +1,6 @@
|
||||||
using Microsoft.Xna.Framework.Audio;
|
using Microsoft.Xna.Framework.Audio;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -10,11 +11,11 @@ namespace Capy64.Core;
|
||||||
public class Audio
|
public class Audio
|
||||||
{
|
{
|
||||||
public const int SampleRate = 48000;
|
public const int SampleRate = 48000;
|
||||||
public static TimeSpan Play(byte[] buffer)
|
public static TimeSpan Play(byte[] buffer, out SoundEffect soundEffect)
|
||||||
{
|
{
|
||||||
var soundEffect = new SoundEffect(buffer, SampleRate, AudioChannels.Mono);
|
soundEffect = new SoundEffect(buffer, SampleRate, AudioChannels.Stereo);
|
||||||
|
|
||||||
soundEffect.Play();
|
soundEffect.Play(1, 0, 0);
|
||||||
|
|
||||||
return soundEffect.Duration;
|
return soundEffect.Duration;
|
||||||
}
|
}
|
||||||
|
|
98
Capy64/Runtime/Libraries/Audio.cs
Normal file
98
Capy64/Runtime/Libraries/Audio.cs
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
using Capy64.API;
|
||||||
|
using KeraLua;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace Capy64.Runtime.Libraries;
|
||||||
|
|
||||||
|
public class Audio : IPlugin
|
||||||
|
{
|
||||||
|
private const int queueLimit = 8;
|
||||||
|
|
||||||
|
private static ConcurrentQueue<byte[]> queue = new();
|
||||||
|
private static bool isProcessing = false;
|
||||||
|
private static IGame _game;
|
||||||
|
public Audio(IGame game)
|
||||||
|
{
|
||||||
|
_game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LuaRegister[] AudioLib = new LuaRegister[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "play",
|
||||||
|
function = L_Play,
|
||||||
|
},
|
||||||
|
new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
public void LuaInit(Lua L)
|
||||||
|
{
|
||||||
|
L.RequireF("audio", OpenLib, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int OpenLib(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
L.NewLib(AudioLib);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task PlayAudio(byte[] buffer)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var time = Core.Audio.Play(buffer, out var soundEffect);
|
||||||
|
await Task.Delay(time - TimeSpan.FromMilliseconds(1000 / 60));
|
||||||
|
_game.LuaRuntime.QueueEvent("audio_end", LK =>
|
||||||
|
{
|
||||||
|
soundEffect.Dispose();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int L_Play(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
var buffer = L.CheckBuffer(1);
|
||||||
|
|
||||||
|
if (queue.Count > queueLimit)
|
||||||
|
{
|
||||||
|
L.PushBoolean(false);
|
||||||
|
L.PushString("queue is full");
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.Enqueue(buffer);
|
||||||
|
|
||||||
|
if (!isProcessing)
|
||||||
|
{
|
||||||
|
isProcessing = true;
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
while (queue.TryDequeue(out var buffer))
|
||||||
|
{
|
||||||
|
await PlayAudio(buffer);
|
||||||
|
}
|
||||||
|
isProcessing = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue