public void Convert(string inputFile, string outputFile)
        {
            using (var outputStream = File.Create(outputFile))
            {
                var channels = AudioSampleReader.ReadChannels(inputFile, out var waveFormat);

                var oggStream = new OggStream(StaticRandom.Rng.Next());

                // Build header
                var headerBuilder  = new HeaderPacketBuilder();
                var audioInfo      = VorbisInfo.InitVariableBitRate(channels.Count, waveFormat.SampleRate, 0.1f);
                var infoPacket     = headerBuilder.BuildInfoPacket(audioInfo);
                var commentsPacket = headerBuilder.BuildCommentsPacket(new Comments());
                var booksPacket    = headerBuilder.BuildBooksPacket(audioInfo);
                oggStream.PacketIn(infoPacket);
                oggStream.PacketIn(commentsPacket);
                oggStream.PacketIn(booksPacket);
                WriteHeader(oggStream, outputStream);

                // Store audio
                var processingState    = ProcessingState.Create(audioInfo);
                var normalizedChannels = Normalize(channels);
                processingState.WriteData(normalizedChannels, normalizedChannels[0].Length);
                processingState.WriteEndOfStream();
                WriteAudio(oggStream, outputStream, processingState);
            }
        }
    private static void InitOggStream(int sampleRate, int channels, out OggStream oggStream, out ProcessingState processingState)
    {
        // Stores all the static vorbis bitstream settings
        var info = VorbisInfo.InitVariableBitRate(channels, sampleRate, 0.5f);

        // set up our packet->stream encoder
        var serial = new Random().Next();

        oggStream = new OggStream(serial);

        // =========================================================
        // HEADER
        // =========================================================
        // Vorbis streams begin with three headers; the initial header (with
        // most of the codec setup parameters) which is mandated by the Ogg
        // bitstream spec.  The second header holds any comment fields.  The
        // third header holds the bitstream codebook.
        var comments = new Comments();

        comments.AddTag("ARTIST", "TTS");

        var infoPacket     = HeaderPacketBuilder.BuildInfoPacket(info);
        var commentsPacket = HeaderPacketBuilder.BuildCommentsPacket(comments);
        var booksPacket    = HeaderPacketBuilder.BuildBooksPacket(info);

        oggStream.PacketIn(infoPacket);
        oggStream.PacketIn(commentsPacket);
        oggStream.PacketIn(booksPacket);

        // =========================================================
        // BODY (Audio Data)
        // =========================================================
        processingState = ProcessingState.Create(info);
    }
        /// <summary>
        /// VorbisFileWriter that actually writes to a stream
        /// </summary>
        /// <param name="outStream">Stream to be written to</param>
        /// <param name="sampleRate">The sample rate to use</param>
        /// <param name="channels">The number of channels to use</param>
        /// <param name="quality">The base quality for Vorbis encoding</param>
        public VorbisFileWriter(Stream outStream, int sampleRate, int channels, float quality = 0.5f)
        {
            this.outStream = outStream;
            SampleRate     = sampleRate;
            Channels       = channels;

            if (!startBuffers.ContainsKey(sampleRate))
            {
                throw new InvalidOperationException($"Vorbis writer does not support {sampleRate} sample rate.");
            }

            // Stores all the static vorbis bitstream settings
            Console.WriteLine($"Initiating variable bit rate: {channels} channels, {sampleRate} sample rate, {quality} quality");
            var info = VorbisInfo.InitVariableBitRate(channels, sampleRate, quality);

            // set up our packet->stream encoder
            var serial = MainWindow.MainRandom.Next();

            oggStream = new OggStream(serial);

            // =========================================================
            // HEADER
            // =========================================================
            // Vorbis streams begin with three headers; the initial header (with
            // most of the codec setup parameters) which is mandated by the Ogg
            // bitstream spec.  The second header holds any comment fields.  The
            // third header holds the bitstream codebook.
            var headerBuilder = new HeaderPacketBuilder();

            var comments = new Comments();

            var infoPacket     = headerBuilder.BuildInfoPacket(info);
            var commentsPacket = headerBuilder.BuildCommentsPacket(comments);
            var booksPacket    = headerBuilder.BuildBooksPacket(info);

            oggStream.PacketIn(infoPacket);
            oggStream.PacketIn(commentsPacket);
            oggStream.PacketIn(booksPacket);

            // Flush to force audio data onto its own page per the spec
            FlushPages(oggStream, outStream, true);

            // =========================================================
            // BODY (Audio Data)
            // =========================================================
            processingState = ProcessingState.Create(info);

            // Append some zeros at the start so the result has the same length as the input
            int bufferSize = startBuffers[sampleRate];

            float[][] outSamples = new float[channels][];
            for (int ch = 0; ch < channels; ch++)
            {
                outSamples[ch] = new float[bufferSize];
            }

            processingState.WriteData(outSamples, bufferSize);
        }
        /// <summary>
        /// Encodes and writes a number of float samples
        /// </summary>
        /// <param name="floatSamples">The samples. The array shape is [channel][sample]</param>
        /// <param name="count">The number of samples to write.</param>
        public void WriteFloatSamples(float[][] floatSamples, int count)
        {
            //Console.WriteLine($"Writing {count} samples!");
            processingState.WriteData(floatSamples, count);

            while (!oggStream.Finished && processingState.PacketOut(out var packet))
            {
                //Console.WriteLine($"Got packet with {packet.PacketData.Length} bytes of data");
                oggStream.PacketIn(packet);

                FlushPages(oggStream, outStream, false);
            }
        }
    private static void ProcessChunk(float[][] floatSamples, ProcessingState processingState, OggStream oggStream, int writeBufferSize)
    {
        processingState.WriteData(floatSamples, writeBufferSize, 0);

        while (!oggStream.Finished && processingState.PacketOut(out OggPacket packet))
        {
            oggStream.PacketIn(packet);
        }
    }
        private static void WriteAudio(
            OggStream oggStream,
            Stream outputStream,
            ProcessingState processingState)
        {
            while (!oggStream.Finished && processingState.PacketOut(out var packet))
            {
                oggStream.PacketIn(packet);

                while (!oggStream.Finished && oggStream.PageOut(out var page, false))
                {
                    outputStream.Write(page.Header, 0, page.Header.Length);
                    outputStream.Write(page.Body, 0, page.Body.Length);
                }
            }
        }
    private static byte[] GenerateFile(float[][] floatSamples, int sampleRate, int channels)
    {
        using MemoryStream outputData = new MemoryStream();

        // Stores all the static vorbis bitstream settings
        var info = VorbisInfo.InitVariableBitRate(channels, sampleRate, 0.5f);

        // set up our packet->stream encoder
        var serial    = new Random().Next();
        var oggStream = new OggStream(serial);

        // =========================================================
        // HEADER
        // =========================================================
        // Vorbis streams begin with three headers; the initial header (with
        // most of the codec setup parameters) which is mandated by the Ogg
        // bitstream spec.  The second header holds any comment fields.  The
        // third header holds the bitstream codebook.

        var comments = new Comments();

        comments.AddTag("ARTIST", "TEST");

        var infoPacket     = HeaderPacketBuilder.BuildInfoPacket(info);
        var commentsPacket = HeaderPacketBuilder.BuildCommentsPacket(comments);
        var booksPacket    = HeaderPacketBuilder.BuildBooksPacket(info);

        oggStream.PacketIn(infoPacket);
        oggStream.PacketIn(commentsPacket);
        oggStream.PacketIn(booksPacket);

        // Flush to force audio data onto its own page per the spec
        FlushPages(oggStream, outputData, true);

        // =========================================================
        // BODY (Audio Data)
        // =========================================================
        var processingState = ProcessingState.Create(info);

        for (int readIndex = 0; readIndex <= floatSamples[0].Length; readIndex += WriteBufferSize)
        {
            if (readIndex == floatSamples[0].Length)
            {
                processingState.WriteEndOfStream();
            }
            else
            {
                processingState.WriteData(floatSamples, WriteBufferSize, readIndex);
            }

            while (!oggStream.Finished && processingState.PacketOut(out OggPacket packet))
            {
                oggStream.PacketIn(packet);

                FlushPages(oggStream, outputData, false);
            }
        }

        FlushPages(oggStream, outputData, true);

        return(outputData.ToArray());
    }
Beispiel #8
0
        private static void Main()
        {
            var stdin  = new FileStream(@"unencoded.raw", FileMode.Open, FileAccess.Read);
            var stdout = new FileStream(@"encoded.ogg", FileMode.Create, FileAccess.Write);

            // StripWavHeader(stdin);

            // Stores all the static vorbis bitstream settings
            var info = VorbisInfo.InitVariableBitRate(2, 44100, 0.1f);

            // set up our packet->stream encoder
            var serial    = new Random().Next();
            var oggStream = new OggStream(serial);

            // =========================================================
            // HEADER
            // =========================================================
            // Vorbis streams begin with three headers; the initial header (with
            // most of the codec setup parameters) which is mandated by the Ogg
            // bitstream spec.  The second header holds any comment fields.  The
            // third header holds the bitstream codebook.
            var headerBuilder = new HeaderPacketBuilder();

            var comments = new Comments();

            comments.AddTag("ARTIST", "TEST");

            var infoPacket     = headerBuilder.BuildInfoPacket(info);
            var commentsPacket = headerBuilder.BuildCommentsPacket(comments);
            var booksPacket    = headerBuilder.BuildBooksPacket(info);

            oggStream.PacketIn(infoPacket);
            oggStream.PacketIn(commentsPacket);
            oggStream.PacketIn(booksPacket);

            // Flush to force audio data onto its own page per the spec
            OggPage page;

            while (oggStream.PageOut(out page, true))
            {
                stdout.Write(page.Header, 0, page.Header.Length);
                stdout.Write(page.Body, 0, page.Body.Length);
            }

            // =========================================================
            // BODY (Audio Data)
            // =========================================================
            var processingState = ProcessingState.Create(info);

            var buffer = new float[info.Channels][];

            buffer[0] = new float[SampleSize];
            buffer[1] = new float[SampleSize];

            var readbuffer = new byte[SampleSize * 4];

            while (!oggStream.Finished)
            {
                var bytes = stdin.Read(readbuffer, 0, readbuffer.Length);

                if (bytes == 0)
                {
                    processingState.WriteEndOfStream();
                }
                else
                {
                    var samples = bytes / 4;

                    for (var i = 0; i < samples; i++)
                    {
                        // uninterleave samples
                        buffer[0][i] = (short)((readbuffer[i * 4 + 1] << 8) | (0x00ff & readbuffer[i * 4])) / 32768f;
                        buffer[1][i] = (short)((readbuffer[i * 4 + 3] << 8) | (0x00ff & readbuffer[i * 4 + 2])) / 32768f;
                    }

                    processingState.WriteData(buffer, samples);
                }

                OggPacket packet;
                while (!oggStream.Finished &&
                       processingState.PacketOut(out packet))
                {
                    oggStream.PacketIn(packet);

                    while (!oggStream.Finished &&
                           oggStream.PageOut(out page, false))
                    {
                        stdout.Write(page.Header, 0, page.Header.Length);
                        stdout.Write(page.Body, 0, page.Body.Length);
                    }
                }
            }

            stdin.Close();
            stdout.Close();
        }
Beispiel #9
0
        // OGG-Conversion
        private void OGGConversion()
        {
            progBarVisible = true;
            try
            {
                FileStream stdin;
                FileStream stdout;
                if (!ConvUsespreset)
                {
                    stdin  = new FileStream(ConvTitle + ".wav", FileMode.Open, FileAccess.Read);
                    stdout = new FileStream(ConvTitle + ".ogg", FileMode.Create, FileAccess.Write);
                }
                else
                {
                    stdin  = new FileStream(Filepath + "\\" + ConvTitle + ".wav", FileMode.Open, FileAccess.Read);
                    stdout = new FileStream(Filepath + "\\" + ConvTitle + ".ogg", FileMode.Create, FileAccess.Write);
                }

                var info = VorbisInfo.InitVariableBitRate(2, 48000, 0.1f);

                var serial    = new Random().Next();
                var oggStream = new OggStream(serial);

                var headerBuilder = new HeaderPacketBuilder();

                var comments = new Comments();
                comments.AddTag("ARTIST", "");

                var infoPacket     = headerBuilder.BuildInfoPacket(info);
                var commentsPacket = headerBuilder.BuildCommentsPacket(comments);
                var booksPacket    = headerBuilder.BuildBooksPacket(info);

                oggStream.PacketIn(infoPacket);
                oggStream.PacketIn(commentsPacket);
                oggStream.PacketIn(booksPacket);

                OggPage page;
                while (oggStream.PageOut(out page, true))
                {
                    stdout.Write(page.Header, 0, page.Header.Length);
                    stdout.Write(page.Body, 0, page.Body.Length);
                }

                var processingState = ProcessingState.Create(info);

                var buffer = new float[info.Channels][];
                buffer[0] = new float[SampleSize];
                buffer[1] = new float[SampleSize];

                var readbuffer = new byte[SampleSize * 4];
                while (!oggStream.Finished)
                {
                    var bytes = stdin.Read(readbuffer, 0, readbuffer.Length);

                    if (bytes == 0)
                    {
                        processingState.WriteEndOfStream();
                    }
                    else
                    {
                        var samples = bytes / 4;

                        progBarMax = samples;
                        progBarWEE = false;

                        for (var i = 0; i < samples; i++)
                        {
                            // uninterleave samples
                            buffer[0][i] = (short)((readbuffer[i * 4 + 1] << 8) | (0x00ff & readbuffer[i * 4])) / 32768f;
                            buffer[1][i] = (short)((readbuffer[i * 4 + 3] << 8) | (0x00ff & readbuffer[i * 4 + 2])) / 32768f;
                            progBarValue = i;
                        }
                        progBarWEE = true;

                        processingState.WriteData(buffer, samples);
                    }

                    OggPacket packet;
                    while (!oggStream.Finished &&
                           processingState.PacketOut(out packet))
                    {
                        oggStream.PacketIn(packet);

                        while (!oggStream.Finished &&
                               oggStream.PageOut(out page, false))
                        {
                            stdout.Write(page.Header, 0, page.Header.Length);
                            stdout.Write(page.Body, 0, page.Body.Length);
                        }
                    }
                }

                stdin.Close();
                stdout.Close();
                if (!ConvUsespreset)
                {
                    File.Delete(ConvTitle + ".wav");
                }
                else
                {
                    File.Delete(Filepath + "\\" + ConvTitle + ".wav");
                }
            }
            catch (Exception error)
            {
                errortext = Convert.ToString(error);
            }

            progBarVisible = false;
            Thread.CurrentThread.Abort();
        }
Beispiel #10
0
    public static void WriteFile(Unity_Studio.EndianStream stream, string file, int offset, int size, Ogg ogg)
    {
        // Write to disk
        using (BinaryWriter writer = new BinaryWriter(File.Open(file, FileMode.Create)))
        {
            // Only support header CRC 3605052372 for now
            OggVorbisHeader head = new OggVorbisHeader();

            HeaderPacketBuilder hpb    = new HeaderPacketBuilder();
            CodecSetup          cSetup = new CodecSetup(null);
            cSetup.BlockSizes[0] = 256;
            cSetup.BlockSizes[1] = 2048;

            VorbisInfo info = new VorbisInfo(cSetup, (int)ogg.channels, (int)ogg.frequency, 0);

            OggPacket headerInfo = hpb.BuildInfoPacket(info);

            Comments comments = new Comments();
            if (ogg.loopStart > 0 && ogg.loopEnd > 0)
            {
                comments.AddTag("LOOP_START", ogg.loopStart.ToString());
                comments.AddTag("LOOP_END", ogg.loopEnd.ToString());
            }
            OggPacket headerComment = hpb.BuildCommentsPacket(comments);
            OggPacket headerSetup   = new OggPacket(OggVorbisHeader.GetHeader(ogg.crc32), false, 0, 2);

            OggStream output = new OggStream(1);
            output.PacketIn(headerInfo);
            output.PacketIn(headerComment);
            output.PacketIn(headerSetup);

            stream.Position = offset;

            UInt16 packetSize     = stream.ReadUInt16();
            int    prevPacketNo   = 2;
            int    prevGranulePos = 0;

            while (packetSize > 0)
            {
                OggPacket packet = new OggPacket(stream.ReadBytes(packetSize), false, 0, prevPacketNo + 1);

                byte firstByte = packet.PacketData[0];

                // OK for stereo
                int granuleSize = 128;
                if ((firstByte & 2) != 0)
                {
                    granuleSize = 1024;
                }

                if (ogg.channels == 1)
                {
                    granuleSize /= 4;
                }
                packet.GranulePosition = prevGranulePos + granuleSize;

                if (stream.Position + 2 < offset + size)
                {
                    packetSize = stream.ReadUInt16();
                }
                else
                {
                    packetSize = 0;
                }
                packet.EndOfStream = packetSize == 0;
                prevGranulePos     = packet.GranulePosition;
                prevPacketNo       = packet.PacketNumber;

                output.PacketIn(packet);
                OggPage page = null;
                if (output.PageOut(out page, true))
                {
                    writer.Write(page.Header);
                    writer.Write(page.Body);
                }
            }

            //float vorbis_quality = ((ogg.quality - 1) + (ogg.quality - 100) * 0.1f) / 99.0f;
            //VorbisInfo.InitVariableBitRate(ogg.channels, ogg.frequency, ogg.)
            //writer.Write();
            writer.Close();
        }
    }
Beispiel #11
0
        public byte[] ConvertWaveBytes(byte[] waveBytes)
        {
            // Stores all the static vorbis bitstream settings
            VorbisInfo info = VorbisInfo.InitVariableBitRate(2, 44100, 0.1f);

            // set up our packet->stream encoder
            int       serial    = new Random().Next();
            OggStream oggStream = new OggStream(serial);

            MemoryStream streamIn  = new MemoryStream(waveBytes);
            MemoryStream streamOut = new MemoryStream();

            // Vorbis streams begin with three headers; the initial header (with
            // most of the codec setup parameters) which is mandated by the Ogg
            // bitstream spec.  The second header holds any comment fields.  The
            // third header holds the bitstream codebook.
            var headerBuilder = new HeaderPacketBuilder();

            var comments       = new Comments();
            var infoPacket     = headerBuilder.BuildInfoPacket(info);
            var commentsPacket = headerBuilder.BuildCommentsPacket(comments);
            var booksPacket    = headerBuilder.BuildBooksPacket(info);

            oggStream.PacketIn(infoPacket);
            oggStream.PacketIn(commentsPacket);
            oggStream.PacketIn(booksPacket);

            // Flush to force audio data onto its own page per the spec
            OggPage page;

            while (oggStream.PageOut(out page, true))
            {
                streamOut.Write(page.Header, 0, page.Header.Length);
                streamOut.Write(page.Body, 0, page.Body.Length);
            }

            var processingState = ProcessingState.Create(info);

            var buffer = new float[info.Channels][];

            buffer[0] = new float[SampleSize];
            buffer[1] = new float[SampleSize];

            var readbuffer = new byte[SampleSize];

            while (!oggStream.Finished)
            {
                int bytes = streamIn.Read(readbuffer, 0, readbuffer.Length);

                if (bytes == 0)
                {
                    processingState.WriteEndOfStream();
                }
                else
                {
                    var samples = bytes;

                    for (var i = 1; i < samples; i += 2)
                    {
                        buffer[0][i] = (short)((readbuffer[i] << 8) | (0x00ff & readbuffer[i - 1])) / 32768f;
                        buffer[1][i] = buffer[0][i];
                    }

                    processingState.WriteData(buffer, bytes);
                }

                while (!oggStream.Finished &&
                       processingState.PacketOut(out OggPacket packet))
                {
                    oggStream.PacketIn(packet);

                    while (!oggStream.Finished &&
                           oggStream.PageOut(out page, false))
                    {
                        streamOut.Write(page.Header, 0, page.Header.Length);
                        streamOut.Write(page.Body, 0, page.Body.Length);
                    }
                }
            }

            byte[] oggBytes = streamOut.ToArray();

            streamIn.Close();
            streamOut.Close();

            return(oggBytes);
        }
Beispiel #12
0
        public static string ConvertMp3toOgg(string mp3Path, string outputDir)
        {
            var oggName = Path.GetFileNameWithoutExtension(mp3Path) + ".ogg";

            try
            {
                using (var mp3 = new Mp3FileReader(mp3Path))
                    using (var wav = WaveFormatConversionStream.CreatePcmStream(mp3))
                        using (var ogg = new FileStream(Path.Combine(outputDir, oggName), FileMode.Create, FileAccess.Write))
                        {
                            const int SampleSize = 4096;

                            // Here's a reference for the code below:
                            //   https://github.com/SteveLillis/.NET-Ogg-Vorbis-Encoder/blob/master/OggVorbisEncoder.Example/Encoder.cs
                            var info = VorbisInfo.InitVariableBitRate(2, wav.WaveFormat.SampleRate, 0.5f);

                            // set up our packet->stream encoder
                            var serial    = new Random().Next();
                            var oggStream = new OggStream(serial);

                            // =========================================================
                            // HEADER
                            // =========================================================
                            // Vorbis streams begin with three headers; the initial header (with
                            // most of the codec setup parameters) which is mandated by the Ogg
                            // bitstream spec.  The second header holds any comment fields.  The
                            // third header holds the bitstream codebook.

                            var comments = new Comments();
                            // comments.AddTag("ARTIST", "TEST");

                            var infoPacket     = HeaderPacketBuilder.BuildInfoPacket(info);
                            var commentsPacket = HeaderPacketBuilder.BuildCommentsPacket(comments);
                            var booksPacket    = HeaderPacketBuilder.BuildBooksPacket(info);

                            oggStream.PacketIn(infoPacket);
                            oggStream.PacketIn(commentsPacket);
                            oggStream.PacketIn(booksPacket);

                            // Flush to force audio data onto its own page per the spec
                            OggPage page;
                            while (oggStream.PageOut(out page, true))
                            {
                                ogg.Write(page.Header, 0, page.Header.Length);
                                ogg.Write(page.Body, 0, page.Body.Length);
                            }

                            // =========================================================
                            // BODY (Audio Data)
                            // =========================================================
                            var processingState = ProcessingState.Create(info);

                            var buffer = new float[info.Channels][];
                            buffer[0] = new float[SampleSize];
                            buffer[1] = new float[SampleSize];

                            var readbuffer = new byte[SampleSize * 4];
                            while (!oggStream.Finished)
                            {
                                var bytes = wav.Read(readbuffer, 0, readbuffer.Length);

                                if (bytes == 0)
                                {
                                    processingState.WriteEndOfStream();
                                }
                                else
                                {
                                    var samples = bytes / 4;

                                    for (var i = 0; i < samples; i++)
                                    {
                                        // uninterleave samples
                                        buffer[0][i] = (short)((readbuffer[i * 4 + 1] << 8) | (0x00ff & readbuffer[i * 4])) / 32768f;
                                        buffer[1][i] = (short)((readbuffer[i * 4 + 3] << 8) | (0x00ff & readbuffer[i * 4 + 2])) / 32768f;
                                    }

                                    processingState.WriteData(buffer, samples);
                                }

                                while (!oggStream.Finished &&
                                       processingState.PacketOut(out OggPacket packet))
                                {
                                    oggStream.PacketIn(packet);

                                    while (!oggStream.Finished &&
                                           oggStream.PageOut(out page, false))
                                    {
                                        ogg.Write(page.Header, 0, page.Header.Length);
                                        ogg.Write(page.Body, 0, page.Body.Length);
                                    }
                                }
                            }
                        }
            }
            catch (NAudio.MmException e)
            {
                Console.WriteLine(e);
                // Just retry
                return(ConvertMp3toOgg(mp3Path, outputDir));
            }
            catch (InvalidOperationException e)
            {
                Console.WriteLine(e);
                Console.WriteLine("Error while converting to " + oggName);
                return(oggName);
            }
            return(oggName);
        }