Skip to content

Distinguish important TimingChanges from simple subdivision changes #14

@LumpBloom7

Description

@LumpBloom7

Currently, on master, there is no way to tell whether a TimingChange is important (holding a different BPM or different timing), or simply describes subdivision changes of a previous timing point.

SimaiSharp should distinguish between pure subdivision changes (where the BPM is inherited from a past TimingChange).

Use case:
TimingChanges are generated for every change in the subdivision. In a typical chart, several hundreds or thousands of these may be generated. For a visual editor, these may display as way too many timing changes. However, not all of them are "critical" in a sense. Filtering out simple subdivision changes will prevent blasting the charter with unimportant timing information.

Example structure change

namespace SimaiSharp.Internal.SyntacticAnalysis
{
    public struct TimingChange
    {
+        /// <summary>
+        /// If this field is <c>true</c>, then this TimingChange is likely to have been placed intentionally by a charter, as opposed to a simple subdivision change.
+        /// </summary>
+        /// <remarks>
+        /// <list type="bullet">
+        ///    <item>
+        ///        <description>If you are making a visual editor with displays the timing changes, you'd want to only display the important timing changes.</description>
+        ///    </item>
+        ///    <item>
+        ///        <description><see cref="NoteCollection"/>s created during SimaiSharp decoding will <i>not</i> ignore unimportant TimingChanges, as such, their start times will be correct.</description>
+        ///    </item>
+        ///</list>
+        /// </remarks>
+        public bool IsImportant;
+
+        /// <summary>
+        /// If this field is <c>true</c>, then the charter has provided a manual interval as an override. Typically, this implies that the note may be intentionally unaligned to the active TimingChange.
+        /// </summary>
+        /// 
+        /// <remarks>
+        /// If you are making a visual editor with displays the timing changes, you'd likely be able to get away with not including this TimingChange as "important".
+        /// </remarks>
+        public bool IsAbsoluteInterval;
+
        public double time;
        public double tempo;
        public double subdivisions;

        /// <summary>
        ///     Used in duration parsing.
        /// </summary>
        public double SecondsPerBar => tempo == 0 ? 0 : 60 / tempo;

        public double SecondsPerBeat => SecondsPerBar / ((subdivisions == 0 ? 4 : subdivisions) / 4);

        public void SetSeconds(double value)
        {
            tempo = 60 / value;
            subdivisions = 4;
+            IsAbsoluteInterval = true;
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions