public Metadata(byte[] array)
        {
            ArraySize = array.Length;

            NumOfSamples = ArraySize - DataStartIndex;

            var numOfChannelsArray = array.SubArray(NumOfChannels.StartIndex, NumOfChannels.Length);

            NumOfChannels = new NumOfChannels(Converters.ConvertToUShort(numOfChannelsArray));

            var sampleRateArray = array.SubArray(SampleRate.StartIndex, SampleRate.Length);

            SampleRate = new SampleRate(Converters.ConvertToUInt(sampleRateArray));

            var bitsPerSampleArray = array.SubArray(BitsPerSample.StartIndex, BitsPerSample.Length);

            BitsPerSample = new BitsPerSample(Converters.ConvertToUShort(bitsPerSampleArray));

            var          chunkIdArray         = array.SubArray(ChunkId.StartIndex, ChunkId.Length);
            const string chunkIdExpectedValue = "RIFF";

            ChunkId = new ChunkId(Converters.ConvertToString(chunkIdArray), chunkIdExpectedValue);

            var chunkSizeArray         = array.SubArray(ChunkSize.StartIndex, ChunkSize.Length);
            var chunkSizeExpectedValue = ArraySize - 8;

            ChunkSize = new ChunkSize(Converters.ConvertToUInt(chunkSizeArray), (uint)chunkSizeExpectedValue);

            var          formatArray = array.SubArray(Format.StartIndex, Format.Length);
            const string formatArrayExpectedValue = "WAVE";

            Format = new Format(Converters.ConvertToString(formatArray), formatArrayExpectedValue);

            var          subChunk1IdArray         = array.SubArray(SubChunk1Id.StartIndex, SubChunk1Id.Length);
            const string subChunk1IdExpectedValue = "fmt ";

            SubChunk1Id = new SubChunk1Id(Converters.ConvertToString(subChunk1IdArray), subChunk1IdExpectedValue);

            var subChunk1SizeArray = array.SubArray(SubChunk1Size.StartIndex, SubChunk1Size.Length);

            SubChunk1Size = new SubChunk1Size(Converters.ConvertToUInt(subChunk1SizeArray));

            var audioFormatArray = array.SubArray(AudioFormat.StartIndex, AudioFormat.Length);

            AudioFormat = new AudioFormat(Converters.ConvertToUShort(audioFormatArray));

            var  byteRateArray         = array.SubArray(ByteRate.StartIndex, ByteRate.Length);
            uint byteRateExpectedValue = SampleRate.Value * NumOfChannels.Value * BitsPerSample.Value / 8;

            ByteRate = new ByteRate(Converters.ConvertToUInt(byteRateArray), byteRateExpectedValue);

            var blockAlignArray         = array.SubArray(BlockAlign.StartIndex, BlockAlign.Length);
            var blockAlignExpectedValue = NumOfChannels.Value * BitsPerSample.Value / 8;

            BlockAlign = new BlockAlign(Converters.ConvertToUShort(blockAlignArray), (ushort)blockAlignExpectedValue);

            var subChunk2IdArray = array.SubArray(SubChunk2Id.StartIndex, SubChunk2Id.Length);

            SubChunk2Id = new SubChunk2Id(Converters.ConvertToString(subChunk2IdArray));

            var subChunk2SizeArray         = array.SubArray(SubChunk2Size.StartIndex, SubChunk2Size.Length);
            var subChunk2SizeExpectedValue = ArraySize - SubChunk2Size.StartIndex - SubChunk2Size.Length;

            SubChunk2Size = new SubChunk2Size(Converters.ConvertToUInt(subChunk2SizeArray), (uint)subChunk2SizeExpectedValue);

            DataStartIndex = GetDataStartIndex(array);

            //https://www.recordingblogs.com/wiki/list-chunk-of-a-wave-file
            var listOfKeys = new List <string>
            {
                "IARL", "IART", "ICMS", "ICMT", "ICOP",
                "ICRD", "ICRP", "IDIM", "IDPI", "IENG",
                "IGNR", "IKEY", "ILGT", "IMED", "INAM",
                "IPLT", "IPRD", "ISBJ", "ISFT", "ISRC",
                "ISRF", "ITCH"
            };
            var dictionary = PopulateInfo(listOfKeys, array);

            Info = new ReadOnlyDictionary <string, string>(dictionary);
        }