mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-12 11:08:32 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cb3e4eaae | ||
|
|
233f5280e8 |
+10
-3
@@ -1114,7 +1114,7 @@ def _build_xml(
|
|||||||
ET.SubElement(root, "arrangement").text = arrangement
|
ET.SubElement(root, "arrangement").text = arrangement
|
||||||
ET.SubElement(root, "offset").text = f"{audio_offset:.3f}"
|
ET.SubElement(root, "offset").text = f"{audio_offset:.3f}"
|
||||||
ET.SubElement(root, "songLength").text = f"{song_length:.3f}"
|
ET.SubElement(root, "songLength").text = f"{song_length:.3f}"
|
||||||
ET.SubElement(root, "startBeat").text = f"{beats[0].time:.3f}" if beats else "0.000"
|
ET.SubElement(root, "startBeat").text = f"{beats[0].time:.6f}" if beats else "0.000000"
|
||||||
ET.SubElement(root, "averageTempo").text = str(tempo)
|
ET.SubElement(root, "averageTempo").text = str(tempo)
|
||||||
ET.SubElement(root, "artistName").text = artist
|
ET.SubElement(root, "artistName").text = artist
|
||||||
ET.SubElement(root, "albumName").text = album
|
ET.SubElement(root, "albumName").text = album
|
||||||
@@ -1139,10 +1139,17 @@ def _build_xml(
|
|||||||
tuning_el.set(f"string{i}", str(tuning[i] if i < len(tuning) else 0))
|
tuning_el.set(f"string{i}", str(tuning[i] if i < len(tuning) else 0))
|
||||||
ET.SubElement(root, "capo").text = "0"
|
ET.SubElement(root, "capo").text = "0"
|
||||||
|
|
||||||
# Ebeats
|
# Ebeats — write beat times at MICROSECOND (6-decimal) precision, not
|
||||||
|
# millisecond (3-decimal). The editor/timeline DERIVES per-bar BPM from beat
|
||||||
|
# spans (bpm = beats·60/span), which amplifies any rounding: at 3 decimals a
|
||||||
|
# constant-tempo GP (e.g. 140) shows a spurious ±0.05–0.7 BPM per-bar drift
|
||||||
|
# (worse for fast/odd meters) because most bar lengths don't land on a ms
|
||||||
|
# boundary. gp2rs computes these times exactly from the GP tempo map, so the
|
||||||
|
# only loss is this format string — 6 decimals makes the derived tempo match
|
||||||
|
# GP's authored value. (Everything else stays at :.3f; only beats drive tempo.)
|
||||||
ebeats = ET.SubElement(root, "ebeats", count=str(len(beats)))
|
ebeats = ET.SubElement(root, "ebeats", count=str(len(beats)))
|
||||||
for b in beats:
|
for b in beats:
|
||||||
ET.SubElement(ebeats, "ebeat", time=f"{b.time:.3f}", measure=str(b.measure))
|
ET.SubElement(ebeats, "ebeat", time=f"{b.time:.6f}", measure=str(b.measure))
|
||||||
|
|
||||||
# Sections
|
# Sections
|
||||||
sections_el = ET.SubElement(root, "sections", count=str(len(sections)))
|
sections_el = ET.SubElement(root, "sections", count=str(len(sections)))
|
||||||
|
|||||||
+4
-1
@@ -121,7 +121,10 @@ def _converter_ebeats(converter, numerator, denominator, tempo_changes=None):
|
|||||||
def _assert_ebeats(converter, numerator, denominator, expected_times, tempo_changes=None):
|
def _assert_ebeats(converter, numerator, denominator, expected_times, tempo_changes=None):
|
||||||
ebeats = _converter_ebeats(converter, numerator, denominator, tempo_changes)
|
ebeats = _converter_ebeats(converter, numerator, denominator, tempo_changes)
|
||||||
|
|
||||||
assert [ebeat.get("time") for ebeat in ebeats] == expected_times
|
# Compare by value, not string: beat times are written at 6-decimal
|
||||||
|
# (microsecond) precision so the derived per-bar tempo matches the authored
|
||||||
|
# GP value, but these tests only care about the spacing, not the format.
|
||||||
|
assert [float(ebeat.get("time")) for ebeat in ebeats] == [float(t) for t in expected_times]
|
||||||
assert [ebeat.get("measure") for ebeat in ebeats] == [
|
assert [ebeat.get("measure") for ebeat in ebeats] == [
|
||||||
"1",
|
"1",
|
||||||
*["-1"] * (len(expected_times) - 1),
|
*["-1"] * (len(expected_times) - 1),
|
||||||
|
|||||||
Reference in New Issue
Block a user