public MOD(Data.Buffer data) { data.SetEndianess(Endian.Endianess.Big); Log.Info.Write(ErrorSystemType.Data, $"Loading MOD song: {System.Text.Encoding.ASCII.GetString(data.Pop(20).ReinterpretAsArray(20))}"); // songname // add dummy sample 0 samples.Add(new Sample()); for (int i = 1; i < 32; ++i) // samples 1-31 { Log.Info.Write(ErrorSystemType.Data, $"Sample {i} name: {System.Text.Encoding.ASCII.GetString(data.Pop(22).ReinterpretAsArray(22))}"); // samplename samples.Add(new Sample() { Length = data.Pop <UInt16>() * 2, FineTune = ConvertFineTune(data.Pop <byte>() & 0xf), Volume = data.Pop <byte>(), // 0-64, change in dB = 20*log10(Volume/64) RepeatPointOffset = data.Pop <UInt16>() * 2, RepeatLength = Math.Max(0, data.Pop <UInt16>() - 1) * 2 }); } int songLength = data.Pop <byte>(); if (songLength < 1 || songLength > 128) { throw new ExceptionAudio("Invalid MOD format."); } data.Skip(1); byte[] songPatterns = data.Pop(128).ReinterpretAsArray(128); var magic = data.Pop(4).ToString(); if (magic != "M!K!" && magic != "M.K.") { throw new ExceptionAudio("Invalid or unsupported MOD format."); } int numPatterns = songPatterns.Max() + 1; List <Pattern> patterns = new List <Pattern>(numPatterns); for (int i = 0; i < numPatterns; ++i) { var pattern = new Pattern(); for (int div = 0; div < 64; ++div) { for (int chan = 0; chan < 4; ++chan) { pattern.AddNote(chan, new Note(data)); } } patterns.Add(pattern); } for (int i = 0; i < samples.Count; ++i) { if (samples[i].Length > 0) { data.Skip(2); // ignore tracker word samples[i].Length -= 2; uint length = (uint)samples[i].Length; if (length > 0) { samples[i].SetData(data.Pop(length).ReinterpretAsArray(length)); } } } for (int i = 0; i < songLength; ++i) { song.Add(patterns[songPatterns[i]]); } }