from music21 import *
s
is a music21 stream object.
If a unique key is given by key objects in the stream, returns this key
object. If there are no key objects or if there are more than one keys
identified, returns None
.
def getKeyFromStream(s):
keys = set()
for el in s.flat.getElementsByClass('Key'):
keys.add(el)
if len(keys) == 1:
return keys.pop()
else:
return None
corpus.chorales.Iterator
"is a class for iterating over many chorales."
See http://web.mit.edu/music21/doc/moduleReference/
moduleCorpusChorales.html#iterator for more details.
BCI = corpus.chorales.Iterator()
total = len(BCI)
Empty list to hold stream objects for every chorale iterated through below.
chorales = []
Iterate over all chorales in the corpus. Each chorale is parsed by default.
for i, chorale in enumerate(BCI):
Note this syntax within the print statement. See https://pyformat.info/ for more info on string formatting.
print("%d out of %d chorales parsed" % (i + 1, total))
chorales.append(chorale)
One-line version of the code above, in this case limited to chorales 1-10.
chorales = [chorale for chorale in corpus.chorales.Iterator(1, 10)]
for chorale in chorales:
get labeled key for current chorale
current_key = getKeyFromStream(chorale)
if current_key is not None:
Title and other information can be found in the metadata
object.
See http://web.mit.edu/music21/doc/
moduleReference/moduleMetadata.html for more details.
print("Chorale title:", chorale.metadata.title)
print("Labeled key:", current_key)
Analyze the key of the chorale using a key-analysis algorithm. We'll
go over these details later in the course. Note that s.analyze()
is equivalent to analysis.discrete.analyzeStream(s)
.
See http://web.mit.edu/music21/doc/moduleReference/
moduleAnalysisDiscrete.html#keyweightkeyanalysis for more details.
k = chorale.analyze('key')
print("Analyzed key:", k)
Key objects derived from analyze
have additional properties,
correlationCoefficient
which measures the correlation between
the expected pitch-class distribution for the analyzed key and the
actual distribution in the analyzed stream.
print("Correlation coefficient:", k.correlationCoefficient)
alternateInterpretations
is a list of key objects for the remaining
23 major and minor keys sorted from most to least likely.
alt_keys = k.alternateInterpretations
Print the three most likely alternate keys and their correlation coefficients.
for alt_key in alt_keys[:3]:
print("Top alternate keys:", alt_key,
"Correlation coefficient:", alt_key.correlationCoefficient)
match = current_key == k
if match:
print("Key analysis matches labeled key!")
else:
print("Key analysis does not match labeled key! :-(")
.index(x)
finds the first index of a list that matches x.
If there is no match, index
returns ValueError
.
>>> a = [1, 2, 3]
>>> a.index(2)
1
>>> a.index(4)
ValueError: 4 is not in list
key_index = alt_keys.index(current_key) + 2
print("Labeled key was the number %d analyzed key" % key_index)
print()