Exemple #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);
                }
        }
Exemple #2
0
        OggPacket RebuildSetupPacket(byte[] setup_packet)
        {
            var packet = new OggPacket();

            packet.SetPacket(2, setup_packet);
            return(packet);
        }
Exemple #3
0
        OggPacket RebuildCommentPacket()
        {
            var comment = new VorbisComment();
            var packet  = new OggPacket();

            comment.HeaderOut(packet);
            return(packet);
        }
Exemple #4
0
        SoundInput RebuildVorbis(Sample sample)
        {
            if (!sample.MetaData.ContainsKey(ChunkType.VorbisData))
            {
                throw new InvalidFormatException("No VORBISDATA chunk in FSB5 Vorbis stream.");
            }
            var vorbis_data = sample.MetaData[ChunkType.VorbisData] as VorbisData;
            var setup_data  = GetVorbisHeader(vorbis_data.Crc32);
            var state       = new OggStreamState(1);

            var id_packet      = RebuildIdPacket(sample, 0x100, 0x800);
            var comment_packet = RebuildCommentPacket();
            var setup_packet   = RebuildSetupPacket(setup_data);
            var info           = CreateVorbisInfo(sample, setup_packet);

            var output = new MemoryStream();

            state.PacketIn(id_packet);
            state.Write(output);
            state.PacketIn(comment_packet);
            state.Write(output);
            state.PacketIn(setup_packet);
            state.Write(output);
            state.Flush(output);

            long packet_no       = setup_packet.PacketNo + 1;
            long granule_pos     = 0;
            int  prev_block_size = 0;

            using (var input = new BinMemoryStream(sample.Data))
            {
                var packet      = new OggPacket();
                int packet_size = ReadPacketSize(input);
                while (packet_size > 0)
                {
                    packet.SetPacket(packet_no++, input.ReadBytes(packet_size));
                    packet_size = ReadPacketSize(input);
                    packet.EoS  = 0 == packet_size;

                    int block_size = info.PacketBlockSize(packet);
                    if (prev_block_size != 0)
                    {
                        granule_pos += (block_size + prev_block_size) / 4;
                    }
                    else
                    {
                        granule_pos = 0;
                    }
                    packet.GranulePos = granule_pos;
                    prev_block_size   = block_size;

                    state.PacketIn(packet);
                    state.Write(output);
                }
            }
            output.Position = 0;
            return(new OggInput(output));
        }
Exemple #5
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);
        }
Exemple #6
0
 private void AddPacket(byte[] data, uint sampleLength, bool delayWrite)
 {
     var packet = new OggPacket();
     if (data.Length >= 255)
     {
         ThrowExceptions.Custom(Exc.GetStackTrace(), type, Exc.CallingMethod(),ExtractionException("Packet exceeds maximum size.");
     }
     _granulePosition += sampleLength;
     packet.Data = data;
     packet.GranulePosition = _granulePosition;
     _packetList.Add(packet);
     _packetListDataSize += data.Length;
     if (!delayWrite || (_packetListDataSize >= _targetPageDataSize) || (_packetList.Count == 255))
     {
         WritePage();
     }
 }
        private void AddPacket(byte[] data, uint sampleLength, bool delayWrite)
        {
            var packet = new OggPacket();

            if (data.Length >= 255)
            {
                throw new Exception("Packet exceeds maximum size.");
            }
            _granulePosition      += sampleLength;
            packet.Data            = data;
            packet.GranulePosition = _granulePosition;
            _packetList.Add(packet);
            _packetListDataSize += data.Length;
            if (!delayWrite || _packetListDataSize >= _targetPageDataSize || _packetList.Count == 255)
            {
                WritePage();
            }
        }
    public void PacketIn(OggPacket packet)
    {
        if (packet == null)
        {
            return;
        }

        ClearReturnedBody();

        var bytes            = packet.PacketData.Length;
        var lacingValueCount = (int)(bytes / 255f + 1);

        // make sure we have the buffer storage
        ExpandBody(bytes);
        ExpandLacing(lacingValueCount);

        // Copy in the submitted packet.
        Array.Copy(packet.PacketData, 0, _bodyData, _bodyFill, bytes);
        _bodyFill += bytes;

        // Store lacing vals for this packet
        int i;

        for (i = 0; i < lacingValueCount - 1; i++)
        {
            _lacingValues[_lacingFill + i]  = 255;
            _granuleValues[_lacingFill + i] = _granulePosition;
        }

        _lacingValues[_lacingFill + i] = (int)(bytes % 255f);
        _granulePosition = _granuleValues[_lacingFill + i] = packet.GranulePosition;

        // flag the first segment as the beginning of the packet
        _lacingValues[_lacingFill] |= 0x100;

        _lacingFill += lacingValueCount;

        if (packet.EndOfStream)
        {
            Finished = true;
        }
    }
Exemple #9
0
        public void Encode(OggStreamState oggStreamState, VorbisBlock block, Stream stream)
        {
            OggPacket packet = new OggPacket();
            OggPage   page   = new OggPage();

            /* vorbis does some data preanalysis, then divvies up blocks for
             * more involved (potentially parallel) processing.  Get a single
             * block for encoding now */
            while (BlockOut(block))
            {
                /* analysis, assume we want to use bitrate management */
                block.Analyze();
                block.BitrateAddBlock();

                while (BitrateFlushPacket(packet) != 0)
                {
                    /* weld the packet into the bitstream */
                    NativeMethods.ogg_stream_packetin(ref oggStreamState.InternalStruct, ref packet.InternalStruct);

                    /* write out pages (if any) */
                    bool eos = false;
                    while (!eos)
                    {
                        int result = NativeMethods.ogg_stream_pageout(ref oggStreamState.InternalStruct, ref og);
                        if (result == 0)
                        {
                            break;
                        }
                        page.Write(stream);

                        /* this could be set above, but for illustrative purposes, I do
                         * it here (to show that vorbis does know where the stream ends) */

                        if (xm.ogg_page_eos(ref page.InternalStruct) != 0)
                        {
                            eos = true;
                        }
                    }
                }
            }
        }
Exemple #10
0
 private void AddPacket(byte[] data, uint sampleLength, bool delayWrite)
 {
     var packet = new OggPacket();
     if (data.Length >= 255)
     {
         throw new ExtractionException("Packet exceeds maximum size.");
     }
     _granulePosition += sampleLength;
     packet.Data = data;
     packet.GranulePosition = _granulePosition;
     _packetList.Add(packet);
     _packetListDataSize += data.Length;
     if (!delayWrite || (_packetListDataSize >= _targetPageDataSize) || (_packetList.Count == 255))
     {
         WritePage();
     }
 }
Exemple #11
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();
        }
    }
Exemple #12
0
 public int BitrateFlushPacket(OggPacket packet)
 {
     return(NativeMethods.vorbis_bitrate_flushpacket(ref InternalStruct, ref packet.InternalStruct));
 }
Exemple #13
0
    public bool PacketOut(out OggPacket packet)
    {
        packet = null;

        // Have we started?
        if (!_preExtrapolated)
        {
            return(false);
        }

        // Are we done?
        if (_eofFlag == -1)
        {
            return(false);
        }

        var codecSetup = _vorbisInfo.CodecSetup;

        // By our invariant, we have lW, W and centerW set.  Search for
        // the next boundary so we can determine nW (the next window size)
        // which lets us compute the shape of the current block's window
        // we do an envelope search even on a single blocksize; we may still
        // be throwing more bits at impulses, and envelope search handles
        // marking impulses too.
        var testWindow =
            _centerWindow +
            codecSetup.BlockSizes[_currentWindow] / 4 +
            codecSetup.BlockSizes[1] / 2 +
            codecSetup.BlockSizes[0] / 4;

        var bp = _lookups.EnvelopeLookup.Search(_pcm, _pcmCurrent, _centerWindow, testWindow);

        if (bp == -1)
        {
            if (_eofFlag == 0)
            {
                return(false); // not enough data currently to search for a full int block
            }
            _nextWindow = 0;
        }
        else
        {
            _nextWindow = codecSetup.BlockSizes[0] == codecSetup.BlockSizes[1] ? 0 : bp;
        }

        var centerNext = _centerWindow
                         + codecSetup.BlockSizes[_currentWindow] / 4
                         + codecSetup.BlockSizes[_nextWindow] / 4;

        // center of next block + next block maximum right side.
        var blockbound = centerNext + codecSetup.BlockSizes[_nextWindow] / 2;

        // Not enough data yet
        if (_pcmCurrent < blockbound)
        {
            return(false);
        }

        // copy the vectors; ampPtr uses the local storage in vb
        // ampPtr tracks 'strongest peak' for later psychoacoustics
        var n = codecSetup.BlockSizes[_currentWindow] / 2;

        _lookups.PsyGlobalLookup.DecayAmpMax(n, _vorbisInfo.SampleRate);

        var pcmEnd      = codecSetup.BlockSizes[_currentWindow];
        var pcm         = new float[_pcm.Length][];
        var beginWindow = _centerWindow - codecSetup.BlockSizes[_currentWindow] / 2;

        for (var channel = 0; channel < _pcm.Length; channel++)
        {
            pcm[channel] = new float[pcmEnd];
            Array.Copy(_pcm[channel], beginWindow, pcm[channel], 0, pcm[channel].Length);
        }

        // handle eof detection: eof==0 means that we've not yet received EOF eof>0
        // marks the last 'real' sample in pcm[] eof<0  'no more to do'; doesn't get here
        var eofFlag = false;

        if (_eofFlag != 0)
        {
            if (_centerWindow >= _eofFlag)
            {
                _eofFlag = -1;
                eofFlag  = true;
            }
        }

        var data = PerformAnalysis(pcm, pcmEnd);

        packet = new OggPacket(data, eofFlag, _granulePosition, _sequence++);

        if (!eofFlag)
        {
            AdvanceStorageVectors(centerNext);
        }

        return(true);
    }