SoundInput RebuildVorbis(Sample sample) { if (!sample.MetaData.ContainsKey(ChunkType.VorbisData)) { throw new InvalidFormatException("No VORBISDATA chunk in FSB5 Vorbis stream."); } var vorbis_data = sample.MetaData[ChunkType.VorbisData] as VorbisData; var setup_data = GetVorbisHeader(vorbis_data.Crc32); var state = new OggStreamState(1); var id_packet = RebuildIdPacket(sample, 0x100, 0x800); var comment_packet = RebuildCommentPacket(); var setup_packet = RebuildSetupPacket(setup_data); var info = CreateVorbisInfo(sample, setup_packet); var output = new MemoryStream(); state.PacketIn(id_packet); state.Write(output); state.PacketIn(comment_packet); state.Write(output); state.PacketIn(setup_packet); state.Write(output); state.Flush(output); long packet_no = setup_packet.PacketNo + 1; long granule_pos = 0; int prev_block_size = 0; using (var input = new BinMemoryStream(sample.Data)) { var packet = new OggPacket(); int packet_size = ReadPacketSize(input); while (packet_size > 0) { packet.SetPacket(packet_no++, input.ReadBytes(packet_size)); packet_size = ReadPacketSize(input); packet.EoS = 0 == packet_size; int block_size = info.PacketBlockSize(packet); if (prev_block_size != 0) { granule_pos += (block_size + prev_block_size) / 4; } else { granule_pos = 0; } packet.GranulePos = granule_pos; prev_block_size = block_size; state.PacketIn(packet); state.Write(output); } } output.Position = 0; return(new OggInput(output)); }
public void WriteHeaders(OggStreamState oggStreamState, VorbisComment comment) { ogg_packet header = new ogg_packet(); ogg_packet header_comm = new ogg_packet(); ogg_packet header_code = new ogg_packet(); OggPage page = new OggPage(); Errors.CheckVorbisError(NativeMethods.vorbis_analysis_headerout(ref InternalStruct, ref comment.InternalStruct, ref header, ref header_comm, ref header_code)); Errors.CheckOggError(NativeMethods.ogg_stream_packetin(ref oggStreamState.InternalStruct, ref header)); // automatically placed in its own page Errors.CheckOggError(NativeMethods.ogg_stream_packetin(ref oggStreamState.InternalStruct, ref header_comm)); Errors.CheckOggError(NativeMethods.ogg_stream_packetin(ref oggStreamState.InternalStruct, ref header_code)); }
public void Encode(OggStreamState oggStreamState, VorbisBlock block, Stream stream) { OggPacket packet = new OggPacket(); OggPage page = new OggPage(); /* vorbis does some data preanalysis, then divvies up blocks for * more involved (potentially parallel) processing. Get a single * block for encoding now */ while (BlockOut(block)) { /* analysis, assume we want to use bitrate management */ block.Analyze(); block.BitrateAddBlock(); while (BitrateFlushPacket(packet) != 0) { /* weld the packet into the bitstream */ NativeMethods.ogg_stream_packetin(ref oggStreamState.InternalStruct, ref packet.InternalStruct); /* write out pages (if any) */ bool eos = false; while (!eos) { int result = NativeMethods.ogg_stream_pageout(ref oggStreamState.InternalStruct, ref og); if (result == 0) { break; } page.Write(stream); /* this could be set above, but for illustrative purposes, I do * it here (to show that vorbis does know where the stream ends) */ if (xm.ogg_page_eos(ref page.InternalStruct) != 0) { eos = true; } } } } }