Пример #1
0
        /* static void Main(string[] args)
         * {
         *   // Display the number of command line arguments.
         *   Console.WriteLine(args.Length);
         * }*/

        static void ToWav()
        {
            var filePath = $@"C:\Users\blabla\foo\bar\";
            var fileOgg  = "testAudio.ogg";
            var fileWav  = "testAudio.wav";

            using (FileStream fileIn = new FileStream($"{filePath}{fileOgg}", FileMode.Open))
                using (MemoryStream pcmStream = new MemoryStream())
                {
                    OpusDecoder       decoder = OpusDecoder.Create(48000, 1);
                    OpusOggReadStream oggIn   = new OpusOggReadStream(decoder, fileIn);
                    while (oggIn.HasNextPacket)
                    {
                        short[] packet = oggIn.DecodeNextPacket();
                        if (packet != null)
                        {
                            for (int i = 0; i < packet.Length; i++)
                            {
                                var bytes = BitConverter.GetBytes(packet[i]);
                                pcmStream.Write(bytes, 0, bytes.Length);
                            }
                        }
                    }
                    pcmStream.Position = 0;
                    var wavStream      = new RawSourceWaveStream(pcmStream, new WaveFormat(48000, 1));
                    var sampleProvider = wavStream.ToSampleProvider();
                    WaveFileWriter.CreateWaveFile16($"{filePath}{fileWav}", sampleProvider);
                }
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OpusSource"/> class.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="sampleRate">The sample rate.</param>
        /// <param name="channels">The channels.</param>
        public OpusSource(Stream stream, int sampleRate, int channels)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("Stream is not readable.", nameof(stream));
            }

            _stream = stream;

            WaveFormat = new WaveFormat(sampleRate, BitsPerSample, channels);

            var decoder = new OpusDecoder(WaveFormat.SampleRate, WaveFormat.Channels);

            _opusReadStream = new OpusOggReadStream(decoder, stream);

            _cts.Token.Register(() =>
            {
                decoder.ResetState();
            });
        }
Пример #3
0
    public void ConvertToWave(string inputFileOgg, string outputFileWav)
    {
        using (FileStream fileIn = new FileStream(inputFileOgg, FileMode.Open))
            using (MemoryStream pcmStream = new MemoryStream())
            {
                OpusDecoder decoder = OpusDecoder.Create(48000, 1);

                OpusOggReadStream oggIn = new OpusOggReadStream(decoder, fileIn);
                while (oggIn.HasNextPacket)
                {
                    short[] packet = oggIn.DecodeNextPacket();
                    if (packet != null)
                    {
                        for (int i = 0; i < packet.Length; i++)
                        {
                            var bytes = BitConverter.GetBytes(packet[i]);
                            pcmStream.Write(bytes, 0, bytes.Length);
                        }
                    }
                }
                pcmStream.Position = 0;
                var wavStream      = new RawSourceWaveStream(pcmStream, new WaveFormat(48000, 1));
                var sampleProvider = wavStream.ToSampleProvider();
                WaveFileWriter.CreateWaveFile16(outputFileWav, sampleProvider);
            }
    }
Пример #4
0
        /// <summary>
        /// Takes an ogg file and splits it down to a list of pcms
        /// </summary>
        /// <param name="fileName">The full file name</param>
        /// <returns>A list of byte arrays (pcms) that represent the full audio file</returns>
        public static List <byte[]> Extract(string fileName)
        {
            const int     CHANNELS = 2;
            List <byte[]> samples  = new List <byte[]>();

            using (FileStream stream = File.Open($"./audio_files/{fileName}", FileMode.Open))
            {
                OpusEncoder       encoder = new OpusEncoder(48000, CHANNELS, Concentus.Enums.OpusApplication.OPUS_APPLICATION_AUDIO);
                OpusDecoder       decoder = new OpusDecoder(48000, CHANNELS);
                OpusOggReadStream oggIn   = new OpusOggReadStream(decoder, stream);
                while (oggIn.HasNextPacket)
                {
                    short[] pcm = oggIn.DecodeNextPacket();
                    if (pcm != null)
                    {
                        byte[] outputBytes       = new byte[1920 * 4];
                        int    outputBytesLength = encoder.Encode(pcm, 0, 1920, outputBytes, 0, outputBytes.Length);
                        outputBytes = outputBytes.Take(outputBytesLength).ToArray();
                        samples.Add(outputBytes);
                    }
                }
            }

            return(samples);
        }
Пример #5
0
        public async Task <Stream> TextToAudioStreamAsync(string text, string language = "fr-FR", SsmlVoiceGender voiceGender = SsmlVoiceGender.Male, CancellationToken token = default)
        {
            var request = new SynthesizeSpeechRequest
            {
                AudioConfig = new AudioConfig
                {
                    AudioEncoding = AudioEncoding.OggOpus,
                },
                Input = new SynthesisInput
                {
                    Text = text
                },
                Voice = new VoiceSelectionParams
                {
                    LanguageCode = language,
                    SsmlGender   = voiceGender,
                },
            };

            var response = await ttsClient.SynthesizeSpeechAsync(request, token);

            using var opusStream = new MemoryStream();
            response.AudioContent.WriteTo(opusStream);
            opusStream.Position = 0;

            var opusDecoder = new OpusDecoder(48000, 2);
            var oggIn       = new OpusOggReadStream(opusDecoder, opusStream);

            var pcmStream = new MemoryStream();

            while (oggIn.HasNextPacket)
            {
                short[] packet = oggIn.DecodeNextPacket();
                if (packet != null)
                {
                    for (int i = 0; i < packet.Length; i++)
                    {
                        byte[] bytes = BitConverter.GetBytes(packet[i]);
                        pcmStream.Write(bytes, 0, bytes.Length);
                    }
                }
            }

            pcmStream.Position = 0;
            return(pcmStream);
        }
        public OpusFileStream(string filename)
        {
            int samplesPerPacket;

            this.FileName          = filename;
            this.OpusFile          = new FileStream(filename, FileMode.Open);
            this.Decoder           = new OpusDecoder(DefaultSampleRate, 1);
            this.OpusOggReadStream = new OpusOggReadStream(this.Decoder, this.OpusFile);

            if (!this.OpusOggReadStream.HasNextPacket)
            {
                throw new Exception("No opus packets found");
            }

            this.SampleRate       = this.OpusOggReadStream.InputSampleRate;
            this.FirstPacket      = this.OpusOggReadStream.RetrieveNextPacket();
            this.FramesPerPacket  = OpusPacketInfo.GetNumFrames(this.FirstPacket, 0, this.FirstPacket.Length);
            samplesPerPacket      = OpusPacketInfo.GetNumSamples(this.FirstPacket, 0, this.FirstPacket.Length, (int)this.SampleRate);
            this.PacketDurationMs = (samplesPerPacket * 1000) / (int)this.SampleRate;
        }
Пример #7
0
        public static void Main(string[] args)
        {
            string opusfile = @"C:\Users\Logan Stromberg\Desktop\Prisencolinensinainciusol.opus";
            string rawFile  = @"C:\Users\Logan Stromberg\Desktop\Prisencolinensinainciusol.raw";
            string rawFile2 = @"C:\Users\Logan Stromberg\Desktop\Prisencolinensinainciusol_out.raw";

            using (FileStream fileOut = new FileStream(opusfile, FileMode.Create))
            {
                OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO);
                encoder.Bitrate = 96000;

                OpusTags tags = new OpusTags();
                tags.Fields[OpusTagName.Title]  = "Prisencolinensinainciusol";
                tags.Fields[OpusTagName.Artist] = "Adriano Celetano";
                OpusOggWriteStream oggOut = new OpusOggWriteStream(encoder, fileOut, tags);

                byte[]  allInput = File.ReadAllBytes(rawFile);
                short[] samples  = BytesToShorts(allInput);

                oggOut.WriteSamples(samples, 0, samples.Length);
                oggOut.Finish();
            }

            using (FileStream fileIn = new FileStream(opusfile, FileMode.Open))
            {
                using (FileStream fileOut = new FileStream(rawFile2, FileMode.Create))
                {
                    OpusDecoder       decoder = OpusDecoder.Create(48000, 2);
                    OpusOggReadStream oggIn   = new OpusOggReadStream(decoder, fileIn);
                    while (oggIn.HasNextPacket)
                    {
                        short[] packet = oggIn.DecodeNextPacket();
                        if (packet != null)
                        {
                            byte[] binary = ShortsToBytes(packet);
                            fileOut.Write(binary, 0, binary.Length);
                        }
                    }
                }
            }
        }
Пример #8
0
        private async Task InjectStreamIntoRecognizerAsync(PushAudioInputStream audioInputStream, BlobClient blobStream)
        {
            using (var stream = await blobStream.OpenReadAsync())
            {
                var decoder = new OpusDecoder(16000, 1);
                var opus    = new OpusOggReadStream(decoder, stream);

                while (opus.HasNextPacket)
                {
                    short[] packet = opus.DecodeNextPacket();
                    if (packet != null)
                    {
                        for (int i = 0; i < packet.Length; i++)
                        {
                            var bytes = BitConverter.GetBytes(packet[i]);
                            audioInputStream.Write(bytes, bytes.Length);
                        }
                    }
                }
            }

            audioInputStream.Close();
        }
Пример #9
0
        public void Convert(Stream inputOgg, Stream outputWav)
        {
            using MemoryStream pcmStream = new();
            OpusDecoder       decoder   = OpusDecoder.Create(INPUT_FREQUENCY, CHANNELS);
            OpusOggReadStream oggReader = new OpusOggReadStream(decoder, inputOgg);

            while (oggReader.HasNextPacket)
            {
                short[] packet = oggReader.DecodeNextPacket();
                if (packet != null)
                {
                    for (int i = 0; i < packet.Length; i++)
                    {
                        var bytes = BitConverter.GetBytes(packet[i]);
                        pcmStream.Write(bytes, 0, bytes.Length);
                    }
                }
            }
            pcmStream.Position  = 0;
            using var wavStream = new RawSourceWaveStream(pcmStream, new WaveFormat(INPUT_FREQUENCY, CHANNELS));
            using var resampler = new MediaFoundationResampler(wavStream, new WaveFormat(OUTPUT_FREQUENCY, CHANNELS));
            WaveFileWriter.WriteWavFileToStream(outputWav, resampler);
        }
Пример #10
0
 private void button1_Click(object sender, EventArgs e)
 {
     //string localFileName = "a.ogg";
     //string localFileName2 = localFileName.Replace(".ogg", ".wav");
     //var vorbisStream = new NAudio.Vorbis.VorbisWaveReader(localFileName);
     //NAudio.Wave.WaveFileWriter.CreateWaveFile(localFileName2, vorbisStream);
     try
     {
         using (FileStream fileIn = new FileStream($"{this.fileOgg}", FileMode.Open))
             using (MemoryStream pcmStream = new MemoryStream())
             {
                 OpusDecoder       decoder = OpusDecoder.Create(48000, 1);
                 OpusOggReadStream oggIn   = new OpusOggReadStream(decoder, fileIn);
                 while (oggIn.HasNextPacket)
                 {
                     short[] packet = oggIn.DecodeNextPacket();
                     if (packet != null)
                     {
                         for (int i = 0; i < packet.Length; i++)
                         {
                             var bytes = BitConverter.GetBytes(packet[i]);
                             pcmStream.Write(bytes, 0, bytes.Length);
                         }
                     }
                 }
                 pcmStream.Position = 0;
                 var wavStream      = new RawSourceWaveStream(pcmStream, new WaveFormat(48000, 1));
                 var sampleProvider = wavStream.ToSampleProvider();
                 WaveFileWriter.CreateWaveFile16($"{this.fileWav}", sampleProvider);
             }
         MessageBox.Show("success!");
         this.wavlab.Text = this.fileWav;
     }
     catch (Exception ee) {
         MessageBox.Show(ee.ToString());
     }
 }
Пример #11
0
        public async Task StartAsync()
        {
            ulong guildId   = 463430274823356417;
            ulong channelId = 463471372589465622;

            var guild        = _client.GetGuild(guildId);
            var voiceChannel = (IVoiceChannel)guild.GetChannel(channelId);

            // var sessionIdTsc = new TaskCompletionSource<string>();
            // var socketVoiceServerTsc = new TaskCompletionSource<SocketVoiceServer>();

            // _client.UserVoiceStateUpdated += VoiceStateUpdatedAsync;
            // _client.VoiceServerUpdated += VoiceServerUpdatedAsync;

            // Task VoiceStateUpdatedAsync(SocketUser user, SocketVoiceState oldState, SocketVoiceState newState)
            // {
            //     if (user.Id != _client.CurrentUser.Id || string.IsNullOrWhiteSpace(newState.VoiceSessionId))
            //         return Task.CompletedTask;

            //     sessionIdTsc.TrySetResult(newState.VoiceSessionId);

            //     return Task.CompletedTask;
            // }

            // Task VoiceServerUpdatedAsync(SocketVoiceServer arg)
            // {
            //     if (arg.Guild.Id == guildId)
            //     {
            //         socketVoiceServerTsc.TrySetResult(arg);
            //     }

            //     return Task.CompletedTask;
            // }\
            var youtubeClient = new YoutubeClient();
            var manifest      = await youtubeClient.Videos.Streams.GetManifestAsync("https://www.youtube.com/watch?v=CY8E6N5Nzec");

            var streamInfos = manifest.GetAudioOnly();
            var streamInfo  = streamInfos
                              .Where(a => a.AudioCodec.Equals("opus"))
                              .FirstOrDefault();

            var sourceStream = await youtubeClient.Videos.Streams.GetAsync(streamInfo);

            var info = await FFProbe.AnalyseAsync(sourceStream);

            var streamReader = new OggStreamReader(sourceStream);
            var reader       = new OpusOggReadStream(new OpusDecoder(48000, 2), sourceStream);

            using var audioClient = await voiceChannel.ConnectAsync();

            using var outStream = audioClient.CreateOpusStream();

            sourceStream.Position = 0;

            byte[] buffer = null;

            // _ = Task.Delay(TimeSpan.FromSeconds(30))
            // .ContinueWith((_) =>
            // {
            //     streamReader.SeekTo(TimeSpan.FromSeconds(0));
            // });

            while ((buffer = streamReader.GetNextPacket()) != null)
            {
                await outStream.WriteAsync(buffer.AsMemory());
            }

            await outStream.FlushAsync();

            await voiceChannel.DisconnectAsync();

            // var sessionId = await sessionIdTsc.Task;
            // var voiceServer = await socketVoiceServerTsc.Task;

            // var voiceClient = _voiceFactory.Create(voiceServer, sessionId);

            // await voiceClient.StartAsync();

            // await Task.Delay(TimeSpan.FromMinutes(10));

            // _client.UserVoiceStateUpdated -= VoiceStateUpdatedAsync;
            // _client.VoiceServerUpdated -= VoiceServerUpdatedAsync;
        }
Пример #12
0
        public void Setup()
        {
            // --- opus encoded data from resource ---

            opusData    = new Int16[1000000];
            opusData48k = new Int16[5000000];
            var assembly     = Assembly.GetExecutingAssembly();
            var resourceName = "TestEchoPrintSharp.Resources.NIN-999999-11025.opus";

            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
            {
                // setup decoder
                OpusDecoder       decoder = OpusDecoder.Create(48000, 1);
                OpusOggReadStream oggIn   = new OpusOggReadStream(decoder, stream);

                // store decoded PCM data in opusData
                opusLength48k = 0;
                while (oggIn.HasNextPacket)
                {
                    short[] packet = oggIn.DecodeNextPacket();
                    if (packet != null)
                    {
                        for (int i = 0; i < packet.Length && opusLength48k < opusData48k.Length; i++)
                        {
                            opusData48k[opusLength48k++] = packet[i];
                        }
                    }
                }

                // downsampling got 11025 samples per second
                for (opusLength = 0; opusLength < opusData.Length; opusLength++)
                {
                    opusData[opusLength] = opusData48k[opusLength * 1920 / 441];
                }
            }

            // --- PCM data from resource ---


            resourceName = "TestEchoPrintSharp.Resources.NIN-999999-11025.wav";

            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                using (BinaryReader reader = new BinaryReader(stream, System.Text.Encoding.ASCII))
                {
                    string chunkId        = new string(reader.ReadChars(4));
                    UInt32 chunkSize      = reader.ReadUInt32();
                    string riffType       = new string(reader.ReadChars(4));
                    string fmtId          = new string(reader.ReadChars(4));
                    UInt32 fmtSize        = reader.ReadUInt32();
                    UInt16 formatTag      = reader.ReadUInt16();
                    UInt16 channels       = reader.ReadUInt16();
                    UInt32 samplesPerSec  = reader.ReadUInt32();
                    UInt32 avgBytesPerSec = reader.ReadUInt32();
                    UInt16 blockAlign     = reader.ReadUInt16();
                    UInt16 bitsPerSample  = reader.ReadUInt16();
                    string dataID         = new string(reader.ReadChars(4));
                    UInt32 dataSize       = reader.ReadUInt32();

                    if (chunkId != "RIFF" || riffType != "WAVE" || fmtId != "fmt " || dataID != "data" || fmtSize != 16)
                    {
                        Console.WriteLine("Malformed WAV header");
                        return;
                    }

                    if (channels != 1 || samplesPerSec != 11025 || avgBytesPerSec != 22050 || blockAlign != 2 || bitsPerSample != 16 || formatTag != 1 || chunkSize < 48)
                    {
                        Console.WriteLine("Unexpected WAV format, need 11025 Hz mono 16 bit (little endian integers)");
                        return;
                    }

                    pcmLength = (int)Math.Min(dataSize / 2, 1000000); // max 30 seconds
                    pcmData   = new Int16[pcmLength];
                    for (int i = 0; i < pcmLength; i++)
                    {
                        pcmData[i] = reader.ReadInt16();
                    }
                }
        }
Пример #13
0
        async Task Run()
        {
            using (var cts = new CancellationTokenSource())
            {
                Console.InputEncoding   = Encoding.Unicode;
                Console.OutputEncoding  = Encoding.Unicode;
                Console.CancelKeyPress += (s, e) =>
                {
                    e.Cancel = true;
                    cts.Cancel();
                };

                try
                {
                    using var input  = new StreamReader(Console.OpenStandardInput(), Encoding.Unicode);
                    using var api    = PickBestApi(input, PortAudioHostApi.SupportedHostApis, cts.Token);
                    using var device = GetOutputDevice(input, api.Devices, cts.Token);

                    Console.Write("Saisir le code de langue voulu (défaut : fr-FR): ");
                    if (!ReadLine(input, cts.Token, out string language))
                    {
                        return;
                    }
                    if (string.IsNullOrWhiteSpace(language))
                    {
                        language = "fr-FR";
                    }

                    Console.WriteLine("Choisir le type de voix (femme/homme):");
                    Console.WriteLine("[0] - Non spécifié");
                    Console.WriteLine("[1] - Homme");
                    Console.WriteLine("[2] - Femme");
                    Console.WriteLine("[2] - Neutre");

                    if (!ReadLine(input, cts.Token, out string voiceGenderStr) || !int.TryParse(voiceGenderStr, out int voiceGenderInt))
                    {
                        return;
                    }

                    var voiceGender = (SsmlVoiceGender)voiceGenderInt;

                    Console.WriteLine($"Prêt à parler sur {device.Name}");

                    while (!cts.IsCancellationRequested)
                    {
                        Console.Write("->");

                        // Handle user input
                        if (!ReadLine(input, cts.Token, out string line) || line is null)
                        {
                            return;
                        }

                        Console.WriteLine("Récupération du son pour le texte : " + line);
                        Console.WriteLine("Son récupéré, lecture...");

                        using var audioStream = await TextToAudioStreamAsync(line, language, voiceGender, cts.Token);

                        using var pump = new PortAudioDevicePump(
                                  device,
                                  2,
                                  new PortAudioSampleFormat(PortAudioSampleFormat.PortAudioNumberFormat.Signed, 2),
                                  device.DefaultLowOutputLatency,
                                  48000,
                                  (buffer, offset, count) => audioStream.Read(buffer, offset, count));

                        using var handle     = new ManualResetEventSlim(false);
                        pump.StreamFinished += FinishedHandler;
                        pump.Start();
                        handle.Wait();
                        pump.StreamFinished -= FinishedHandler;

                        void FinishedHandler(object sender, EventArgs eventArgs) => handle.Set();

                        Console.WriteLine("Lecture terminée");
                    }
                }
                catch (OperationCanceledException)
                {
                }
            }

            async Task <Stream> TextToAudioStreamAsync(string text, string language, SsmlVoiceGender voiceGender, CancellationToken token)
            {
                var request = new SynthesizeSpeechRequest
                {
                    AudioConfig = new AudioConfig
                    {
                        AudioEncoding = AudioEncoding.OggOpus,
                    },
                    Input = new SynthesisInput
                    {
                        Text = text
                    },
                    Voice = new VoiceSelectionParams
                    {
                        LanguageCode = language,
                        SsmlGender   = voiceGender,
                    },
                };

                var response = await ttsClient.SynthesizeSpeechAsync(request, token);

                using (var opusStream = new MemoryStream())
                {
                    response.AudioContent.WriteTo(opusStream);
                    opusStream.Position = 0;

                    var opusDecoder = new OpusDecoder(48000, 2);
                    var oggIn       = new OpusOggReadStream(opusDecoder, opusStream);

                    var pcmStream = new MemoryStream();
                    while (oggIn.HasNextPacket)
                    {
                        short[] packet = oggIn.DecodeNextPacket();
                        if (packet != null)
                        {
                            for (int i = 0; i < packet.Length; i++)
                            {
                                var bytes = BitConverter.GetBytes(packet[i]);
                                pcmStream.Write(bytes, 0, bytes.Length);
                            }
                        }
                    }

                    pcmStream.Position = 0;
                    return(pcmStream);
                }
            }
        }
Пример #14
0
        private async Task PlayMusic(IVoiceChannel channel, Playlist playlist)
        {
            var token = tokenSource.Token;

            PlayerState  = PlayerState.Idle;
            VoiceChannel = channel;
            Playlist     = playlist;
            playedSongs.Clear();
            var logTag = $"[Music {VoiceChannel.GuildId}] ";

            logger.LogInformation($"{logTag}Starting music player in guild {Guild.Name}, channel {VoiceChannel.Name}");
            ConnectionState = ConnectionState.Connecting;

            IAudioClient   audioClient   = null;
            AudioOutStream discordStream = null;

            try
            {
                audioClient = await VoiceChannel.ConnectAsync();

                discordStream = audioClient.CreateOpusStream();
                logger.LogDebug($"{logTag}Connected");
                ConnectionState = ConnectionState.Connected;

                while (!token.IsCancellationRequested)
                {
                    var songId = playlist.GetNextSong();
                    if (songId == null)
                    {
                        break;
                    }
                    logger.LogDebug($"{logTag}Playing next song (Id: {songId})");
                    var song = await musicService.GetSong(songId);

                    if (song == null)
                    {
                        logger.LogWarning($"{logTag}Failed to get data for song id {songId}");
                        continue;
                    }
                    var playHistoryEntry = new PlayHistoryEntry {
                        song = song, state = SongState.Playing
                    };
                    var oggStream = await song.GetOggStream();

                    if (oggStream == null)
                    {
                        logger.LogWarning($"{logTag}Failed to get ogg stream for current song (Id: {songId})");
                        playHistoryEntry.state = SongState.Error;
                        playedSongs.Add(playHistoryEntry);
                        continue;
                    }
                    playedSongs.Add(playHistoryEntry);
                    try
                    {
                        var opusStream = new OpusOggReadStream(null, oggStream);
                        PlayerState = PlayerState.Playing;
                        while (opusStream.HasNextPacket && !token.IsCancellationRequested)
                        {
                            var packet = opusStream.RetrieveNextPacket();
                            if (packet == null)
                            {
                                break;
                            }
                            await discordStream.WriteAsync(packet, 0, packet.Length);
                        }
                        playHistoryEntry.state             = SongState.Finished;
                        playedSongs[playedSongs.Count - 1] = playHistoryEntry;
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, $"{logTag}Exception while playing, skipping to next track");
                        playHistoryEntry.state             = SongState.Error;
                        playedSongs[playedSongs.Count - 1] = playHistoryEntry;
                    }
                    finally
                    {
                        oggStream.Dispose();
                        await discordStream.FlushAsync();
                    }
                    PlayerState = PlayerState.Idle;
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"{logTag}Exception in music player");
            }
            finally
            {
                logger.LogInformation($"{logTag}Stopping music player");
                VoiceChannel    = null;
                Playlist        = null;
                ConnectionState = ConnectionState.Disconnecting;
                discordStream?.Dispose();
                if (audioClient != null)
                {
                    audioClient.Disconnected -= ClientDisconnected;
                    audioClient.Dispose();
                }
                ConnectionState = ConnectionState.Disconnected;
                PlayerState     = PlayerState.Disconnected;
                logger.LogDebug($"{logTag}Stopped music player");
            }


            Task ClientDisconnected(Exception ex)
            {
                return(Task.Run(() => {
                    if (ex != null)
                    {
                        logger.LogError(ex, "Audio client disconnected with exception");
                    }
                    tokenSource.Cancel();
                }));
            }
        }
Пример #15
0
        public override SoundInput TryOpen(IBinaryStream file)
        {
            if (file.Signature != 0x5367674F) // 'OggS'
            {
                return(null);
            }
            var header     = file.ReadHeader(0x1C);
            int table_size = header[0x1A];

            if (table_size < 1)
            {
                return(null);
            }
            int header_size = header[0x1B];

            if (header_size < 0x10)
            {
                return(null);
            }
            int header_pos = 0x1B + table_size;

            header = file.ReadHeader(header_pos + header_size);
            if (!header.AsciiEqual(header_pos, "OpusHead"))
            {
                return(null);
            }
            int channels = header[header_pos + 9];
//            int rate = header.ToInt32 (header_pos+0xC);
            int rate = 48000;

            file.Position = 0;
            var decoder = OpusDecoder.Create(rate, channels);
            var ogg_in  = new OpusOggReadStream(decoder, file.AsStream);
            var pcm     = new MemoryStream();

            try
            {
                using (var output = new BinaryWriter(pcm, System.Text.Encoding.UTF8, true))
                {
                    while (ogg_in.HasNextPacket)
                    {
                        var packet = ogg_in.DecodeNextPacket();
                        if (packet != null)
                        {
                            for (int i = 0; i < packet.Length; ++i)
                            {
                                output.Write(packet[i]);
                            }
                        }
                    }
                }
                var format = new WaveFormat
                {
                    FormatTag        = 1,
                    Channels         = (ushort)channels,
                    SamplesPerSecond = (uint)rate,
                    BitsPerSample    = 16,
                };
                format.BlockAlign            = (ushort)(format.Channels * format.BitsPerSample / 8);
                format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlign;
                pcm.Position = 0;
                var sound = new RawPcmInput(pcm, format);
                file.Dispose();
                return(sound);
            }
            catch
            {
                pcm.Dispose();
                throw;
            }
        }