OpenUtau icon indicating copy to clipboard operation
OpenUtau copied to clipboard

Add MusicXML Import

Open porime42 opened this issue 1 year ago • 17 comments

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 avatar May 20 '24 02:05 porime42

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

porime42 avatar May 20 '24 02:05 porime42

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 avatar May 22 '24 07:05 porime42

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 avatar May 24 '24 23:05 porime42

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

porime42 avatar May 24 '24 23:05 porime42

Addressing oxygendioxide's concern on character encoding, remember to check for it. Can see for an example: https://github.com/stakira/OpenUtau/blob/b969d52860bf03502418b0f9353723c9f61d0450/OpenUtau.Core/Format/Midi.cs#L32

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 avatar May 25 '24 06:05 porime42

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 avatar May 25 '24 06:05 porime42

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 avatar Jun 01 '24 12:06 porime42

image Export menu item added and functionality working

porime42 avatar Jun 08 '24 10:06 porime42

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

Now to figure out exporting notes.

porime42 avatar Jun 08 '24 10:06 porime42

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 avatar Jun 08 '24 11:06 porime42

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

porime42 avatar Jun 08 '24 22:06 porime42

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 avatar Jun 10 '24 07:06 porime42

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 avatar Jun 10 '24 07:06 porime42

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 avatar Jun 10 '24 16:06 porime42

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 :thinking:

porime42 avatar Jun 14 '24 06:06 porime42

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

porime42 avatar Aug 06 '24 17:08 porime42

Could please you add some unit tests for this importer?

stakira avatar Aug 14 '24 06:08 stakira

I added some unit tests for this musicxml importer.

https://github.com/oxygen-dioxide/OpenUtau/commit/23b9183adefebb62508512cf478daf7819f00a0b

Musicxml files come from cuthbertLab/musicxmlTestSuite

oxygen-dioxide avatar Dec 17 '24 02:12 oxygen-dioxide

Thank you!

On Mon, Dec 16, 2024 at 20:49 oxygen-dioxide @.***> wrote:

I added some unit tests for this musicxml importer.

@.*** https://github.com/oxygen-dioxide/OpenUtau/commit/23b9183adefebb62508512cf478daf7819f00a0b

Musicxml files come from cuthbertLab/musicxmlTestSuite https://github.com/cuthbertLab/musicxmlTestSuite

— Reply to this email directly, view it on GitHub https://github.com/stakira/OpenUtau/pull/1152#issuecomment-2547390019, or unsubscribe https://github.com/notifications/unsubscribe-auth/BFDBW7U5EV6NRGAYQXBAD4T2F6GM3AVCNFSM6AAAAABI73ZCKOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNBXGM4TAMBRHE . You are receiving this because you authored the thread.Message ID: @.***>

porime42 avatar Dec 18 '24 19:12 porime42

@oxygen-dioxide Rebased onto the latest commit from master and then applied the commit from your branch on top.

On Wed, Dec 18, 2024 at 13:42 四十二porime @.***> wrote:

Thank you!

On Mon, Dec 16, 2024 at 20:49 oxygen-dioxide @.***> wrote:

I added some unit tests for this musicxml importer.

@.*** https://github.com/oxygen-dioxide/OpenUtau/commit/23b9183adefebb62508512cf478daf7819f00a0b

Musicxml files come from cuthbertLab/musicxmlTestSuite https://github.com/cuthbertLab/musicxmlTestSuite

— Reply to this email directly, view it on GitHub https://github.com/stakira/OpenUtau/pull/1152#issuecomment-2547390019, or unsubscribe https://github.com/notifications/unsubscribe-auth/BFDBW7U5EV6NRGAYQXBAD4T2F6GM3AVCNFSM6AAAAABI73ZCKOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKNBXGM4TAMBRHE . You are receiving this because you authored the thread.Message ID: @.***>

porime42 avatar Dec 20 '24 02:12 porime42