示例#1
0
 def do_t(self, value: str) -> None:
     self.current_tempo = Decimal(value)
     self.timing_events.append(
         BPMEvent(
             time=self._current_beat(),
             BPM=self.current_tempo,
         ))
示例#2
0
def bpm_changes(
    draw: DrawFunc,
    bpm_strat: st.SearchStrategy[Decimal] = bpms(),
    time_strat: st.SearchStrategy[BeatsTime] = beat_time(min_section=1,
                                                         max_section=10),
) -> BPMEvent:
    time = draw(time_strat)
    bpm = draw(bpm_strat)
    return BPMEvent(time, bpm)
示例#3
0
    def append_chart_line(self, raw_line: RawMemo2ChartLine) -> None:
        if (len(
                raw_line.position.encode("shift-jis-2004",
                                         errors="surrogateescape")) !=
                4 * self.bytes_per_panel):
            raise SyntaxError(
                f"Invalid chart line for #bpp={self.bytes_per_panel} : {raw_line}"
            )

        if raw_line.timing is not None and self.bytes_per_panel == 2:
            if any(
                    len(
                        e.string.encode("shift-jis-2004",
                                        errors="surrogateescape")) % 2 != 0
                    for e in raw_line.timing if isinstance(e, NoteCluster)):
                raise SyntaxError(
                    f"Invalid chart line for #bpp=2 : {raw_line}")

        if not raw_line.timing:
            line = Memo2ChartLine(raw_line.position, None)
        else:
            # split notes
            bar: List[Union[str, Stop, BPM]] = []
            for raw_event in raw_line.timing:
                if isinstance(raw_event, NoteCluster):
                    bar.extend(self._split_chart_line(raw_event.string))
                else:
                    bar.append(raw_event)
            # extract timing info
            bar_length = sum(1 for e in bar if isinstance(e, str))
            symbol_duration = BeatsTime(1, bar_length)
            in_bar_beat = BeatsTime(0)
            for event in bar:
                if isinstance(event, str):
                    in_bar_beat += symbol_duration
                elif isinstance(event, BPM):
                    self.timing_events.append(
                        BPMEvent(time=self._current_beat() + in_bar_beat,
                                 BPM=event.value))
                elif isinstance(event, Stop):
                    time = self._current_beat() + in_bar_beat
                    if time != 0:
                        raise ValueError(
                            "Chart contains a pause that's not happening at the "
                            "very first beat, these are not supported by jubeatools"
                        )
                    self.offset += event.duration

            bar_notes = [e for e in bar if isinstance(e, str)]
            line = Memo2ChartLine(raw_line.position, bar_notes)

        self.current_chart_lines.append(line)
        if len(self.current_chart_lines) == 4:
            self._push_frame()
示例#4
0
def test_that_a_single_long_note_roundtrips(note: LongNote) -> None:
    timing = Timing(
        events=[BPMEvent(BeatsTime(0), Decimal(120))], beat_zero_offset=SecondsTime(0)
    )
    chart = Chart(level=Decimal(0), timing=timing, notes=[note])
    metadata = Metadata("", "", Path(""), Path(""))
    string_io = _dump_mono_column_chart("", chart, metadata, timing)
    chart_text = string_io.getvalue()
    parser = MonoColumnParser()
    for line in chart_text.split("\n"):
        parser.load_line(line)
    actual = set(parser.notes())
    assert set([note]) == actual
示例#5
0
def test_that_notes_roundtrip(notes: List[Union[TapNote, LongNote]]) -> None:
    timing = Timing(events=[BPMEvent(BeatsTime(0), Decimal(120))],
                    beat_zero_offset=SecondsTime(0))
    chart = Chart(
        level=Decimal(0),
        timing=timing,
        notes=sorted(notes, key=lambda n: (n.time, n.position)),
    )
    metadata = Metadata("", "", Path(""), Path(""))
    string_io = _dump_memo2_chart("", chart, metadata, timing)
    chart_text = string_io.getvalue()
    parser = Memo2Parser()
    for line in chart_text.split("\n"):
        parser.load_line(line)
    parser.finish_last_few_notes()
    actual = set(parser.notes())
    assert notes == actual
示例#6
0
def test_that_a_set_of_tap_notes_roundtrip(notes: Set[TapNote]) -> None:
    timing = Timing(
        events=[BPMEvent(BeatsTime(0), Decimal(120))], beat_zero_offset=SecondsTime(0)
    )
    chart = Chart(
        level=Decimal(0),
        timing=timing,
        notes=sorted(notes, key=lambda n: (n.time, n.position)),
    )
    metadata = Metadata("", "", Path(""), Path(""))
    string_io = _dump_mono_column_chart("", chart, metadata, timing)
    chart_text = string_io.getvalue()
    parser = MonoColumnParser()
    for line in chart_text.split("\n"):
        parser.load_line(line)
    actual = set(parser.notes())
    assert notes == actual
示例#7
0
def timing_info(
    draw: DrawFunc,
    with_bpm_changes: bool = True,
    bpm_strat: st.SearchStrategy[Decimal] = bpms(),
    beat_zero_offset_strat: st.SearchStrategy[Decimal] = st.decimals(
        min_value=0, max_value=20, places=3),
    time_strat: st.SearchStrategy[BeatsTime] = beat_time(min_section=1,
                                                         max_section=10),
) -> Timing:
    first_bpm = draw(bpm_strat)
    first_event = BPMEvent(BeatsTime(0), first_bpm)
    events = [first_event]
    if with_bpm_changes:
        raw_bpm_changes = st.lists(bpm_changes(bpm_strat, time_strat),
                                   unique_by=get_bpm_change_time)
        sorted_bpm_changes = raw_bpm_changes.map(
            lambda l: sorted(l, key=get_bpm_change_time))
        other_events = draw(sorted_bpm_changes)
        events += other_events
    beat_zero_offset = draw(beat_zero_offset_strat)
    return Timing(events=events, beat_zero_offset=beat_zero_offset)
示例#8
0
 def do_t(self, value: str) -> None:
     self.timing_events.append(
         BPMEvent(self._current_beat(), BPM=Decimal(value)))