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