Improve wording in terminology cleanup

Replace the placeholder noun left by the previous pass with context-fit
phrasing (arrangement XML, chart, custom songs, etc.).
This commit is contained in:
Sin
2026-06-16 19:43:45 +01:00
parent 4148b0e72e
commit c1870a0597
11 changed files with 38 additions and 38 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
"""Audio extraction and conversion for the source game custom song."""
"""Audio extraction and conversion for custom songs."""
import logging
import os
+13 -13
View File
@@ -1,4 +1,4 @@
"""Convert Guitar Pro files (.gp5/.gp4/.gp3) to the source game arrangement XML."""
"""Convert Guitar Pro files (.gp5/.gp4/.gp3) to arrangement XML."""
import logging
import re
@@ -544,7 +544,7 @@ def convert_track(
*,
expand_repeats: bool = True,
) -> str:
"""Convert a GP track to the source game arrangement XML string.
"""Convert a GP track to arrangement XML string.
Args:
song: Parsed Guitar Pro song
@@ -558,7 +558,7 @@ def convert_track(
once in authored order — equivalent to the pre-expansion behavior.
Returns:
XML string of the the source game arrangement
XML string of the chart arrangement
"""
track = song.tracks[track_index]
num_strings = len(track.strings)
@@ -1149,7 +1149,7 @@ def list_tracks(gp_path: str) -> list[dict]:
def auto_select_tracks(gp_path: str) -> tuple[list[int], dict[int, str]]:
"""Auto-select guitar/bass/keys tracks and assign the source game arrangement names.
"""Auto-select guitar/bass/keys tracks and assign the standard arrangement names.
Includes piano/keyboard tracks as "Keys" arrangements alongside
guitar and bass tracks.
@@ -1205,7 +1205,7 @@ def auto_select_tracks(gp_path: str) -> tuple[list[int], dict[int, str]]:
role = "bass" if t["is_bass"] else "guitar"
selected.append((t["index"], role))
# Assign the source game names: Lead, Rhythm, Combo, Bass, Keys, Drums
# Assign the standard arrangement names: Lead, Rhythm, Combo, Bass, Keys, Drums
track_indices = []
name_map = {}
lead_count = 0
@@ -1243,14 +1243,14 @@ def convert_piano_track(
*,
expand_repeats: bool = True,
) -> str:
"""Convert a GP piano/keyboard track to the source game XML using MIDI encoding.
"""Convert a GP piano/keyboard track to arrangement XML using MIDI encoding.
Encodes MIDI notes into the source game's string+fret format:
Encodes MIDI notes into the string+fret format:
string = midi_note // 24
fret = midi_note % 24
This gives a range of 0-143, covering the full piano range within
the source game's 6-string x 24-fret structure. The piano highway plugin
the 6-string x 24-fret structure. The piano highway plugin
decodes back via: midi = string * 24 + fret.
Honors GP repeat brackets and D.S./D.C./Coda/Fine jumps when
@@ -1342,7 +1342,7 @@ def convert_piano_track(
base_midi = 60 # fallback to middle C
midi_note = base_midi + note.value
# Encode into the source game string+fret
# Encode into the string+fret
rs_string = midi_note // 24
rs_fret = midi_note % 24
@@ -1449,9 +1449,9 @@ def convert_drum_track(
*,
expand_repeats: bool = True,
) -> str:
"""Convert a GP drum/percussion track to the source game XML using MIDI encoding.
"""Convert a GP drum/percussion track to arrangement XML using MIDI encoding.
Encodes MIDI drum note numbers into the source game's string+fret format:
Encodes MIDI drum note numbers into the string+fret format:
string = midi_note // 24
fret = midi_note % 24
@@ -1534,7 +1534,7 @@ def convert_drum_track(
if midi_note not in GM_DRUM_MAP:
continue # Skip unknown percussion sounds
# Encode into the source game string+fret
# Encode into the string+fret
rs_string = midi_note // 24
rs_fret = midi_note % 24
@@ -1778,7 +1778,7 @@ def convert_file(
*,
expand_repeats: bool = True,
) -> list[str]:
"""Convert a GP file to the source game XMLs.
"""Convert a GP file to arrangement XMLs.
Args:
gp_path: Path to .gp5/.gp4/.gp3 file
+9 -9
View File
@@ -663,7 +663,7 @@ def list_tracks(gp_path: str) -> list[dict]:
# ---------------------------------------------------------------------------
# convert_file — mirrors gp2rs.convert_file interface
# Converts GPX tracks directly to the source game XML, reusing gp2rs._build_xml
# Converts GPX tracks directly to arrangement XML, reusing gp2rs._build_xml
# ---------------------------------------------------------------------------
@@ -816,7 +816,7 @@ def _collect_tone_events(
def _inject_tones(xml_str: str, tone_events: list[tuple[float, str]]) -> str:
"""
Inject a <tones> element into a the source game arrangement XML string.
Inject a <tones> element into a chart arrangement XML string.
Parses the prettified XML returned by _build_xml, inserts the tones
block before </song>, and re-serialises. Noop if tone_events is empty.
@@ -1124,7 +1124,7 @@ def convert_file(
*,
expand_repeats: bool = True,
) -> list[str]:
"""Convert a .gpx file to the source game XML arrangement files.
"""Convert a .gpx file to arrangement XML arrangement files.
Mirrors gp2rs.convert_file so the editor plugin can call it transparently.
expand_repeats is accepted for API compatibility but repeat expansion from
@@ -1809,10 +1809,10 @@ def _is_vocal_track(track: dict) -> bool:
def _gpx_lyric_to_rs(raw: str) -> str:
"""
Convert a GPX lyric token to the source game vocal lyric format.
Convert a GPX lyric token to the vocal lyric format.
GPX encodes syllable continuation with a trailing hyphen (e.g. "in-", "t-").
the source game uses the same convention for mid-word syllables. For word-final
charts use the same convention for mid-word syllables. For word-final
syllables with no hyphen, RS requires a "+" suffix to signal "connect to
next syllable without a space" — but only when the next beat is a
continuation of the same word. We handle this at the sequence level in
@@ -1849,7 +1849,7 @@ def convert_vocal_track(
arr_name: str = 'Vocals',
) -> str:
"""
Convert a GPX vocal track to a the source game vocals arrangement XML.
Convert a GPX vocal track to a chart vocals arrangement XML.
Each beat with a lyric and a note becomes a <vocal> element:
time — seconds from song start + audio_offset
@@ -1864,7 +1864,7 @@ def convert_vocal_track(
Beats with a lyric but no pitch note are included as pitch-0 rests so the
display timeline stays intact. Beats with no lyric are skipped entirely.
The output is a minimal but valid the source game vocals XML. It does not include
The output is a minimal but valid vocals XML. It does not include
ebeats or phrases (RS parses vocal XMLs without them).
"""
string_pitches = track['string_pitches'] # high→low, standard guitar if vocal
@@ -2018,10 +2018,10 @@ def _build_vocals_xml(
vocals: list[dict],
tempo: int,
) -> str:
"""Build a the source game vocals arrangement XML string."""
"""Build a chart vocals arrangement XML string."""
from xml.dom import minidom
# the source game vocals arrangement is a flat <vocals> document — NOT a
# vocals arrangement is a flat <vocals> document — NOT a
# <song> wrapper. Every lyric consumer in the codebase keys off the root
# tag being literally "vocals" (lib/loosefolder.py, server.py highway
# loader), so a <song> root would be silently skipped and the generated
+1 -1
View File
@@ -128,7 +128,7 @@ def _resolve_audio_asset(zf, root=None) -> tuple[str, str | None]:
# GP8 uses 44100 Hz internally for FrameOffset values regardless of the
# OGG file's own sample rate. The embedded OGG is typically 48000 Hz
# (the source game's preferred rate) and should be passed through as-is —
# (the preferred rate) and should be passed through as-is —
# do NOT resample it. The 44100 constant is only used here to convert
# FrameOffset integers to seconds for timing math; it never touches audio.
# Verified: 44100 gives <10ms sync error; 48000 gives ~530ms error.
+1 -1
View File
@@ -176,7 +176,7 @@ def _arr_type_from_filename(stem: str) -> tuple:
def _parse_xml_meta(xml_path: Path) -> dict:
"""Parse a the source game arrangement XML and return song-level metadata."""
"""Parse a chart arrangement XML and return song-level metadata."""
try:
root = ET.parse(str(xml_path)).getroot()
if root.tag != "song":
+1 -1
View File
@@ -349,7 +349,7 @@ def instrument_for_arrangement(arr_entry) -> str:
# arrangements often carry a generic type (lead/rhythm/combo) but have a
# name like "Keys" or "Piano". Name overrides the generic type for all
# well-known non-guitar instruments so that scored keys runs advance the
# keys path and quests even when the the source game XML type was not updated.
# keys path and quests even when the chart XML type was not updated.
if "bass" in name:
return "bass"
if "drum" in name or "percussion" in name:
+8 -8
View File
@@ -1,4 +1,4 @@
"""the source game arrangement XML parser and song data models."""
"""arrangement XML parser and song data models."""
from dataclasses import dataclass, field
from pathlib import Path
@@ -88,7 +88,7 @@ class HandShape:
@dataclass
class PhraseLevel:
"""One difficulty tier's worth of note/chord/anchor/hand-shape data for a
single phrase iteration. the source game's XML stores these as `<level
single phrase iteration. the arrangement XML stores these as `<level
difficulty="N">` blocks that repeat for every difficulty tier the chart
author wrote; slopsmith used to collapse them to the phrase's
maxDifficulty and throw the rest away. Keeping them around lets the
@@ -129,7 +129,7 @@ class Arrangement:
chord_templates: list[ChordTemplate] = field(default_factory=list)
# None for single-level sources (GP converter, old sloppaks) — frontends
# should treat a missing `phrases` as "no per-phrase difficulty data
# available, disable the slider". Populated from the source game XML when
# available, disable the slider". Populated from arrangement XML when
# multiple `<level>` tiers exist.
phrases: list[Phrase] | None = None
# Tone data lifted from the source archive by the sloppak converter and
@@ -681,7 +681,7 @@ def _int_optional(elem, attr, default=-1):
Use for fields that are merely metadata hints (right-hand fingering,
pick direction, etc.) where a malformed value from a third-party
the source game XML emitter shouldn't abort the whole arrangement parse.
arrangement XML emitter shouldn't abort the whole arrangement parse.
Required-field readers (`string`, `fret`, `chordId`, ) keep using
`_int` so a corrupted required attribute still fails fast at parse
@@ -708,7 +708,7 @@ def _bool(elem, attr):
def _hand_shape_arpeggio_flag(elem) -> bool:
"""the source game / EOF may mark arpeggio on ``<handShape>`` (various casings)."""
"""charts / EOF may mark arpeggio on ``<handShape>`` (various casings)."""
for attr in ("arpeggio", "Arpeggio", "arp", "Arp"):
if _bool(elem, attr):
return True
@@ -716,7 +716,7 @@ def _hand_shape_arpeggio_flag(elem) -> bool:
def _chord_template_arpeggio_flag(elem) -> bool:
"""the source game commonly tags arpeggio templates in ``displayName`` via ``-arp``."""
"""charts commonly tag arpeggio templates in ``displayName`` via ``-arp``."""
for attr in ("arpeggio", "Arpeggio", "arp", "Arp"):
if _bool(elem, attr):
return True
@@ -766,7 +766,7 @@ def _parse_note(n) -> Note:
def parse_arrangement(xml_path: str) -> Arrangement:
"""Parse a the source game arrangement XML file."""
"""Parse a chart arrangement XML file."""
tree = ET.parse(xml_path)
root = tree.getroot()
@@ -1049,7 +1049,7 @@ def parse_arrangement(xml_path: str) -> Arrangement:
# wrote at or below this phrase's max — these are what the
# master-difficulty slider selects between at render time.
# Tiers above max_diff exist in some XMLs (authoring leftovers)
# and are skipped to match the source game's in-game behaviour.
# and are skipped to match the reference player's behaviour.
# Capture the extracted slices so the flat max-mastery merge
# below can reuse one of them.
phrase_levels: list[PhraseLevel] = []
+1 -1
View File
@@ -58,7 +58,7 @@ def _convert_riff_wem(data: bytes, output_path: str) -> bool:
if codec == 0xFFFF or codec == 0x0069:
# Wwise Vorbis — audio_data contains raw Ogg pages or encoded Vorbis
# For the source game custom song, the data is typically packed Vorbis
# For custom songs, the data is typically packed Vorbis
# Try writing raw data as OGG (some WEM files have valid OGG inside)
if _try_extract_ogg_pages(audio_data, output_path):
return True