Ejemplo n.º 1
0
        // TODO: refactor with ScoreExtensions.CalculateDuration().
        public static void UpdateStartTime([NotNull] this Bar bar)
        {
            var score       = bar.Basic.Score;
            var notes       = score.GetAllNotes();
            var allBpmNotes = notes.Where(n => n.Basic.Type == NoteType.VariantBpm).ToArray();

            var currentTiming   = score.Project.Settings.StartTimeOffset;
            var currentBpm      = score.Project.Settings.BeatPerMinute;
            var currentInterval = BeatmapMathHelper.BpmToInterval(currentBpm);

            foreach (var b in score.Bars)
            {
                if (b == bar)
                {
                    break;
                }

                var currentGridPerSignature = b.GetGridPerSignature();
                var numGrids = b.GetNumberOfGrids();

                if (allBpmNotes.Any(n => n.Basic.Bar == b))
                {
                    var bpmNotesInThisBar = allBpmNotes.Where(n => n.Basic.Bar == b).ToList();

                    bpmNotesInThisBar.Sort((n1, n2) => n1.Basic.IndexInGrid.CompareTo(n2.Basic.IndexInGrid));

                    var bpmNoteIndex = 0;

                    for (var i = 0; i < numGrids; ++i)
                    {
                        if (bpmNoteIndex < bpmNotesInThisBar.Count)
                        {
                            var bpmNote = bpmNotesInThisBar[bpmNoteIndex];

                            Debug.Assert(bpmNote.Params != null, "bpmNote.Params != null");

                            if (i == bpmNote.Basic.IndexInGrid)
                            {
                                currentBpm      = bpmNote.Params.NewBpm;
                                currentInterval = BeatmapMathHelper.BpmToInterval(currentBpm);

                                ++bpmNoteIndex;
                            }
                        }

                        currentTiming += currentInterval / currentGridPerSignature;
                    }
                }
                else
                {
                    var currentSignature = b.GetSignature();

                    currentTiming += currentInterval * currentSignature;
                }
            }

            var startTime = TimeSpan.FromSeconds(currentTiming);

            bar.Temporary.StartTime = startTime;
        }
Ejemplo n.º 2
0
        private void BtnOneMeasureMore_Click(object sender, EventArgs e)
        {
            if (!CheckFields())
            {
                return;
            }

            var bpm         = double.Parse(txtBPM.Text, NumberStyles.Number, CultureInfo.CurrentCulture);
            var startOffset = double.Parse(txtMusicOffset.Text, NumberStyles.Number, CultureInfo.CurrentCulture);
            var interval    = BeatmapMathHelper.BpmToInterval(bpm);
            int beatCount;

            switch (_primaryBeatMode)
            {
            case PrimaryBeatMode.EveryFourBeats:
                beatCount = 4;
                break;

            case PrimaryBeatMode.EveryThreeBeats:
                beatCount = 3;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            startOffset        += beatCount * interval;
            _musicOffset        = startOffset;
            txtMusicOffset.Text = _musicOffset.ToString("0.000");
            txtMusicOffset.Focus();
            txtMusicOffset.SelectAll();
        }
Ejemplo n.º 3
0
        public static TimeSpan CalculateDuration([NotNull] this Bar bar)
        {
            var notes      = bar.Notes;
            var score      = bar.Basic.Score;
            var currentBpm = score.Project.Settings.BeatPerMinute;

            foreach (var b in score.Bars)
            {
                if (b == bar)
                {
                    break;
                }

                var thisBarHasBpm = b.Notes.Count != 0 && b.Notes.Any(n => n.Basic.Type == NoteType.VariantBpm);

                if (!thisBarHasBpm)
                {
                    continue;
                }

                var bpmNotes = b.Notes.Where(n => n.Basic.Type == NoteType.VariantBpm).ToList();

                bpmNotes.Sort(Note.TimingComparison);

                var currentBpmNote = bpmNotes[bpmNotes.Count - 1];

                Debug.Assert(currentBpmNote.Params != null, "currentBpmNote.Params != null");

                currentBpm = currentBpmNote.Params.NewBpm;
            }

            var    hasAnyBpmNote   = notes.Count != 0 && notes.Any(n => n.Basic.Type == NoteType.VariantBpm);
            var    currentInterval = BeatmapMathHelper.BpmToInterval(currentBpm);
            double seconds;

            if (hasAnyBpmNote)
            {
                var bpmNotesInThisBar       = bar.Notes.Where(n => n.Basic.Bar == bar).ToList();
                var numGrids                = bar.GetNumberOfGrids();
                var currentGridPerSignature = bar.GetGridPerSignature();

                bpmNotesInThisBar.Sort((n1, n2) => n1.Basic.IndexInGrid.CompareTo(n2.Basic.IndexInGrid));

                var bpmNoteIndex = 0;

                seconds = 0;

                for (var i = 0; i < numGrids; ++i)
                {
                    if (bpmNoteIndex < bpmNotesInThisBar.Count)
                    {
                        var bpmNote = bpmNotesInThisBar[bpmNoteIndex];

                        if (i == bpmNote.Basic.IndexInGrid)
                        {
                            currentInterval = BeatmapMathHelper.BpmToInterval(currentBpm);
                            ++bpmNoteIndex;
                        }
                    }

                    seconds += currentInterval * i / currentGridPerSignature;
                }
            }
            else
            {
                seconds = BeatmapMathHelper.BpmToInterval(currentBpm) * bar.GetSignature();
            }

            return(TimeSpan.FromSeconds(seconds));
        }
Ejemplo n.º 4
0
        private static CompiledScore Compile([NotNull] Score score, [CanBeNull] TimeSpan?userDefinedEnding)
        {
            var notes = score.GetAllNotes();

            // First, calculate all timing at the grid lines.
            var allBpmNotes = notes.Where(n => n.Basic.Type == NoteType.VariantBpm).ToArray();
            var timings     = new Dictionary <Bar, double[]>();

            var currentTiming   = score.Project.Settings.StartTimeOffset;
            var currentBpm      = score.Project.Settings.BeatPerMinute;
            var currentInterval = BeatmapMathHelper.BpmToInterval(currentBpm);

            foreach (var bar in score.Bars)
            {
                var currentGridPerSignature = bar.GetGridPerSignature();
                var numGrids = bar.GetNumberOfGrids();
                var t        = new double[numGrids];

                if (allBpmNotes.Any(n => n.Basic.Bar == bar))
                {
                    // If there are variant BPM notes, we have to do some math...
                    var bpmNotesInThisBar = allBpmNotes.Where(n => n.Basic.Bar == bar).ToList();

                    bpmNotesInThisBar.Sort((n1, n2) => n1.Basic.IndexInGrid.CompareTo(n2.Basic.IndexInGrid));

                    var bpmNoteIndex = 0;

                    for (var i = 0; i < numGrids; ++i)
                    {
                        if (bpmNoteIndex < bpmNotesInThisBar.Count)
                        {
                            var bpmNote = bpmNotesInThisBar[bpmNoteIndex];

                            if (i == bpmNote.Basic.IndexInGrid)
                            {
                                Debug.Assert(bpmNote.Params != null, "bpmNote.Params != null");

                                // Yes! We have a visitor: a variant BPM note!
                                currentBpm      = bpmNote.Params.NewBpm;
                                currentInterval = BeatmapMathHelper.BpmToInterval(currentBpm);

                                ++bpmNoteIndex;
                            }
                        }

                        t[i] = currentTiming;

                        currentTiming += currentInterval / currentGridPerSignature;
                    }
                }
                else
                {
                    // If there are no variant BPM notes, things get a lot easier.
                    for (var i = 0; i < numGrids; ++i)
                    {
                        t[i] = currentTiming + currentInterval * i / currentGridPerSignature;
                    }

                    var currentSignature = bar.GetSignature();

                    currentTiming += currentInterval * currentSignature;
                }

                timings[bar] = t;
            }

            // Then, create a list and fill in basic information.
            var compiledNotes = new List <CompiledNote>();
            var noteMap1      = new Dictionary <CompiledNote, Note>();
            var noteMap2      = new Dictionary <Note, CompiledNote>();

            foreach (var note in notes)
            {
                if (!note.Helper.IsGaming)
                {
                    continue;
                }

                var compiledNote = new CompiledNote();

                compiledNote.Type           = note.Basic.Type;
                compiledNote.HitTiming      = timings[note.Basic.Bar][note.Basic.IndexInGrid];
                compiledNote.StartPosition  = note.Basic.StartPosition;
                compiledNote.FinishPosition = note.Basic.FinishPosition;
                compiledNote.FlickType      = note.Basic.FlickType;
                compiledNote.IsSync         = note.Helper.IsSync;

                compiledNotes.Add(compiledNote);

                noteMap1[compiledNote] = note;
                noteMap2[note]         = compiledNote;
            }

            compiledNotes.Sort((n1, n2) => n1.HitTiming.CompareTo(n2.HitTiming));

            // ReSharper disable once InconsistentNaming
            // Then, calculate group IDs.
            var currentGroupID = 1;

            foreach (var compiledNote in compiledNotes)
            {
                if (compiledNote.GroupID != 0)
                {
                    continue;
                }

                var note = noteMap1[compiledNote];

                if (!note.Helper.IsFlick && !note.Helper.IsSlide)
                {
                    continue;
                }

                var cn = compiledNote;

                if (note.Helper.IsFlick)
                {
                    var n = note;

                    while (n != null)
                    {
                        cn.GroupID = currentGroupID;
                        n          = n.Editor.NextFlick;

                        if (n != null)
                        {
                            cn = noteMap2[n];
                        }
                    }

                    ++currentGroupID;
                }
                else if (note.Helper.IsSlide)
                {
                    var n  = note;
                    var n2 = n;

                    while (n != null)
                    {
                        cn.GroupID = currentGroupID;
                        n2         = n;
                        n          = n.Editor.NextSlide;

                        if (n != null)
                        {
                            cn = noteMap2[n];
                        }
                    }
                    // A slide group, directly followed by a flick group.
                    if (n2.Helper.HasNextFlick)
                    {
                        n = n2.Editor.NextFlick;

                        while (n != null)
                        {
                            cn         = noteMap2[n];
                            cn.GroupID = currentGroupID;
                            n          = n.Editor.NextFlick;
                        }
                    }

                    ++currentGroupID;
                }
            }

            // Then, add three key notes. (Keynotes, hahaha.)
            var totalNoteCount = compiledNotes.Count;
            var scoreInfoNote  = new CompiledNote();

            scoreInfoNote.Type = NoteType.NoteCount;
            // Here I used a trick. This will run well while violating the meaning of enum.
            scoreInfoNote.FlickType = (NoteFlickType)totalNoteCount;

            var songStartNote = new CompiledNote {
                Type = NoteType.MusicStart
            };
            var endTiming   = userDefinedEnding?.TotalSeconds ?? currentTiming;
            var songEndNote = new CompiledNote {
                Type      = NoteType.MusicEnd,
                HitTiming = endTiming
            };

            compiledNotes.Insert(0, scoreInfoNote);
            compiledNotes.Insert(1, songStartNote);
            compiledNotes.Add(songEndNote);

            // ReSharper disable once InconsistentNaming
            // Finally, ID them.
            var currentNoteID = 1;

            foreach (var note in compiledNotes)
            {
                note.ID = currentNoteID;
                ++currentNoteID;
            }

            // We did it! Oh yeah!
            var compiledScore = new CompiledScore(compiledNotes);

            return(compiledScore);
        }
Ejemplo n.º 5
0
        public static IReadOnlyList <IReadOnlyList <TimeSpan> > UpdateNoteHitTimings([NotNull] this Score score)
        {
            var notes = score.GetAllNotes();

            // First, calculate all timing at the grid lines.
            var allBpmNotes = notes.Where(n => n.Basic.Type == NoteType.VariantBpm).ToArray();
            var timings     = new List <TimeSpan[]>();


            var currentTiming   = TimeSpan.FromSeconds(score.Project.Settings.StartTimeOffset);
            var currentBpm      = score.Project.Settings.BeatPerMinute;
            var currentInterval = BeatmapMathHelper.BpmToInterval(currentBpm);

            foreach (var bar in score.Bars)
            {
                var currentGridPerSignature = bar.GetGridPerSignature();
                var numGrids = bar.GetNumberOfGrids();
                var t        = new TimeSpan[numGrids];

                if (allBpmNotes.Any(n => n.Basic.Bar == bar))
                {
                    // If there are variant BPM notes, we have to do some math...
                    var bpmNotesInThisBar = allBpmNotes.Where(n => n.Basic.Bar == bar).ToList();

                    bpmNotesInThisBar.Sort((n1, n2) => n1.Basic.IndexInGrid.CompareTo(n2.Basic.IndexInGrid));

                    var bpmNoteIndex = 0;

                    for (var i = 0; i < numGrids; ++i)
                    {
                        if (bpmNoteIndex < bpmNotesInThisBar.Count)
                        {
                            var bpmNote = bpmNotesInThisBar[bpmNoteIndex];

                            if (i == bpmNote.Basic.IndexInGrid)
                            {
                                Debug.Assert(bpmNote.Params != null, "bpmNote.Params != null");

                                // Yes! We have a visitor: a variant BPM note!
                                currentBpm      = bpmNote.Params.NewBpm;
                                currentInterval = BeatmapMathHelper.BpmToInterval(currentBpm);

                                ++bpmNoteIndex;
                            }
                        }

                        t[i] = currentTiming;

                        currentTiming += TimeSpan.FromSeconds(currentInterval / currentGridPerSignature);
                    }
                }
                else
                {
                    // If there are no variant BPM notes, things get a lot easier.
                    for (var i = 0; i < numGrids; ++i)
                    {
                        t[i] = currentTiming + TimeSpan.FromSeconds(currentInterval * i / currentGridPerSignature);
                    }

                    var currentSignature = bar.GetSignature();

                    currentTiming += TimeSpan.FromSeconds(currentInterval * currentSignature);
                }

                // The timing index should equal corresponding bar index.
                timings.Add(t);
            }

            // Update the HitTiming property of each gaming note.
            foreach (var note in notes)
            {
                if (!note.Helper.IsGaming)
                {
                    continue;
                }

                note.Temporary.HitTiming = timings[note.Basic.Bar.Basic.Index][note.Basic.IndexInGrid];
            }

            return(timings);
        }