private IEnumerable <IEvent> GetMeasureEvents(BmsCommand command, IDictionary <int, BigRational> bpmMap) { var measure = Alphabet.DecodeNumeric(command.Name.AsSpan(0, 3)); var lane = Alphabet.DecodeHex(command.Name.AsSpan(3, 2)); switch (lane) { case 0x02: { return(new[] { new Event { [NumericData.MeasureLength] = BigRationalParser.ParseString(command.Value), [NumericData.MetricOffset] = measure } }); } } var events = new List <Event>(); var total = command.Value.Length / 2; for (var index = 0; index < total; index++) { var valueMemory = command.Value.AsMemory(index << 1, 2); var value = valueMemory.Span; if (value[0] == '0' && value[1] == '0') { continue; } void AddEvent(Event ev) { ev[NumericData.MetricOffset] = new BigRational(new BigInteger(measure), new BigInteger(index), new BigInteger(total)); ev[NumericData.SourceData] = Alphabet.DecodeAlphanumeric(valueMemory.Span); ev[NumericData.SourceCommand] = lane; events.Add(ev); } switch (lane) { case 0x01: { AddEvent(new Event { [NumericData.PlaySound] = Alphabet.DecodeAlphanumeric(value) }); break; } case 0x03: { AddEvent(new Event { [NumericData.Bpm] = Alphabet.DecodeHex(value) }); break; } case 0x04: { AddEvent(new Event { [NumericData.BgaBase] = Alphabet.DecodeAlphanumeric(value) }); break; } case 0x05: { AddEvent(new Event { [NumericData.BgaObject] = Alphabet.DecodeAlphanumeric(value) }); break; } case 0x06: { AddEvent(new Event { [NumericData.BgaPoor] = Alphabet.DecodeAlphanumeric(value) }); break; } case 0x07: { AddEvent(new Event { [NumericData.BgaLayer] = Alphabet.DecodeAlphanumeric(value) }); break; } case 0x08: { var number = Alphabet.DecodeAlphanumeric(value); if (bpmMap.ContainsKey(number)) { AddEvent(new Event { [NumericData.Bpm] = bpmMap[number] }); } break; } case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: { AddEvent(new Event { [NumericData.Player] = (lane & 0x20) >> 5, [FlagData.Note] = true, [NumericData.Column] = lane & 0x0F }); break; } case 0x18: case 0x19: case 0x28: case 0x29: { AddEvent(new Event { [NumericData.Player] = (lane & 0x20) >> 5, [FlagData.Note] = true, [NumericData.Column] = (lane & 0x0F) - 2 }); break; } case 0x16: case 0x26: { AddEvent(new Event { [NumericData.Player] = (lane & 0x20) >> 5, [FlagData.Scratch] = true, [FlagData.Note] = true }); break; } case 0x17: case 0x27: { AddEvent(new Event { [NumericData.Player] = (lane & 0x20) >> 5, [FlagData.FreeZone] = true, [FlagData.Note] = true }); break; } case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: { AddEvent(new Event { [NumericData.Player] = (lane & 0x20) >> 5, [NumericData.Column] = lane & 0x0F, [NumericData.LoadSound] = Alphabet.DecodeAlphanumeric(value) }); break; } case 0x38: case 0x39: case 0x48: case 0x49: { AddEvent(new Event { [NumericData.Player] = (lane & 0x20) >> 5, [NumericData.Column] = (lane & 0x0F) - 2, [NumericData.LoadSound] = Alphabet.DecodeAlphanumeric(value) }); break; } case 0x36: case 0x37: case 0x46: case 0x47: { AddEvent(new Event { [NumericData.Player] = (lane & 0x20) >> 5, [FlagData.Scratch] = true, [NumericData.LoadSound] = Alphabet.DecodeAlphanumeric(value) }); break; } } } return(events); }