mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-11 03:09:57 +00:00
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:
+1
-1
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user