# spp2musicxml

Converts songs of Score Perfect Professional (`.son` files, SPP 5.0 to 6.0) to MusicXML, which MuseScore, Finale, Sibelius, Dorico and most other music notation programs read. Score Perfect's own MusicXML export leaves out much of a song; this converter reads the `.son` file itself.

Background, and the file format as far as it is known: <https://www.geekabit.nl/projects/score-perfect-to-musicxml-converter/>

## Use

It needs Python 3.11 or later, and nothing else.

The easiest: download `spp2musicxml.pyz`, one file, from the page above. Double-click it, or run `python3 spp2musicxml.pyz`, for the window; give it songs, `python3 spp2musicxml.pyz songs/`, for the command line below. On Windows, `py spp2musicxml.pyz` does the same. `tools/zipapp.sh` builds it from the source, into `build/`.

With a window: run `python -m spp2musicxml`, without songs, from the `src` directory, or `spp2musicxml-gui` once installed. Choose a song or a folder of songs, choose where to save the MusicXML files (by default next to the songs; uncheck that to choose a folder, and whether songs in subfolders go to the same subfolders there), and press Convert. The list shows per song what happened.

On the command line:

```
python -m spp2musicxml songs/            # every .son in songs/ and below, MusicXML next to each
python -m spp2musicxml -o out/ song.son  # into out/
python -m spp2musicxml -o out/ songs/    # into out/, songs in subfolders into the same subfolders there
python -m spp2musicxml --flat -o out/ songs/  # all into out/ itself
python -m spp2musicxml --debug-log debug.txt song.son  # what the reader saw, for finding faults
python -m spp2musicxml --log run.log songs/  # also add what became of each song to run.log
```

Installed with `pip install .`, the commands are `spp2musicxml` and `spp2musicxml-gui`.

`--version` shows the version, the git commit it was built from, and when; the log and the MusicXML files say the same.

Pictures in a song are saved next to the MusicXML file as PNG.

When a song's MusicXML file is already there, both ask whether to overwrite it: per song, or for all. On the command line, `--overwrite` or `--skip` decides without asking; without a terminal to ask on, such songs are skipped.

With `--log FILE`, what became of each song, converted or not and why, is added to FILE, with the date and time. In the window, "Write a log" turns that on or off, and it is `spp2musicxml.log` in the folder the MusicXML files go to; and "Write a debug log" also writes `spp2musicxml-debug.log` there, the same as `--debug-log` on the command line.

## What is converted

Notes, rests, chords, durations (dots, triplets), ties, slurs, accidentals and spelling, key and time signatures and their changes, clefs, bar lines and repeats, voltas, upbeats, lyrics, chord symbols, dynamics, articulations, trills and turns, tremolos, arpeggios, glissandos, ottavas, free texts and rehearsal marks, part names, note colours, note head shapes (hidden, x, diamond, slash, ...), tempo changes, MIDI programs and mixer volumes and pans, parts drawn on one staff (as voices), brackets and braces (a piano or organ as one part with two or three staves), and pictures.

Songs of the format from before SPP 5 (SPP 1.4 to 4.94) are read as well, so far their notes, lyrics, ornaments and marks, keys, time signatures, bar lines, clefs and clef changes, voltas and part names, brackets and braces, titles and texts, and slurs. Saving such a song in SPP 5 first, where possible, still gives the fuller result.

Not yet: parts drawn on one staff, other tuplets than triplets as such, chord diagrams, note heads, breath marks, and more; see `TODO.md`.

## Development

`tools/check.sh` runs every check: ruff, mypy, pylint, shellcheck, the spelling, and the tests, which convert the corpus of songs in `../songs` when it is there. `tools/survey.py` counts what the reader does not understand yet over a set of songs; `tools/dump_notes.py` shows the note records of a song. `research/wine/` drives Score Perfect under Wine, to make test songs.

## Licence

CC0 1.0: public domain. See `LICENSE`.
