Converter for parsing the tabular representations of harmonic analysis such as the DCMLab’s Annotated Beethoven Corpus (Neuwirth et al. 2018).


class music21.romanText.tsvConverter.M21toTSV(m21Stream)

Conversion starting with a music21 stream. Exports to tabular data format and (optionally) writes the file.

>>> bachHarmony = corpus.parse('bach/choraleAnalyses/riemenschneider001.rntxt')

The initialisation includes the preparation of a list of lists, so

>>> initial = romanText.tsvConverter.M21toTSV(bachHarmony)
>>> tsvData = initial.tsvData
>>> tsvData[1][0]

M21toTSV methods


Converts a list of music21 chords to a list of lists which can then be written to a tsv file with toTsv(), or processed another way.


Writes a list of lists (e.g. from m21ToTsv()) to a tsv file.


class music21.romanText.tsvConverter.TabChord

An intermediate representation format for moving between tabular data and music21 chords.

TabChord methods


Creates and returns a music21.roman.RomanNumeral() object from a TabChord with all shared attributes. NB: call changeRepresentation() first if .representationType is not ‘m21’ but you plan to process it with m21 (e.g. moving it into a stream).

>>> tabCd = romanText.tsvConverter.TabChord()
>>> tabCd.numeral = 'vii'
>>> tabCd.global_key = 'F'
>>> tabCd.local_key = 'V'
>>> tabCd.representationType = 'm21'
>>> m21Ch = tabCd.tabToM21()

Now we can check it’s a music21 RomanNumeral():

>>> m21Ch.figure


class music21.romanText.tsvConverter.TsvHandler(tsvFile)

Conversion starting with a TSV file.

First we need to get a score. (Don’t worry about this bit.)

>>> name = 'tsvEg.tsv'
>>> path = common.getSourceFilePath() / 'romanText' / name
>>> handler = romanText.tsvConverter.TsvHandler(path)
>>> handler.tsvToChords()

These should be TabChords now.

>>> testTabChord1 = handler.chordList[0]
>>> testTabChord1.combinedChord

Good. We can make them into music21 Roman-numerals.

>>> m21Chord1 = testTabChord1.tabToM21()
>>> m21Chord1.figure

And for our last trick, we can put the whole lot in a music21 stream.

>>> out_stream = handler.toM21Stream()

TsvHandler methods


Imports TSV file data for further processing.


Prepares a music21 stream for the harmonic analysis to go into. Specifically: creates the score, part, and measure streams, as well as some (the available) metadata based on the original TSV data. Works like the .template() method, except that we don’t have a score to base the template on as such.


Takes a list of TabChords (self.chordList, prepared by .tsvToChords()), converts those TabChords in RomanNumerals (converting to the music21 representation format as necessary), creates a suitable music21 stream (by running .prepStream() using data from the TabChords), and populates that stream with the new RomanNumerals.


Converts a list of lists (of the type imported by importTsv) into TabChords (i.e. a list of TabChords).


music21.romanText.tsvConverter.characterSwaps(preString, minor=True, direction='m21-DCML')

Character swap function to coordinate between the two notational versions, for instance swapping between ‘%’ and ‘/o’ for the notation of half diminished (for example).

>>> testStr = 'ii%'
>>> romanText.tsvConverter.characterSwaps(testStr, minor=False, direction='DCML-m21')

In the case of minor key, additional swaps for the different default 7th degrees: - raised in m21 (natural minor) - not raised in DCML (melodic minor)

>>> testStr1 = '.f.vii'
>>> romanText.tsvConverter.characterSwaps(testStr1, minor=True, direction='m21-DCML')
>>> testStr2 = '.f.#vii'
>>> romanText.tsvConverter.characterSwaps(testStr2, minor=True, direction='DCML-m21')
music21.romanText.tsvConverter.getLocalKey(local_key, global_key, convertDCMLToM21=False)

Re-casts comparative local key (e.g. ‘V of G major’) in its own terms (‘D’).

>>> romanText.tsvConverter.getLocalKey('V', 'G')
>>> romanText.tsvConverter.getLocalKey('ii', 'C')

By default, assumes an m21 input, and operates as such:

>>> romanText.tsvConverter.getLocalKey('vii', 'a')

Set convert=True to convert from DCML to m21 formats. Hence;

>>> romanText.tsvConverter.getLocalKey('vii', 'a', convertDCMLToM21=True)
music21.romanText.tsvConverter.getSecondaryKey(rn, local_key)

Separates comparative Roman-numeral for tonicisiations like ‘V/vi’ into the component parts of a Roman-numeral (V) and a (very) local key (vi) and expresses that very local key in relation to the local key also called (DCML column 11).

While .getLocalKey() work on the figure and key pair:

>>> romanText.tsvConverter.getLocalKey('vi', 'C')

With .getSecondaryKey(), we’re interested in the relative root of a secondaryRomanNumeral:

>>> romanText.tsvConverter.getSecondaryKey('V/vi', 'C')

Checks whether a key is minor or not simply by upper vs lower case.

>>> romanText.tsvConverter.is_minor('F')
>>> romanText.tsvConverter.is_minor('f')

Makes a TabChord out of a list imported from TSV data (a row of the original tabular format – see TsvHandler.importTsv()).

This is how to make the TabChord:

>>> tabRowAsString1 = ['.C.I6', '', '1', '1.0', '1.0', '2/4', '1', '2', '3', '2.0',
...                                        'C', 'I', '', 'I', '', '', '', '', 'false']
>>> testTabChord1 = romanText.tsvConverter.makeTabChord(tabRowAsString1)

And now let’s check that it really is a TabChord:

>>> testTabChord1.numeral