music21.romanText.tsvConverter

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

M21toTSV

class music21.romanText.tsvConverter.M21toTSV(m21Stream: Score, dcml_version: int = 2)

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

>>> bachHarmony = corpus.parse('bach/choraleAnalyses/riemenschneider001.rntxt')
>>> bachHarmony.parts[0].measure(1)[0].figure
'I'

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

>>> initial = romanText.tsvConverter.M21toTSV(bachHarmony, dcml_version=2)
>>> tsvData = initial.tsvData
>>> from music21.romanText.tsvConverter import DCML_V2_HEADERS
>>> tsvData[1][DCML_V2_HEADERS.index('chord')]
'I'

M21toTSV methods

M21toTSV.m21ToTsv() List[List[str]]

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.

M21toTSV.write(filePathAndName: str)

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

TabChord

class music21.romanText.tsvConverter.TabChord

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

TabChord bases

TabChord read/write properties

Read/write properties inherited from TabChordBase:

TabChord methods

Methods inherited from TabChordBase:

TabChordBase

class music21.romanText.tsvConverter.TabChordBase

Abstract base class for intermediate representation format for moving between tabular data and music21 chords.

TabChordBase read/write properties

TabChordBase.combinedChord

For easier interoperability with the DCML standards, we now use the column name ‘chord’ from the DCML file. But to preserve backwards- compatibility, we add this property, which is an alias for ‘chord’.

>>> tabCd = romanText.tsvConverter.TabChord()
>>> tabCd.chord = 'viio7'
>>> tabCd.combinedChord
'viio7'
>>> tabCd.combinedChord = 'IV+'
>>> tabCd.chord
'IV+'

TabChordBase methods

TabChordBase.populateFromRow(row: List[str], headIndices: Dict[str, Tuple[int, Type]], extraIndices: Dict[int, str]) None
TabChordBase.tabToM21() Harmony

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
'vii'

TabChordV2

class music21.romanText.tsvConverter.TabChordV2

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

TabChordV2 bases

TabChordV2 read/write properties

TabChordV2.beat

‘beat’ has been removed from DCML v2 in favor of ‘mn_onset’ and ‘mc_onset’. ‘mn_onset’ is equivalent to ‘beat’, except that ‘mn_onset’ is zero-indexed where ‘beat’ was 1-indexed, and ‘mn_onset’ is in fractions of a whole-note rather than in quarter notes.

>>> tabCd = romanText.tsvConverter.TabChordV2()
>>> tabCd.mn_onset = 0.0
>>> tabCd.beat
1.0
>>> tabCd.mn_onset = 0.5
>>> tabCd.beat
3.0
>>> tabCd.beat = 1.5
>>> tabCd.beat
1.5
TabChordV2.global_key

‘global_key’ has been renamed ‘globalkey’ in DCML v2. This property is provided as an alias for ‘globalkey’ so that TabChord and TabChordV2 can be used in the same way.

TabChordV2.local_key

‘local_key’ has been renamed ‘localkey’ in DCML v2. This property is provided as an alias for ‘localkey’ so that TabChord and TabChordV2 can be used in the same way.

TabChordV2.measure

‘measure’ has been removed from DCML v2 in favor of ‘mn’ and ‘mc’. ‘mn’ is equivalent to ‘measure’, so this property is provided as an alias.

Read/write properties inherited from TabChordBase:

TabChordV2 methods

Methods inherited from TabChordBase:

TsvHandler

class music21.romanText.tsvConverter.TsvHandler(tsvFile: str, dcml_version: int = 1)

Conversion starting with a TSV file.

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

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

These should be TabChords now.

>>> testTabChord1 = handler.chordList[0]
>>> testTabChord1.combinedChord
'.C.I6'

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

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

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

>>> out_stream = handler.toM21Stream()
>>> out_stream.parts[0].measure(1)[roman.RomanNumeral][0].figure
'I'

TsvHandler methods

TsvHandler.prepStream() Score

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.

TsvHandler.toM21Stream() Score

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.

TsvHandler.tsvToChords() None

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

Functions

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

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')
'iiø'
music21.romanText.tsvConverter.getForm(rn: RomanNumeral) str

Takes a music21.roman.RomanNumeral object and returns the string indicating ‘form’ expected by the DCML standard.

>>> romanText.tsvConverter.getForm(roman.RomanNumeral('V'))
''
>>> romanText.tsvConverter.getForm(roman.RomanNumeral('viio7'))
'o'
>>> romanText.tsvConverter.getForm(roman.RomanNumeral('IVM7'))
'M'
>>> romanText.tsvConverter.getForm(roman.RomanNumeral('III+'))
'+'
>>> romanText.tsvConverter.getForm(roman.RomanNumeral('IV+M7'))
'+M'
>>> romanText.tsvConverter.getForm(roman.RomanNumeral('viiø7'))
'%'
music21.romanText.tsvConverter.getLocalKey(local_key: str, global_key: str, convertDCMLToM21: bool = False) str

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

>>> romanText.tsvConverter.getLocalKey('V', 'G')
'D'
>>> romanText.tsvConverter.getLocalKey('ii', 'C')
'd'
>>> romanText.tsvConverter.getLocalKey('i', 'C')
'c'

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

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

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

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

Separates comparative Roman-numeral for tonicizations 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')
'a'

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

>>> romanText.tsvConverter.getSecondaryKey('V/vi', 'C')
'a'
music21.romanText.tsvConverter.handleAddedTones(dcmlChord: str) str

Converts DCML added-tone syntax to music21.

>>> romanText.tsvConverter.handleAddedTones('V(64)')
'Cad64'
>>> romanText.tsvConverter.handleAddedTones('i(4+2)')
'i[no3][add4][add2]'
>>> romanText.tsvConverter.handleAddedTones('Viio7(b4-5)/V')
'Viio7[no3][no5][addb4]/V'

When in root position, 7 does not replace 8: >>> romanText.tsvConverter.handleAddedTones(‘vi(#74)’) ‘vi[no3][add#7][add4]’

When not in root position, 7 does replace 8: >>> romanText.tsvConverter.handleAddedTones(‘ii6(11#7b6)’) ‘ii6[no8][no5][add11][add#7][addb6]’

‘0’ can be used to indicate root-replacement by 7 in a root-position chord. We need to change ‘0’ to ‘7’ because music21 changes the 0 to ‘o’ (i.e., a diminished chord). >>> romanText.tsvConverter.handleAddedTones(‘i(#0)’) ‘i[no1][add#7]’

music21.romanText.tsvConverter.isMinor(test_key: str) bool

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

>>> romanText.tsvConverter.isMinor('F')
False
>>> romanText.tsvConverter.isMinor('f')
True
music21.romanText.tsvConverter.localKeyAsRn(local_key: Key, global_key: Key) str

Takes two music21.key.Key objects and returns the roman numeral for local_key relative to global_key.

>>> k1 = key.Key('C')
>>> k2 = key.Key('e')
>>> romanText.tsvConverter.localKeyAsRn(k1, k2)
'VI'
>>> k3 = key.Key('C#')
>>> romanText.tsvConverter.localKeyAsRn(k3, k2)
'#VI'
>>> romanText.tsvConverter.localKeyAsRn(k2, k1)
'iii'