diff --git a/README.md b/README.md index d538f7a..7aef34f 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,28 @@ # ireal-musicxml - iReal Pro to MusicXML converter. [![npm version](https://badge.fury.io/js/ireal-musicxml.svg)](https://badge.fury.io/js/ireal-musicxml) ![GitHub Build Status](https://github.com/infojunkie/ireal-musicxml/workflows/Test/badge.svg) # Demo - [Check out the demo!](https://blog.karimratib.me/demos/chirp/) You can upload one of the [iReal Pro main playlists](https://www.irealpro.com/main-playlists/) as a test. -# Usage +# Installation +- Install `xmllint` (included in [libxml2](http://www.xmlsoft.org/) on most platforms) +- `npm install && npm run build` +- `npm test` +# Usage ```javascript -import * as iRealMusicXml from 'ireal-musicxml' +import { + convertSync, + convert, + Playlist, + Converter +} from 'ireal-musicxml' const ireal = // Content of HTML file generated by iReal Pro or irealb:// URI -const playlistSync = iRealMusicXml.convertSync(ireal) -const playlistAsync = await iRealMusicXml.convert(ireal) +const playlistSync = convertSync(ireal) +const playlistAsync = await convert(ireal) // => { // name: // Playlist name // songs: [{ @@ -33,26 +40,40 @@ const playlistAsync = await iRealMusicXml.convert(ireal) // }] // } -const playlistManual = new iRealMusicXml.Playlist(ireal) -// => Same as above minus `musicXml` attribute +const playlistManual = new Playlist(ireal) +// => Same as above minus `musicXml` attribute. -const musicXml = iRealMusicXml.Converter.convert(playlistManual.songs[0]) -// => MusicXML output +const musicXml = Converter.convert(playlistManual.songs[0]) +// => MusicXML output of the first song in the above playlist. ``` ```bash -$ ireal-musicxml test/data/jazz.txt --songs=Blues +$ ireal-musicxml test/data/jazz.txt --songs=Blues --validate ``` -# Development +# Theory of operation +This module parses an iReal Pro URI or playlist file, and transforms each song it finds to a MusicXML lead sheet. The [iReal Pro format](doc/irealpro.md) does not feature melody lines, only chords and backing styles. The conversion tries to produce a high-fidelity replica of the source sheet by replicating the following aspects of the iReal Pro format: -`xmllint` is required to run tests and the cli tool (but NOT for the library). Tests are used to ensure that the generated MusicXML is valid. +## Harmonic information +The chords found in the iReal Pro song are translated to their MusicXML representation. Because the chords supported by iReal Pro are a subset of the [harmonic expressivity of MusicXML](https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/harmony/), this translation is exact. [More information can be found in this blog post](https://blog.karimratib.me/2020/11/30/ireal-musicxml.html#emitting-correct-chord-information). -``` -npm install -npm run test -``` +An additional detail is the handling of "alternate chords" that can be specified in iReal Pro - these also [will be handled in this converter eventually](https://github.com/infojunkie/ireal-musicxml/issues/2). + +## Rhythmic information +Because iReal Pro uses a fixed grid for each bar, rhythmic assumptions need to be made, [both in the iReal Pro app itself](https://www.irealb.com/forums/showthread.php?25161-Using-empty-cells-to-control-chord-duration) and in this converter. The [timing algorithm is described in this blog post](https://blog.karimratib.me/2020/11/30/ireal-musicxml.html#emulating-the-ireal-pro-playback-model), and some [follow-up works remains to be done](https://github.com/infojunkie/ireal-musicxml/issues/54). + +## Layout and styling information +The styling and layout of lead sheets has evolved over time to improve their accessibility in live situations, where musical information needs to be concise and readable. This includes the following score customizations: +- Using rhythmic notation or slash notation to display the chords +- Enhancing the size of the noteheads and chord names +- Removing uneeded elements from the score, such as clef and staff lines +- Fitting the score on one page where at all possible + +The MusicXML layouting support is expressive enough to represent all these customizations. Unfortunately, existing engraving software do not support the full set of MusicXML directives, thus being only partially able to recreate the intended scores. The (heavy-handed) solution is to go one additional step to [manually convert the MusicXML output from this present converter to the native format of the desired engraving software](https://github.com/infojunkie/ireal-musicxml/issues/16). + +## Backing track information +The backing track patterns of the iReal Pro styles are not documented. Therefore, a mapping needs to be made to support a play back of the converted MusicXML scores that replicates or approximates the original iReal Pro playback. This is achieved in 2 phases: + + - First, the MusicXML `sound/play/other-play[@type = 'groove']` element is used to capture the playback style as specified in the iReal Pro song. Because MusicXML does not currently feature a dedicated element to specify the performance style, the generic `other-play` element was [selected to capture this information](https://github.com/w3c/musicxml/discussions/449). -# Documentation -- More information [about the iReal Pro format](doc/irealpro.md). -- More information [about the MusicXML format](https://w3c.github.io/musicxml/). + - Next, the downstream playback component interprets the above MusicXML element to generate a backing track for the score. This is done in the [`musicxml-midi`](https://github.com/infojunkie/musicxml-midi) component that utilizes an extensive library of "grooves" to map the incoming iReal Pro style to MIDI accompaniment tracks.