Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MusicXML Import #1152

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Add MusicXML Import #1152

wants to merge 5 commits into from

Conversation

porime42
Copy link
Contributor

@porime42 porime42 commented May 20, 2024

Adding MusicXML capabilities may be the starting point for future support with NEUTRINO. This PR is for importing.

XmlSchemaClassGenerator used to generate MusicXML 4.0 schema for use with XmlSerializer. Most of new lines of code comes from it in: MusicXMLSchema.cs

Corresponding Discord Thread

@porime42
Copy link
Contributor Author

image
image
Able to use filepicker to open musicxml files and read lyrics atm

@porime42
Copy link
Contributor Author

image
Pitch, Tone, and Duration fields being read.

Thinking now about how key signatures, time signatures, and whole/half/eighth/sixteenth/etc. notes interpreted.

@porime42
Copy link
Contributor Author

porime42 commented May 24, 2024

Each individual notes includes information under the <alter> tag when exported:
https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/alter/

Verified under MuseScore by examining the musicxml export under different key signatures. As such, keeping track of key signatures is unneeded.

Also for reference: https://www.musicxml.com/publications/makemusic-recordare/notation-and-analysis/a-sample-musicxml-encoding/

@porime42
Copy link
Contributor Author

porime42 commented May 24, 2024

There exists compressed musicxml following the zip compression method under the file format .mxl but that can be addressed as separate concern.

@porime42
Copy link
Contributor Author

porime42 commented May 25, 2024

Addressing oxygendioxide's concern on character encoding, remember to check for it. Can see for an example:

// Detects lyric encoding

Check the entire .musicxml file to determine character encoding. It is assumed if the lyrics have a specific character encoding, so shall the overall .musicxml file and vice-versa.

@porime42
Copy link
Contributor Author

porime42 commented May 25, 2024

Regarding length of time, the <divisions> and <duration> are linked to one another: https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/divisions/

Seems to be a viable way of interpreting note length. A paper published on 2021 provides details on the <duration> element and a survey on how it is used in various programs: https://musescore.org/sites/musescore.org/files/2021-05/TN-MXML-duration-overview-i01.pdf

The <type> element may be an alternative usable with the single dot <dot> element and double dot <double-tongue> element. https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/type/

@porime42
Copy link
Contributor Author

porime42 commented Jun 1, 2024

Went with <divisions> and <duration> route for interpreting note length

Importing a basic MusicXML with Open... or Import Tracks... completed.

Using a sample MusicXML provided by NEUTRINO, importing into OpenUTAU, and rendering with Teto appears to match the result of the render from NEUTRINO with Zundamon

@porime42
Copy link
Contributor Author

porime42 commented Jun 8, 2024

image
Export menu item added and functionality working

@porime42
Copy link
Contributor Author

porime42 commented Jun 8, 2024

Valid skeleton MusicXML being exported. This is the export being opened in MuseScore
image

Now to figure out exporting notes.

@porime42
Copy link
Contributor Author

porime42 commented Jun 8, 2024

Export compatibility is in context of NEUTRINO. MusicXML is actually only used as an intermediary format to be converted to HTS .lab with a bundled utility named musicXMLtoLabel according to the the script which runs NETURINO:
image

The utility appears to be derived from https://github.com/taroushirani/xml2lab which itself seems to draw from https://www.sinsy.jp/

Food for thought, perhaps it's possible to skip straight to the .lab format.

@porime42
Copy link
Contributor Author

porime42 commented Jun 8, 2024

Able to have no elements under for full rest like <measure number="1"/>. Measures don't appear skip-able in number however

@porime42
Copy link
Contributor Author

porime42 commented Jun 10, 2024

Order that elements occur in a measure seem to matter to NEUTRINO

image
image

One would think generating MusicXMLSchema.cs with -r option to define order XmlSchemaClassGenerator would work. Turns out it's way too strict requiring deserialization to be in the same order. Even though order matters, MusicXML does not require strict ordering so this cannot be a solution.

One way to modify order on serialization is rearranging the order of the definitions themselves in whatever class within MusicXMLSchema.cs. Kinda hacky although

@porime42
Copy link
Contributor Author

porime42 commented Jun 10, 2024

There might be some incompatibility between programs. OpenUTAU and pals allows time signature change basically anywhere. MuseScore only allows placement at the start of the measure and following from that I dunno whether this is acceptable in the MusicXML standard.

Related to previous comment about order of elements mattering(?)

@porime42
Copy link
Contributor Author

For sake of simplicity, leaving out support for tempo and time signature changes in the middle of a measure.

Future changes add it can probably rewrite/customization serialization behaviour to do stuff like target NEUTRINO

@porime42
Copy link
Contributor Author

porime42 commented Jun 14, 2024

Use GetMinDurTick or related to get minimum length. Can use that with BPM and time signature number to calculate the total number of measures to export.

Use dynamic programming to efficiently translate OpenUtau notes to optimal number of MusicXML notes. See coin change and/or knapsack problem for reference. Data structures and algorithms coming in handy out in the wild kinda surprising 🤔

@porime42
Copy link
Contributor Author

porime42 commented Aug 6, 2024

Splitting Import/Export into different PR's to reduce complexity and have Import for testing earlier. Export will be handled in another PR

@porime42 porime42 changed the title [WIP] Add Import/Export support for MusicXML Add MusicXML Import Aug 6, 2024
@porime42 porime42 marked this pull request as ready for review August 6, 2024 17:07
@stakira
Copy link
Owner

stakira commented Aug 14, 2024

Could please you add some unit tests for this importer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants