Adding Speech Output to Discord using C# - #2


This is the continuation of my Intial post to this Topic

Using some simple Code to pay some audio from a random WAV-File:

    using (var audio = File.OpenRead("audio.wav")) {
        using (var audioStream = audioClient.CreatePCMStream(AudioApplication.Music, voiceChannel.Bitrate)) 
        {
            _logger.LogInformation("Start Talking");

            await naudio.CopyToAsync(audioStream, 1920);

            await audioStream.FlushAsync();
            _logger.LogInformation("Finished Talking");
        }
    }

If the audio is long enough you hear something - but it sounds like its straigth out of a Chipmunks-Movie. If its too short - you don’t hear anything at all….

What costed hours of googling and many trial and errors was: Sending Audio for Discord using this Method has to be a WAV-File with exactly

Any deviation leads to strange sounds.

so i used NAudio for conversion.

$ dotnet add package NAudio
$ dotnet add package NAudioSampleRate

In my case i used NAudio in Version 1.10.

I also used this for TTS so i got everything as a Stream (Linear 16 from google)

so this is the code that works for me:

        using (IAudioClient audioClient = await voiceChannel.ConnectAsync())
        {
            // thats what i get from the input Audiocontent (24kHz, 16bit, 1channel)
            var content = response.AudioContent.ToByteArray();
            var format = new WaveFormat(24000, 16, 1);

            // need to convert this to a WaveStream so NAudio can work with it
            using (var source = new RawSourceWaveStream(new MemoryStream(content), format))
            {
                int channels = 2;
                int sampleRate = 48000;

                var outFormat = new WaveFormat(sampleRate, 16, channels);   
                var naudio = new WaveFormatConversionStream(outFormat, source);

                // and now we can give this over to discord
                await audioClient.SetSpeakingAsync(true);

                using (var audioStream = audioClient.CreatePCMStream(AudioApplication.Music, voiceChannel.Bitrate)) 
                {
                    _logger.LogInformation("Start Talking");

                    await naudio.CopyToAsync(audioStream, 1920);

                    // if anything goes wrong - Flush tends to hang the process.
                    await audioStream.FlushAsync();
                    _logger.LogInformation("Finished Talking");
                }
                await audioClient.SetSpeakingAsync(false);
            }
        }

IF you want to play some Music, you can use any input file (new WavFileReader(name)). In that case, NAudio also reads the correct Samplingrate and bitness Information from the File.

Hope this helps not to waste as much time as i did.