Monday, October 6, 2025

Music21 v9.9 released

Music21 v9.9 has been released.  It primarily fixes bugs that have been identified (and often fixed) by the community and adds enhancements from community contributions.

Update with 

pip install -u music21

Full change list: https://github.com/cuthbertLab/music21/releases/tag/v9.9.0

Highlights:

* Support Dorico as MusicXML reader

* music21.text.assembleLyrics: support custom word separator

* Add Docker and github codespace support

* Modernization of Lilypond syntax

* Unofficial support for Python 3.14 (to be released tomorrow)

* Stream.template(removeAll=True, exemptFromRemove={dynamic.Dynamics})

* UserSettings.items() and .values()

Bug fixes:

Lilypond support in Windows, spanner support in partsToVoices, RepeatBrackets import properly from musicxml for pianos, etc.

Improved docs, fixed links etc.

Next release will begin the v10 series with some backwards incompatibilities and new features.  I am hoping to replace the core Stream search with sortedcontainers which should give substantial speedups for large scores while being the same speed for faster for small scores.

As always thanks to the Seaver Institute, the National Endowment for the Humanities, and MIT SHASS for their past support of music21 and my wife Elina Hamilton for the current support <3.

Thursday, May 22, 2025

Music21 9.7 Released

Music21 v9.7 is an incremental, but still substantial release focusing mainly on import and export quality and speed. 

  • MIDI Lyrics are improved 
  • PedalMarks are added (with more to come)
  • Substantial new tools for FretBend and other tablature-based work. 
  • numpy 2.0–2.2 is now supported, which makes it possible to run music21 on Windows with Python 3.13 without a compiler -- this was the main reason for moving up the release by a month! 
 An update to the CONTRIBUTING guidelines -- all AI contributions must be explicitly mentioned. AI-generated contributions (whether properly declared or suspected) that do not pass tests will be closed without comment -- see Simon Williamson's blog about how AI is shifting the coding burden from programmers to reviewers for context. 

Thanks to @gregchapman-dev, @adhooge, @TimFelixBeyer, @jacobtylerwalls and many others for contributions to code.  And new, special thanks to Anne G. Hamill who has been helping very much with the music21list through some very difficult Google Groups times!

For detailed information, see https://github.com/cuthbertLab/music21/releases/tag/v9.7.0

Friday, June 16, 2023

Music21 v9 released!

 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.

See https://github.com/cuthbertLab/music21/releases/tag/v9.1.0 for a list of all major changes.

There are improvements to Corpus, Typing, DOCS!, RomanText and related formats, RomanNumerals and ChordSymbols, MusicXML (tempo, RN, measures, fingering), Speed improvements throughout, Braille, Converter, Frozen Objects, expanding subconverter, Ornaments, Spanners, Percussion, MIDI import, ABC, and stream tools, along with tons of bug fixes, and a few incompatible changes and deprecations.

I want to give a shoutout to Jacob Walls, Greg Chapman, and new contributor in a big way Tim Felix Beyer for major contributions.  Also to Sara Mildenstein and Philippee Rigaux for their first contributions to the code.  And to long-time contributors Mark Gothan, Malcolm Sailor, and Louis Bigo, and to everyone who made the system better with discussions here, bug reports, and articles, presentations, and mentions (thanks Carol Willing at PyCon!) of music21.  And to the Seaver Institute, NEH, and MIT for making so much possible!

v9 is a major milestone which I hope everyone will enjoy!  

Upgrade with

    pip3 install --upgrade music21


Thursday, October 27, 2022

Music21 v8 Released

 (this message should have gone out last month...)

I'm proud to release v8 of music21, the toolkit for computer-aided music analysis, score manipulation, computational musicology, etc. This release (technically 8.1) builds on 12.5 months of work from v7, and like all new big number releases has a few backwards incompatible changes from before, in exchange for cool new features.

Version 8 supports Python 3.8+, if you need Python 3.7 (such as on Google Colab which is now 3+ Python versions behind) stick to music21 v7. V8 is the first to fully support Python 3.10 and will receive patches to support Python 3.11 in the future. There will be a change to music21's Python support policy in v9: music21 v9 will support Python 3.10 and above only.

Big Changes

  • The biggest new improvement in v8 is an all new Dublin-Core / MARC based metadata system that allows for encoding a huge amount of information about a score. Look at the new docs for music21.metadata for more information. Thanks to Greg Chapman for the big amount of work on this.
  • Modern installation system, based on Hatch. If you have problems, please let me know -- I expect some growing pains on this.
  • ArpeggioMark and ArpeggioMarkSpanner classes.
  • Adding DCML v2 parsing to tsvConverter.py
  • Explicit Keywords on all music21 objects
  • Continued Major improvements in Typing across music21. If you are using a modern IDE, you will find the number of music21-related bugs you create will go down hugely.
  • Ever more docs and more relevant (and diverse examples)

Other changes/fixes since v7.3

  • opFrac speedup
  • Fix MIDI in Google Colab Notebooks (backported to 7.3.3)
  • Use more classes in getElementsByClass
  • Improve graphing docs and options
  • Accidentals never and if-absolutely-necessary
  • Add typing to key.py
  • makeRests(inPlace=True) returns None for scores
  • StreamCore is now a Music21Object; Iterator improvements
  • Avoid <forward> tags from expressions out of measure bounds
  • Avoid writing empty <movement-title /> and <creator /> tags when title and author have no defaults
  • harmonicFunction. maps between RN figures and function labels
  • Make cautionaryPitchClass=True work with chords
  • Export Unpitched to MIDI
  • Fix getPitches(direction=DESCENDING) returning ascending scales
  • Make Key instances compare equal regardless of tonic octave
  • Fix midmeasure clef export regression involving voices
  • Fix a bug in musicxml/partStaffExporter.py where a clef-octave-change
  • Musicxml export: Preserve whitespace in TextBox
  • Fix bug in Capella parsing
  • Patch duration linked bugs
  • deprecate gcd in favor of C math
  • makeTies within makeNotation; getTimeSignatures recurse
  • First docs and improvements to trees
  • Fix shiftElements docs
  • SixthMinor carries to secondary dominants
  • Add makeNotation routines for completing or consolidating tuplets
  • Demonstrate ties in splitElementsToCompleteTuplets doctest
  • MusicXML export: Make rests before making notation
  • Validate figures provided to RomanNumeral()
  • Clear cache when adding notes w/o sort
  • match d43, d65, etc.
  • Use requests lib. for URL getting
  • Allow iterables of qualified class names in Stream.__getitem__ searches
  • Fix problem with add#7
  • Add makeNotation argument to test utility
  • Prevent too large <backup> values in PartStaffExporter
  • Prevent zero-duration ChordSymbols from matching stripTies algorithm
  • fixed up romanText repeats
  • Remove *arguments where not used
  • Standardize DatePrimitive -> Date interaction
  • Emphasize Pitches in Interval classes
  • Voice numbers written in MusicXML must be unique
  • Parse double flats in RomanText
  • Fix (and test) writing of multi-measure RepeatBrackets to MusicXML
  • romanText write to file-like objects
  • Closing too many TinyNotation states is now a TNException
  • Fix loss of forward repeat marks when exporting PartStaffs
  • Add typing for contextSites, yieldSites
  • Get rid of imp / load_source()
  • Remove tons of unnecessary imports in doctests
  • Clarify copyright entities
  • Use hatch for building

Sunday, March 27, 2022

Music21 v7.3 released

Music21 version 7.3 is released.  This is the second and probably final release on the v7 line.  I begin work on version 8 today.

Version 7.3 is a bug-fix, improvement, and maintenance release of music21.  Aside from a few obscure corners of the code, it is designed to be fully backwards compatible with the previous v7 releases (7.1).  It represents half a year's work since the original v7.1 release.

Thanks go especially to Jacob Tyler Walls who really steered the contributions to this release.

Among the major improvements in this branch are:

  • Full support for Python 3.10.
    • I've been doing all my recent dev on 3.10 taking advantage of new features, and it's great, and plays well with numpy, tensorflow, and so many other cutting edge analysis tools.
    • In keeping with music21's policy of supporting the last three versions of Python, music21 v7.3 will be the last version of music21 to support Python 3.7.  A decision on whether 3.8 or 3.9 will be the minimum version for music21 v8 will come later, depending on its release date; we may also update policy somewhat and raise the minimum version to 3.9 during the v8 cycle.
  • MIDI and MusicXML import/export will create and use Unpitched and PercussionChord objects. (slight incompatibility but worth it).
  • The stripTies method's "matchByPitch" setting is improved.
  • Slight incompatibility:  3/8 is default configured to one beat with two sub beats (like 6/8)
  • Lots more typing improvements.  mypy is now being run on a subset of the music21 code to ensure that our docs match our work.
  • Individual notes in Chords can be styled more easily and robustly.
  • The tree module is slightly better documented, for anyone who wants to work with insane speed (and complexity)
  • Some superfluous natural signs no longer appear after running makeNotation; makeAccidentals improvements throughout.  displayType="never" is now respected.
  • Improvements in instrument names and lookup (Thanks Mark Gotham)
  • Music21 gives better introspection in more developer environments. Music21 now imports its own modules individually.  The former way of doing its own imports while "legal" was preventing code analysis on some IDEs.
  • Dissonance score on certain compound intervals has been improved.
  • ChordSymbol constructor has been improved
  • Metronome marks only appear on the top staff of piano and other PartStaff scores.  Other superfluous meters and key signatures on various outputs (especially MIDI) have been fixed.
  • Braille exports voices properly; full scores including piano (PartStaff) export to Braille.
  • Ottava objects import better from musicxml
  • Bug fixes on changing RomanNumeral objects, or round-tripping chordFromFigure(romanNumeralFromChord(ch).figure), especially with bracketed alterations and on minor vi/VI/vio and vii/VII/viio
  • GarageBand is now set as the default MIDI player on MacOS.  It's a bit of overkill to be sure, but it's the only MIDI player that comes with the system, and to be honest, it sounds really good.
  • More .commonName improvements for enharmonic respellings of common chords.
  • TempoText preserves styles even if the text changes (thanks Greg Chapman)
  • RomanNumerals now treat common ways of inputting suspensions (V54, etc.) as suspensions rather than obscure 11th chords, etc.  Note, however, that RomanNumerals are not a fully consistent/comprehensive chord description format, so there will always be some gaps in coverage.
Smaller improvements and features include:

  • Root position Neapolitan chords can be written as "N53"
  • Better support for output on systems where UTF-8 is not the default.
  • Time Signatures export to MIDI
  • Instruments that normally have a certain transposition (Trumpet = Bb, etc.) now respect part parsing of "Trumpet in C"
  • More gaps in streams export to MusicXML as "forward" tags.
  • Braille output supports more technical indications beyond fingerings, such as bowings.
  • Hidden features in chord.tables are now exposed and documented.
  • chordReduction (beta) crashes less often. 
  • Figured bass input supports notation like "64" (same as RomanNumeral) in addition to the older "6, 4" syntax.
  • Date metadata supports error ranges better.
  • attachIntervalsBetweenStreams is now more robust on subsequent runs if the streams are being edited.
  • Some edge cases of ChordSymbol's with add/subtract/alter/omit have been fixed.
  • A corpus file with an offensive name has been renamed and edited.  It came from a bulk import of an existing collection that was never closely scrutinized.  There are files in the corpus from minstrel show traditions that would never been added today; however, because so many existing tutorials etc. rely on these files being in the corpus, they have not been removed now.  They may be in the future.
  • ChordSymbols with realized durations are exported properly.
  • Up to 2048th notes can now be beamed.
  • getSpannerSites can now take classes.
  • Correct spelling of "bemol" in Spanish.
  • localCorpus.removePath fixed.
  • harmony.NoChord improvements.
  • Faster MIDI import/export
  • Crescendo and Decrescendo wedges have correct and sane id numbers in musicxml output.
  • el.next(activeSiteOnly=True) no longer occasionally finds things in other streams.
  • .show('musicxml') on a single measure is improved (and works well in Finale 27).
  • Users who choose to skip makeNotation on musicxml writing (in general don't!) will have exceptions thrown if notation that cannot appear in musicxml gets through, rather than just corrupt musicxml.  This does not affect the 99.9% of us who let music21 change notation to reflect what can be written in a score. 
Deprecations:
  • TimeSignature.loadRatio() deprecated.  Use TimeSignature.load() [same] or TimeSignature.ratioString = '4/4'
  • Score.flattenParts() -- just iterate over .parts and call flatten() on that.
  • Duration.fill() -- this was a testing routine that got exposed.
Goals for the upcoming v.8 include support for MusicXML 4.0 and SMuFL and better round-tripping between various formats, cleaner typing, improved docs and faster operations.  Improved support for IDEs including Jupyter notebook and Colab will also be prioritized.

There are other new features, such as improving OMR post-processing, restoring the web/VexFlow 4.0 connection, etc., but (as people who have proposed major new features on GitHub will be aware), I'm planning on considering the core music21 largely "feature complete" and encouraging people to make external libraries (now that pip + GitHub makes this so much easier) rather than stuffing more into music21.  I'd rather focus music21 on being the core system for so much else than putting more into it.  I don't plan on removing anything currently in music21 in the next version, but you may find that they're being imported from other libraries instead.  This will let the community move at the pace some people there want while letting me guide the core project as 15 years of development on it has taught me.

As ever, music21 would not have been possible without support from the Seaver Institute, the National Endowment for the Humanities and the multinational Digging into Data challenge, and the support of MIT/SHASS/Music & Theater Arts.