Я пытаюсь реализовать голосовой чат в Godot с помощью Steamworks.NET. Я последовал официальному руководству Steam по Godot и адаптировал его к своей собственной многопользовательской настройке. Передача голоса работает, но во время воспроизведения слышится потрескивание. Я пробовал изменять различные случайные значения, чтобы увидеть, изменилось ли что-нибудь, а также добавил множество средств обработки ошибок и проверок, но мне не удалось найти источник потрескивающих звуков.
Чтобы записать голос игрока, я использую голосовую систему Steamworks. А затем, чтобы воспроизвести его, я использую Godot AudioStreamGeneratorPlayback, связанный с AudioStreamPlayer3D. Длина буфера генератора аудиопотока установлена на 0,5f, а скорость микширования установлена на возвращаемое значение SteamUser.GetVoiceOptimalSampleRate().
Вот мой код, который я максимально упростил, но при этом сохранил управление ошибками для устранения возможных ошибок:
public partial class ProximityChat : Node3D
{
uint voiceSampleRate = 0;
private const int MaxCompressedBufferSize = 1024;
private const int MaxUncompressedBufferSize = 88200;
private byte[] reusableCompressedBuffer = new byte[MaxCompressedBufferSize];
private byte[] reusableUncompressedBuffer = new byte[MaxUncompressedBufferSize];
private double voiceProcessTimer = 0.0;
private const double VoiceProcessInterval = 1.0 / 20.0; // 20fps
public override void _Ready()
{
SteamUser.StartVoiceRecording();
ServerAbstract.Instance.OnVoiceDataReceived += HandleVoiceDataReceived;
voiceSampleRate = SteamUser.GetVoiceOptimalSampleRate();
}
public override void _Process(double delta)
{
voiceProcessTimer += delta;
if (voiceProcessTimer >= VoiceProcessInterval)
{
voiceProcessTimer = 0.0;
ProcessVoiceData();
}
}
private void ProcessVoiceData()
{
uint countCompressedData = 0;
EVoiceResult result = SteamUser.GetAvailableVoice(out countCompressedData);
if (countCompressedData >= MaxCompressedBufferSize)
{
GD.PrintErr("Voice data size exceeds buffer size.");
return;
}
if (result == EVoiceResult.k_EVoiceResultOK && countCompressedData > 0)
{
uint nBytesWritten = 0;
SteamUser.GetVoice(true, reusableCompressedBuffer, (uint)MaxCompressedBufferSize, out nBytesWritten);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)ServerAbstract.Instance.UserIndex);
writer.Write(nBytesWritten);
writer.Write(reusableCompressedBuffer, 0, (int)nBytesWritten);
ServerAbstract.Instance.SendToAll(memoryStream.ToArray(), (int)memoryStream.Length, ServerAbstractClass.DeliveryMethod.Unreliable);
}
}
private void HandleVoiceDataReceived(BinaryReader reader, byte[] dataBuffer)
{
byte userIndex = reader.ReadByte();
uint dataSize = reader.ReadUInt32();
byte[] compressedData = reader.ReadBytes((int)dataSize);
uint nBytesWritten = 0;
EVoiceResult result = SteamUser.DecompressVoice(compressedData, dataSize, reusableUncompressedBuffer, (uint)MaxUncompressedBufferSize, out nBytesWritten, voiceSampleRate);
if (result == EVoiceResult.k_EVoiceResultOK)
{
Character character = (Character)ReplicationServer.Instance.GetReplicatedObject(userIndex);
if (character?.voiceStreamPlayback == null)
{
GD.PrintErr("Character or voice stream playback is null.");
return;
}
int requiredFrames = (int)(nBytesWritten / 2);
if (!character.voiceStreamPlayback.CanPushBuffer(requiredFrames))
{
GD.PrintErr("Voice stream buffer full, dropping old data.");
return;
}
Vector2[] stereoData = new Vector2[requiredFrames];
for (int i = 0; i < requiredFrames; i++)
{
short sample = (short)(
reusableUncompressedBuffer[i * 2] |
(reusableUncompressedBuffer[i * 2 + 1]
Подробнее здесь: https://stackoverflow.com/questions/798 ... imity-chat
Я слышу потрескивание в моем бесконтактном чате ⇐ C#
Место общения программистов C#
-
Anonymous
1769114167
Anonymous
Я пытаюсь реализовать голосовой чат в Godot с помощью Steamworks.NET. Я последовал официальному руководству Steam по Godot и адаптировал его к своей собственной многопользовательской настройке. Передача голоса работает, но во время воспроизведения слышится потрескивание. Я пробовал изменять различные случайные значения, чтобы увидеть, изменилось ли что-нибудь, а также добавил множество средств обработки ошибок и проверок, но мне не удалось найти источник потрескивающих звуков.
Чтобы записать голос игрока, я использую голосовую систему Steamworks. А затем, чтобы воспроизвести его, я использую Godot AudioStreamGeneratorPlayback, связанный с AudioStreamPlayer3D. Длина буфера генератора аудиопотока установлена на 0,5f, а скорость микширования установлена на возвращаемое значение SteamUser.GetVoiceOptimalSampleRate().
Вот мой код, который я максимально упростил, но при этом сохранил управление ошибками для устранения возможных ошибок:
public partial class ProximityChat : Node3D
{
uint voiceSampleRate = 0;
private const int MaxCompressedBufferSize = 1024;
private const int MaxUncompressedBufferSize = 88200;
private byte[] reusableCompressedBuffer = new byte[MaxCompressedBufferSize];
private byte[] reusableUncompressedBuffer = new byte[MaxUncompressedBufferSize];
private double voiceProcessTimer = 0.0;
private const double VoiceProcessInterval = 1.0 / 20.0; // 20fps
public override void _Ready()
{
SteamUser.StartVoiceRecording();
ServerAbstract.Instance.OnVoiceDataReceived += HandleVoiceDataReceived;
voiceSampleRate = SteamUser.GetVoiceOptimalSampleRate();
}
public override void _Process(double delta)
{
voiceProcessTimer += delta;
if (voiceProcessTimer >= VoiceProcessInterval)
{
voiceProcessTimer = 0.0;
ProcessVoiceData();
}
}
private void ProcessVoiceData()
{
uint countCompressedData = 0;
EVoiceResult result = SteamUser.GetAvailableVoice(out countCompressedData);
if (countCompressedData >= MaxCompressedBufferSize)
{
GD.PrintErr("Voice data size exceeds buffer size.");
return;
}
if (result == EVoiceResult.k_EVoiceResultOK && countCompressedData > 0)
{
uint nBytesWritten = 0;
SteamUser.GetVoice(true, reusableCompressedBuffer, (uint)MaxCompressedBufferSize, out nBytesWritten);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)ServerAbstract.Instance.UserIndex);
writer.Write(nBytesWritten);
writer.Write(reusableCompressedBuffer, 0, (int)nBytesWritten);
ServerAbstract.Instance.SendToAll(memoryStream.ToArray(), (int)memoryStream.Length, ServerAbstractClass.DeliveryMethod.Unreliable);
}
}
private void HandleVoiceDataReceived(BinaryReader reader, byte[] dataBuffer)
{
byte userIndex = reader.ReadByte();
uint dataSize = reader.ReadUInt32();
byte[] compressedData = reader.ReadBytes((int)dataSize);
uint nBytesWritten = 0;
EVoiceResult result = SteamUser.DecompressVoice(compressedData, dataSize, reusableUncompressedBuffer, (uint)MaxUncompressedBufferSize, out nBytesWritten, voiceSampleRate);
if (result == EVoiceResult.k_EVoiceResultOK)
{
Character character = (Character)ReplicationServer.Instance.GetReplicatedObject(userIndex);
if (character?.voiceStreamPlayback == null)
{
GD.PrintErr("Character or voice stream playback is null.");
return;
}
int requiredFrames = (int)(nBytesWritten / 2);
if (!character.voiceStreamPlayback.CanPushBuffer(requiredFrames))
{
GD.PrintErr("Voice stream buffer full, dropping old data.");
return;
}
Vector2[] stereoData = new Vector2[requiredFrames];
for (int i = 0; i < requiredFrames; i++)
{
short sample = (short)(
reusableUncompressedBuffer[i * 2] |
(reusableUncompressedBuffer[i * 2 + 1]
Подробнее здесь: [url]https://stackoverflow.com/questions/79873849/i-can-hear-some-crackling-noise-in-my-proximity-chat[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия