Follow-up to #1017.
#1017 makes the sloppak loader synthesize a Drums placeholder whenever a drum_tab is present with no drum arrangement, so drums appear in the player's arrangement picker for drum+bass packs. But the library scanner path doesn't go through load_song(): extract_meta() (lib/sloppak.py) reads only manifest["arrangements"]. Since the editor strips drum arrangements to drum_tab on save, a drum+bass pack indexes with no drum arrangement — the library's arrangement list and instrument filters won't show drums, while the player picker (post-#1017) does. Picker and library now disagree.
Fix shape: extract_meta() already has the manifest in hand — when manifest.get("drum_tab") is set and no arrangement entry is drum-named, append the same {"name": "Drums", "notes": 0} placeholder to the returned arrangements list (metadata-only; notes is already 0 for all entries in this fast path). Reuse the shared drum-name helper requested on #1017 rather than a third copy of the keyword sniff.
Scope: lib/sloppak.py extract_meta() + a test in tests/. No format surface — reader-side only, same as #1017.
Follow-up to #1017.
#1017 makes the sloppak loader synthesize a Drums placeholder whenever a
drum_tabis present with no drum arrangement, so drums appear in the player's arrangement picker for drum+bass packs. But the library scanner path doesn't go throughload_song():extract_meta()(lib/sloppak.py) reads onlymanifest["arrangements"]. Since the editor strips drum arrangements todrum_tabon save, a drum+bass pack indexes with no drum arrangement — the library's arrangement list and instrument filters won't show drums, while the player picker (post-#1017) does. Picker and library now disagree.Fix shape:
extract_meta()already has the manifest in hand — whenmanifest.get("drum_tab")is set and no arrangement entry is drum-named, append the same{"name": "Drums", "notes": 0}placeholder to the returnedarrangementslist (metadata-only;notesis already 0 for all entries in this fast path). Reuse the shared drum-name helper requested on #1017 rather than a third copy of the keyword sniff.Scope:
lib/sloppak.pyextract_meta()+ a test intests/. No format surface — reader-side only, same as #1017.