Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

496
Views
Cómo convertir audio PCM S16LE a MU-LAW/8000 usando .NET (Windows/Mac/Linux)

Estoy tratando de recibir y transmitir audio entre una llamada de voz de Twilio y un canal de voz de Discord. Estoy luchando por descubrir cómo convertir los datos de audio que recibo de DSharpPlus (biblioteca Discord para .NET) al formato requerido por Twilio Voice.

Si estoy leyendo los documentos de DSharpPlus correctamente , los datos PCM que provienen de DSharpPlus están en formato PCM S16LE . Twilio espera que los datos estén en formato MU-LAW/8000 (excluyendo los encabezados, creo).

Estoy tratando de usar NAudio para convertir los datos, pero todo lo que escucho a través del teléfono son ruidos agudos y dolorosos. No puedo usar la biblioteca completa de NAudio ya que este proyecto debería funcionar en Windows/Mac/Linux y algunas API de NAudio son solo para Windows.
Aquí está el código relevante que tengo actualmente:

 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; }

También necesitaré convertir de MU-LAW a PCM S16LE nuevamente, pero lo primero es lo primero.
Soy completamente ajeno a lo que se refiere al procesamiento de audio, así que ten cuidado conmigo.

Aquí está el resto del código fuente: https://github.com/Swimburger/DiscordTwilioVoiceBot

Esencialmente, mi pregunta es, ¿cómo convierto audio PCM S16LE a MU-LAW/8000 usando .NET mientras admito Windows/Linux/Mac ?


Actualización 1:

La gente ha sugerido usar ffmpeg en lugar de NAudio, lo que creo que estoy haciendo correctamente aquí, pero sigo escuchando un ruido agudo en lugar del audio real.

 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); } }

Esto está en unarama separada .

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Tuve una pregunta similar al convertir MU-LAW de Twilio a PCM 16LE para transmitir al servicio de transcripción de Azure Cognitive Services. Estaba escribiendo en Java en lugar de dotnet, y no encontré una buena solución de biblioteca.

Sin embargo, la conversión se puede realizar byte a byte con una tabla de búsqueda (tenga en cuenta que un byte de mulaw está representado por 2 bytes de pcm). Hay una descripción bastante abstracta del algoritmo en wikipedia , y encontré que el código de este dotnet repo se puede traducir fácilmente a Java y funcionó bien. Para tu caso querrás buscar en MulawDecoder.cs.

Mi código Java resultante para mulaw->pcm está aquí .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!