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("ヘッダーの生成中にエラーが発生しました。"); } }
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ファイルを生成中にエラーが発生しました。"); } } }