Пример #1
0
        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();
        }
Пример #2
0
        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();
        }