audio translation from Naudio to Opus codec is accelerated during playback

62 Views Asked by At

When translating audio by url in Naudio and further converting and encoding in Opus with further sending to Discord, the quality of the original audio is severely degraded, the volume is lost and the audio itself is sped up by several times

In general, I want to improve the quality of the transmitted audio, and normalize the audio speed.

sample code operation:https://youtu.be/4zwvP-Ral3g

code:

public async Task StreamAudioAsync(string url, SocketMessage msg)
    {
        try
        {
            // Create audioClient
            var audioClient = await (msg.Author as IGuildUser)?.VoiceChannel.ConnectAsync();
            
            // Create a resampler to convert MP3 to PCM
            using (var mp3Reader = new MediaFoundationReader(url))
            {
                var resampler = new WdlResamplingSampleProvider(mp3Reader.ToSampleProvider(), 48000);
                // Create an instance of the OpusEncoder class with the desired parameters
                var opusEncoder = new OpusEncoder(48000, 2, Concentus.Enums.OpusApplication.OPUS_APPLICATION_AUDIO);
                opusEncoder.Bitrate = 96000; // Set the bitrate to 96 kbps.

                // Create a stream that accepts data encoded in Opus
                using (var opusStream = audioClient.CreateOpusStream())
                {
                    try
                    {
                        // Create a buffer to store audio data
                        float[] buffer = new float[3840];
                        int byteCount;

                        // Read audio data from the resampler
                        while ((byteCount = resampler.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            // Create a byte array that is four times the size of the float array
                            var byteBuffer = new byte[byteCount * 4];

                            // Convert each element of the float array into a byte array and copy it into byteBuffer
                            for (int i = 0; i < byteCount; i++)
                            {
                                byte[] bytes = BitConverter.GetBytes(buffer[i]);
                                Array.Copy(bytes, 0, byteBuffer, i * 4, 4);
                            }

                            // Create an instance of the WaveBuffer class using the byte array
                            var waveBuffer = new WaveBuffer(byteBuffer);

                            // Access the float array, which represents the audio signal
                            var floatBuffer = waveBuffer.FloatBuffer;

                            // Determine the frame size depending on the sampling rate
                            // int frameSize = 960 * resampler.WaveFormat.SampleRate / 48000;
                            int frameSize = 960; // it can't be higher than 960 or lower (I don't know what it is).
                            // Console.WriteLine($"framesize :{frameSize}");

                            // Encode audio data into Opus format
                            var opusPacket = new byte[2000]; // Maximum Opus packet size
                            int len = opusEncoder.Encode(floatBuffer, 0, frameSize, opusPacket, 0, opusPacket.Length);


                            // Send audio data to the Opus stream
                            await opusStream.WriteAsync(opusPacket, 0, len);
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("test exception: "+e);
            Console.WriteLine();
        }
    }

msg - message that came, it is necessary to receive audio channel and connect to it url - link to the page where the audio file is located

0

There are 0 best solutions below