simfile.notes.group =================== .. py:module:: simfile.notes.group Attributes ---------- .. autoapisummary:: simfile.notes.group.GroupedNotes Exceptions ---------- .. autoapisummary:: simfile.notes.group.OrphanedNoteException Classes ------- .. autoapisummary:: simfile.notes.group.NoteWithTail simfile.notes.group.SameBeatNotes simfile.notes.group.OrphanedNotes Functions --------- .. autoapisummary:: simfile.notes.group.group_notes simfile.notes.group.ungroup_notes Module Contents --------------- .. py:class:: NoteWithTail Bases: :py:obj:`NamedTuple` A hold/roll head note with its corresponding tail note. .. py:attribute:: beat :type: simfile.timing.Beat .. py:attribute:: column :type: int .. py:attribute:: note_type :type: simfile.notes.NoteType .. py:attribute:: tail_beat :type: simfile.timing.Beat .. py:attribute:: player :type: int :value: 0 Only used in routine charts. The second player's note data will have this value set to 1. .. py:attribute:: keysound_index :type: Optional[int] :value: None Only used in keysounded SSC charts. Notes followed by a number in square brackets will have this value set to the bracketed number. .. py:data:: GroupedNotes A sequence of :class:`.Note` and possibly :class:`NoteWithTail` objects. .. py:class:: SameBeatNotes(*args, **kwds) Bases: :py:obj:`enum.Enum` Choices for :func:`group_notes`' `same_beat_notes` parameter. When multiple notes land on the same beat... * `KEEP_SEPARATE`: each note is emitted separately * `JOIN_BY_NOTE_TYPE`: notes of the same type are emitted together * `JOIN_ALL`: all notes are emitted together .. py:attribute:: KEEP_SEPARATE :value: 1 .. py:attribute:: JOIN_BY_NOTE_TYPE :value: 2 .. py:attribute:: JOIN_ALL :value: 3 .. py:exception:: OrphanedNoteException Bases: :py:obj:`Exception` Raised by :func:`group_notes` to flag an orphaned head or tail note. .. py:class:: OrphanedNotes(*args, **kwds) Bases: :py:obj:`enum.Enum` Choices for :func:`group_notes`' `orphaned_head|tail` parameters. When `join_heads_to_tails` is True and a head or tail note is missing its counterpart... * `RAISE_EXCEPTION`: raise :class:`OrphanedNoteException` * `KEEP_ORPHAN`: emit the orphaned :class:`Note` * `DROP_ORPHAN`: do not emit the orphaned note .. py:attribute:: RAISE_EXCEPTION :value: 1 .. py:attribute:: KEEP_ORPHAN :value: 2 .. py:attribute:: DROP_ORPHAN :value: 3 .. py:function:: group_notes(notes: Iterable[simfile.notes.Note], *, same_beat_notes: SameBeatNotes = SameBeatNotes.KEEP_SEPARATE, join_heads_to_tails: bool = False, orphaned_head: OrphanedNotes = OrphanedNotes.RAISE_EXCEPTION, orphaned_tail: OrphanedNotes = OrphanedNotes.RAISE_EXCEPTION) -> Iterator[GroupedNotes] Join certain notes together: either ones that occur on the same beat ("jumps"), hold & roll heads to their tails, or both. This function yields :class:`GroupedNotes` objects, which are sequences of :class:`Note` and :class:`NoteWithTail` objects. :class:`GroupedNotes` objects may contain multiple items only if `same_beat_notes` is set to `JOIN_BY_NOTE_TYPE` or `JOIN_ALL`; they may contain :class:`NoteWithTail` objects only if `join_heads_to_tails` is set to True. When `join_heads_to_tails` is set to True, tail notes are attached to their corresponding hold/roll heads as :class:`NoteWithTail` objects. The tail itself will not be emitted as a separate note. If a head or tail note is missing its counterpart, `orphaned_head` and `orphaned_tail` determine the behavior. (These parameters are ignored if `join_heads_to_tails` is omitted or False.) Refer to each enum's documentation for the other configuration options. .. py:function:: ungroup_notes(grouped_notes: Iterable[GroupedNotes], *, orphaned_notes: OrphanedNotes = OrphanedNotes.RAISE_EXCEPTION) -> Iterator[simfile.notes.Note] Convert grouped notes back into a plain note stream. If a note falls within a :class:`NoteWithTail`'s head and tail (on the same column), it would cause the head and tail to be orphaned. `orphaned_notes` determines how to handle the splitting note: `KEEP_ORPHAN` will yield the note (allowing the head and tail notes to become orphans) and `DROP_ORPHAN` will drop the note (preserving the link between the head and tail notes). Note that this check only applies to heads and tails joined as a :class:`NoteAndTail`. If :func:`group_notes` was called without specifying `join_heads_to_tails`, specifying `orphaned_notes` here will have no effect. This mirrors how :func:`group_notes`' `orphaned_head` and `orphaned_tail` parameters behave.