void Preload() { while (true) { VocBlock block = new VocBlock(); try { block.Code = stream.ReadByte(); block.Length = 0; } catch (EndOfStreamException) { // Stream is allowed to end without a last block break; } if (block.Code == 0 || block.Code > 9) { break; } block.Length = stream.ReadByte(); block.Length |= stream.ReadByte() << 8; block.Length |= stream.ReadByte() << 16; var skip = 0; switch (block.Code) { // Sound data case 1: { if (block.Length < 2) { throw new InvalidDataException("Invalid sound data block length in voc file"); } var freqDiv = stream.ReadByte(); block.SampleBlock.Rate = GetSampleRateFromVocRate(freqDiv); var codec = stream.ReadByte(); if (codec != 0) { throw new InvalidDataException("Unhandled codec used in voc file"); } skip = block.Length - 2; block.SampleBlock.Samples = skip; block.SampleBlock.Offset = stream.Position; // See if last block contained additional information if (blocks.Count > 0) { var b = blocks.Last(); if (b.Code == 8) { block.SampleBlock.Rate = b.SampleBlock.Rate; blocks.Remove(b); } } SampleRate = Math.Max(SampleRate, block.SampleBlock.Rate); break; } // Silence case 3: { if (block.Length != 3) { throw new InvalidDataException("Invalid silence block length in voc file"); } block.SampleBlock.Offset = 0; block.SampleBlock.Samples = stream.ReadUInt16() + 1; var freqDiv = stream.ReadByte(); block.SampleBlock.Rate = GetSampleRateFromVocRate(freqDiv); break; } // Repeat start case 6: { if (block.Length != 2) { throw new InvalidDataException("Invalid repeat start block length in voc file"); } block.LoopBlock.Count = stream.ReadUInt16() + 1; break; } // Repeat end case 7: break; // Extra info case 8: { if (block.Length != 4) { throw new InvalidDataException("Invalid info block length in voc file"); } int freqDiv = stream.ReadUInt16(); if (freqDiv == 65536) { throw new InvalidDataException("Invalid frequency divisor 65536 in voc file"); } var codec = stream.ReadByte(); if (codec != 0) { throw new InvalidDataException("Unhandled codec used in voc file"); } var channels = stream.ReadByte() + 1; if (channels != 1) { throw new InvalidDataException("Unhandled number of channels in voc file"); } block.SampleBlock.Offset = 0; block.SampleBlock.Samples = 0; block.SampleBlock.Rate = (int)(256000000L / (65536L - freqDiv)); break; } // Sound data (New format) case 9: default: throw new InvalidDataException("Unhandled code in voc file"); } if (skip > 0) { stream.Seek(skip, SeekOrigin.Current); } blocks.Add(block); } // Check validity and calculated total number of samples foreach (var b in blocks) { if (b.Code == 8) { throw new InvalidDataException("Unused block 8 in voc file"); } if (b.Code != 1 && b.Code != 9) { continue; } if (b.SampleBlock.Rate != SampleRate) { throw new InvalidDataException("Voc file contains chunks with different sample rate"); } totalSamples += b.SampleBlock.Samples; } Rewind(); }
void Preload() { while (true) { VocBlock block = new VocBlock(); try { block.Code = stream.ReadByte(); block.Length = 0; } catch (EndOfStreamException) { // Stream is allowed to end without a last block break; } if (block.Code == 0 || block.Code > 9) break; block.Length = stream.ReadByte(); block.Length |= stream.ReadByte() << 8; block.Length |= stream.ReadByte() << 16; var skip = 0; switch (block.Code) { // Sound data case 1: { if (block.Length < 2) throw new InvalidDataException("Invalid sound data block length in voc file"); var freqDiv = stream.ReadByte(); block.SampleBlock.Rate = GetSampleRateFromVocRate(freqDiv); var codec = stream.ReadByte(); if (codec != 0) throw new InvalidDataException("Unhandled codec used in voc file"); skip = block.Length - 2; block.SampleBlock.Samples = skip; block.SampleBlock.Offset = stream.Position; // See if last block contained additional information if (blocks.Count > 0) { var b = blocks.Last(); if (b.Code == 8) { block.SampleBlock.Rate = b.SampleBlock.Rate; blocks.Remove(b); } } SampleRate = Math.Max(SampleRate, block.SampleBlock.Rate); break; } // Silence case 3: { if (block.Length != 3) throw new InvalidDataException("Invalid silence block length in voc file"); block.SampleBlock.Offset = 0; block.SampleBlock.Samples = stream.ReadUInt16() + 1; var freqDiv = stream.ReadByte(); block.SampleBlock.Rate = GetSampleRateFromVocRate(freqDiv); break; } // Repeat start case 6: { if (block.Length != 2) throw new InvalidDataException("Invalid repeat start block length in voc file"); block.LoopBlock.Count = stream.ReadUInt16() + 1; break; } // Repeat end case 7: break; // Extra info case 8: { if (block.Length != 4) throw new InvalidDataException("Invalid info block length in voc file"); int freqDiv = stream.ReadUInt16(); if (freqDiv == 65536) throw new InvalidDataException("Invalid frequency divisor 65536 in voc file"); var codec = stream.ReadByte(); if (codec != 0) throw new InvalidDataException("Unhandled codec used in voc file"); var channels = stream.ReadByte() + 1; if (channels != 1) throw new InvalidDataException("Unhandled number of channels in voc file"); block.SampleBlock.Offset = 0; block.SampleBlock.Samples = 0; block.SampleBlock.Rate = (int)(256000000L / (65536L - freqDiv)); break; } // Sound data (New format) case 9: default: throw new InvalidDataException("Unhandled code in voc file"); } if (skip > 0) stream.Seek(skip, SeekOrigin.Current); blocks.Add(block); } // Check validity and calculated total number of samples foreach (var b in blocks) { if (b.Code == 8) throw new InvalidDataException("Unused block 8 in voc file"); if (b.Code != 1 && b.Code != 9) continue; if (b.SampleBlock.Rate != SampleRate) throw new InvalidDataException("Voc file contains chunks with different sample rate"); totalSamples += b.SampleBlock.Samples; } Rewind(); }