music21.alpha.contour¶
This module defines the ContourFinder and AggregateContour objects.
ContourFinder¶
-
class
music21.alpha.contour.
ContourFinder
(s=None)¶
ContourFinder
methods
-
ContourFinder.
dissonanceMetric
(inpStream)¶ inpStream is a stream containing some number of measures which each contain chords. Output is a number between 0 and 1 which is proportional to the number of dissonant chords.
To work correctly, input must contain measures and no parts.
>>> c = corpus.parse('bwv102.7').chordify() >>> alpha.contour.ContourFinder().dissonanceMetric( c.measures(1, 1) ) 0.25 >>> alpha.contour.ContourFinder().dissonanceMetric( c.measures(8, 8) ) 0.5 >>> alpha.contour.ContourFinder().dissonanceMetric( c.measures(1, 10)) < 1.0 True
-
ContourFinder.
getContour
(cType, window=None, slide=None, overwrite=False, metric=None, needsChordify=False, normalized=False)¶ Stores and then returns a normalized contour of the type cType. cType can be either ‘spacing’, ‘tonality’, or ‘dissonance’.
If using a metric that is not predefined, cType is any string that signifies what your metric measures. In this case, you must pass getContour a metric function which takes in a music21 stream and outputs a score. If passing a metric that requires the music21 stream be just chords, specify needsChordify=True.
Window is how many measures are considered at a time and slide is the number of measures the window moves over each time. By default, measure and slide are both 1.
Each time you call getContour for a cType, the result is cached. If you wish to get the contour for the same cType more than once, with different parameters (with a different window and slide, for example) then specify overwrite=True
To get a contour where measures map to the metric values, use normalized=False (the default), but to get a contour which evenly divides time between 1.0 and 100.0, use normalized=True
>>> cf = alpha.contour.ContourFinder( corpus.parse('bwv10.7')) >>> mycontour = cf.getContour('dissonance') >>> [mycontour[x] for x in sorted(mycontour.keys())] [0.0, 0.25, 0.5, 0.5, 0.0, 0.0, 0.25, 0.75, 0.0, 0.0, 0.5, 0.75, 0.75, 0.0, 0.5, 0.5, 0.5, 0.5, 0.75, 0.75, 0.75, 0.0]
>>> mycontour = cf.getContour('always one', 2, 2, metric= lambda x: 1.0) >>> [mycontour[x] for x in sorted(mycontour.keys())] [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
>>> mycontour = cf.getContour('spacing', metric = lambda x: 2, overwrite=False) Traceback (most recent call last): OverwriteException: Attempted to overwrite 'spacing' metric but did not specify overwrite=True
>>> mycontour = cf.getContour('spacing', slide=3, metric = lambda x: 2.0, overwrite=True) >>> [mycontour[x] for x in sorted(mycontour.keys())] [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]
>>> mycontour = cf.getContour('spacing') >>> [mycontour[x] for x in sorted(mycontour.keys())] [2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]
-
ContourFinder.
getContourValuesForMetric
(metric, window=1, slide=1, needChordified=False)¶ Returns a dictionary mapping measure numbers to that measure’s score under the provided metric. Ignores pickup measures entirely.
Window is a positive integer indicating how many measure the metric should look at at once, and slide is a positive integer indicating by how many measures the window should slide over each time the metric is measured.
e.g. if window=4 and slide=2, metric = f, the result will be of the form: { measures 1-4: f(measures 1-4), measures 3-6: f(measures 3-6), measures 5-8: f( measures5-8), ...}
>>> metric = lambda s: len(s.measureOffsetMap()) >>> c = corpus.parse('bwv10.7') >>> res = alpha.contour.ContourFinder(c).getContourValuesForMetric(metric, 3, 2, False)
>>> resList = sorted(list(res.keys())) >>> resList [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21] >>> [res[x] for x in resList] [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2]
-
ContourFinder.
plot
(cType, contourIn=None, regression=True, order=4, title='Contour Plot', fileName=None)¶
-
ContourFinder.
randomize
(contourDict)¶ Returns a version of contourDict where the keys-to-values mapping is scrambled.
>>> myDict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8, 9:9, 10:10, 11:11, 12:12, 13:13, ... 14:14, 15:15, 16:16, 17:17, 18:18, 19:19, 20:20} >>> res = alpha.contour.ContourFinder().randomize(myDict) >>> res == myDict False >>> sorted(list(res.keys())) == sorted(list(myDict.keys())) True >>> sorted(list(res.values())) == sorted(list(myDict.values())) True
-
ContourFinder.
setKey
(key)¶ Sets the key of ContourFinder’s internal stream. If not set manually, self.key will be determined by self.s.analyze(‘key’).
-
ContourFinder.
spacingMetric
(inpStream)¶ Defines a metric which takes a music21 stream containng measures and no parts. This metric measures how spaced out notes in a piece are.
-
ContourFinder.
tonalDistanceMetric
(inpStream)¶ Returns a number between 0.0 and 1.0 that is a measure of how far away the key of inpStream is from the key of ContourFinder’s internal stream.
AggregateContour¶
-
class
music21.alpha.contour.
AggregateContour
(aggContours=None)¶
AggregateContour
methods
-
AggregateContour.
addPieceToContour
(piece, cType, metric=None, window=1, slide=1, order=8, needsChordify=False)¶ Adds a piece to the aggregate contour.
piece is either a music21 stream, or a ContourFinder object (which should have a stream wrapped inside of it).
cType is the contour type.
If using a metric that is not predefined, cType is any string that signifies what your metric measures. In this case, you must pass getContour a metric function which takes in a music21 stream and outputs a score. If passing a metric that requires the music21 stream be just chords, specify needsChordify=True.
Window is how many measures are considered at a time and slide is the number of measures the window moves over each time. By default, measure and slide are both 1.
-
AggregateContour.
dissimilarityScore
(cType, contourDict)¶ Returns a score based on how dissimilar the input contourDict is from the aggregate contour of type cType.
Requires contourDict be normalized with values from 1.0 to 100.0
-
AggregateContour.
getCombinedContour
(cType)¶ Returns the combined contour of the type specified by cType. Instead of a dictionary, this contour is just a list of ordered pairs (tuples) with the first value being time and the second value being the score.
-
AggregateContour.
getCombinedContourPoly
(cType, order=8)¶ Returns the polynomial fit for the aggregate contour of type cType.
Order is the order of the resulting polynomial. e.g. For a linear regression, order=1.
-
AggregateContour.
plot
(cType, showPoints=True, comparisonContour=None, regression=True, order=6)¶