JMSL Tutorial: JScore's Transcriber, part 1
Consider the problem of notating event durations which do not conform to traditional durations. The user may have any number of note events scattered arbitrarily over time, generated stochastically for example, and wishes to create a score of this material in common music notation. JMSL's Transcriber analyzes the timestamps of such musical material, and loads a Score with a transcription.
Transcribing algorithmically generated music
The input to JMSL's Transcriber is a MusicShape (an ordered list of timestamped musical events) and a list of time signatures and tempos which provide a template for the transcription. The output is a notated Score. The power of the transcriber lies in its generality and customizability.
Customizing the transcriber
Besides providing a template of time signatures and tempos, the composer can customize the beat subdivisions considered by the transcriber (ie triplets, quintuplets, etc). The user can use a default list of beat subdivisions, or may specify precisely which beat subdivisions the transcriber may consider (allowing for example quarter note triplets, eighth note quintuplets, sixteenth note septuplets, and disallowing all others). All such “BeatDivisionSchemes” under consideration are contained in a BeatDivisionSchemeList. By adding BeatDivisionSchemes to this master list, the user can customize the transcriber, which will limit its analysis to those in the list. Excluded subdivisions are not considered.
Additional rhythmic customization can be achieved by specifying the minimum number of elements to be present for a particular BeatDivisionScheme to be considered. For example, one might specify that the minimum number of notes in an eighth note triplet be three, eliminating the possibility of a triplet containing two notes. One can massage this threshold and in general, specify a minimum of any value between 1 and N notes for an N-subdivision.
A powerful call-back mechanism is provided during the transcription process. The composer can create a TranscriberListener and register it with the Transcriber. Every time a Note is added to the Score, the listener is notified. This can been used to add algorithmically generated lyrics, slurs, dynamics, and markings to the Note.
Heuristic Search for path of minimum error, some technical details
The transcriber's goal is to discover a path of BeatDivisionSchemes that expresses the measure's events with minimum error. An example of a winning path through a measure of 4/4 might be quarter note triplets spanning the first two beats of the measure, followed by a eighth note triplet for the third beat, ending with a single quarter note. The search space of all possible paths through a measure's beats grows quickly even when a modest number of possible BeatDivisionSchemes are considered. By default JMSL considers 21 distinct BeatDivisionSchemes. A measure of 4/4 yields a total of 214=194,481 possible paths. To find the minimum cost path efficiently, the transcriber limits this search space by following a heuristic search strategy. Instead of expanding all search paths for every beat, it expands at each beat only the one path which is ranked with minimum error. It expands this lowest cost path into the next beat by building multiple copies of it, each with a new BeatDivisionScheme at its head. After recalculating error of these new paths as well as all old paths, it resorts and again chooses the minimum cost path for expansion into the next beat. An old path might then have the lowest error, which promotes it for expansion. This process is repeated until the last beat is reached and an overall winning path is determined. Note that backtracking is implemented here, since a path which did not promise minimal error early in the search may win in the end.
(C) 2000 Nick Didkovsky and Phil Burk, All Rights Reserved
JMSL is based upon HMSL (C) Phil Burk, Larry Polansky and David Rosenboom.