Пример #1
0
        OggPacket RebuildIdPacket(Sample sample, uint blocksize_short, uint blocksize_long)
        {
            using (var buf = new MemoryStream())
                using (var output = new BinaryWriter(buf))
                {
                    output.Write((byte)1);
                    output.Write("vorbis".ToCharArray());
                    output.Write(0);
                    output.Write((byte)sample.Channels);
                    output.Write(sample.SampleRate);
                    output.Write(0);
                    output.Write(0);
                    output.Write(0);
                    int lo   = VorbisInfo.CountBits(blocksize_short);
                    int hi   = VorbisInfo.CountBits(blocksize_long);
                    int bits = hi << 4 | lo;
                    output.Write((byte)bits);
                    output.Write((byte)1);
                    output.Flush();

                    var packet = new OggPacket();
                    packet.SetPacket(0, buf.ToArray());
                    packet.BoS = true;
                    return(packet);
                }
        }
Пример #2
0
        public Sound LoadOgg(string fileName)
        {
            var                  stream = new OggVorbisFileStream(fileName);
            VorbisInfo           vInfo  = stream.Info;
            WaveFormatExtensible wfe    = new WaveFormatExtensible
            {
                // cbSize
                BitsPerSample         = 16,
                Channels              = (short)vInfo.Channels,
                SamplesPerSecond      = vInfo.Rate, // ogg vorbis always uses 16 bits
                AverageBytesPerSecond = vInfo.Rate * vInfo.Channels * 2,
                BlockAlignment        = (short)(2 * vInfo.Channels),
                FormatTag             = WaveFormatTag.Pcm
            };

            AudioBuffer buffer = new AudioBuffer();

            buffer.AudioData  = stream;
            buffer.AudioBytes = (int)stream.Length;
            buffer.Flags      = BufferFlags.EndOfStream;

            return(new Sound {
                Buffer = buffer, Stream = stream, Format = wfe, Program = this
            });
        }
    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);
    }
        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);
            }
        }
Пример #5
0
        public EnvelopeLookup(PsyGlobal psyGlobal, VorbisInfo info)
        {
            _psyGlobal = psyGlobal;
            var codecSetup = info.CodecSetup;

            _minEnergy  = codecSetup.PsyGlobalParam.PreEchoMinEnergy;
            _cursor     = codecSetup.BlockSizes[1] / 2;
            _mdctWindow = new float[WindowLength];
            _mdctLookup = new MdctLookup(WindowLength);

            for (var i = 0; i < _mdctWindow.Length; i++)
            {
                _mdctWindow[i]  = (float)Math.Sin(i / (WindowLength - 1.0) * Math.PI);
                _mdctWindow[i] *= _mdctWindow[i];
            }

            _bands = new EnvelopeBand[PsyGlobal.EnvelopeBands];

            // Magic follows
            _bands[0] = new EnvelopeBand(2, 4);
            _bands[1] = new EnvelopeBand(4, 5);
            _bands[2] = new EnvelopeBand(6, 6);
            _bands[3] = new EnvelopeBand(9, 8);
            _bands[4] = new EnvelopeBand(13, 8);
            _bands[5] = new EnvelopeBand(17, 8);
            _bands[6] = new EnvelopeBand(22, 8);

            _filters = Enumerable
                       .Range(0, PsyGlobal.EnvelopeBands * info.Channels)
                       .Select(s => new EnvelopeFilterState())
                       .ToArray();

            _mark = new int[WindowLength];
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
    public static OggPacket BuildBooksPacket(VorbisInfo info)
    {
        var buffer = new EncodeBuffer(4096);

        PackBooks(buffer, info);

        var bytes = buffer.GetBytes();

        return(new OggPacket(bytes, false, 0, 2));
    }
Пример #8
0
    public static OggPacket BuildInfoPacket(VorbisInfo info)
    {
        var buffer = new EncodeBuffer();

        PackInfo(buffer, info);

        var bytes = buffer.GetBytes();

        return(new OggPacket(bytes, false, 0, 0));
    }
Пример #9
0
    private static void PackMapping(EncodeBuffer buffer, VorbisInfo info, Mapping mapping)
    {
        /* another 'we meant to do it this way' hack...  up to beta 4, we
         * packed 4 binary zeros here to signify one submapping in use.  We
         * now redefine that to mean four bitflags that indicate use of
         * deeper features; bit0:submappings, bit1:coupling,
         * bit2,3:reserved. This is backward compatible with all actual uses
         * of the beta code. */
        if (mapping.SubMaps > 1)
        {
            buffer.Write(1, 1);
            buffer.Write((uint)mapping.SubMaps - 1, 4);
        }
        else
        {
            buffer.Write(0, 1);
        }

        if (mapping.CouplingSteps > 0)
        {
            buffer.Write(1, 1);
            buffer.Write((uint)mapping.CouplingSteps - 1, 8);

            var couplingBits = Encoding.Log(info.Channels - 1);
            for (var i = 0; i < mapping.CouplingSteps; i++)
            {
                buffer.Write((uint)mapping.CouplingMag[i], couplingBits);
                buffer.Write((uint)mapping.CouplingAng[i], couplingBits);
            }
        }
        else
        {
            buffer.Write(0, 1);
        }

        buffer.Write(0, 2); // 2,3:reserved

        // we don't write the channel submappings if we only have one...
        if (mapping.SubMaps > 1)
        {
            for (var i = 0; i < info.Channels; i++)
            {
                buffer.Write((uint)mapping.ChannelMuxList[i], 4);
            }
        }

        for (var i = 0; i < mapping.SubMaps; i++)
        {
            buffer.Write(0, 8); // time submap unused
            buffer.Write((uint)mapping.FloorSubMap[i], 8);
            buffer.Write((uint)mapping.ResidueSubMap[i], 8);
        }
    }
Пример #10
0
    private int _sequence = 3; // compressed audio packets start after the headers with sequence number 3

    private ProcessingState(
        VorbisInfo vorbisInfo,
        LookupCollection lookups,
        float[][] pcm,
        int[] window,
        int centerWindow)
    {
        _vorbisInfo   = vorbisInfo;
        _lookups      = lookups;
        _pcm          = pcm;
        _window       = window;
        _centerWindow = centerWindow;
    }
Пример #11
0
        VorbisInfo CreateVorbisInfo(Sample sample, OggPacket setup_packet)
        {
            var info = new VorbisInfo {
                Channels = sample.Channels,
                Rate     = sample.SampleRate,
            };

            info.CodecSetup.BlockSizes[0] = 0x100;
            info.CodecSetup.BlockSizes[1] = 0x800;
            var comment = new VorbisComment {
                Vendor = VorbisComment.EncodeVendorString
            };

            info.SynthesisHeaderin(comment, setup_packet);
            return(info);
        }
Пример #12
0
    private static void PackBooks(EncodeBuffer buffer, VorbisInfo info)
    {
        var codecSetup = info.CodecSetup;

        buffer.Write(0x05, 8);
        buffer.WriteString(VorbisString);

        buffer.Write((uint)(codecSetup.BookParams.Count - 1), 8);
        foreach (var book in codecSetup.BookParams)
        {
            PackStaticBook(buffer, book);
        }

        // times; hook placeholders
        buffer.Write(0, 6);
        buffer.Write(0, 16);

        buffer.Write((uint)(codecSetup.FloorParams.Count - 1), 6);
        foreach (var floor in codecSetup.FloorParams)
        {
            buffer.Write(1, 16); // For now we're only using floor type 1
            PackFloor(buffer, floor);
        }

        buffer.Write((uint)(codecSetup.ResidueParams.Count - 1), 6);
        foreach (var residue in codecSetup.ResidueParams)
        {
            buffer.Write((uint)residue.ResidueType, 16);
            PackResidue(buffer, residue);
        }

        buffer.Write((uint)(codecSetup.MapParams.Count - 1), 6);
        foreach (var mapping in codecSetup.MapParams)
        {
            buffer.Write(0, 16); // Mapping type is always zero
            PackMapping(buffer, info, mapping);
        }

        buffer.Write((uint)(codecSetup.ModeParams.Count - 1), 6);
        for (var i = 0; i < codecSetup.ModeParams.Count; i++)
        {
            PackModes(buffer, codecSetup, i);
        }

        buffer.Write(1, 1);
    }
Пример #13
0
    private static void PackInfo(EncodeBuffer buffer, VorbisInfo info)
    {
        var codecSetup = info.CodecSetup;

        // preamble
        buffer.Write(0x01, 8);
        buffer.WriteString(VorbisString);

        // basic information about the stream
        buffer.Write(0x00, 32);
        buffer.Write((uint)info.Channels, 8);
        buffer.Write((uint)info.SampleRate, 32);

        buffer.Write(0, 32); // Bit rate upper not used
        buffer.Write((uint)info.BitRateNominal, 32);
        buffer.Write(0, 32); // Bit rate lower not used

        buffer.Write((uint)Encoding.Log(codecSetup.BlockSizes[0] - 1), 4);
        buffer.Write((uint)Encoding.Log(codecSetup.BlockSizes[1] - 1), 4);
        buffer.Write(1, 1);
    }
Пример #14
0
    public static ProcessingState Create(VorbisInfo info)
    {
        if (info == null)
        {
            throw new ArgumentNullException(nameof(info));
        }

        var codecSetup = info.CodecSetup;

        // initialize the storage vectors. blocksize[1] is small for encode, but the correct size for decode
        var pcmStorage = codecSetup.BlockSizes[1];

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

        for (var i = 0; i < pcm.Length; i++)
        {
            pcm[i] = new float[pcmStorage];
        }

        // Vorbis I uses only window type 0
        var window = new int[2];

        window[0] = Encoding.Log(codecSetup.BlockSizes[0]) - 7;
        window[1] = Encoding.Log(codecSetup.BlockSizes[1]) - 7;

        var centerWindow = codecSetup.BlockSizes[1] / 2;

        var lookups = LookupCollection.Create(info);

        return(new ProcessingState(
                   info,
                   lookups,
                   pcm,
                   window,
                   centerWindow));
    }
Пример #15
0
        private void process()
        {
            lock (lockObject)
                preparing = true;
            byte[] outBuffer = new Byte[4096];
            if (byteStream == null)
            {
                oggFile = new OggVorbisFileStream(fileNames[playPointer]);
            }
            else
            {
                oggStream = new OggVorbisEncodedStream(byteStream);
            }


            MemoryStream PcmStream = null;
            int          PcmBytes  = -1;

            PcmStream = new MemoryStream();
            WaveFormat waveFormat = new WaveFormat();

            AudioBuffer[] theBuffers         = new AudioBuffer[maxBuffers];
            int           nextBuffer         = 0;
            bool          firstLoop          = true;
            bool          startedSourceVoice = false;

            // Decode the Ogg Vorbis data into its PCM data
            while (PcmBytes != 0)
            {
                // Get the next chunk of PCM data, pin these so the GC can't
                while (true)
                {
                    PcmBytes = (oggStream == null) ? oggFile.Read(outBuffer, 0, outBuffer.Length)
                                                : oggStream.Read(outBuffer, 0, outBuffer.Length);


                    if (PcmBytes == 0)                     //Reached the end
                    {
                        break;
                    }
                    PcmStream.Flush();
                    PcmStream.Position = 0;
                    PcmStream.Write(outBuffer, 0, PcmBytes);
                    PcmStream.Position = 0;
                    if (theBuffers[nextBuffer] != null)
                    {
                        theBuffers[nextBuffer].Stream.Dispose();
                        theBuffers[nextBuffer] = null;
                    }

                    theBuffers[nextBuffer]            = new AudioBuffer(SharpDX.DataStream.Create <byte>(PcmStream.ToArray(), true, false));
                    theBuffers[nextBuffer].AudioBytes = PcmBytes;
                    theBuffers[nextBuffer].LoopCount  = 0;
                    if (firstLoop)
                    {
                        VorbisInfo info = (oggStream == null) ? oggFile.Info : oggStream.Info;
                        //BlockAlign = info.Channels * (bitsPerSample / 8);
                        //AverageBytesPerSecond = info.Rate * BlockAlign;

                        //waveFormat.AverageBytesPerSecond = AverageBytesPerSecond;
                        //waveFormat.BitsPerSample = (short)bitsPerSample;
                        //waveFormat.BlockAlignment = (short)BlockAlign;
                        //waveFormat.Channels = (short)info.Channels;
                        //waveFormat.SamplesPerSecond = info.Rate;
                        waveFormat = new WaveFormat(info.Rate, bitsPerSample, info.Channels);
                        //waveFormat.Encoding= WaveFormatEncoding.Pcm;

                        sourceVoice = new SourceVoice(device, waveFormat);

                        sourceVoice.SetVolume(volume);
                    }                     //if first time looping, create sourcevoice

                    sourceVoice.SubmitSourceBuffer(theBuffers[nextBuffer], null);
                    if (nextBuffer == theBuffers.Length - 1)
                    {
                        nextBuffer = 0;
                    }
                    else
                    {
                        nextBuffer++;
                    }
                    //If we're done filling the buffer for the first time
                    if (!startedSourceVoice &&
                        sourceVoice.State.BuffersQueued
                        == maxBuffers)
                    {
                        sourceVoice.Start();
                        startedSourceVoice = true;
                        lock (lockObject)
                        {
                            playing   = true;
                            preparing = false;
                        }                         //lock
                    }
                    firstLoop = false;
                    if (startedSourceVoice)
                    {
                        while (sourceVoice.State.BuffersQueued
                               > maxBuffers - 1)
                        {
                            if (stopNow)
                            {
                                break;
                            }
                            Thread.Sleep(5);
                        }
                    }                     //if started source voice
                    if (stopNow)
                    {
                        break;
                    }
                }                //while
                if (stopNow)
                {
                    break;
                }
                //We don't have any more data but file could still be playing the remaining data.
                if (PcmBytes == 0 /*&& !loop*/)
                {
                    if (!stopNow)
                    {
                        while (sourceVoice.State.BuffersQueued > 0 &&
                               !stopNow)
                        {
                            Thread.Sleep(10);
                        }
                    }                     //if doesn't want to stop ogg
                    if (!loop)
                    {
                        break;    //exit the loop since we ran out of data and don't want to loop back
                    }
                }                 //if we ran out of data
                if (PcmBytes == 0 && loop)
                {
                    PcmBytes = -1;
                    if (oggFile != null)
                    {
                        oggFile.Position = 0;
                    }
                    if (oggStream != null)
                    {
                        oggStream.Position = 0;
                    }
                }         //if we ran out of data but want to loop back
            }             //while more data

            //Done playing, or file requested stop,
            //so clean up and tell calling thread that
            //buffer has stopped and cleaned up.
            //calling thread doesn't know buffer has stopped until we clean things up
            //so we don't lose memory

            //Clean up the resources
            if (sourceVoice != null)
            {
                sourceVoice.ExitLoop();                 //stop looping if looping
                sourceVoice.Stop();
            }
            sourceVoice.Dispose();
            sourceVoice = null;
            if (oggFile != null)
            {
                oggFile.Close();
                oggFile = null;
            }
            outBuffer = null;
            for (int i = 0; i < theBuffers.Length; i++)
            {
                if (theBuffers[i] != null)
                {
                    theBuffers[i].Stream.Dispose();
                    theBuffers[i] = null;
                }
            }
            theBuffers = null;
            if (oggStream != null)
            {
                oggStream.Close();
                oggStream = null;
            }
            PcmStream.Dispose();
            PcmStream = null;
            if (stopEvent != null)
            {
                stopEvent();
            }
        }         //method
Пример #16
0
        private void process(bool initializeNextTrack)
        {
            preparing = true;
            SecondarySoundBuffer sBuff = null;
            int p = playPointer;

            if (initializeNextTrack)
            {
                p++;                 // Point to the next track which we will initialize.
            }
            MemoryStream PcmStream = null;
            PlayFlags    f         = PlayFlags.None;

            if (p > soundBuffers.Count - 1)
            {
                SoundBufferDescription desc = new SoundBufferDescription();
                desc.Flags = BufferFlags.ControlPositionNotify | BufferFlags.ControlVolume | BufferFlags.GetCurrentPosition2 | BufferFlags.GlobalFocus;
                byte[] outBuffer = new Byte[4096];
                oggFile   = new OggVorbisFileStream(fileNames[p]);
                PcmStream = new MemoryStream();
                int        PcmBytes   = -1;
                WaveFormat waveFormat = new WaveFormat();
                // Decode the Ogg Vorbis data into its PCM data
                while (PcmBytes != 0)
                {
                    PcmBytes = oggFile.Read(outBuffer, 0, outBuffer.Length);
                    PcmStream.Write(outBuffer, 0, PcmBytes);
                }
                VorbisInfo info = oggFile.Info;
                waveFormat       = new WaveFormat(info.Rate, bitsPerSample, info.Channels);
                desc.Format      = waveFormat;
                desc.BufferBytes = (int)PcmStream.Length;
                lock (lockObject)                 // So we don't lose a simultaneous volume change.
                    soundBuffers.Add(sBuff = new SecondarySoundBuffer(device, desc));
                sBuff.Write(PcmStream.ToArray(), 0, LockFlags.EntireBuffer);
                // In a multi-wave playback, only loop the last track. The preceeding tracks are intros.
                // Next, if we have a multi-file situation, we need to wait for the current file to stop playing before starting the next one.
                // This handler will also fire when a sound is done playing by default so we can explicitly dispose of the soundBuffer.
                stoppedSignal = new AutoResetEvent(false);
                NotificationPosition[] n = { new NotificationPosition()
                                             {
                                                 Offset = (int)PcmStream.Length - 1, WaitHandle = new AutoResetEvent(false)
                                             } };
                stoppedSignal = (AutoResetEvent)(n[0].WaitHandle);
                sBuff.SetNotificationPositions(n);
            }
            else                  // If this buffer has already been initialized ahead of time
            {
                sBuff = soundBuffers[p];
            }
            if (!initializeNextTrack)
            {
                Thread t = new Thread(stopEventHandler);
                t.Start();
                sBuff.Volume = m_volume;
                f            = (loop && p == fileNames.Length - 1) ? PlayFlags.Looping : PlayFlags.None;
                sBuff.Play(0, f);
            }
            if (PcmStream != null)
            {
                oggFile.Close();
                oggFile.Dispose();
                PcmStream.Close();
                PcmStream.Dispose();
            }
            if (!initializeNextTrack && playPointer < fileNames.Length - 1)             // Prepare the next track.
            {
                process(true);
            }
            preparing = false;
        }
Пример #17
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();
        }
Пример #18
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();
        }
Пример #19
0
        //public uint crc32;
        //public int blocksize_short;
        //public int blocksize_long;
        //public uint setup_header_size;
        //public char[] setup_header;

        public Header(int channels, int rate, int quality)
        {
            float      vorbis_quality = ((quality - 1) + (quality - 100) * 0.1f) / 99.0f;
            VorbisInfo info           = VorbisInfo.InitVariableBitRate(channels, rate, vorbis_quality);
            // missing OV_ECTL_COUPLING_SET to 1, is this needed?
        }
Пример #20
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();
        }
    }
    public static LookupCollection Create(VorbisInfo info)
    {
        var codecSetup = info.CodecSetup;

        var psyGlobal = new PsyGlobalLookup(codecSetup.PsyGlobalParam);
        var envelope  = new EnvelopeLookup(codecSetup.PsyGlobalParam, info);

        // MDCT is tranform 0
        var transform = new MdctLookup[2];

        transform[0] = new MdctLookup(codecSetup.BlockSizes[0]);
        transform[1] = new MdctLookup(codecSetup.BlockSizes[1]);

        // analysis always needs an fft
        var fftLookup = new DrftLookup[2];

        fftLookup[0] = new DrftLookup(codecSetup.BlockSizes[0]);
        fftLookup[1] = new DrftLookup(codecSetup.BlockSizes[1]);

        // finish the codebooks
        if (codecSetup.FullBooks == null)
        {
            codecSetup.FullBooks = new CodeBook[codecSetup.BookParams.Count];
            for (var i = 0; i < codecSetup.BookParams.Count; i++)
            {
                codecSetup.FullBooks[i] = CodeBook.InitEncode(codecSetup.BookParams[i]);
            }
        }

        var psyLookup = new PsyLookup[codecSetup.PsyParams.Count];

        for (var i = 0; i < psyLookup.Length; i++)
        {
            psyLookup[i] = new PsyLookup(
                codecSetup.PsyParams[i],
                codecSetup.PsyGlobalParam,
                codecSetup.BlockSizes[codecSetup.PsyParams[i].BlockFlag] / 2,
                info.SampleRate);
        }

        // initialize all the backend lookups
        var floor = new FloorLookup[codecSetup.FloorParams.Count];

        for (var i = 0; i < floor.Length; i++)
        {
            floor[i] = new FloorLookup(codecSetup.FloorParams[i]);
        }

        var residue = new ResidueLookup[codecSetup.ResidueParams.Count];

        for (var i = 0; i < residue.Length; i++)
        {
            residue[i] = new ResidueLookup(codecSetup.ResidueParams[i], codecSetup.FullBooks);
        }

        return(new LookupCollection(
                   envelope,
                   transform,
                   psyGlobal,
                   psyLookup,
                   fftLookup,
                   floor,
                   residue));
    }
Пример #22
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);
        }
Пример #23
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);
        }
Пример #24
0
    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());
    }
Пример #25
0
        private void process64()
        {
            byte[]       outBuffer = null;
            MemoryStream PcmStream = null;
            int          PcmBytes  = 0;
            WaveFormat   waveFormat;

            AudioBuffer[] theBuffers         = null;
            int           nextBuffer         = 0;
            bool          firstLoop          = false;
            bool          startedSourceVoice = false;

            while (true)
            {
                //This is the outer loop
                //which controls looping in
                //64-bit ogg decoding.
                lock (lockObject)
                    preparing = true;
                outBuffer = new Byte[4096];
                if (byteStream == null)
                {
                    oggFile = new OggVorbisFileStream(fileNames[playPointer]);
                }
                else
                {
                    oggStream = new OggVorbisEncodedStream(byteStream);
                }
                PcmBytes = -1;
                //AverageBytesPerSecond = 0;
                //BlockAlign = 0;
                PcmStream          = new MemoryStream();
                waveFormat         = new WaveFormat();
                theBuffers         = new AudioBuffer[maxBuffers];
                nextBuffer         = 0;
                firstLoop          = true;
                startedSourceVoice = false;
                // Decode the Ogg Vorbis data into its PCM data
                while (PcmBytes != 0)
                {
                    // Get the next chunk of PCM data, pin these so the GC can't
                    while (true)
                    {
                        PcmBytes = (oggStream == null) ? oggFile.Read(outBuffer, 0, outBuffer.Length)
                                                        : oggStream.Read(outBuffer, 0, outBuffer.Length);


                        if (PcmBytes == 0)                         //Reached the end
                        {
                            break;
                        }
                        PcmStream.Flush();
                        PcmStream.Position = 0;
                        PcmStream.Write(outBuffer, 0, PcmBytes);
                        PcmStream.Position = 0;
                        if (theBuffers[nextBuffer] != null)
                        {
                            theBuffers[nextBuffer].Stream.Dispose();
                            theBuffers[nextBuffer] = null;
                        }
                        theBuffers[nextBuffer]            = new AudioBuffer(SharpDX.DataStream.Create <byte>(PcmStream.ToArray(), true, true));
                        theBuffers[nextBuffer].AudioBytes = PcmBytes;
                        theBuffers[nextBuffer].LoopCount  = 0;
                        if (firstLoop)
                        {
                            VorbisInfo info = (oggStream == null) ? oggFile.Info : oggStream.Info;
                            //BlockAlign = info.Channels * (bitsPerSample / 8);
                            //AverageBytesPerSecond = info.Rate * BlockAlign;

                            //waveFormat.AverageBytesPerSecond = AverageBytesPerSecond;
                            //waveFormat.BitsPerSample = (short)bitsPerSample;
                            //waveFormat.BlockAlignment = (short)BlockAlign;
                            //waveFormat.Channels = (short)info.Channels;
                            //waveFormat.SamplesPerSecond = info.Rate;
                            waveFormat = new WaveFormat(info.Rate, bitsPerSample, info.Channels);
                            //waveFormat.Encoding= WaveFormatEncoding.Pcm;

                            sourceVoice = new SourceVoice(device, waveFormat);

                            sourceVoice.SetVolume(volume);
                        }                         //if first time looping, create sourcevoice

                        sourceVoice.SubmitSourceBuffer(theBuffers[nextBuffer], null);
                        if (nextBuffer == theBuffers.Length - 1)
                        {
                            nextBuffer = 0;
                        }
                        else
                        {
                            nextBuffer++;
                        }
                        //If we're done filling the buffer for the first time
                        if (!startedSourceVoice &&
                            sourceVoice.State.BuffersQueued == maxBuffers)
                        {
                            sourceVoice.Start();
                            startedSourceVoice = true;
                            lock (lockObject)
                            {
                                playing   = true;
                                preparing = false;
                            }                             //lock
                        }
                        firstLoop = false;
                        if (startedSourceVoice)
                        {
                            while (sourceVoice.State.BuffersQueued > maxBuffers - 1)
                            {
                                if (stopNow)
                                {
                                    break;
                                }
                                Thread.Sleep(5);
                            }
                        }                         //if started source voice
                        if (stopNow)
                        {
                            break;
                        }
                    }                    //while
                    if (stopNow)
                    {
                        break;
                    }
                    //We don't have any more data but file could still be playing the remaining data.
                    if (PcmBytes == 0 /*&& !loop*/)
                    {
                        if (!stopNow)
                        {
                            while (sourceVoice.State.BuffersQueued > 0 &&
                                   !stopNow)
                            {
                                Thread.Sleep(10);
                            }
                        }         //if doesn't want to stop ogg
                        break;    //exit the loop since we ran out of data and don't want to loop back
                    }             //if we ran out of data
                }                 //while more data

                //Clean everything up for another loop.
                //Must do clean up here since in 64-bit implementation,
                //we need to recreate all the objects.
                if (sourceVoice != null)
                {
                    sourceVoice.ExitLoop();                     //stop looping if looping
                    sourceVoice.Stop();
                }
                sourceVoice.Dispose();
                sourceVoice = null;
                if (oggFile != null)
                {
                    oggFile.Close();
                    oggFile = null;
                }
                outBuffer = null;
                for (int i = 0; i < theBuffers.Length; i++)
                {
                    if (theBuffers[i] != null)
                    {
                        theBuffers[i].Stream.Dispose();
                        theBuffers[i] = null;
                    }
                }
                theBuffers = null;
                if (oggStream != null)
                {
                    oggStream.Close();
                    oggStream = null;
                }
                PcmStream.Dispose();
                PcmStream = null;

                //We must loop this way,
                //since unlike the 32-bit implementation,
                //64-bit does not support native seek.
                if (PcmBytes == 0 && loop)
                {
                    if (!stopNow)
                    {
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {         //if we're not looping
                    break;
                }         //if we ran out of data but want to loop back
            }             //outer loop to control
                          //loop of file on 64-bit implementation

            //Finally, notify calling thread
            //that we're done playing.
            if (stopEvent != null)
            {
                stopEvent();
            }
        }         //method