Handle missing SheetSage beat grid in short inputs
Browse files- pipeline.py +7 -3
- test_sampler.py +4 -1
pipeline.py
CHANGED
|
@@ -403,7 +403,8 @@ def generate_all(source: str, instrument: str, styles: dict[str, str], seed: int
|
|
| 403 |
"result_seconds": dict(durations), "drum_hits": drum_count,
|
| 404 |
"yue_requested": include_yue, "yue_timing": dict(yue_timing),
|
| 405 |
"errors": dict(errors), "complete": complete,
|
| 406 |
-
"source_timing_preserved":
|
|
|
|
| 407 |
"bass_transpose_semitones": bass_shift,
|
| 408 |
"bass_source": bass_source,
|
| 409 |
"transcription_source": transcription_source,
|
|
@@ -411,7 +412,8 @@ def generate_all(source: str, instrument: str, styles: dict[str, str], seed: int
|
|
| 411 |
"yue_vocal_absence_guaranteed": False,
|
| 412 |
"elapsed_seconds": round(time.monotonic() - began, 2)}
|
| 413 |
return (*(outputs[name] for name in VARIANTS), str(melody_midi),
|
| 414 |
-
str(drums_midi) if drums_midi else None,
|
|
|
|
| 415 |
str(folder / "instrumental-melody.abc"), metadata)
|
| 416 |
|
| 417 |
if progress:
|
|
@@ -428,7 +430,7 @@ def generate_all(source: str, instrument: str, styles: dict[str, str], seed: int
|
|
| 428 |
try:
|
| 429 |
midi, melody_abc, full_abc, beat_lab = transcribe(pcm24, folder, log)
|
| 430 |
except RuntimeError as error:
|
| 431 |
-
if "could not export ABC" not in str(error):
|
| 432 |
raise
|
| 433 |
errors["sheet_sage"] = "SheetSage2 не смог записать ноты в ABC"
|
| 434 |
midi, melody_abc, full_abc, beat_lab = (
|
|
@@ -451,6 +453,8 @@ def generate_all(source: str, instrument: str, styles: dict[str, str], seed: int
|
|
| 451 |
progress(.30, desc="Синтезирую инструмент и барабаны")
|
| 452 |
melody_raw, melody_midi = render_instrument(midi, folder, instrument, duration, log)
|
| 453 |
try:
|
|
|
|
|
|
|
| 454 |
drums_raw, drums_midi, drum_count = render_drums(midi, beat_lab, folder,
|
| 455 |
duration, log)
|
| 456 |
solo_raw, combined_raw = pair_with_drums(melody_raw, drums_raw, folder)
|
|
|
|
| 403 |
"result_seconds": dict(durations), "drum_hits": drum_count,
|
| 404 |
"yue_requested": include_yue, "yue_timing": dict(yue_timing),
|
| 405 |
"errors": dict(errors), "complete": complete,
|
| 406 |
+
"source_timing_preserved": [name for name in SAMPLER_VARIANTS
|
| 407 |
+
if outputs[name]],
|
| 408 |
"bass_transpose_semitones": bass_shift,
|
| 409 |
"bass_source": bass_source,
|
| 410 |
"transcription_source": transcription_source,
|
|
|
|
| 412 |
"yue_vocal_absence_guaranteed": False,
|
| 413 |
"elapsed_seconds": round(time.monotonic() - began, 2)}
|
| 414 |
return (*(outputs[name] for name in VARIANTS), str(melody_midi),
|
| 415 |
+
str(drums_midi) if drums_midi else None,
|
| 416 |
+
str(beat_lab) if beat_lab.is_file() else None,
|
| 417 |
str(folder / "instrumental-melody.abc"), metadata)
|
| 418 |
|
| 419 |
if progress:
|
|
|
|
| 430 |
try:
|
| 431 |
midi, melody_abc, full_abc, beat_lab = transcribe(pcm24, folder, log)
|
| 432 |
except RuntimeError as error:
|
| 433 |
+
if "SheetSage2 could not export" not in str(error) or "ABC" not in str(error):
|
| 434 |
raise
|
| 435 |
errors["sheet_sage"] = "SheetSage2 не смог записать ноты в ABC"
|
| 436 |
midi, melody_abc, full_abc, beat_lab = (
|
|
|
|
| 453 |
progress(.30, desc="Синтезирую инструмент и барабаны")
|
| 454 |
melody_raw, melody_midi = render_instrument(midi, folder, instrument, duration, log)
|
| 455 |
try:
|
| 456 |
+
if not beat_lab.is_file():
|
| 457 |
+
raise ValueError("SheetSage2 не дал сетку долей; барабаны пропущены")
|
| 458 |
drums_raw, drums_midi, drum_count = render_drums(midi, beat_lab, folder,
|
| 459 |
duration, log)
|
| 460 |
solo_raw, combined_raw = pair_with_drums(melody_raw, drums_raw, folder)
|
test_sampler.py
CHANGED
|
@@ -25,7 +25,6 @@ class SamplerTest(unittest.TestCase):
|
|
| 25 |
("empty.mid", "empty.abc", "beat.lab"))
|
| 26 |
pretty_midi.PrettyMIDI().write(str(empty))
|
| 27 |
abc.write_text("unusable empty melody")
|
| 28 |
-
beat.write_text("0 1 4 4\n.5 2 4 4\n1 3 4 4\n")
|
| 29 |
|
| 30 |
def fake_mp3(_, target, __, **___):
|
| 31 |
target.write_bytes(b"fake mp3")
|
|
@@ -46,6 +45,10 @@ class SamplerTest(unittest.TestCase):
|
|
| 46 |
self.assertIn("SheetSage2 не нашёл нот", result[-1]["errors"]["sheet_sage"])
|
| 47 |
self.assertEqual(len(pretty_midi.PrettyMIDI(str(empty)).instruments[0].notes), 1)
|
| 48 |
self.assertNotIn("Vocal", abc.read_text())
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
def test_archive_keeps_original_bytes_and_uses_opaque_name(self):
|
| 51 |
from pipeline import archive_recording, source_sha256
|
|
|
|
| 25 |
("empty.mid", "empty.abc", "beat.lab"))
|
| 26 |
pretty_midi.PrettyMIDI().write(str(empty))
|
| 27 |
abc.write_text("unusable empty melody")
|
|
|
|
| 28 |
|
| 29 |
def fake_mp3(_, target, __, **___):
|
| 30 |
target.write_bytes(b"fake mp3")
|
|
|
|
| 45 |
self.assertIn("SheetSage2 не нашёл нот", result[-1]["errors"]["sheet_sage"])
|
| 46 |
self.assertEqual(len(pretty_midi.PrettyMIDI(str(empty)).instruments[0].notes), 1)
|
| 47 |
self.assertNotIn("Vocal", abc.read_text())
|
| 48 |
+
self.assertIsNone(result[12])
|
| 49 |
+
self.assertEqual(result[-1]["errors"]["instrument_drums"],
|
| 50 |
+
"SheetSage2 не дал сетку долей; барабаны пропущены")
|
| 51 |
+
self.assertNotIn("instrument_drums", result[-1]["source_timing_preserved"])
|
| 52 |
|
| 53 |
def test_archive_keeps_original_bytes_and_uses_opaque_name(self):
|
| 54 |
from pipeline import archive_recording, source_sha256
|