public override void Read(BinaryReader reader, Resource resource) { // NTRO only in version 0? if (resource.IntrospectionManifest == null) { var block = new Blocks.ResourceIntrospectionManifest.ResourceDiskStruct(); var field = new Blocks.ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_bitpackedsoundinfo", Type = DataType.UInt32 }; block.FieldIntrospection.Add(field); field = new Blocks.ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_loopStart", Type = DataType.Int32, OnDiskOffset = 4, }; block.FieldIntrospection.Add(field); field = new Blocks.ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_flDuration", Type = DataType.Float, OnDiskOffset = 12, }; block.FieldIntrospection.Add(field); resource.Blocks[BlockType.NTRO] = new Blocks.ResourceIntrospectionManifest(); resource.IntrospectionManifest.ReferencedStructs.Add(block); } reader.BaseStream.Position = Offset; base.Read(reader, resource); LoopStart = ((NTROSerialization.NTROValue <int>)Output["m_loopStart"]).Value; Duration = ((NTROSerialization.NTROValue <float>)Output["m_flDuration"]).Value; var bitpackedSoundInfo = ((NTROSerialization.NTROValue <uint>)Output["m_bitpackedsoundinfo"]).Value; Type = (AudioFileType)ExtractSub(bitpackedSoundInfo, 0, 2); Bits = ExtractSub(bitpackedSoundInfo, 2, 5); Channels = ExtractSub(bitpackedSoundInfo, 7, 2); SampleSize = ExtractSub(bitpackedSoundInfo, 9, 3); AudioFormat = ExtractSub(bitpackedSoundInfo, 12, 2); SampleRate = ExtractSub(bitpackedSoundInfo, 14, 17); if (Type != AudioFileType.MP3 && Type != AudioFileType.WAV) { throw new NotImplementedException($"Unknown audio file format '{Type}', please report this on GitHub."); } }
private const int SIGNATURE = 55987030; // "VKV\x03" aka valve keyvalue, version 3 public override void Read(BinaryReader reader, Resource resource) { if (resource.IntrospectionManifest == null) { var block = new Blocks.ResourceIntrospectionManifest.ResourceDiskStruct(); var field = new Blocks.ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_Signature", Count = 1, Type = DataType.Int32 }; block.FieldIntrospection.Add(field); field = new Blocks.ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_Encoding", Count = 4, OnDiskOffset = 4, Type = DataType.Boolean }; block.FieldIntrospection.Add(field); field = new Blocks.ResourceIntrospectionManifest.ResourceDiskStruct.Field { FieldName = "m_Format", Count = 4, OnDiskOffset = 20, Type = DataType.Boolean }; block.FieldIntrospection.Add(field); resource.IntrospectionManifest = new Blocks.ResourceIntrospectionManifest(); resource.IntrospectionManifest.ReferencedStructs.Add(block); } base.Read(reader, resource); reader.BaseStream.Position = Offset; // TODO: Use parsed NTRO data if (reader.ReadUInt32() != SIGNATURE) { throw new InvalidDataException("Wrong signature."); } reader.BaseStream.Position += 32; // encoding + format (guids?) // TODO }