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
- 48000 Hz SamplingRate
- 2 Channels
- 16 bits
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.