예제 #1
0
        protected override void WriteStream(Stream stream)
        {
            var oggStream = new OpusOggWriteStream(stream, Format.SampleRate, Format.ChannelCount, Format.PreSkipCount, Format.SampleCount);

            foreach (OpusFrame frame in Format.Frames)
            {
                oggStream.WriteSamples(frame);
            }

            oggStream.Finish();
        }
예제 #2
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);
                        }
                    }
                }
            }
        }
예제 #3
0
        private void ConvertToOgg(string uri, string fileLocation, string FileName)
        {
            MediaFoundationReader      reader    = new MediaFoundationReader(uri);
            WaveFormat                 newFormat = new WaveFormat(48000, reader.WaveFormat.Channels);
            WaveFormatConversionStream newStream = new WaveFormatConversionStream(newFormat, reader);
            WaveStream                 conv      = WaveFormatConversionStream.CreatePcmStream(newStream);

            byte[] bytes = new byte[conv.Length];
            conv.Position = 0;
            conv.Read(bytes, 0, (int)conv.Length);
            OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO);
            var         memo    = new MemoryStream();
            var         oggOut  = new OpusOggWriteStream(encoder, memo);
            var         shorts  = ByteToShort(bytes);

            oggOut.WriteSamples(shorts, 0, shorts.Count());
            oggOut.Finish();
            var result = memo.ToArray();

            using (var stream = new FileStream(fileLocation + FileName, FileMode.Create))
            {
                stream.Write(result, 0, result.Length);
            }
        }
예제 #4
0
        public MusicVersion ConvertTrack(MusicTrack musicTrack)
        {
            var path    = Path.Combine(folderPath, musicTrack.Id + ".ogg");
            var wavPath = musicTrack.MusicVersions.SingleOrDefault(p => p.Extension == "wav");

            byte[] bytes = ReadAllBytes(wavPath.TrackPath);

            using (var fileOut = new FileStream(path, FileMode.Create))
            {
                var encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO);
                var oggOut  = new OpusOggWriteStream(encoder, fileOut);

                //byte[] allInput = File.ReadAllBytes(wavPath.TrackPath);
                short[] samples = BytesToShorts(bytes);

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

            return(new MusicVersion()
            {
                MusicTrack = musicTrack, TrackPath = path, Extension = "ogg"
            });
        }
예제 #5
0
        private void GenerateAudio(List <string> sourceFiles, uint audioId, int bitRate, bool useVbr, string prefixLocation = null)
        {
            int         channels     = 2;
            int         samplingRate = 48000;
            List <uint> chapters     = new List <uint>();

            var outFormat = new WaveFormat(samplingRate, 2);

            OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO);

            encoder.Bitrate = bitRate;
            encoder.UseVBR  = useVbr;

            if (audioId == 0)
            {
                audioId = (uint)((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds();
            }

            using (MemoryStream outputData = new MemoryStream())
            {
                byte[]   buffer = new byte[2880 * channels * 2];
                OpusTags tags   = new OpusTags();
                tags.Comment                   = "Lavf56.40.101";
                tags.Fields["encoder"]         = "opusenc from opus-tools 0.1.9";
                tags.Fields["encoder_options"] = "--quiet --bitrate 96 --vbr";
                tags.Fields["pad"]             = new string('0', 0x138);

                OpusOggWriteStream oggOut = new OpusOggWriteStream(encoder, outputData, tags, samplingRate, (int)audioId);

                uint lastIndex = 0;
                int  track     = 0;

                foreach (var sourceFile in sourceFiles)
                {
                    try
                    {
                        int bytesReturned  = 1;
                        int totalBytesRead = 0;

                        track++;
                        chapters.Add(lastIndex);

                        int    lastPct     = 0;
                        int    snipLen     = 15;
                        string displayName = new FileInfo(sourceFile).Name;
                        try
                        {
                            var tag = new Mp3(sourceFile, Mp3Permissions.Read).GetAllTags().FirstOrDefault();
                            if (tag != null && tag.Title.IsAssigned)
                            {
                                displayName = tag.Title.Value;
                            }
                        }
                        catch (Exception ex)
                        {
                        }

                        string shortName = displayName.PadRight(snipLen).Substring(0, snipLen);

                        Console.Write(" Track " + track.ToString().PadLeft(3) + " - " + shortName + "  [");


                        /* prepend a audio file for e.g. chapter number */
                        if (prefixLocation != null)
                        {
                            string prefixFile = Path.Combine(prefixLocation, track.ToString("0000") + ".mp3");

                            if (!File.Exists(prefixFile))
                            {
                                throw new FileNotFoundException("Missing prefix file '" + prefixFile + "'");
                            }

                            try
                            {
                                var prefixStream    = new Mp3FileReader(prefixFile);
                                var prefixResampled = new MediaFoundationResampler(prefixStream, outFormat);

                                while (true)
                                {
                                    bytesReturned = prefixResampled.Read(buffer, 0, buffer.Length);

                                    if (bytesReturned <= 0)
                                    {
                                        break;
                                    }

                                    bool isEmpty = (buffer.Where(v => v != 0).Count() == 0);
                                    if (!isEmpty)
                                    {
                                        float[] sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels);

                                        oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length);
                                    }
                                    lastIndex = (uint)oggOut.PageCounter;
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Failed processing prefix file '" + prefixFile + "'");
                            }
                        }

                        /* then the real audio file */
                        var stream          = new Mp3FileReader(sourceFile);
                        var streamResampled = new MediaFoundationResampler(stream, outFormat);

                        while (true)
                        {
                            bytesReturned = streamResampled.Read(buffer, 0, buffer.Length);

                            if (bytesReturned <= 0)
                            {
                                break;
                            }
                            totalBytesRead += bytesReturned;

                            float progress = (float)stream.Position / stream.Length;

                            if ((int)(progress * 20) != lastPct)
                            {
                                lastPct = (int)(progress * 20);
                                if (lastPct % 5 == 0)
                                {
                                    if (lastPct != 20)
                                    {
                                        Console.Write("" + (lastPct * 5) + "%");
                                    }
                                }
                                else
                                {
                                    Console.Write(".");
                                }
                            }

                            bool isEmpty = (buffer.Where(v => v != 0).Count() == 0);
                            if (!isEmpty)
                            {
                                float[] sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels);

                                oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length);
                            }
                            lastIndex = (uint)oggOut.PageCounter;
                        }

                        Console.WriteLine("]");
                        stream.Close();
                    }
                    catch (OpusOggWriteStream.PaddingException e)
                    {
                        Console.WriteLine();
                        throw new EncodingException("Failed to pad opus data properly. Please try CBR with bitrates a multiple of 24 kbps");
                    }
                    catch (FileNotFoundException e)
                    {
                        Console.WriteLine();
                        throw new FileNotFoundException(e.Message);
                    }
                    catch (InvalidDataException e)
                    {
                        Console.WriteLine();
                        throw new Exception("Failed processing " + sourceFile);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine();
                        throw new Exception("Failed processing " + sourceFile);
                    }
                }

                oggOut.Finish();
                Audio = outputData.ToArray();

                var prov = new SHA1CryptoServiceProvider();
                Header.Hash          = prov.ComputeHash(Audio);
                Header.AudioChapters = chapters.ToArray();
                Header.AudioId       = oggOut.LogicalStreamId;
                Header.AudioLength   = Audio.Length;
                Header.Padding       = new byte[0];
            }
        }
예제 #6
0
        private void GenerateAudio(List <string> sourceFiles, uint audioId, int bitRate, bool useVbr, string prefixLocation = null, EncodeCallback cbr = null)
        {
            int         channels     = 2;
            int         samplingRate = 48000;
            List <uint> chapters     = new List <uint>();

            var outFormat = new WaveFormat(samplingRate, 2);

            if (cbr == null)
            {
                cbr = new EncodeCallback();
            }

            OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO);

            encoder.Bitrate = bitRate;
            encoder.UseVBR  = useVbr;

            if (audioId == 0)
            {
                audioId = (uint)((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds();
            }

            string tempName = Path.GetTempFileName();

            using (Stream outputData = new FileStream(tempName, FileMode.OpenOrCreate))
            {
                byte[]   buffer = new byte[2880 * channels * 2];
                OpusTags tags   = new OpusTags();
                tags.Comment                   = "Lavf56.40.101";
                tags.Fields["encoder"]         = "opusenc from opus-tools 0.1.9";
                tags.Fields["encoder_options"] = "--quiet --bitrate 96 --vbr";
                tags.Fields["pad"]             = new string('0', 0x138);

                OpusOggWriteStream oggOut = new OpusOggWriteStream(encoder, outputData, tags, samplingRate, (int)audioId);

                uint lastIndex = 0;
                int  track     = 0;
                bool warned    = false;
                long maxSize   = 0x77359400;

                foreach (var sourceFile in sourceFiles)
                {
                    if ((outputData.Length + 0x1000) >= maxSize)
                    {
                        cbr.Warning("Close to 2 GiB, stopping");
                        break;
                    }

                    try
                    {
                        int bytesReturned  = 1;
                        int totalBytesRead = 0;

                        track++;
                        chapters.Add(lastIndex);

                        int lastPct = 0;
                        cbr.FileStart(track, sourceFile);


                        /* prepend a audio file for e.g. chapter number */
                        if (prefixLocation != null)
                        {
                            string prefixFile = Path.Combine(prefixLocation, track.ToString("0000") + ".mp3");

                            if (!File.Exists(prefixFile))
                            {
                                throw new FileNotFoundException("Missing prefix file '" + prefixFile + "'");
                            }

                            try
                            {
                                var prefixStream    = new Mp3FileReader(prefixFile);
                                var prefixResampled = new MediaFoundationResampler(prefixStream, outFormat);

                                while (true)
                                {
                                    bytesReturned = prefixResampled.Read(buffer, 0, buffer.Length);

                                    if (bytesReturned <= 0)
                                    {
                                        break;
                                    }

                                    bool isEmpty = (buffer.Where(v => v != 0).Count() == 0);
                                    if (!isEmpty)
                                    {
                                        float[] sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels);

                                        if ((outputData.Length + 0x1000 + sampleBuffer.Length) >= maxSize)
                                        {
                                            break;
                                        }
                                        oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length);
                                    }
                                    lastIndex = (uint)oggOut.PageCounter;
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Failed processing prefix file '" + prefixFile + "'");
                            }
                        }

                        /* then the real audio file */
                        var stream          = new Mp3FileReader(sourceFile);
                        var streamResampled = new MediaFoundationResampler(stream, outFormat);

                        while (true)
                        {
                            bytesReturned = streamResampled.Read(buffer, 0, buffer.Length);

                            if (bytesReturned <= 0)
                            {
                                break;
                            }
                            totalBytesRead += bytesReturned;

                            decimal progress = (decimal)stream.Position / stream.Length;

                            if ((int)(progress * 20) != lastPct)
                            {
                                lastPct = (int)(progress * 20);
                                cbr.Progress(progress);
                            }

                            bool isEmpty = (buffer.Where(v => v != 0).Count() == 0);
                            if (!isEmpty)
                            {
                                float[] sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels);

                                oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length);
                            }
                            lastIndex = (uint)oggOut.PageCounter;
                        }

                        cbr.FileDone();
                        stream.Close();
                    }
                    catch (OpusOggWriteStream.PaddingException e)
                    {
                        string msg = "Failed to pad opus data properly. Please try CBR with bitrates a multiple of 24 kbps";
                        cbr.Failed(msg);
                        throw new EncodingException(msg);
                    }
                    catch (FileNotFoundException e)
                    {
                        cbr.Failed(e.Message);
                        throw new FileNotFoundException(e.Message);
                    }
                    catch (InvalidDataException e)
                    {
                        string msg = "Failed processing " + sourceFile;
                        cbr.Failed(msg);
                        throw new Exception(msg);
                    }
                    catch (Exception e)
                    {
                        string msg = "Failed processing " + sourceFile;
                        cbr.Failed(msg);
                        throw new Exception(msg);
                    }

                    if (!warned && outputData.Length >= maxSize / 2)
                    {
                        cbr.Warning("Approaching 2 GiB, please reduce the bitrate");
                        warned = true;
                    }
                }

                oggOut.Finish();
                Header.AudioId = oggOut.LogicalStreamId;
            }

            Audio = File.ReadAllBytes(tempName);

            var prov = new SHA1CryptoServiceProvider();

            Header.Hash          = prov.ComputeHash(Audio);
            Header.AudioChapters = chapters.ToArray();
            Header.AudioLength   = Audio.Length;
            Header.Padding       = new byte[0];

            File.Delete(tempName);
        }
예제 #7
0
        private void GenerateAudio(List <string> sourceFiles, uint audioId, int bitRate, bool useVbr, string prefixLocation = null)
        {
            int         channels     = 2;
            int         samplingRate = 48000;
            List <uint> chapters     = new List <uint>();

            var outFormat = new WaveFormat(samplingRate, 2);

            OpusEncoder encoder = OpusEncoder.Create(48000, 2, OpusApplication.OPUS_APPLICATION_AUDIO);

            encoder.Bitrate = bitRate;
            encoder.UseVBR  = useVbr;

            if (audioId == 0)
            {
                audioId = (uint)((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds();
            }

            string tempName = Path.GetTempFileName();

            using (Stream outputData = new FileStream(tempName, FileMode.OpenOrCreate))
            {
                byte[]   buffer = new byte[2880 * channels * 2];
                OpusTags tags   = new OpusTags();
                tags.Comment                   = "Lavf56.40.101";
                tags.Fields["encoder"]         = "opusenc from opus-tools 0.1.9";
                tags.Fields["encoder_options"] = "--quiet --bitrate 96 --vbr";
                tags.Fields["pad"]             = new string('0', 0x138);

                OpusOggWriteStream oggOut = new OpusOggWriteStream(encoder, outputData, tags, samplingRate, (int)audioId);

                uint lastIndex = 0;
                int  track     = 0;
                bool warned    = false;
                long maxSize   = 0x77359400;

                foreach (var sourceFile in sourceFiles)
                {
                    if ((outputData.Length + 0x1000) >= maxSize)
                    {
                        Console.WriteLine("Error: Close to 2 GiB, aborting");
                        break;
                    }

                    try
                    {
                        int bytesReturned  = 1;
                        int totalBytesRead = 0;

                        track++;
                        chapters.Add(lastIndex);

                        int    lastPct     = 0;
                        int    snipLen     = 15;
                        string displayName = new FileInfo(sourceFile).Name;
                        try
                        {
                            var tag = new Mp3(sourceFile, Mp3Permissions.Read).GetAllTags().FirstOrDefault();
                            if (tag != null && tag.Title.IsAssigned)
                            {
                                displayName = tag.Title.Value;
                            }
                        }
                        catch (Exception ex)
                        {
                        }

                        string shortName = displayName.PadRight(snipLen).Substring(0, snipLen);

                        Console.Write(" Track " + track.ToString().PadLeft(3) + " - " + shortName + "  [");


                        /* prepend a audio file for e.g. chapter number */
                        if (prefixLocation != null)
                        {
                            string prefixFile = Path.Combine(prefixLocation, track.ToString("0000") + ".mp3");

                            if (!File.Exists(prefixFile))
                            {
                                throw new FileNotFoundException("Missing prefix file '" + prefixFile + "'");
                            }

                            try
                            {
                                Stream prefixResampled = new MemoryStream();

                                // Linux
                                string prefixTmpWavFile = "";

                                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                                {
                                    prefixTmpWavFile = Path.ChangeExtension(Path.GetTempFileName(), "wav");

                                    //Console.Write(" Convert file " + sourceFile + " to WAV. Temp file " + prefixTmpWavFile);

                                    // The isReady flag and error test variables are not a nice solution but is working
                                    bool   isReadyPrefix         = false;
                                    String FFmpegErrorTextPrefix = "";

                                    // Convert to WAV
                                    Task.Run(async() =>
                                    {
                                        try
                                        {
                                            // Convert to WAV and resample
                                            IMediaInfo prefixInputFile = await FFmpeg.GetMediaInfo(sourceFile);

                                            IAudioStream prefixAudioStream = prefixInputFile.AudioStreams.First()
                                                                             .SetCodec(AudioCodec.pcm_f32le)
                                                                             .SetChannels(2)
                                                                             .SetSampleRate(samplingRate);

                                            IConversionResult prefixConversionResult = await FFmpeg.Conversions.New()
                                                                                       .AddStream(prefixAudioStream)
                                                                                       .SetOutput(prefixTmpWavFile)
                                                                                       .Start();
                                        }
                                        catch (Exception e)
                                        {
                                            FFmpegErrorTextPrefix = e.Message;
                                            throw new Exception("FFmepg error " + e.Message + "\n");
                                        }

                                        isReadyPrefix = true;
                                    });

                                    while (!isReadyPrefix)
                                    {
                                        Thread.Sleep(200);
                                        if (FFmpegErrorTextPrefix != "")
                                        {
                                            throw new Exception("FFmepg error: " + FFmpegErrorTextPrefix + "\n");
                                        }
                                    }

                                    // Read WAV file
                                    byte[] prefixWavBytes = File.ReadAllBytes(prefixTmpWavFile);
                                    prefixResampled.Write(prefixWavBytes, 0, prefixWavBytes.Length);
                                    prefixResampled.Seek(0, SeekOrigin.Begin);

                                    // Skip WAV header
                                    byte[] bytes = new byte[4];
                                    prefixResampled.Seek(16, 0);
                                    prefixResampled.Read(bytes, 0, 4);
                                    int Subchunk1Size = BitConverter.ToInt32(bytes, 0); // Get FMT size

                                    // Skip some header information
                                    prefixResampled.Read(buffer, 0, Subchunk1Size + 12); // Data starts at FMT size + 12 bytes

                                    // Read data chunk
                                    prefixResampled.Read(bytes, 0, 4);
                                    var str = System.Text.Encoding.Default.GetString(bytes);
                                    if (str != "data")
                                    {
                                        throw new Exception("WAV error: Data section not found \n");
                                    }

                                    // Skip data length
                                    prefixResampled.Read(bytes, 0, 4);
                                }
                                else
                                {
                                    var prefixStream       = new Mp3FileReader(prefixFile);
                                    var prefixResampledTmp = new MediaFoundationResampler(prefixStream, outFormat);

                                    // Convert NAudioStream to System.IO.Stream
                                    byte[] sampleByte = { 0 };
                                    int    read;
                                    while ((read = prefixResampledTmp.Read(sampleByte, 0, sampleByte.Length)) > 0)
                                    {
                                        prefixResampled.Write(sampleByte, 0, read);
                                    }

                                    prefixResampled.Seek(0, SeekOrigin.Begin);
                                }

                                while (true)
                                {
                                    bytesReturned = prefixResampled.Read(buffer, 0, buffer.Length);

                                    if (bytesReturned <= 0)
                                    {
                                        break;
                                    }

                                    bool isEmpty = (buffer.Where(v => v != 0).Count() == 0);
                                    if (!isEmpty)
                                    {
                                        float[] sampleBuffer;
                                        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                                        {
                                            sampleBuffer = MemoryMarshal.Cast <byte, float>(buffer.AsSpan()).ToArray();
                                        }
                                        else
                                        {
                                            sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels);
                                        }

                                        if ((outputData.Length + 0x1000 + sampleBuffer.Length) >= maxSize)
                                        {
                                            break;
                                        }
                                        oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length);
                                    }
                                    lastIndex = (uint)oggOut.PageCounter;
                                }

                                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                                {
                                    File.Delete(prefixTmpWavFile);
                                }
                            }
                            catch (Exception ex)
                            {
                                throw new Exception("Failed processing prefix file '" + prefixFile + "'");
                            }
                        }

                        Stream streamResampled = new MemoryStream();

                        // Linux
                        string tmpWavFile = "";

                        /* then the real audio file */
                        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                        {
                            tmpWavFile = Path.ChangeExtension(Path.GetTempFileName(), "wav");

                            //Console.Write(" Convert file " + sourceFile + " to WAV. Temp file " + TmpWavFile);

                            // The isReady flag and error test variables are not a nice solution but is working
                            bool   isReady         = false;
                            String FFmpegErrorText = "";

                            // Convert to WAV and resample
                            Task.Run(async() =>
                            {
                                try
                                {
                                    IMediaInfo inputFile = await FFmpeg.GetMediaInfo(sourceFile);

                                    IAudioStream audioStream = inputFile.AudioStreams.First()
                                                               .SetCodec(AudioCodec.pcm_f32le)
                                                               .SetChannels(2)
                                                               .SetSampleRate(samplingRate);

                                    IConversionResult conversionResult = await FFmpeg.Conversions.New()
                                                                         .AddStream(audioStream)
                                                                         .SetOutput(tmpWavFile)
                                                                         .AddParameter("-map_metadata -1 -fflags +bitexact -flags:v +bitexact -flags:a +bitexact") // Remove meta data
                                                                         .Start();
                                }
                                catch (Exception e)
                                {
                                    FFmpegErrorText = e.Message;
                                    Console.WriteLine(e.Message);
                                    throw new Exception("FFmepg error " + e.Message + "\n");
                                }

                                isReady = true;
                            });

                            while (!isReady)
                            {
                                Thread.Sleep(200);
                                if (FFmpegErrorText != "")
                                {
                                    throw new Exception("FFmepg error: " + FFmpegErrorText + "\n");
                                }
                            }

                            // Read WAV file
                            byte[] wavBytes = File.ReadAllBytes(tmpWavFile);
                            streamResampled.Write(wavBytes, 0, wavBytes.Length);
                            streamResampled.Seek(0, SeekOrigin.Begin);

                            // Skip WAV header
                            byte[] bytes = new byte[4];
                            streamResampled.Seek(16, 0);
                            streamResampled.Read(bytes, 0, 4);
                            int Subchunk1Size = BitConverter.ToInt32(bytes, 0); // Get FMT size

                            // Skip some header information
                            streamResampled.Read(buffer, 0, Subchunk1Size + 12); // Data starts at FMT size + 12 bytes

                            // Read data chunk
                            streamResampled.Read(bytes, 0, 4);
                            var str = System.Text.Encoding.Default.GetString(bytes);
                            if (str != "data")
                            {
                                throw new Exception("WAV error: Data section not found \n");
                            }

                            // Skip data length
                            streamResampled.Read(bytes, 0, 4);
                        }
                        else
                        {
                            var stream             = new Mp3FileReader(sourceFile);
                            var streamResampledTmp = new MediaFoundationResampler(stream, outFormat);

                            // Convert NAudioStream to System.IO.Stream
                            byte[] sampleByte = { 0 };
                            int    read;
                            while ((read = streamResampledTmp.Read(sampleByte, 0, sampleByte.Length)) > 0)
                            {
                                streamResampled.Write(sampleByte, 0, read);
                            }

                            streamResampled.Seek(0, SeekOrigin.Begin);
                        }

                        while (true)
                        {
                            bytesReturned = streamResampled.Read(buffer, 0, buffer.Length);

                            if (bytesReturned <= 0)
                            {
                                break;
                            }
                            totalBytesRead += bytesReturned;

                            float progress = (float)streamResampled.Position / streamResampled.Length;

                            if ((int)(progress * 20) != lastPct)
                            {
                                lastPct = (int)(progress * 20);
                                if (lastPct % 5 == 0)
                                {
                                    if (lastPct != 20)
                                    {
                                        Console.Write("" + (lastPct * 5) + "%");
                                    }
                                }
                                else
                                {
                                    Console.Write(".");
                                }
                            }

                            bool isEmpty = (buffer.Where(v => v != 0).Count() == 0);
                            if (!isEmpty)
                            {
                                float[] sampleBuffer;
                                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                                {
                                    sampleBuffer = MemoryMarshal.Cast <byte, float>(buffer.AsSpan()).ToArray();
                                }
                                else
                                {
                                    sampleBuffer = ConvertToFloat(buffer, bytesReturned, channels);
                                }

                                oggOut.WriteSamples(sampleBuffer, 0, sampleBuffer.Length);
                            }
                            lastIndex = (uint)oggOut.PageCounter;
                        }

                        Console.WriteLine("]");
                        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                        {
                            File.Delete(tmpWavFile);
                        }

                        streamResampled.Close();
                    }
                    catch (OpusOggWriteStream.PaddingException e)
                    {
                        Console.WriteLine();
                        throw new EncodingException("Failed to pad opus data properly. Please try CBR with bitrates a multiple of 24 kbps");
                    }
                    catch (FileNotFoundException e)
                    {
                        Console.WriteLine();
                        throw new FileNotFoundException(e.Message);
                    }
                    catch (InvalidDataException e)
                    {
                        Console.WriteLine();
                        throw new Exception("Failed processing " + sourceFile);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine();
                        throw new Exception("Failed processing " + sourceFile + "\n Error: " + e.Message + "\n");
                    }

                    if (!warned && outputData.Length >= maxSize / 2)
                    {
                        Console.WriteLine("Warning: Approaching 2 GiB, please reduce the bitrate");
                        warned = true;
                    }
                }

                oggOut.Finish();
                Header.AudioId = oggOut.LogicalStreamId;
            }

            Audio = File.ReadAllBytes(tempName);

            var prov = new SHA1CryptoServiceProvider();

            Header.Hash          = prov.ComputeHash(Audio);
            Header.AudioChapters = chapters.ToArray();
            Header.AudioLength   = Audio.Length;
            Header.Padding       = new byte[0];

            File.Delete(tempName);
        }