Spaces:
Running
Running
Strip ties and beams for score preview fallback
Browse files- apps/theme_lab/app.py +29 -12
apps/theme_lab/app.py
CHANGED
|
@@ -46,6 +46,7 @@ MARKOV_CACHE_DIR = ROOT / "models" / "theme_lab_markov_cache"
|
|
| 46 |
DEFAULT_MARKOV_CACHE = MARKOV_CACHE_DIR / "default.pkl"
|
| 47 |
MARKOV_CACHE_FORMAT_VERSION = 1
|
| 48 |
MARKOV_PRECOMPUTED_WARM_SAMPLES = 4
|
|
|
|
| 49 |
GENERATED_ROOT.mkdir(parents=True, exist_ok=True)
|
| 50 |
CATALOG_SCORE_ROOT.mkdir(parents=True, exist_ok=True)
|
| 51 |
|
|
@@ -126,6 +127,7 @@ def health() -> dict[str, object]:
|
|
| 126 |
"verovio": verovio_cli or verovio_python,
|
| 127 |
"verovio_cli": verovio_cli,
|
| 128 |
"verovio_python": verovio_python,
|
|
|
|
| 129 |
"markov_cache_entries": len(_markov_cache),
|
| 130 |
"default_markov_cache": DEFAULT_MARKOV_CACHE.exists(),
|
| 131 |
"transformer_checkpoint": DEFAULT_TRANSFORMER_CHECKPOINT.exists(),
|
|
@@ -383,32 +385,44 @@ def has_python_verovio_renderer() -> bool:
|
|
| 383 |
return True
|
| 384 |
|
| 385 |
|
| 386 |
-
def
|
| 387 |
try:
|
| 388 |
root = ET.fromstring(musicxml_data)
|
| 389 |
except ET.ParseError:
|
| 390 |
return None
|
| 391 |
for note in root.findall(".//note"):
|
| 392 |
-
|
| 393 |
-
note.
|
|
|
|
| 394 |
notations = note.find("notations")
|
| 395 |
-
if notations is None:
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
|
|
|
|
|
|
| 401 |
ET.indent(root)
|
| 402 |
return ET.tostring(root, encoding="unicode", short_empty_elements=True)
|
| 403 |
|
| 404 |
|
| 405 |
-
def render_musicxml_with_python_verovio(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 406 |
try:
|
| 407 |
import verovio
|
| 408 |
|
| 409 |
musicxml_data = musicxml_path.read_text(encoding="utf-8")
|
| 410 |
-
if strip_ties:
|
| 411 |
-
musicxml_data =
|
|
|
|
|
|
|
|
|
|
| 412 |
toolkit = verovio.toolkit()
|
| 413 |
toolkit.setOptions({"scale": 42})
|
| 414 |
svg = toolkit.renderData(musicxml_data, {}) if hasattr(toolkit, "renderData") else ""
|
|
@@ -431,6 +445,9 @@ def render_musicxml_to_svg(musicxml_path: Path) -> Path | None:
|
|
| 431 |
if python_svg is not None:
|
| 432 |
return python_svg
|
| 433 |
python_svg = render_musicxml_with_python_verovio(musicxml_path, svg_path, strip_ties=True)
|
|
|
|
|
|
|
|
|
|
| 434 |
if python_svg is not None:
|
| 435 |
return python_svg
|
| 436 |
verovio = shutil.which("verovio")
|
|
|
|
| 46 |
DEFAULT_MARKOV_CACHE = MARKOV_CACHE_DIR / "default.pkl"
|
| 47 |
MARKOV_CACHE_FORMAT_VERSION = 1
|
| 48 |
MARKOV_PRECOMPUTED_WARM_SAMPLES = 4
|
| 49 |
+
SCORE_PREVIEW_RENDER_VERSION = "strip-ties-beams-v1"
|
| 50 |
GENERATED_ROOT.mkdir(parents=True, exist_ok=True)
|
| 51 |
CATALOG_SCORE_ROOT.mkdir(parents=True, exist_ok=True)
|
| 52 |
|
|
|
|
| 127 |
"verovio": verovio_cli or verovio_python,
|
| 128 |
"verovio_cli": verovio_cli,
|
| 129 |
"verovio_python": verovio_python,
|
| 130 |
+
"score_preview_render_version": SCORE_PREVIEW_RENDER_VERSION,
|
| 131 |
"markov_cache_entries": len(_markov_cache),
|
| 132 |
"default_markov_cache": DEFAULT_MARKOV_CACHE.exists(),
|
| 133 |
"transformer_checkpoint": DEFAULT_TRANSFORMER_CHECKPOINT.exists(),
|
|
|
|
| 385 |
return True
|
| 386 |
|
| 387 |
|
| 388 |
+
def musicxml_preview_data(musicxml_data: str, *, strip_ties: bool = False, strip_beams: bool = False) -> str | None:
|
| 389 |
try:
|
| 390 |
root = ET.fromstring(musicxml_data)
|
| 391 |
except ET.ParseError:
|
| 392 |
return None
|
| 393 |
for note in root.findall(".//note"):
|
| 394 |
+
if strip_ties:
|
| 395 |
+
for tie in list(note.findall("tie")):
|
| 396 |
+
note.remove(tie)
|
| 397 |
notations = note.find("notations")
|
| 398 |
+
if strip_ties and notations is not None:
|
| 399 |
+
for tied in list(notations.findall("tied")):
|
| 400 |
+
notations.remove(tied)
|
| 401 |
+
if len(notations) == 0:
|
| 402 |
+
note.remove(notations)
|
| 403 |
+
if strip_beams:
|
| 404 |
+
for beam in list(note.findall("beam")):
|
| 405 |
+
note.remove(beam)
|
| 406 |
ET.indent(root)
|
| 407 |
return ET.tostring(root, encoding="unicode", short_empty_elements=True)
|
| 408 |
|
| 409 |
|
| 410 |
+
def render_musicxml_with_python_verovio(
|
| 411 |
+
musicxml_path: Path,
|
| 412 |
+
svg_path: Path,
|
| 413 |
+
*,
|
| 414 |
+
strip_ties: bool = False,
|
| 415 |
+
strip_beams: bool = False,
|
| 416 |
+
) -> Path | None:
|
| 417 |
try:
|
| 418 |
import verovio
|
| 419 |
|
| 420 |
musicxml_data = musicxml_path.read_text(encoding="utf-8")
|
| 421 |
+
if strip_ties or strip_beams:
|
| 422 |
+
musicxml_data = (
|
| 423 |
+
musicxml_preview_data(musicxml_data, strip_ties=strip_ties, strip_beams=strip_beams)
|
| 424 |
+
or musicxml_data
|
| 425 |
+
)
|
| 426 |
toolkit = verovio.toolkit()
|
| 427 |
toolkit.setOptions({"scale": 42})
|
| 428 |
svg = toolkit.renderData(musicxml_data, {}) if hasattr(toolkit, "renderData") else ""
|
|
|
|
| 445 |
if python_svg is not None:
|
| 446 |
return python_svg
|
| 447 |
python_svg = render_musicxml_with_python_verovio(musicxml_path, svg_path, strip_ties=True)
|
| 448 |
+
if python_svg is not None:
|
| 449 |
+
return python_svg
|
| 450 |
+
python_svg = render_musicxml_with_python_verovio(musicxml_path, svg_path, strip_ties=True, strip_beams=True)
|
| 451 |
if python_svg is not None:
|
| 452 |
return python_svg
|
| 453 |
verovio = shutil.which("verovio")
|