public void Flush(Stream stream) { int paketPos = 0; var dataLen = _packets.Sum(p => p.PacketData.Length); while (_packets.Count > 0) { int segmentsCount = Math.Max((dataLen / 255) + 1, _packets.Count); int segmentPerPage = segmentsCount > 255 ? 255 : segmentsCount; var oggsHeader = new OggsHeader(PageNo, SerialNo, CreateSegmentalTable(segmentPerPage), _packets[0].Granulepos, paketPos != 0, Bos == 0, Eos && segmentPerPage == segmentsCount); Bos = 1; PageNo++; // set pointers in the ogg_page struct var og = new Page { header = oggsHeader, header_len = oggsHeader.Data.Length, body_len = oggsHeader.SegmentTableSum }; og.body = new byte[og.body_len]; int saved = 0; while (saved < og.body_len) { var savingPaket = _packets.First(); var copyLen = Math.Min(og.body_len - saved, savingPaket.PacketData.Length); Array.Copy(savingPaket.PacketData, paketPos, og.body, saved, copyLen); dataLen -= copyLen; if (copyLen == savingPaket.PacketData.Length) { _packets.Remove(savingPaket); } else { #if DEBUG if (saved + copyLen != og.body_len) { throw new ArithmeticException(); } #endif paketPos = savingPaket.PacketData.Length - copyLen; } saved += copyLen; og.header.GranulePosition = savingPaket.Granulepos; } ogg_page_checksum_set(og); og.Write(stream); } _totalBits = 0; }
private void SetPageCheckSum(Page og) { UInt32 crcReg = 0; /* safety; needed for API behavior, but not framing code */ og.Header.CrcChecksum = 0; for (int i = 0; i < og.HeaderLen; i++) { crcReg = (crcReg << 8) ^ _crcLookup[((crcReg >> 24) & 0xff) ^ og.Header.Data[i]]; } for (int i = 0; i < og.BodyLen; i++) { crcReg = (crcReg << 8) ^ _crcLookup[((crcReg >> 24) & 0xff) ^ og.Body[i]]; } og.Header.CrcChecksum = crcReg; }
private Page GetPage(ref int unsavedPaketIndex) { int savedPacketCount; int unsavedCount; var table = CreateSegmentalTable(unsavedPaketIndex, out savedPacketCount, out unsavedCount); var oggsHeader = new OggsHeader(_pageNo, SerialNo, table, _packets[savedPacketCount - 1].GranulePos, unsavedPaketIndex != 0, _bos == 0, Eos && savedPacketCount == _packets.Count); _bos = 1; _pageNo++; //set pointers in the ogg_page struct var og = new Page { Header = oggsHeader, HeaderLen = oggsHeader.Data.Length, BodyLen = oggsHeader.SegmentTableSum, Body = new byte[oggsHeader.SegmentTableSum] }; int saved = 0; var savingPaket = _packets.FirstOrDefault(); foreach (var count in table) { Array.Copy(savingPaket.PacketData, unsavedPaketIndex, og.Body, saved, count); saved += count; if (count == savingPaket.PacketDataLength - unsavedPaketIndex) { _packets.Remove(savingPaket); unsavedPaketIndex = 0; savedPacketCount--; savingPaket = _packets.FirstOrDefault(); } else { unsavedPaketIndex += count; } _totalBits -= count; } SetPageCheckSum(og); return og; }
private void ogg_page_checksum_set(Page og) { UInt32 crcReg = 0; /* safety; needed for API behavior, but not framing code */ og.header.CrcChecksum = 0; for (int i = 0; i < og.header_len; i++) { crcReg = (crcReg << 8) ^ Presets.Presets.CrcLookup[((crcReg >> 24) & 0xff) ^ og.header.Data[i]]; } for (int i = 0; i < og.body_len; i++) { crcReg = (crcReg << 8) ^ Presets.Presets.CrcLookup[((crcReg >> 24) & 0xff) ^ og.body[i]]; } og.header.CrcChecksum = crcReg; }