public BarIndexCalculator(int barTick, IEnumerable <TimeSignatureChangeEvent> events, bool hasPaddingBar) { this.hasPaddingBar = hasPaddingBar; this.barTick = barTick; var ordered = events.OrderBy(p => p.Tick).ToList(); var dic = new SortedDictionary <int, TimeSignatureItem>(); int pos = 0; int barIndex = hasPaddingBar ? 1 : 0; for (int i = 0; i < ordered.Count; i++) { var item = new TimeSignatureItem() { StartTick = pos, StartBarIndex = barIndex, TimeSignature = ordered[i] }; // 時間逆順で追加 if (dic.ContainsKey(pos)) { dic[-pos] = item; } else { dic.Add(-pos, item); } if (i < ordered.Count - 1) { int barLength = barTick * ordered[i].Numerator / ordered[i].Denominator; int duration = ordered[i + 1].Tick - pos; pos += duration / barLength * barLength; barIndex += duration / barLength; } } timeSignatures = dic; }
/// <summary> /// TicksPerBeatと拍子変更イベントから<see cref="BarIndexCalculator"/>のインスタンスを初期化します。 /// </summary> /// <param name="ticksPerBeat">譜面のTicksPerBeat</param> /// <param name="sigs">拍子変更イベントを表す<see cref="TimeSignatureChangeEvent"/>のリスト</param> public BarIndexCalculator(int ticksPerBeat, IEnumerable <TimeSignatureChangeEvent> sigs) { TicksPerBeat = ticksPerBeat; var ordered = sigs.OrderBy(p => p.Tick).ToList(); var dic = new SortedDictionary <int, TimeSignatureItem>(); int pos = 0; int barIndex = 0; for (int i = 0; i < ordered.Count; i++) { // 小節先頭に配置されていないイベント if (pos != ordered[i].Tick) { throw new InvalidTimeSignatureException($"TimeSignatureChangeEvent does not align at the head of bars (Tick: {ordered[i].Tick}).", ordered[i].Tick); } var item = new TimeSignatureItem(barIndex, ordered[i]); // 時間逆順で追加 if (dic.ContainsKey(-pos)) { throw new InvalidTimeSignatureException($"TimeSignatureChangeEvents duplicated (Tick: {ordered[i].Tick}).", ordered[i].Tick); } else { dic.Add(-pos, item); } if (i < ordered.Count - 1) { int barLength = BarTick * ordered[i].Numerator / ordered[i].Denominator; int duration = ordered[i + 1].Tick - pos; pos += duration / barLength * barLength; barIndex += duration / barLength; } } ReversedTimeSignatures = dic.Values.ToList(); }