music21.romanText.clercqTemperley¶
Parses the de Clercq-Temperley popular music flavor of RomanText. The Clercq-Temperley file format and additional rock corpus analysis information may be located at http://rockcorpus.midside.com
CTSong¶
- class music21.romanText.clercqTemperley.CTSong(textFile: str | Path = '', **keywords)¶
This parser is an object-oriented approach to parsing clercqTemperley text files into music. It is an advanced method. Most people should just run:
>>> p = converter.parse('clercqTemperley/dt/BrownEyedGirl.cttxt')
or if the file ends in .txt then give the format explicitly as either ‘clerqTemperley’ or ‘cttxt’:
>>> p = converter.parse('BrownEyedGirl.txt', format='clercqTemperley')
Advanced: if you want access to a CTSong object itself (for manipulating the input before converting to a string, etc. then create a CTSong object with one of the following inputs:
by passing in the string, with newline characters (\n) at the end of each line
by passing in the filename as a string or path, and have Python open the file and read the text
Given this file, you could create a CTSong object with:
>>> exampleClercqTemperley = ''' ... % Brown-Eyed Girl ... VP: I | IV | I | V | ... In: $VP*2 ... Vr: $VP*4 IV | V | I | vi | IV | V | I | V | % Second half could be called chorus ... Ch: V | | $VP*2 I |*4 ... Ch2: V | | $VP*3 % Fadeout ... S: [G] $In $Vr $Vr $Ch $VP $Vr $Ch2 ... '''
Or:
>>> s = romanText.clercqTemperley.CTSong('C:/Brown-Eyed_Girl.txt')
When you call the .toPart() method on the newly created CTSong object, the code extracts meaningful properties (such as title, text, comments, year, rules, home time Signature, and home Key Signature) from the text file and returns a new Part object. It also makes these properties available on the CTSong object.
The toPart() method has two optional labeling parameters, labelRomanNumerals and labelSubsectionsOnScore. Both are set to True by default. Thus, the created score will have labels (on the chord’s lyric) for each roman numeral as well as for each section in the song (LHS). In case of a recursive definition (a rule contains a reference to another rule), both labels are printed, with the deepest reference on the smallest lyric line.
>>> p = s.toPart() >>> p.show()
>>> firstRN = p[roman.RomanNumeral][0] >>> firstRN.lyric 'I\nVP\nIn'
All roman numerals mark which formal division they are in:
>>> 'formalDivision' in firstRN.editorial True >>> firstRN.editorial.formalDivision ['VP', 'In']
The second RomanNumeral is at the start of no formal divisions
>>> secondRN = p[roman.RomanNumeral][1] >>> secondRN.lyric 'IV' >>> secondRN.editorial.formalDivision []
>>> s.title 'Brown-Eyed Girl'
>>> s.homeTimeSig <music21.meter.TimeSignature 4/4>
>>> s.homeKey <music21.key.Key of G major>
>>> s.comments [['Vr:', 'Second half could be called chorus'], ['Ch2:', 'Fadeout']]
Year is not defined as part of the Clercq-Temperley format, but it will be helpful to have it as a property. So let’s assign a year to this song:
>>> s.year = 1967 >>> s.year 1967
Upon calling toPart(), CTRule objects are also created. CTRule objects are the individual rules that make up the song object. For example,
>>> s.rules OrderedDict([('VP', <music21.romanText.clercqTemperley.CTRule text='VP: I | IV | I | V |'>), ('In', <music21.romanText.clercqTemperley.CTRule text='In: $VP*2'>), ('Vr', <music21.romanText.clercqTemperley.CTRule text='Vr: $VP*4 IV | V | I | vi | IV | V | I | V | % Second half could be called chorus'>), ('Ch', <music21.romanText.clercqTemperley.CTRule text='Ch: V | | $VP*2 I |*4'>), ('Ch2', <music21.romanText.clercqTemperley.CTRule text='Ch2: V | | $VP*3 % Fadeout'>), ('S', <music21.romanText.clercqTemperley.CTRule text='S: [G] $In $Vr $Vr $Ch $VP $Vr $Ch2'>)])
The parser extracts meaningful properties to each rule, such as sectionName, home time signature of that rule, home key of that rule, and of course the individual stream from the song corresponding to the rule.
The following examples display the instantiated properties of the second rule (list indexes start at one) as created above.
>>> rule = s.rules['In'] >>> rule.text 'In: $VP*2'
>>> rule.sectionName 'Introduction'
With this object-oriented approach to parsing the clercq-temperley text file format, we now have the ability to analyze a large corpus (200 files) of popular music using the full suite of harmonic tools of music21. We can not only analyze each song as a whole, as presented in Clercq and Temperley’s research, but we can also analyze each individual section (or rule) of a song. This may provide interesting insight into popular music beyond our current understanding.
Examples used throughout this class utilize the following Clercq-Temperley text file
>>> BlitzkriegBopCT = ''' ... % Blitzkrieg Bop ... BP: I | IV V | %THIS IS A COMMENT ... In: $BP*3 I IV | I | $BP*3 I IV | I | R |*4 I |*4 ... Vr: $BP*3 I IV | I | ... Br: IV | | I | IV I | IV | | ii | IV V | ... Co: R |*4 I |*4 ... S: [A] $In $Vr $Vr $Br $Vr $Vr $Br $Vr $Vr $Co ... '''
Another example using a different Clercq-Temperley file
RockClockCT = % Rock Around the Clock % just a general comment In: I | | | | | | V | | Vr: I | | | | IVd7 | | I | | V7 | | I | | %a comment on verse Vrf: I | | | | IVd7 | | I | | V7 | | I | IV iv | V | . I | S: [A] $In $Vr $Vr $Vr $Vr $Vr $Vr $Vrf % 3rd and 6th verses are instrumental
>>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.RockClockCT) >>> part = s.toPart() >>> part.highestTime 376.0
>>> s.title 'Rock Around the Clock'
>>> s.homeTimeSig <music21.meter.TimeSignature 4/4>
>>> s.homeKey <music21.key.Key of A major>
>>> s.comments [['just a general comment'], ['Vr:', 'a comment on verse'], ['S:', '3rd and 6th verses are instrumental']]
>>> s.year = 1952 >>> s.year 1952
>>> s.rules OrderedDict([('In', <music21.romanText.clercqTemperley.CTRule text='In: I | | | | | | V | |'>), ('Vr', <music21.romanText.clercqTemperley.CTRule text='Vr: I | | | | IVd7 | | I | | V7 | | I | | %a comment on verse'>), ('Vrf', <music21.romanText.clercqTemperley.CTRule text='Vrf: I | | | | IVd7 | | I | | V7 | | I | IV iv | V | . I |'>), ('S', <music21.romanText.clercqTemperley.CTRule text='S: [A] $In $Vr $Vr $Vr $Vr $Vr $Vr $Vrf % 3rd and 6th verses are instrumental'>)])
>>> rule = s.rules['In'] >>> rule.text 'In: I | | | | | | V | |'
>>> rule.sectionName 'Introduction'
CTSong
bases
CTSong
read-only properties
- CTSong.comments¶
Get the comments list of all CTRule objects.
comments are stored as a list of comments, each comment on a line as a list. If the comment is on a rule line, the list contains both the line’s LHS (like “In:”) and the comment if the comment is on a line of its own, only the comment is appended as a list of length one.
The title is not a comment. The title is stored under self.title
textString = ‘’’%Simple Gifts% A wonderful shaker melodyVr: I | I | %incomplete verseS: [A] $Vr % Not quite finished!’’’>>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.textString) >>> s <music21.romanText.clercqTemperley.CTSong title='Simple Gifts' year=None> >>> s.comments [['A wonderful shaker melody'], ['Vr:', 'incomplete verse'], ['S:', 'Not quite finished!']]
- CTSong.homeKey¶
gets the initial, or ‘home’, Key by looking at the music text and locating the key signature at the start of the S: rule.
>>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.textString) >>> s.homeKey <music21.key.Key of A major>
- CTSong.homeTimeSig¶
gets the initial, or ‘home’, time signature in a song by looking at the ‘S’ substring and returning the provided time signature. If not present, returns a default music21 time signature of 4/4
>>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.textString) >>> s.homeTimeSig <music21.meter.TimeSignature 4/4>
>>> change = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.changeIsGonnaCome) >>> change.homeTimeSig <music21.meter.TimeSignature 12/8> >>> change.homeTimeSig.beatSequence <music21.meter.core.MeterSequence {{1/8+1/8+1/8}+{1/8+1/8+1/8}+{1/8+1/8+1/8}+{1/8+1/8+1/8}}>
- CTSong.rules¶
Get the rules of a CTSong. the Rules is an OrderedDict of objects of type CTRule. If only a text file provided, this goes through text file and creates the rule object out of each line containing an LHS including the Song line, which should always be last.
>>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.BlitzkriegBopCT) >>> len(s.rules) 6 >>> for rule in s.rules: ... (rule, s.rules[rule]) ('BP', <music21.romanText.clercqTemperley.CTRule text='BP: I | IV V | %THIS IS A COMMENT'>) ('In', <music21.romanText.clercqTemperley.CTRule text='In: $BP*3 I IV | I | $BP*3 I IV | I | R |*4 I |*4'>) ('Vr', <music21.romanText.clercqTemperley.CTRule text='Vr: $BP*3 I IV | I |'>) ('Br', <music21.romanText.clercqTemperley.CTRule text='Br: IV | | I | IV I | IV | | ii | IV V |'>) ('Co', <music21.romanText.clercqTemperley.CTRule text='Co: R |*4 I |*4'>) ('S', <music21.romanText.clercqTemperley.CTRule text='S: [A] $In $Vr $Vr $Br $Vr $Vr $Br $Vr $Vr $Co'>)
Rules S is where we begin:
>>> s.rules['S'] <music21.romanText.clercqTemperley.CTRule text='S: [A] $In $Vr $Vr $Br $Vr $Vr $Br $Vr $Vr $Co'>
- CTSong.title¶
Get or set the title of the CTSong. If not specified explicitly but the clercq-Temperley text exists, this attribute searches first few lines of text file for title (a string preceded by a ‘%’) if found, sets title attribute to this string and returns this title)
>>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.textString) >>> s.title 'Simple Gifts'
Read-only properties inherited from ProtoM21Object
:
CTSong
methods
- CTSong.parse(textFile: str | Path)¶
Called when a CTSong is created by passing a string or filename; in the second case, it opens the file and removes all blank lines, and adds in new line characters returns pieceString that CTSong can call .expand() on.
>>> exCT = romanText.clercqTemperley.exampleClercqTemperley
This calls parse implicitly:
>>> s = romanText.clercqTemperley.CTSong(exCT)
>>> print(s.text) % Brown-Eyed Girl VP: I | IV | I | V | In: $VP*2 Vr: $VP*4 IV | V | I | vi | IV | V | I | V | % Second half could be called chorus Ch: V | | $VP*2 I |*4 Ch2: V | | $VP*3 % Fadeout S: [G] $In $Vr $Vr $Ch $VP $Vr $Ch2
>>> s.lines[0] '% Brown-Eyed Girl'
>>> s.lines[-1] 'S: [G] $In $Vr $Vr $Ch $VP $Vr $Ch2'
- CTSong.toPart(labelRomanNumerals=True, labelSubsectionsOnScore=True) Part ¶
creates a Part object out of a from CTSong and also creates CTRule objects in the process, filling their .streamFromCTSong attribute with the corresponding smaller inner stream. Individual attributes of a rule are defined by the entire CTSong, such as meter and time signature, so creation of CTRule objects typically occurs only from this method and directly from the clercqTemperley text.
>>> s = romanText.clercqTemperley.CTSong(romanText.clercqTemperley.BlitzkriegBopCT) >>> partObj = s.toPart() >>> partObj.highestOffset 380.0
- CTSong.toScore(labelRomanNumerals=True, labelSubsectionsOnScore=True) Part ¶
DEPRECATED: use .toPart() instead. This method will be removed in v.10
Methods inherited from ProtoM21Object
:
CTSong
instance variables
- CTSong.year¶
The year of the CTSong; not formally defined by the Clercq-Temperley format.
CTRule¶
- class music21.romanText.clercqTemperley.CTRule(text='', parent: CTSong | None = None)¶
CTRule objects correspond to the individual lines defined in a
CTSong
object. They are typically created by the parser after a CTSong object has been created and the .toPart() method has been called on that object. The usefulness of each CTRule object is that each has astreamFromCTSong()
attribute, which is the stream from the entire score that the rule corresponds to.To parse, put the text into the
CTRule
bases
CTRule
read-only properties
- CTRule.comment¶
Get the comment of a CTRule object.
>>> rs = 'In: $BP*3 I IV | I | $BP*3 I IV | I | R |*4 I |*4 % This is a comment' >>> s = romanText.clercqTemperley.CTRule(rs) >>> s.comment 'This is a comment'
- CTRule.sectionName¶
Returns the expanded version of the Left-hand side (LHS) such as Introduction, Verse, etc. if text is present (uses LHS to expand)
Currently supported abbreviations:
In: Introduction
Br: Bridge
Vr: Verse
Ch: Chorus
Fadeout: Fadeout
S: Song
>>> s = romanText.clercqTemperley.CTRule('Vr2: $BP*3 I IV | I |') >>> s.sectionName 'Verse2'
Read-only properties inherited from ProtoM21Object
:
CTRule
read/write properties
- CTRule.LHS¶
Get the LHS (Left Hand Side) of the CTRule. If not specified explicitly but CTtext present, searches first characters up until ‘:’ for rule and returns string)
>>> rs = 'In: $BP*3 I IV | R |*4 I |*4 % This is a comment' >>> s = romanText.clercqTemperley.CTRule(rs) >>> s.LHS 'In'
- CTRule.musicText¶
Gets just the music text of the CTRule, excluding the left hand side and comments
>>> rs = 'In: $BP*3 I IV | I | $BP*3 I IV | I | R |*4 I |*4 % This is a comment' >>> s = romanText.clercqTemperley.CTRule(rs) >>> s.text 'In: $BP*3 I IV | I | $BP*3 I IV | I | R |*4 I |*4 % This is a comment' >>> s.musicText '$BP*3 I IV | I | $BP*3 I IV | I | R |*4 I |*4'
- CTRule.parent¶
A reference to the CTSong object housing the CTRule if any.
CTRule
methods
- CTRule.addOptionalTieAndLyrics(rn: roman.RomanNumeral, lastChord: chord.Chord | None) None ¶
Adds ties to chords that are the same. Adds lyrics to chords that change.
- CTRule.expand(tsContext: TimeSignature | None = None, keyContext: Key | None = None) list[music21.stream.base.Measure] ¶
The meat of it all – expand one rule completely and return a list of Measure objects.
Parses within the local time signature context and key context.
- CTRule.expandExpansionContent(content: str, numReps: int) None ¶
Expand a rule that contains an expansion (i.e., a $) in it.
Requires CTSong parent to be set.
- CTRule.expandSimpleContent(content: str, numReps: int) None ¶
- CTRule.fixupChordAtom(atom: str) str ¶
changes some CT values into music21 values
>>> s = romanText.clercqTemperley.CTRule() >>> s.fixupChordAtom('iix') 'iio' >>> s.fixupChordAtom('viih7') 'vii/o7' >>> s.fixupChordAtom('iia') 'ii+'
- CTRule.insertKsTs(m: Measure, ts: TimeSignature, keyObj: Key) None ¶
Insert a new time signature or Key into measure m, if it’s not already in the stream somewhere.
Note that the name “ks” is slightly misnamed. It requires a Key, not KeySignature object.
- CTRule.isSame(rn: roman.RomanNumeral, lastChord: chord.Chord | None) bool ¶
Returns True if the pitches of the RomanNumeral are the same as the pitches of lastChord. Returns False if lastChord is None.
Methods inherited from ProtoM21Object
:
CTRule
instance variables
- CTRule.text¶
The full text of the CTRule, including the LHS, chords, and comments.