Music21 v9 (June 2023) is the latest release of `music21`, a toolkit for computational music research.
Version 9 contains about 600 new commits and features from the version 8 release from September 2022. It is the latest and best release in the industry standard toolkit for doing music research and composition ("traditional" computation and AI/ML) with musical scores.
As a new Version X release, `music21` gains a lot of its power with a few non-backwards compatible changes that make the system easier to use, faster, and more up to date. People using music21 in existing environments should read the change logs to make sure their systems work with it before upgrading.
A big change in music21 is that v9 is compatible with Python 3.10 and 3.11 only. The version 9 release will be updated to be compatible with at least Python 3.12 when it is released. Users on Python 3.8 and 3.9 should stick with v8 and those on older versions should look at the README to see what version will be installed for their systems.
Two weeks from the release of version 9 (July 1, 2023), Michael Asato Cuthbert, the lead developer of music21 will take a 6-12-month sabbatical from monitoring the mailing list, answering questions/issues, and merging PRs in order to focus on what he does best and what is best for the community: developing core parts of the system and documenting what already exists. Working with the user community has been amazing, but given that he only has about 10-15 hours per week to devote to the project, it often means deviating from efforts that help a large number of people to instead work through PRs and issues that are important to a smaller community. This news will probably not be welcomed by some, but the results should be better for the larger community.
What's Changed
* Music21 v9 is for Python 3.10 and 3.11 only and uses tools and speedups only available to those versions. Music21 drops its prior policy of supporting previous 3 versions and now supports the latest 2 versions only (to improve developer experience).
* Notebook/Jupyter: All pages are now shown on .show(). Compatible with Jupyter 7.0beta and JupyterLab. MIDI improvements (mscuthbert in https://github.com/cuthbertLab/music21/pull/1592)
* Added to corpus: (1) Queen Liliuokalani’s Aloha Oe, (2) J.R. Johnson’s Lift Every Voice And Sing (3) Vincente Lusitano’s madrigal Allor che Ignuda – part of a larger project to make the music21 corpus more representative.
* Lots more typing! Use `music21` in a modern IDE to see it. Uses Python 3.10 TypeGuards. Add common.classTools.holdsType([‘a’, ‘b’], str) which asserts that everything in a collection has the same type. (mscuthbert in https://github.com/cuthbertLab/music21/pull/1447). converter and corpus are fully typed.
* Docs! Documentation of equality explained better. braille, corpus, converter much improved. (1) Much better aesthetics and utility mscuthbert in https://github.com/cuthbertLab/music21/pull/1455 and #1452). (2) Add “developerReference/startingOver” – mistakes made in designing `music21` that are too late to fix, but the next generation of software should not emulate. (3) add docs about abcFormat support (mscuthbert in https://github.com/cuthbertLab/music21/pull/1484). (4) coreInsert (mscuthbert in https://github.com/cuthbertLab/music21/pull/1549). (5) layout (mscuthbert in https://github.com/cuthbertLab/music21/pull/1554). (6) clercqTemperley (RS100 dataset) format (#1558)
* RomanText and related formats: (1) Repeats in RT and TSV are improved (malcolmsailor in https://github.com/cuthbertLab/music21/pull/1434, https://github.com/cuthbertLab/music21/pull/1435, https://github.com/cuthbertLab/music21/pull/1503) (2) anacrusis support (mscuthbert in https://github.com/cuthbertLab/music21/pull/1532) (3) measure numbers on ClercqTemperley (mscuthbert in https://github.com/cuthbertLab/music21/pull/1558)
* harmony: (1) RomanNumerals and ChordSymbols with front accidentals (flat II, sharp IV, etc.) now take their 7ths, 9ths, etc. from the underlying keys (mscuthbert w/ thanks to malcolmsailor in https://github.com/cuthbertLab/music21/pull/1439), (2) RomanNumeral’s writeAsChord works properly (mscuthbert in https://github.com/cuthbertLab/music21/pull/1445)
and (3) transpose properly (malcolmsailor in https://github.com/cuthbertLab/music21/pull/1414). (4) roman.RomanNumeral(2, ‘C’) will now give d-minor, not d-major (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1481), (5) preferSecondaryDominants implements V/x (MarkGotham in https://github.com/cuthbertLab/music21/pull/796).
* MusicXML improvements: (1) TempoText is exported (gregchapman-dev in https://github.com/cuthbertLab/music21/pull/1437)
(2) harmony/numeral figures are MusicXML 4.0 compatible (mscuthbert in https://github.com/cuthbertLab/music21/pull/1445) (3) Preserve multiple fingerings on chords in musicxml import (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1475) (4) Translate "implicit" attribute of MusicXML measures (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1493) (5) Synchronize Measure IDs on Musicxml out (rigaux in https://github.com/cuthbertLab/music21/pull/1490) (6) MusicXML sound tag finds metronome marks (TimFelixBeyer in https://github.com/cuthbertLab/music21/pull/1579) (7) Add MusicXML security warning (mscuthbert in https://github.com/cuthbertLab/music21/pull/1584)
* Speed/Performance improvements on (1) deepcopy (mscuthbert in https://github.com/cuthbertLab/music21/pull/1464) (2) ABC (mscuthbert in https://github.com/cuthbertLab/music21/pull/1461) (3) LanguageDetector (mscuthbert in https://github.com/cuthbertLab/music21/pull/1456) (4) quantize() (TimFelixBeyer in https://github.com/cuthbertLab/music21/pull/1594) (5) use deques instead of pop(0) #1466, (6) searching/MetadataBundles cache in tests (mscuthbert in https://github.com/cuthbertLab/music21/pull/1511)
(7) findGaps() on gapless streams (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1515) (8) ChordSymbols (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1527)
* Braille – add segment.BrailleElementGrouping. Good amount of refactoring. (mscuthbert in 1495)
* Converter/Corpus: converter.toData – like .write or .show but gives the raw data as a string or byte by mscuthbert in https://github.com/cuthbertLab/music21/pull/1451
* Frozen/Immutable objects can be created now; this will allow for creating, for instance, one default 4/4 meter that cannot be changed but used as a default in many places. common.FrozenObject and duration.FrozenDuration (mscuthbert in https://github.com/cuthbertLab/music21/pull/1460)
* New subConverters register above default subConverters, so it is now possible to develop a subConverter like Greg’s converter21 project that handles a format music21 supports but do it differently or better. (mscuthbert in https://github.com/cuthbertLab/music21/pull/1520)
* Ornaments/Expressions (all by gregchapman-dev) – (1) ornament accidentals have a great new system and are aware of their measure and key context (https://github.com/cuthbertLab/music21/pull/1545) (2) Mordents get placement like Turn and Trill (https://github.com/cuthbertLab/music21/pull/1516) (3) Support for delayed turns (https://github.com/cuthbertLab/music21/pull/1533)
* Spanners: (1) Spanner.fill() – say you’ve set a slur to just include the first and last notes. .fill() will find all the intermediate notes. (gregchapman-dev in https://github.com/cuthbertLab/music21/pull/1486) (2) spanner.SpannerAnchor class allows a spanner to start and stop at a point where there is no other Music21Object at the offset (like a whole note crescendo that begins on beat 2 and ends on beat 3) (gregchapman-dev in https://github.com/cuthbertLab/music21/pull/1479). (3) Guitar: Hammer-on and Pull-off as Spanners (louisbigo in https://github.com/cuthbertLab/music21/pull/1142)
* Streams – (1) new module stream.tools and stream.tools.removeDuplicates (e.g. keys, clefs, by MarkGotham in https://github.com/cuthbertLab/music21/pull/1454) . (2) stream.makeNotation.saveAccidentalDisplayStatus() context manager for restoring pitches’ accidentalDisplayStatus after a manipulation (like transposition by octave) gregchapman-dev. (3) stream.makeNotation.makeOrnamentalAccidentals (#1545)
* Percussion: (1) Implement useful `PercussionChord.pitches` property (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1547), (2) Ignore Unpitched objects in key analysis (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1543, (3) Search support (mscuthbert in https://github.com/cuthbertLab/music21/pull/1597)
* MIDI: (1) Minimize gaps produced by quantization algorithm (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1540) (2) fix jupyter/colab MIDI (mscuthbert in https://github.com/cuthbertLab/music21/pull/1565) (3) Increase default MIDI ticksPerQuarter for higher accuracy of tuplets (TimFelixBeyer in https://github.com/cuthbertLab/music21/pull/1577)
* ABC: set version from I:abc-version information (mscuthbert in https://github.com/cuthbertLab/music21/pull/1589)
* pitch module gets: isValidAccidentalName, standardizeAccidentalName.
Bug fixes
* Ottava transposition bugs (in m21 and in musicxml output) (gregchapman-dev in https://github.com/cuthbertLab/music21/pull/1486)
* diminished and half-diminished 11th chord types were incorrect (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1497)
* Avoid creating duplicative ChordStepModifications (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1509)
* Zero quarterLengths will not be represented as Fraction(0, 1)
* MIDI: (1) Don't set status byte on Meta Message (TimFelixBeyer in https://github.com/cuthbertLab/music21/pull/1575) (2) unknown meta message still parses (TimFelixBeyer in https://github.com/cuthbertLab/music21/pull/1573)
* Fix stripTies when accidentals are natural & none (TimFelixBeyer in https://github.com/cuthbertLab/music21/pull/1556)
* Scores could previously change after .write()(TimFelixBeyer in https://github.com/cuthbertLab/music21/pull/1560)
* `requests` should have been in the minimum requirements (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1568)
* Prevent doubly-flatted sevenths in chord symbols (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1572)
Incompatible Changes not mentioned above:
* Equality: == or `__eq__` comparison on many objects has changed. – it is now based on a class hierarchy where the object needs to be equal in all of its super-classes (mscuthbert in https://github.com/cuthbertLab/music21/pull/1466 and https://github.com/cuthbertLab/music21/pull/1459).
For time signatures: (MarkGotham in https://github.com/cuthbertLab/music21/pull/1457). For ChordStepModification (jacobtylerwalls in https://github.com/cuthbertLab/music21/pull/1482). An exception is made for RomanNumerals which do not need to have pitches in the same octave (like their chord.Chord superclass requires)
* schumann folder is moved to schumann_robert to match (equally amazing) schumann_clara.
* subConverter is consistently spelled with capital C in all contexts. Before it was a mismash of capital C and lowercase C. (in 1592)
* Full Measure Rests taken into account Finale usage of the measure=”yes” tag on pickups (mscuthbert in https://github.com/cuthbertLab/music21/pull/1595)
* All Music21Objects must be hashable and default instantiate (mscuthbert in https://github.com/cuthbertLab/music21/pull/1467)
* Duration, volume, and StreamStatus all keep string references to clients (major change if you were playing with _client private variables. Only a public change if you were counting on garbage collection to run more often)
* contextSites that are derived fixes a bug.
* Developers using the private _deepcopySubclassable should know that “removeFromIgnore” has been removed for performance reasons.
* Spanner.prePostObjectSpanners is renamed “relatedSpanners()”
* A number of cases where an attribute which is usually a string started with None now start with ‘’ instead (typing improvement)
* Refactors to ipython21 and the IPython (now Jupyter), MIDI, MusicXML subconverters in 1592.
Removals
* Music21Exception subclasses not used in the system are removed. Reduce 172 Exceptions to 154 (mscuthbert in https://github.com/cuthbertLab/music21/pull/1465)
* musicxml.xmlToM21.textNotNone – use new strippedText() and check for False.
* Already marked for deprecation and removed: common.cleanupFloat() (use opFrac), common.euclidGCD (use math.gcd), Metadata.setWorkId (use md.uniqueName = value), VoiceLeadingQuartet.color() (assign colors to individual notes with .style.color), (1440)
Deprecations
* Spanner.numberRange replaces Spanner.getNumberList() — they do the same thing. (https://github.com/cuthbertLab/music21/pull/1447)
* romanText.clercqTemperley – toScore() – call toPart() instead since that is what it does.
* scale.next() – use scale.nextPitch() instead – since it shadows Music21Object.next()
New Contributors
* sararocks made her first contribution in https://github.com/cuthbertLab/music21/pull/1472
* rigaux made their first contribution in https://github.com/cuthbertLab/music21/pull/1490
* TimFelixBeyer made his first contribution in https://github.com/cuthbertLab/music21/pull/1560
**Full Changelog**: https://github.com/cuthbertLab/music21/compare/v8.3.0...v9.1.0