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, ))
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)
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()
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
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
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
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)
def do_t(self, value: str) -> None: self.timing_events.append( BPMEvent(self._current_beat(), BPM=Decimal(value)))