gpt4 book ai didi

c# - 如何使用 .NET (Windows/Mac/Linux) 将 PCM S16LE 音频转换为 MU-LAW/8000

转载 作者:行者123 更新时间:2023-12-05 05:49:54 25 4
gpt4 key购买 nike

我正在尝试在 Twilio 语音通话和 Discord 语音 channel 之间接收和传输音频。我正在努力弄清楚如何转换我从 DSharpPlus 接收的音频数据(.NET 的 Discord 库)转换为 Twilio Voice 所需的格式。

如果我正在阅读 DSharpPlus' docs correctly来自 DSharpPlus 的 PCM 数据是 PCM S16LE 格式。Twilio 希望数据采用 MU-LAW/8000 格式(我认为不包括标题)。

我正在尝试使用 NAudio转换数据,但我从电话里听到的只是刺耳的痛苦噪音。我不能使用完整的 NAudio 库,因为这个项目应该在 Windows/Mac/Linux 上工作,并且一些 NAudio API 仅适用于 Windows。
这是我目前拥有的相关代码:

private async Task VoiceReceiveHandler(VoiceNextConnection connection, VoiceReceiveEventArgs args)
{

if (twilioSocketConnectionManager.TryGetSocketById(socketId, out var twilioSocket) && twilioSocket.Socket.State == WebSocketState.Open)
{
var media = ConvertPcmToMulawBase64Encoded(args.AudioFormat, args.PcmData.ToArray());
var json = JsonSerializer.Serialize<MediaMessage>
(
new MediaMessage("media", twilioSocket.StreamSid, new MediaPayload(media)),
jsonSerializerOptions
);
logger.LogInformation(json);
var bytes = Encoding.Default.GetBytes(json);
var arraySegment = new ArraySegment<byte>(bytes, 0, bytes.Length);
await twilioSocket.Socket.SendAsync(arraySegment, WebSocketMessageType.Text, WebSocketMessageFlags.EndOfMessage, CancellationToken.None);
}
}

private static string ConvertPcmToMulawBase64Encoded(AudioFormat audioFormat, byte[] pcmData)
{

var sourceFormat = new WaveFormat(audioFormat.SampleRate, 16, audioFormat.ChannelCount);
return Convert.ToBase64String(EncodeMuLaw(pcmData, 0, pcmData.Length));
}

public static byte[] EncodeMuLaw(byte[] data, int offset, int length)
{
var encoded = new byte[length / 2];
int outIndex = 0;
for(int n = 0; n < length; n+=2)
{
encoded[outIndex++] = MuLawEncoder.LinearToMuLawSample(BitConverter.ToInt16(data, offset + n));
}
return encoded;
}

我还需要再次从 MU-LAW 转换为 PCM S16LE,但首先要做的是。
我对音频处理一窍不通,所以请放轻松。

这是源代码的其余部分:https://github.com/Swimburger/DiscordTwilioVoiceBot

基本上我的问题是,如何在支持 Windows/Linux/Mac 的情况下使用 .NET 将 PCM S16LE 音频转换为 MU-LAW/8000


更新 1:

人们建议使用 ffmpeg 而不是 NAudio,我认为我在这里做的是正确的,但我仍然听到尖锐的噪音而不是实际的音频。

private async Task VoiceReceiveHandler(VoiceNextConnection connection, VoiceReceiveEventArgs args)
{
var ffmpeg = Process.Start(new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $@"-hide_banner -ac 2 -f s16le -ar 48000 -i pipe:0 -c:a pcm_mulaw -f mulaw -ar 8000 -ac 1 pipe:1",
RedirectStandardInput = true,
RedirectStandardOutput = true
});

//byte[] trimmedData = new byte[args.PcmData.Length - 44];
//Buffer.BlockCopy(args.PcmData.ToArray(), 44, trimmedData, 0, trimmedData.Length);

await ffmpeg.StandardInput.BaseStream.WriteAsync(args.PcmData);
ffmpeg.StandardInput.Close();
byte[] data;
using(var memoryStream = new MemoryStream())
{
ffmpeg.StandardOutput.BaseStream.CopyTo(memoryStream);
data = memoryStream.ToArray();
}
ffmpeg.Dispose();

//byte[] trimmedData = new byte[data.Length - 44];
//Buffer.BlockCopy(data, 44, trimmedData, 0, trimmedData.Length);

//return;

if (twilioSocketConnectionManager.TryGetSocketById(socketId, out var twilioSocket) && twilioSocket.Socket.State == WebSocketState.Open)
{
var json = JsonSerializer.Serialize<MediaMessage>
(
new MediaMessage("media", twilioSocket.StreamSid, new MediaPayload(Convert.ToBase64String(data))),
jsonSerializerOptions
);
logger.LogInformation(json);
var bytes = Encoding.Default.GetBytes(json);
var arraySegment = new ArraySegment<byte>(bytes, 0, bytes.Length);
await twilioSocket.Socket.SendAsync(arraySegment, WebSocketMessageType.Text, WebSocketMessageFlags.EndOfMessage, CancellationToken.None);
}
}

这是在 separate branch 上.

最佳答案

我有一个类似的问题,将 Twilio 的 MU-LAW 转换为 PCM 16LE 以流式传输到 Azure 认知服务转录服务。我是用 Java 而不是 dotnet 编写的,我没有找到好的库解决方案。

但是,可以使用查找表一次一个字节地完成转换(请注意,一个字节的 mulaw 由 2 个字节的 pcm 表示)。有一个 rather abstract description of the algorithm on wikipedia ,然后我找到了 this dotnet repo的代码很容易翻译成 Java,并且运行良好。对于您的情况,您需要查看 MulawDecoder.cs。

我为 mulaw->pcm 生成的 Java 代码是 here .

关于c# - 如何使用 .NET (Windows/Mac/Linux) 将 PCM S16LE 音频转换为 MU-LAW/8000,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70599169/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com