/// <summary> /// Unpacks next section of the compressed replay /// </summary> /// <param name="length">The length of the section</param> /// <returns>The decoded data</returns> protected byte[] UnpackNextSection(int length) { byte[] result = new byte[length]; Decoder decoder = new Decoder(); DecodeBuffer buffer = new DecodeBuffer(result); decoder.DecodeBuffer = buffer; int checksum = _reader.ReadInt32(); int blocks = _reader.ReadInt32(); for (int block = 0; block < blocks; block++) { // read the length of the next block of encoded data int encodedLength = _reader.ReadInt32(); // we error if there is no space for the next block of encoded data if (encodedLength > result.Length - buffer.ResultOffset) { throw new Exception("Insufficient space in decode buffer"); } // read the block of encoded data into the result (decoded data will overwrite). _reader.Read(result, buffer.ResultOffset, encodedLength); // skip decoding if the encoded data filled the remaining space if (encodedLength == Math.Min(result.Length - buffer.ResultOffset, buffer.BufferLength)) { continue; } // set the decode buffer parameters buffer.EncodedOffset = 0; buffer.DecodedLength = 0; buffer.EncodedLength = encodedLength; // decode the block if (decoder.DecodeBlock() != 0) { throw new Exception("Error decoding block offset " + block); } // sanity check the decoded length if (buffer.DecodedLength == 0 || buffer.DecodedLength > buffer.BufferLength || buffer.DecodedLength > result.Length) { throw new Exception("Decode data length mismatch"); } // flush the decoded bytes into the result buffer.WriteDecodedBytes(); } return result; }
public static IEnumerable<StereoShortSoundSample> DecodeBlocksStream(Block[] Blocks) { var DecodedBlock = new short[28]; var Decoder = new Decoder(); int SamplesOffset = 0; bool Ended = false; var LastSample = default(StereoShortSoundSample); var CurrentSample = default(StereoShortSoundSample); for (int n = 0; !Ended && (n < Blocks.Length); n++) { var CurrentBlock = Blocks[n]; SamplesOffset = 0; Decoder.DecodeBlock(CurrentBlock, DecodedBlock, ref SamplesOffset); switch (CurrentBlock.Type) { case Block.TypeEnum.None: // 16 bytes = 56 stereo 44100 samples foreach (var DecodedMonoSample in DecodedBlock) { CurrentSample = new StereoShortSoundSample(DecodedMonoSample, DecodedMonoSample); yield return StereoShortSoundSample.Mix(LastSample, CurrentSample); yield return CurrentSample; LastSample = CurrentSample; } break; case Block.TypeEnum.End: Ended = true; break; } } }
public static short[] DecodeBlocks(Block* Blocks, int BlockCount) { var Data = new short[28 * BlockCount]; var Decoder = new Decoder(); int SamplesOffset = 0; for (int n = 0; n < BlockCount; n++) { if (Decoder.DecodeBlock(Blocks[n], Data, ref SamplesOffset)) { //Console.WriteLine("STOP: {0}/{1}", n, BlockCount); Data = Data.Slice(0, SamplesOffset); break; } } return Data; }