Exemple #1
0
        internal void Rebuild(uint index, OggStream ogg)
        {
            byte[] codebook     = GetCodebook(index);
            uint   codebookSize = GetCodebookSize(index);

            if (codebookSize == 0xFFFFFFFF || codebook == null)
            {
                throw new Exception("コードブックのインデックスが破損しています。");
            }
            Rebuild(new BitStream(new MemoryStream(codebook)), codebookSize, ogg);
        }
Exemple #2
0
        internal void Rebuild(uint index, OggStream ogg)
        {
            byte[] codebook     = GetCodebook(index);
            uint   codebookSize = GetCodebookSize(index);

            if (codebookSize == 0xFFFFFFFF || codebook == null)
            {
                throw new Exception("Invalid Codebook Index");
            }

            Rebuild(new BitStream(new MemoryStream(codebook)), codebookSize, ogg);
        }
Exemple #3
0
        internal void Copy(BitStream bitStream, OggStream ogg)
        {
            byte[] id = new byte[]
            {
                (byte)bitStream.Read(8),
                (byte)bitStream.Read(8),
                (byte)bitStream.Read(8)
            };
            ushort dimensions = (ushort)bitStream.Read(16);
            uint   entries    = bitStream.Read(24);

            if (id[0] != 0x42 || id[1] != 0x43 || id[2] != 0x56)
            {
                throw new Exception("コードブックのパターンが見つかりませんでした。");
            }
            ogg.BitWrite(id[0]);
            ogg.BitWrite(id[1]);
            ogg.BitWrite(id[2]);
            ogg.BitWrite(dimensions);
            ogg.BitWrite(entries, 24);
            byte orderedFlag = (byte)bitStream.Read(1);

            ogg.WriteBit(orderedFlag);
            if (orderedFlag == 1)
            {
                byte initialLength = (byte)bitStream.Read(5);
                ogg.BitWrite(initialLength, 5);
                uint currentEntry = 0;
                while (currentEntry < entries)
                {
                    uint bitCount = ILog(entries - currentEntry);
                    uint number   = bitStream.Read((int)bitCount);
                    ogg.BitWrite(number, (byte)bitCount);
                    currentEntry += number;
                }
                if (currentEntry > entries)
                {
                    throw new Exception("コードブックをコピーできませんでした。");
                }
            }
            else
            {
                byte sparseFlag = (byte)bitStream.Read(1);
                ogg.WriteBit(sparseFlag);
                for (int i = 0; i < entries; i++)
                {
                    bool presentBool = true;
                    if (sparseFlag == 1)
                    {
                        byte sparsePresenceFlag = (byte)bitStream.Read(1);
                        ogg.WriteBit(sparsePresenceFlag);
                        presentBool = sparsePresenceFlag == 1;
                    }
                    else
                    {
                        byte codewordLength = (byte)bitStream.Read(5);
                        ogg.BitWrite(codewordLength, 5);
                    }
                }
            }
            byte lookupType = (byte)bitStream.Read(4);

            ogg.BitWrite(lookupType, 4);
            if (lookupType == 1)
            {
                ogg.BitWrite(bitStream.Read(32));
                ogg.BitWrite(bitStream.Read(32));
                byte valueLength = (byte)bitStream.Read(4);
                ogg.BitWrite(valueLength, 4);
                ogg.WriteBit((byte)bitStream.Read(1));
                uint quantValues = QuantValues(entries, dimensions);
                for (int i = 0; i < quantValues; i++)
                {
                    uint value = bitStream.Read(valueLength + 1);
                    ogg.BitWrite(value, (byte)(valueLength + 1));
                }
            }
            else
            {
                throw new Exception("コードブックをコピーできませんでした。");
            }
        }
Exemple #4
0
        internal void Rebuild(BitStream bitStream, uint codebookSize, OggStream ogg)
        {
            byte   dimensions = (byte)bitStream.Read(4);
            ushort entries    = (ushort)bitStream.Read(14);

            ogg.BitWrite(0x564342, 24);
            ogg.BitWrite((ushort)dimensions, 16);
            ogg.BitWrite((uint)entries, 24);
            byte orderedFlag = (byte)bitStream.Read(1);

            ogg.WriteBit(orderedFlag);
            if (orderedFlag == 1)
            {
                byte initialLength = (byte)bitStream.Read(5);
                ogg.BitWrite(initialLength, 5);
                uint currentEntry = 0;
                while (currentEntry < entries)
                {
                    uint bitCount = ILog(entries - currentEntry);
                    uint number   = bitStream.Read((int)bitCount);
                    ogg.BitWrite(number, (byte)bitCount);
                    currentEntry += number;
                }
                if (currentEntry > entries)
                {
                    throw new Exception("コードブックをリビルドできませんでした。");
                }
            }
            else
            {
                byte codewordLengthLength = (byte)bitStream.Read(3);
                byte sparseFlag           = (byte)bitStream.Read(1);
                ogg.WriteBit(sparseFlag);
                if (codewordLengthLength == 0 || codewordLengthLength > 5)
                {
                    throw new Exception("コードブックをリビルドできませんでした。");
                }
                for (int i = 0; i < entries; i++)
                {
                    bool presentBool = true;
                    if (sparseFlag == 1)
                    {
                        byte sparsePresenceFlag = (byte)bitStream.Read(1);
                        ogg.WriteBit(sparsePresenceFlag);
                        presentBool = sparsePresenceFlag == 1;
                    }
                    if (presentBool)
                    {
                        byte codewordLength = (byte)bitStream.Read(codewordLengthLength);
                        ogg.BitWrite(codewordLength, 5);
                    }
                }
            }
            byte lookupType = (byte)bitStream.Read(1);

            ogg.BitWrite(lookupType, 4);
            if (lookupType == 1)
            {
                ogg.BitWrite(bitStream.Read(32));
                ogg.BitWrite(bitStream.Read(32));
                byte valueLength = (byte)bitStream.Read(4);
                ogg.BitWrite(valueLength, 4);
                ogg.WriteBit((byte)bitStream.Read(1));
                uint quantValues = QuantValues(entries, dimensions);
                for (int i = 0; i < quantValues; i++)
                {
                    uint value = bitStream.Read(valueLength + 1);
                    ogg.BitWrite(value, (byte)(valueLength + 1));
                }
            }
            else if (lookupType != 0)
            {
                throw new Exception("コードブックをコピーできませんでした。");
            }
            if (codebookSize != 0 && bitStream.TotalBitsRead / 8 + 1 != codebookSize)
            {
                throw new Exception("コードブックをリビルドできませんでした。");
            }
        }
Exemple #5
0
        private void GenerateOGGHeader(OggStream ogg, string codebooksLocation, bool inlineCodebooks, bool fullSetup, ref bool[] modeBlockFlag, ref uint modeBits)
        {
            ogg.WriteVorbisHeader(1);
            ogg.BitWrite((uint)0);
            ogg.BitWrite((byte)this.Channels);
            ogg.BitWrite(this.SampleRate);
            ogg.BitWrite((uint)0);
            ogg.BitWrite(this.AverageBytesPerSecond * 8);
            ogg.BitWrite((uint)0);
            ogg.BitWrite(this._blocksize0Pow, 4);
            ogg.BitWrite(this._blocksize1Pow, 4);
            ogg.WriteBit(1);
            ogg.FlushPage();
            ogg.WriteVorbisHeader(3);
            byte[] vendor = Encoding.UTF8.GetBytes("Converted from Audiokinetic Wwise by SRTTbacon");
            ogg.BitWrite((uint)vendor.Length);
            for (int i = 0; i < vendor.Length; i++)
            {
                ogg.BitWrite(vendor[i]);
            }
            if (this._loopCount == 0)
            {
                ogg.BitWrite((uint)0);
            }
            else
            {
                ogg.BitWrite((uint)2);
                byte[] loopStart = Encoding.UTF8.GetBytes("LoopStart=" + this._loopStart.ToString());
                ogg.BitWrite((uint)loopStart.Length);
                for (int i = 0; i < loopStart.Length; i++)
                {
                    ogg.BitWrite(loopStart[i]);
                }
                byte[] loopEnd = Encoding.UTF8.GetBytes("LoopEnd=" + this._loopEnd.ToString());
                ogg.BitWrite((uint)loopEnd.Length);
                for (int i = 0; i < loopEnd.Length; i++)
                {
                    ogg.BitWrite(loopEnd[i]);
                }
            }
            ogg.WriteBit(1);
            ogg.FlushPage();
            ogg.WriteVorbisHeader(5);
            Packet setupPacket = new Packet(this._wemFile, this._dataChunkOffset + this._setupPacketOffset, this._noGranule);

            this._wemFile.Seek(setupPacket.GetOffset(), SeekOrigin.Begin);
            if (setupPacket.GetGranule() != 0)
            {
                throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
            }
            BitStream bitStream     = new BitStream(this._wemFile);
            uint      codebookCount = bitStream.Read(8);

            ogg.BitWrite((byte)codebookCount);
            codebookCount++;
            if (inlineCodebooks)
            {
                CodebookLibrary codebook = new CodebookLibrary();
                for (int i = 0; i < codebookCount; i++)
                {
                    if (fullSetup)
                    {
                        codebook.Copy(bitStream, ogg);
                    }
                    else
                    {
                        codebook.Rebuild(bitStream, 0, ogg);
                    }
                }
            }
            else
            {
                CodebookLibrary codebook = new CodebookLibrary(codebooksLocation);
                for (int i = 0; i < codebookCount; i++)
                {
                    ushort codebookID = (ushort)bitStream.Read(10);
                    codebook.Rebuild(codebookID, ogg);
                }
            }
            byte   timeCountLess1 = 0;
            ushort dummyTimeValue = 0;

            ogg.BitWrite(timeCountLess1, 6);
            ogg.BitWrite(dummyTimeValue);
            if (fullSetup)
            {
                while (bitStream.TotalBitsRead < setupPacket.GetSize() * 8U)
                {
                    ogg.WriteBit((byte)bitStream.Read(1));
                }
            }
            else
            {
                byte floorCount = (byte)bitStream.Read(6);
                ogg.BitWrite(floorCount, 6);
                floorCount++;
                for (int i = 0; i < floorCount; i++)
                {
                    ushort floorType = 1;
                    ogg.BitWrite(floorType);
                    byte floor1Partitions = (byte)bitStream.Read(5);
                    ogg.BitWrite(floor1Partitions, 5);
                    uint[] floor1PartitionClassList = new uint[floor1Partitions];
                    uint   maximumClass             = 0;
                    for (int j = 0; j < floor1Partitions; j++)
                    {
                        byte floor1PartitionClass = (byte)bitStream.Read(4);
                        ogg.BitWrite(floor1PartitionClass, 4);
                        floor1PartitionClassList[j] = floor1PartitionClass;
                        if (floor1PartitionClass > maximumClass)
                        {
                            maximumClass = floor1PartitionClass;
                        }
                    }
                    uint[] floor1ClassDimensionList = new uint[maximumClass + 1];
                    for (int j = 0; j <= maximumClass; j++)
                    {
                        byte classDimension = (byte)bitStream.Read(3);
                        ogg.BitWrite(classDimension, 3);
                        floor1ClassDimensionList[j] = classDimension + 1U;
                        byte classSubclasses = (byte)bitStream.Read(2);
                        ogg.BitWrite(classSubclasses, 2);
                        if (classSubclasses != 0)
                        {
                            byte masterbook = (byte)bitStream.Read(8);
                            ogg.BitWrite(masterbook);
                            if (maximumClass >= codebookCount)
                            {
                                throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                            }
                        }
                        for (int k = 0; k < (1 << classSubclasses); k++)
                        {
                            byte subclassBook = (byte)bitStream.Read(8);
                            ogg.BitWrite(subclassBook);
                            if ((subclassBook - 1) >= 0 && (subclassBook - 1) >= codebookCount)
                            {
                                throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                            }
                        }
                    }
                    byte floor1Multiplier = (byte)bitStream.Read(2);
                    ogg.BitWrite(floor1Multiplier, 2);
                    byte rangeBits = (byte)bitStream.Read(4);
                    ogg.BitWrite(rangeBits, 4);
                    for (int j = 0; j < floor1Partitions; j++)
                    {
                        uint currentClassNumber = floor1PartitionClassList[j];
                        for (int k = 0; k < floor1ClassDimensionList[currentClassNumber]; k++)
                        {
                            ogg.BitWrite(bitStream.Read(rangeBits), rangeBits);
                        }
                    }
                }
                byte residueCount = (byte)bitStream.Read(6);
                ogg.BitWrite(residueCount, 6);
                residueCount++;
                for (int i = 0; i < residueCount; i++)
                {
                    byte residueType = (byte)bitStream.Read(2);
                    ogg.BitWrite((ushort)residueType);
                    if (residueType > 2)
                    {
                        throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                    }
                    uint residueBegin           = bitStream.Read(24);
                    uint residueEnd             = bitStream.Read(24);
                    uint residuePartitionSize   = bitStream.Read(24);
                    byte residueClassifications = (byte)bitStream.Read(6);
                    byte residueClassbook       = (byte)bitStream.Read(8);
                    ogg.BitWrite(residueBegin, 24);
                    ogg.BitWrite(residueEnd, 24);
                    ogg.BitWrite(residuePartitionSize, 24);
                    ogg.BitWrite(residueClassifications, 6);
                    ogg.BitWrite(residueClassbook, 8);
                    residueClassifications++;
                    if (residueClassbook >= codebookCount)
                    {
                        throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                    }
                    uint[] residueCascade = new uint[residueClassifications];
                    for (int j = 0; j < residueClassifications; j++)
                    {
                        byte highBits = 0;
                        byte lowBits  = (byte)bitStream.Read(3);
                        ogg.BitWrite(lowBits, 3);
                        byte bitFlag = (byte)bitStream.Read(1);
                        ogg.WriteBit(bitFlag);
                        if (bitFlag == 1)
                        {
                            highBits = (byte)bitStream.Read(5);
                            ogg.BitWrite(highBits, 5);
                        }
                        residueCascade[j] = highBits * 8U + lowBits;
                    }
                    for (int j = 0; j < residueClassifications; j++)
                    {
                        for (int k = 0; k < 8; k++)
                        {
                            if ((residueCascade[j] & (1 << k)) != 0)
                            {
                                byte residueBook = (byte)bitStream.Read(8);
                                ogg.BitWrite(residueBook);
                                if (residueBook >= codebookCount)
                                {
                                    throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                                }
                            }
                        }
                    }
                }
                byte mappingCount = (byte)bitStream.Read(6);
                ogg.BitWrite(mappingCount, 6);
                mappingCount++;
                for (int i = 0; i < mappingCount; i++)
                {
                    ushort mappingType = 0;
                    ogg.BitWrite(mappingType);
                    byte submapsFlag = (byte)bitStream.Read(1);
                    ogg.WriteBit(submapsFlag);
                    uint submaps = 1;
                    if (submapsFlag == 1)
                    {
                        byte submapsLess = (byte)bitStream.Read(4);
                        submaps = submapsLess + 1U;
                        ogg.BitWrite(submapsLess, 4);
                    }
                    byte squarePolarFlag = (byte)bitStream.Read(1);
                    ogg.WriteBit(squarePolarFlag);
                    if (squarePolarFlag == 1)
                    {
                        byte couplingSteps = (byte)bitStream.Read(8);
                        ogg.BitWrite(couplingSteps);
                        couplingSteps++;
                        for (int j = 0; j < couplingSteps; j++)
                        {
                            uint magnitude = bitStream.Read((int)ILog(this.Channels - 1U));
                            uint angle     = bitStream.Read((int)ILog(this.Channels - 1U));
                            ogg.BitWrite(magnitude, (byte)ILog(this.Channels - 1U));
                            ogg.BitWrite(angle, (byte)ILog(this.Channels - 1U));
                            if (angle == magnitude || magnitude >= this.Channels || angle >= this.Channels)
                            {
                                throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                            }
                        }
                    }
                    byte mappingReserved = (byte)bitStream.Read(2);
                    ogg.BitWrite(mappingReserved, 2);
                    if (mappingReserved != 0)
                    {
                        throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                    }
                    if (submaps > 1)
                    {
                        for (int j = 0; j < this.Channels; j++)
                        {
                            byte mappingMux = (byte)bitStream.Read(4);
                            ogg.BitWrite(mappingMux, 4);
                            if (mappingMux >= submaps)
                            {
                                throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                            }
                        }
                    }
                    for (int j = 0; j < submaps; j++)
                    {
                        byte timeConfig = (byte)bitStream.Read(8);
                        ogg.BitWrite(timeConfig);
                        byte floorNumber = (byte)bitStream.Read(8);
                        ogg.BitWrite(floorNumber);
                        if (floorNumber >= floorCount)
                        {
                            throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                        }
                        byte residueNumber = (byte)bitStream.Read(8);
                        ogg.BitWrite(residueNumber);
                        if (residueNumber >= residueCount)
                        {
                            throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                        }
                    }
                }
                byte modeCount = (byte)bitStream.Read(6);
                ogg.BitWrite(modeCount, 6);
                modeCount++;
                modeBlockFlag = new bool[modeCount];
                modeBits      = ILog(modeCount - 1U);
                for (int i = 0; i < modeCount; i++)
                {
                    byte blockFlag = (byte)bitStream.Read(1);
                    ogg.WriteBit(blockFlag);
                    modeBlockFlag[i] = blockFlag == 1;
                    ushort windowType    = 0;
                    ushort transformType = 0;
                    ogg.BitWrite(windowType);
                    ogg.BitWrite(transformType);
                    byte mapping = (byte)bitStream.Read(8);
                    ogg.BitWrite(mapping, 8);
                    if (mapping >= mappingCount)
                    {
                        throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                    }
                }
                ogg.WriteBit(1);
            }
            ogg.FlushPage();
            if ((bitStream.TotalBitsRead + 7) / 8 != setupPacket.GetSize())
            {
                throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
            }
            if (setupPacket.NextOffset() != this._dataChunkOffset + this._firstAudioPacketOffset)
            {
                throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
            }
        }
Exemple #6
0
        private void GenerateOGGHeaderTriad(OggStream ogg)
        {
            uint    offset                = this._dataChunkOffset + this._setupPacketOffset;
            Packet8 informationPacket     = new Packet8(this._wemFile, offset);
            uint    informationPacketSize = informationPacket.GetSize();

            if (informationPacket.GetGranule() != 0)
            {
                throw new Exception("ヘッダーの生成中にエラーが発生しました。");
            }
            this._wemFile.Seek(informationPacket.GetOffset(), SeekOrigin.Begin);
            byte[] informationPacketType = new byte[1];
            this._wemFile.Read(informationPacketType, 0, 1);
            if (informationPacketType[0] != 1)
            {
                throw new Exception("ヘッダーの生成中にエラーが発生しました。");
            }
            ogg.BitWrite(informationPacketType[0]);
            byte[] b = new byte[1];
            for (int i = 0; i < informationPacketSize; i++)
            {
                this._wemFile.Read(b, 0, 1);
                ogg.BitWrite(b[0]);
            }
            ogg.FlushPage();
            offset = informationPacket.NextOffset();
            Packet8 commentPacket     = new Packet8(this._wemFile, offset);
            uint    commentPacketSize = commentPacket.GetSize();

            if (commentPacket.GetGranule() != 0)
            {
                throw new Exception("ヘッダーの生成中にエラーが発生しました。");
            }
            this._wemFile.Seek(commentPacket.GetOffset(), SeekOrigin.Begin);
            byte[] commentPacketType = new byte[1];
            this._wemFile.Read(commentPacketType, 0, 1);
            if (commentPacketType[0] != 3)
            {
                throw new Exception("ヘッダーの生成中にエラーが発生しました。");
            }
            ogg.BitWrite(commentPacketType[0]);
            byte[] c = new byte[1];
            for (int i = 0; i < commentPacketSize; i++)
            {
                this._wemFile.Read(c, 0, 1);
                ogg.BitWrite(c[0]);
            }
            ogg.FlushPage();
            offset = commentPacket.NextOffset();
            Packet8 setupPacket = new Packet8(this._wemFile, offset);

            this._wemFile.Seek(setupPacket.GetOffset(), SeekOrigin.Begin);
            if (setupPacket.GetGranule() != 0)
            {
                throw new Exception("ヘッダーの生成中にエラーが発生しました。");
            }
            BitStream bitStream       = new BitStream(this._wemFile);
            byte      setupPacketType = (byte)bitStream.Read(8);

            if (setupPacketType != 5)
            {
                throw new Exception("ヘッダーの生成中にエラーが発生しました。");
            }
            ogg.BitWrite(setupPacketType);
            for (int i = 0; i < 6; i++)
            {
                ogg.BitWrite((byte)bitStream.Read(8));
            }
            byte codebookCount = (byte)bitStream.Read(8);

            ogg.BitWrite(codebookCount);
            codebookCount++;
            CodebookLibrary codebook = new CodebookLibrary();

            for (int i = 0; i < codebookCount; i++)
            {
                codebook.Copy(bitStream, ogg);
            }
            while (bitStream.TotalBitsRead < setupPacket.GetSize() * 8)
            {
                ogg.WriteBit((byte)bitStream.Read(1));
            }
            ogg.FlushPage();
            offset = setupPacket.NextOffset();
            if (offset != this._dataChunkOffset + this._firstAudioPacketOffset)
            {
                throw new Exception("ヘッダーの生成中にエラーが発生しました。");
            }
        }
Exemple #7
0
 public void GenerateOGG(string fileLocation, string codebooksLocation, bool inlineCodebooks, bool fullSetup)
 {
     if (inlineCodebooks && string.IsNullOrEmpty(codebooksLocation))
     {
         throw new ArgumentException("コードブックが複数設定されています。");
     }
     else if (!inlineCodebooks && string.IsNullOrEmpty(codebooksLocation))
     {
         throw new ArgumentException("コードブックが設定されていません。");
     }
     using (OggStream ogg = new OggStream(File.Create(fileLocation)))
     {
         bool[] modeBlockFlag     = null;
         uint   modeBits          = 0;
         bool   previousBlockFlag = false;
         if (this._headerTriadPresent)
         {
             GenerateOGGHeaderTriad(ogg);
         }
         else
         {
             GenerateOGGHeader(ogg, codebooksLocation, inlineCodebooks, fullSetup, ref modeBlockFlag, ref modeBits);
         }
         uint offset = this._dataChunkOffset + this._firstAudioPacketOffset;
         while (offset < this._dataChunkOffset + this._dataChunkSize)
         {
             uint size;
             uint granule;
             uint packetHeaderSize;
             uint packetPayloadOffset;
             uint nextOffset;
             if (this._oldPacketHeaders)
             {
                 Packet8 audioPacket = new Packet8(this._wemFile, offset);
                 packetHeaderSize    = audioPacket.GetHeaderSize();
                 size                = audioPacket.GetSize();
                 packetPayloadOffset = audioPacket.GetOffset();
                 granule             = audioPacket.GetGranule();
                 nextOffset          = audioPacket.NextOffset();
             }
             else
             {
                 Packet audioPacket = new Packet(this._wemFile, offset, this._noGranule);
                 packetHeaderSize    = audioPacket.GetHeaderSize();
                 size                = audioPacket.GetSize();
                 packetPayloadOffset = audioPacket.GetOffset();
                 granule             = audioPacket.GetGranule();
                 nextOffset          = audioPacket.NextOffset();
             }
             if (offset + packetHeaderSize > this._dataChunkOffset + this._dataChunkSize)
             {
                 throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
             }
             offset = packetPayloadOffset;
             this._wemFile.Seek(offset, SeekOrigin.Begin);
             if (granule == 0xFFFFFFFF)
             {
                 ogg.SetGranule(1);
             }
             else
             {
                 ogg.SetGranule(granule);
             }
             if (this._modPackets)
             {
                 if (modeBlockFlag == null)
                 {
                     throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                 }
                 byte packetType = 0;
                 ogg.WriteBit(packetType);
                 uint modeNumber = 0;
                 uint remainder  = 0;
                 {
                     BitStream bitStream = new BitStream(this._wemFile);
                     modeNumber = bitStream.Read((int)modeBits);
                     ogg.BitWrite(modeNumber, (byte)modeBits);
                     remainder = bitStream.Read(8 - (int)modeBits);
                 }
                 if (modeBlockFlag[modeNumber])
                 {
                     this._wemFile.Seek(nextOffset, SeekOrigin.Begin);
                     bool nextBlockFlag = false;
                     if (nextOffset + packetHeaderSize <= this._dataChunkOffset + this._dataChunkSize)
                     {
                         Packet audioPacket    = new Packet(this._wemFile, nextOffset, this._noGranule);
                         uint   nextPacketSize = audioPacket.GetSize();
                         if (nextPacketSize != 0xFFFFFFFF)
                         {
                             this._wemFile.Seek(audioPacket.GetOffset(), SeekOrigin.Begin);
                             BitStream bitStream      = new BitStream(this._wemFile);
                             uint      nextModeNumber = bitStream.Read((int)modeBits);
                             nextBlockFlag = modeBlockFlag[nextModeNumber];
                         }
                     }
                     byte previousWindowType = previousBlockFlag ? (byte)1 : (byte)0;
                     ogg.WriteBit(previousWindowType);
                     byte nextWindowType = previousBlockFlag ? (byte)1 : (byte)0;
                     ogg.WriteBit(nextWindowType);
                     this._wemFile.Seek(offset + 1, SeekOrigin.Begin);
                 }
                 previousBlockFlag = modeBlockFlag[modeNumber];
                 ogg.BitWrite(remainder, (byte)(8 - modeBits));
             }
             else
             {
                 int b = this._wemFile.ReadByte();
                 if (b < 0)
                 {
                     throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                 }
                 ogg.BitWrite((byte)b);
             }
             for (int i = 1; i < size; i++)
             {
                 int b = this._wemFile.ReadByte();
                 if (b < 0)
                 {
                     throw new Exception("Vorbisパケットの生成中にエラーが発生しました。");
                 }
                 ogg.BitWrite((byte)b);
             }
             offset = nextOffset;
             ogg.FlushPage(false, (offset == this._dataChunkOffset + this._dataChunkSize));
         }
         if (offset > this._dataChunkOffset + this._dataChunkSize)
         {
             throw new Exception("OGGファイルを生成中にエラーが発生しました。");
         }
     }
 }
Exemple #8
0
        internal void Copy(BitStream bitStream, OggStream ogg)
        {
            //https://xiph.org/vorbis/doc/Vorbis_I_spec.pdf

            byte[] id = new byte[]
            {
                (byte)bitStream.Read(8),
                (byte)bitStream.Read(8),
                (byte)bitStream.Read(8)
            };

            ushort dimensions = (ushort)bitStream.Read(16);
            uint   entries    = bitStream.Read(24);

            if (id[0] != 0x42 || id[1] != 0x43 || id[2] != 0x56)
            {
                throw new Exception("Invalid Codebook Sync Pattern");
            }

            ogg.BitWrite(id[0]);
            ogg.BitWrite(id[1]);
            ogg.BitWrite(id[2]);

            ogg.BitWrite(dimensions);
            ogg.BitWrite(entries, 24);

            byte orderedFlag = (byte)bitStream.Read(1);

            ogg.WriteBit(orderedFlag);
            if (orderedFlag == 1)
            {
                byte initialLength = (byte)bitStream.Read(5);
                ogg.BitWrite(initialLength, 5);

                uint currentEntry = 0;
                while (currentEntry < entries)
                {
                    uint bitCount = ILog(entries - currentEntry);
                    uint number   = bitStream.Read((int)bitCount);
                    ogg.BitWrite(number, (byte)bitCount);
                    currentEntry += number;
                }

                if (currentEntry > entries)
                {
                    throw new Exception("There was an error copying a codebook");
                }
            }
            else
            {
                byte sparseFlag = (byte)bitStream.Read(1);
                ogg.WriteBit(sparseFlag);

                for (int i = 0; i < entries; i++)
                {
                    bool presentBool = true;

                    if (sparseFlag == 1)
                    {
                        byte sparsePresenceFlag = (byte)bitStream.Read(1);
                        ogg.WriteBit(sparsePresenceFlag);

                        presentBool = sparsePresenceFlag == 1;
                    }
                    else
                    {
                        byte codewordLength = (byte)bitStream.Read(5);
                        ogg.BitWrite(codewordLength, 5);
                    }
                }
            }

            byte lookupType = (byte)bitStream.Read(4);

            ogg.BitWrite(lookupType, 4);
            if (lookupType == 1)
            {
                ogg.BitWrite(bitStream.Read(32));
                ogg.BitWrite(bitStream.Read(32));
                byte valueLength = (byte)bitStream.Read(4);
                ogg.BitWrite(valueLength, 4);
                ogg.WriteBit((byte)bitStream.Read(1));

                uint quantValues = QuantValues(entries, dimensions);
                for (int i = 0; i < quantValues; i++)
                {
                    uint value = bitStream.Read(valueLength + 1);
                    ogg.BitWrite(value, (byte)(valueLength + 1));
                }
            }
            else
            {
                throw new Exception("There was an error copying a codebook");
            }
        }