Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

498
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda