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