Exemplo n.º 1
0
        /// <summary>
        ///     Finds the most common BPM in a Qua object.
        /// </summary>
        /// <returns></returns>
        public float GetCommonBpm()
        {
            if (TimingPoints.Count == 0)
            {
                return(0);
            }

            // This fallback isn't really justified, but it's only used for tests.
            if (HitObjects.Count == 0)
            {
                return(TimingPoints[0].Bpm);
            }

            var    lastObject = HitObjects.OrderByDescending(x => x.IsLongNote ? x.EndTime : x.StartTime).First();
            double lastTime   = lastObject.IsLongNote ? lastObject.EndTime : lastObject.StartTime;

            var durations = new Dictionary <float, int>();

            for (var i = TimingPoints.Count - 1; i >= 0; i--)
            {
                var point = TimingPoints[i];

                // Make sure that timing points past the last object don't break anything.
                if (point.StartTime > lastTime)
                {
                    continue;
                }

                var duration = (int)(lastTime - (i == 0 ? 0 : point.StartTime));
                lastTime = point.StartTime;

                if (durations.ContainsKey(point.Bpm))
                {
                    durations[point.Bpm] += duration;
                }
                else
                {
                    durations[point.Bpm] = duration;
                }
            }

            if (durations.Count == 0)
            {
                return(TimingPoints[0].Bpm); // osu! hangs on loading the map in this case; we return a sensible result.
            }
            return(durations.OrderByDescending(x => x.Value).First().Key);
        }