90 lines
2.9 KiB
C#
90 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using FragLabs.Audio.Codecs;
|
|
using FragLabs.Audio.Codecs.Opus;
|
|
using Global.Util;
|
|
using Sandbox.Game.VoiceChat;
|
|
using Torch.API;
|
|
using Torch.Managers;
|
|
using Torch.Utils;
|
|
using VRage.Library.Collections;
|
|
using VRage.Network;
|
|
|
|
namespace Global
|
|
{
|
|
public class AudioSendManager : Manager
|
|
{
|
|
[ReflectedMethodInfo(typeof(MyVoiceChatSessionComponent), "SendVoicePlayer")]
|
|
private static readonly MethodInfo _sendVoiceMethod;
|
|
|
|
private readonly LegacyConfig _configData;
|
|
|
|
private readonly object _lock = new object();
|
|
|
|
private readonly Dictionary<ulong, Stream> _plays = new Dictionary<ulong, Stream>();
|
|
private readonly SendBuffer _sendBuffer = new SendBuffer();
|
|
private readonly Thread _thread;
|
|
|
|
private byte[] _buffer = Array.Empty<byte>();
|
|
|
|
private OpusEncoder _encoder;
|
|
|
|
public AudioSendManager(ITorchBase torchInstance, LegacyConfig configData) : base(torchInstance)
|
|
{
|
|
_configData = configData;
|
|
_thread = new Thread(UpdateProc);
|
|
}
|
|
|
|
public override void Attach()
|
|
{
|
|
base.Attach();
|
|
_encoder = OpusEncoder.Create(24000, 1, Application.Restricted_LowLatency);
|
|
_thread.Start();
|
|
}
|
|
|
|
public override void Detach()
|
|
{
|
|
base.Detach();
|
|
_encoder.Dispose();
|
|
_thread.Join(1);
|
|
}
|
|
|
|
private void UpdateProc()
|
|
{
|
|
while (true)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
foreach (var (player, stream) in _plays)
|
|
{
|
|
// if stream can read and is not at the end
|
|
if (stream.CanRead && stream.Position < stream.Length)
|
|
{
|
|
ArrayExtensions.EnsureCapacity(ref _buffer, _configData.SendDataMs * 48);
|
|
var sampleLength = stream.Read(_buffer, 0, _configData.SendDataMs * 48);
|
|
if (sampleLength == 0) continue;
|
|
_sendBuffer.SenderUserId = (long)player;
|
|
_sendBuffer.VoiceDataBuffer =
|
|
_encoder.Encode(_buffer, sampleLength, out var encodedLength);
|
|
_sendBuffer.NumElements = encodedLength;
|
|
NetworkManager.RaiseStaticEvent<ulong, BitReaderWriter>(_sendVoiceMethod, 0UL,
|
|
_sendBuffer,
|
|
new EndpointId(player));
|
|
}
|
|
else
|
|
{
|
|
stream.Dispose();
|
|
_plays.Remove(player);
|
|
}
|
|
}
|
|
|
|
Thread.Sleep(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |