Example #1
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パケットの生成中にエラーが発生しました。");
            }
        }
Example #2
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("ヘッダーの生成中にエラーが発生しました。");
            }
        }