예제 #1
0
 def find_next(self):
     """Returns the index and chord of the next chord in
     the list of expected chords
     """
     assert self.index + 1 < len(self.chords), "No more chords to walk"
     current_chord = self.chords[self.index]
     current_rn = roman.romanNumeralFromChord(current_chord, self.key)
     expected_chord_labels = get_expected_next(current_rn.figure, self.key.type == "major")
     assert len(expected_chord_labels) > 0, "No expected chords given"
     for i, c in enumerate(self.chords[self.index + 1:]):
         rn = roman.romanNumeralFromChord(c, self.key)
         if rn.figure in expected_chord_labels:
             return self.index + i + 1
예제 #2
0
 def __next__(self):
     current_rn = roman.romanNumeralFromChord(self.chords[self.index], self.key)
     self.labeled_chords.append(current_rn.figure)
     new_index = self.find_next()
     if new_index != self.index + 1:
         raise ChordProgressionError(self.index - 1)
     self.index = new_index
예제 #3
0
    def testTrecentoMadrigal(self):
        from music21 import corpus
        # c = corpus.parse('beethoven/opus18no1', 2).measures(1, 19)

        c = corpus.parse('PMFC_06_Giovanni-05_Donna').measures(1, 30)
        # c = corpus.parse('PMFC_06_Giovanni-05_Donna').measures(90, 118)
        # c = corpus.parse('PMFC_06_Piero_1').measures(1, 10)
        # c = corpus.parse('PMFC_06-Jacopo').measures(1, 30)

        # c = corpus.parse('PMFC_12_13').measures(1, 40)

        # fix clef
        fixClef = True
        if fixClef:
            startClefs = c.parts[1].getElementsByClass(
                'Measure').first().getElementsByClass('Clef')
            if startClefs:
                clef1 = startClefs[0]
                c.parts[1].getElementsByClass('Measure').first().remove(clef1)
            c.parts[1].getElementsByClass('Measure').first().insert(
                0, clef.Treble8vbClef())

        cr = ChordReducer()
        # cr.printDebug = True
        p = cr.multiPartReduction(c, maxChords=3)
        # p = cr.multiPartReduction(c, closedPosition=True)
        from music21 import key, roman
        cm = key.Key('G')
        for thisChord in p.recurse().getElementsByClass('Chord'):
            thisChord.lyric = roman.romanNumeralFromChord(
                thisChord, cm, preferSecondaryDominants=True).figure

        c.insert(0, p)
        if self.show:
            c.show()
예제 #4
0
    def comparePitches(self):
        '''
        Single RN-slice comparison for pitches:
        do the chords reflect the pitch content of the score section in question?
        '''

        if self.pitchFeedback is not None:  # already done
            return

        self.pitchFeedback = []

        pitchNumerator = 0

        for comp in self.harmonicRanges:

            overall = 0

            harmonicRangeLength = sum([round(sl.quarterLength, 2) for sl in comp.slices])
            # Note: Avoid division by 0

            for thisSlice in comp.slices:  # NB: Rest slices handled already
                pitchesNameNoOctave = [x[:-1] for x in thisSlice.pitches]  # Pitch only
                proportionSame = self._proportionSimilarity(comp, pitchesNameNoOctave)
                # weighedSimilarity = proportionSame * slice.beatStrength  # TODO
                overall += thisSlice.quarterLength * proportionSame / harmonicRangeLength
                overall = round(overall, 2)

            compLength = comp.endOffset - comp.startOffset

            if overall >= self.tolerance:
                pitchNumerator += compLength

            else:  # overall < self.tolerance:  # Process feedback and reduce pitchScore.

                pitchNumerator += (compLength * overall)

                # Suggestions
                pl = [pList.pitches for pList in comp.slices]
                suggestions = []
                for sl in comp.slices:
                    chd = chord.Chord(sl.pitches)
                    if (chd.isTriad() or chd.isSeventh()):
                        rn = roman.romanNumeralFromChord(chd, comp.key)
                        if rn.figure != comp.figure:
                            suggestions.append([sl.measure, sl.beat, rn.figure, sl.pitches])

                msg = f'Measure {comp.startMeasure}, beat {comp.startBeat}, {comp.figure} in {comp.key}, ' \
                      f'indicating the pitches {comp.pitches} ' \
                      f'accounting for successive slices of {pl}.'
                fb = Feedback(comp, msg)
                fb.matchStrength = f'Match strength estimated at {round(overall * 100, 2)}%.'
                fb.suggestions = []

                if len(suggestions) > 0:
                    for s in suggestions:
                        fb.suggestions.append(f'm{s[0]} b{s[1]} {s[2]} for the slice {s[3]}')

                self.pitchFeedback.append(fb)

            self.pitchScore = round(pitchNumerator * 100 / self.totalLength, 2)
예제 #5
0
    def compareBass(self):
        '''
        Single RN-slice comparison for bass pitches (inversion).
        Creates feedback for cases where
        the bass pitch indicated by the Roman numeral's inversion
        does not appear as the lowest note during the span in question.
        '''

        if self.bassFeedback is not None:  # already done
            return

        self.bassFeedback = []

        bassNumerator = 0

        for comp in self.harmonicRanges:

            # bassPitchesWithOctave = [slice.pitches[0] for slice in comp.slices]
            bassPitchesWithOctave = []  # Sometimes the slice is a rest I guess?
            for slice in comp.slices:
                if len(slice.pitches) > 0:
                    bassPitchesWithOctave.append(slice.pitches[0])

            bassPitchesNoOctave = [p[:-1] for p in bassPitchesWithOctave]
            bassPitchesWithOctave = list(set(bassPitchesWithOctave))

            if comp.bassPitch not in bassPitchesNoOctave:

                inversionSuggestions = []

                for bassPitch in bassPitchesNoOctave:
                    if bassPitch in comp.pitches:  # already retrieved
                        suggestedPitches = comp.pitches
                        suggestedPitches.append(bassPitch + '0')  # To ensure it is lowest
                        suggestedChord = chord.Chord(suggestedPitches)
                        rn = roman.romanNumeralFromChord(suggestedChord, comp.key)
                        inversionSuggestions.append(f'm{comp.startMeasure} b{comp.startBeat} {rn.figure}')

                msg = f'Measure {comp.startMeasure}, beat {comp.startBeat}, {comp.figure} in {comp.key}, ' \
                      f'indicating the bass {comp.bassPitch} ' \
                      f'for lowest note(s) of: {bassPitchesWithOctave}.'
                fb = Feedback(comp, msg)
                # fb.matchStrength = N/A
                fb.suggestions = []

                if len(inversionSuggestions) > 0:
                    fb.suggestions = list(set(inversionSuggestions))  # Once for each suggestion

                self.bassFeedback.append(fb)

            else:  # comp.bassPitch in bassPitchesNoOctave:
                compLength = comp.endOffset - comp.startOffset
                bassNumerator += compLength

        self.bassScore = bassNumerator / self.totalLength
예제 #6
0
 def convert_harmonic_to_roman_numerals(self):
     ret = []
     for c in self.harmony:
         if c == "-":
             ret.append("-")
         else:
             roman_numeral = roman.romanNumeralFromChord(
                 c, self.expected_key)
             ret.append(simplify_roman_name(roman_numeral))
     self.roman_numerals = ret
     return ret
def letter2roman(sym):
    # for now assume in key of C
    print '--- letter2roman', sym,
    try:
        chord_sym = harmony.ChordSymbol(sym)
    except:
        print 'WARNING: chord symbol does not exist'
        return None
    ch = chord.Chord(chord_sym.pitches)
    rn = roman.romanNumeralFromChord(ch, key.Key('C'))
    print rn.figure
    return rn.figure
예제 #8
0
    def testTrecentoMadrigal(self):
        from music21 import corpus
        # c = corpus.parse('beethoven/opus18no1', 2).measures(1, 19)


        c = corpus.parse('PMFC_06_Giovanni-05_Donna').measures(1, 30)
        # c = corpus.parse('PMFC_06_Giovanni-05_Donna').measures(90, 118)
        # c = corpus.parse('PMFC_06_Piero_1').measures(1, 10)
        # c = corpus.parse('PMFC_06-Jacopo').measures(1, 30)

        # c = corpus.parse('PMFC_12_13').measures(1, 40)

        # fix clef
        fixClef = True
        if fixClef:
            startClefs = c.parts[1].getElementsByClass('Measure')[0].getElementsByClass('Clef')
            if startClefs:
                clef1 = startClefs[0]
                c.parts[1].getElementsByClass('Measure')[0].remove(clef1)
            c.parts[1].getElementsByClass('Measure')[0].insert(0, clef.Treble8vbClef())


        cr = ChordReducer()
        #cr.printDebug = True
        p = cr.multiPartReduction(c, maxChords=3)
        #p = cr.multiPartReduction(c, closedPosition=True)
        from music21 import key, roman
        cm = key.Key('G')
        for thisChord in p.recurse().getElementsByClass('Chord'):
            thisChord.lyric = roman.romanNumeralFromChord(thisChord,
                                                          cm,
                                                          preferSecondaryDominants=True).figure


        c.insert(0, p)
        c.show()
예제 #9
0
from music21 import key
from music21 import interval

bci = corpus.chorales.Iterator(2, 371, numberingSystem = 'riemenschneider', numberList = [1,2,3,4,6,190,371], returnType = 'stream')
chordProgressions = []
intervalSets = []

for chorale in bci:
	reduction = chorale.chordify()
	analyzedKey = chorale.analyze('key')
	chords = []
	intervals = []
	for c in reduction.flat.getElementsByClass('Chord'):
		c.closedPosition(forceOctave=4, inPlace = True)
		chordPitches = c.pitches
		chordSize = len(chordPitches)
		mainInterval = interval.notesToChromatic(chordPitches[0], chordPitches[chordSize-1])
		rn = roman.romanNumeralFromChord(c, analyzedKey)
		chords.append(rn)
		intervals.append(mainInterval)
	chordProgressions.append(chords)
	intervalSets.append(intervals)

for ch in chordProgressions:
	print ch
	print "//"

for i in intervalSets:
	print i
	print "//"
예제 #10
0
def roman(chord, key):
    return chord_name(romanNumeralFromChord(chord, key).romanNumeral)
예제 #11
0
    def chfyChordAndLabel(self,
                          ignoreParts: int = 2,
                          tonicizationsRemainInEffect: bool = False):
        '''
        To use in the case of a partial analysis with chords and key information.

        Takes each successive chord and key/tonicization labelling lyric,
        works out the chord, and either
        returns that as data, or
        as appended to the score in question.

        Notes for the markup:
            changes of key remain in effect until the next marking, but
            changes of tonicizations don't by default (settable with tonicizationsRemainInEffect).

        That said, you may want to put in reminders of the prevailing key occasionally
        (after a tonicization, or indeed elsewhere);
        that's fine and doesn't make any different to the analysis.
        '''

        self.deducedAnalysis = []

        reduction = deepcopy(self.score)
        for x in range(ignoreParts):
            reduction.remove(
                reduction.parts[0])  # Top parts of the original score

        self.chfyScore = reduction.stripTies().chordify()
        self.chfyScore.partName = 'Roman'

        currentIndex = 0  # Index
        currentKey = 'FAKE KEY'  # Initialise empty for inclusion of the first key
        currentTonicization = None

        if not self.annotationsAndLocations:
            self.getAnnotationsAndLocations()

        keyData = self.annotationsAndLocations
        lenKeyData = len(keyData)

        for ch in self.chfyScore.recurse().notes:

            startKey = currentKey
            if not tonicizationsRemainInEffect:
                currentTonicization = None  # reset for each chord

            # Key Changes and Tonicization
            if lenKeyData > currentIndex and [ch.measureNumber, ch.beat
                                              ] == keyData[currentIndex][0:2]:
                stringInQuestion = keyData[currentIndex][
                    2]  # Before updating current index
                currentIndex += 1
                if '/' in stringInQuestion:  # Then it's a local tonicization
                    rnFigureString, currentTonicization = stringInQuestion.split(
                        '/')
                    # TODO make use of any rnFigureString specified?
                    # TODO support e.g. '/g' as well as (and converting it to) relative ('/ii')
                elif ':' in stringInQuestion:  # modulation
                    currentKey, rnFigureString = stringInQuestion.split(':')
                    # TODO make use of any rnFigureString specified?
                else:
                    x = re.search('[a-gA-G]', stringInQuestion[0])
                    if x:  # modulation without RN. NB: Doesn't support Fr43 or Ger65
                        currentKey = stringInQuestion
                        currentTonicization = None
                    else:
                        # TODO accept anything else as a full, user-defined Roman numeral?
                        raise ValueError(
                            f'Unrecognised entry {stringInQuestion} '
                            f'in measure {ch.measureNumber}, '
                            f'beat {ch.beat}')

            if not currentTonicization:
                rn = roman.romanNumeralFromChord(ch, key.Key(currentKey))
            else:  # currentTonicization
                localKey = getLocalKey(currentTonicization, currentKey)
                rn = roman.romanNumeralFromChord(
                    ch,
                    key.Key(localKey),
                    # sixthMinor=roman.Minor67Default.CAUTIONARY,
                    # seventhMinor=roman.Minor67Default.CAUTIONARY,
                )  # TODO: issues with sixth and seventh minor

            lyric = str(rn.figure)

            # Lyric modifications. Otherwise the lyric is unchanged
            if startKey != currentKey:
                lyric = currentKey + ': ' + lyric
            elif currentTonicization:
                lyric = lyric + stringInQuestion

            ch.lyric = lyric

            thisData = [ch.measureNumber, ch.beat, lyric]
            self.deducedAnalysis.append(thisData)
예제 #12
0
def determineDissonantIdentificationAccuracy(scoreIn, offsetList, keyStr=None):
    '''
    runs comparison on score to identify dissonances, then compares to the user's
    offsetList of identified
    dissonances. The score is colored according to the results, and appropriate
    information is returned
    as a dictionary. See runPerceivedDissonanceAnalysis for full details and an example.

    *Color key*
    * Green: the user also recognizes this as a dissonant vertical slice GREEN
    * Red: the user did not recognize as a dissonant vertical slice RED
    * Blue: the user recognized it as a dissonant vertical slice BLUE


    >>> s = stream.Score()
    >>> p = stream.Part()
    >>> c1 = chord.Chord(['C3', 'E3', 'G3'])
    >>> c1.isConsonant()
    True
    >>> p.append(c1)
    >>> c2 = chord.Chord(['C3', 'B3', 'D#'])
    >>> c2.isConsonant()
    False
    >>> p.append(c2)
    >>> c3 = chord.Chord(['D3', 'F#3', 'A'])
    >>> c3.isConsonant()
    True
    >>> p.append(c3)
    >>> c4 = chord.Chord(['B-4', 'F#4', 'A-3'])
    >>> c4.isConsonant()
    False
    >>> p.append(c4)
    >>> p.makeMeasures(inPlace=True)
    >>> s.append(p)
    >>> aData = alpha.webapps.commands.determineDissonantIdentificationAccuracy(s, [2.3, 3.2])
    >>> chords = aData['stream'].flat.getElementsByClass('Chord')
    >>> chords[0].style.color is None #BLACK (by default)
    True
    >>> chords[1].style.color #RED
    '#cc3300'
    >>> chords[2].style.color #BLUE
    '#0033cc'
    >>> chords[3].style.color #GREEN
    '#00cc33'
    '''
    from music21 import roman
    ads = theoryAnalyzer.Analyzer()

    score = scoreIn.sliceByGreatestDivisor(addTies=True)
    vsList = ads.getVerticalities(score)
    user = len(offsetList)
    music21VS = 0
    both = 0
    romanFigureList = []
    if keyStr is None:
        pieceKey = scoreIn.analyze('key')
    else:
        pieceKey = key.Key(keyStr)

    for (vsNum, vs) in enumerate(vsList):
        currentVSOffset = vs.offset(leftAlign=False)
        if vsNum + 1 == len(vsList):
            nextVSOffset = scoreIn.highestTime
        else:
            nextVSOffset = vsList[vsNum + 1].offset(leftAlign=False)
        if not vs.isConsonant(): #music21 recognizes this as a dissonant vertical slice
            music21VS += 1
            if _withinRange(offsetList, currentVSOffset, nextVSOffset):
                vs.color = '#00cc33'
                # the user also recognizes this as a dissonant vertical slice GREEN
                both += 1
                c = vs.getChord()
                romanFigureList.append(roman.romanNumeralFromChord(c, pieceKey).figure)
            else:
                vs.color = '#cc3300'
                #the user did not recognize as a dissonant vertical slice RED
        else: #music21 did not recognize this as a dissonant vertical slice
            if _withinRange(offsetList, currentVSOffset, nextVSOffset):
                vs.color = '#0033cc'
                #the user recognized it as a dissonant vertical slice BLUE

    score.insert(metadata.Metadata())
    score.metadata.composer = scoreIn.metadata.composer
    score.metadata.movementName = scoreIn.metadata.movementName
    analysisData = {'stream': score,
                    'numUserIdentified': user,
                    'numMusic21Identified': music21VS,
                    'numBothIdentified': both,
                    'accuracy': both * 100 / music21VS if music21VS != 0 else 100,
                    'romans': romanFigureList,
                    'key': pieceKey}
    return analysisData
예제 #13
0
def determineDissonantIdentificationAccuracy(scoreIn, offsetList, keyStr=None):
    '''
    runs comparison on score to identify dissonances, then compares to the user's
    offsetList of identified
    dissonances. The score is colored according to the results, and appropriate
    information is returned
    as a dictionary. See runPerceivedDissonanceAnalysis for full details and an example.

    *Color key*
    * Green: the user also recognizes this as a dissonant vertical slice GREEN
    * Red: the user did not recognize as a dissonant vertical slice RED
    * Blue: the user recognized it as a dissonant vertical slice BLUE


    >>> s = stream.Score()
    >>> p = stream.Part()
    >>> c1 = chord.Chord(['C3', 'E3', 'G3'])
    >>> c1.isConsonant()
    True
    >>> p.append(c1)
    >>> c2 = chord.Chord(['C3', 'B3', 'D#'])
    >>> c2.isConsonant()
    False
    >>> p.append(c2)
    >>> c3 = chord.Chord(['D3', 'F#3', 'A'])
    >>> c3.isConsonant()
    True
    >>> p.append(c3)
    >>> c4 = chord.Chord(['B-4', 'F#4', 'A-3'])
    >>> c4.isConsonant()
    False
    >>> p.append(c4)
    >>> p.makeMeasures(inPlace=True)
    >>> s.append(p)
    >>> aData = alpha.webapps.commands.determineDissonantIdentificationAccuracy(s, [2.3, 3.2])
    >>> chords = aData['stream'].flat.getElementsByClass('Chord')
    >>> chords[0].style.color is None #BLACK (by default)
    True
    >>> chords[1].style.color #RED
    '#cc3300'
    >>> chords[2].style.color #BLUE
    '#0033cc'
    >>> chords[3].style.color #GREEN
    '#00cc33'
    '''
    from music21 import roman
    ads = theoryAnalyzer.Analyzer()

    score = scoreIn.sliceByGreatestDivisor(addTies=True, inPlace=False)
    vsList = ads.getVerticalities(score)
    user = len(offsetList)
    music21VS = 0
    both = 0
    romanFigureList = []
    if keyStr is None:
        pieceKey = scoreIn.analyze('key')
    else:
        pieceKey = key.Key(keyStr)

    for (vsNum, vs) in enumerate(vsList):
        currentVSOffset = vs.offset(leftAlign=False)
        if vsNum + 1 == len(vsList):
            nextVSOffset = scoreIn.highestTime
        else:
            nextVSOffset = vsList[vsNum + 1].offset(leftAlign=False)
        if not vs.isConsonant(
        ):  #music21 recognizes this as a dissonant vertical slice
            music21VS += 1
            if _withinRange(offsetList, currentVSOffset, nextVSOffset):
                vs.color = '#00cc33'
                # the user also recognizes this as a dissonant vertical slice GREEN
                both += 1
                c = vs.getChord()
                romanFigureList.append(
                    roman.romanNumeralFromChord(c, pieceKey).figure)
            else:
                vs.color = '#cc3300'
                #the user did not recognize as a dissonant vertical slice RED
        else:  #music21 did not recognize this as a dissonant vertical slice
            if _withinRange(offsetList, currentVSOffset, nextVSOffset):
                vs.color = '#0033cc'
                #the user recognized it as a dissonant vertical slice BLUE

    score.insert(metadata.Metadata())
    scoreInMetadata = scoreIn.metadata
    if scoreInMetadata:
        score.metadata.composer = scoreInMetadata.composer
        score.metadata.movementName = scoreInMetadata.movementName
    analysisData = {
        'stream': score,
        'numUserIdentified': user,
        'numMusic21Identified': music21VS,
        'numBothIdentified': both,
        'accuracy': both * 100 / music21VS if music21VS != 0 else 100,
        'romans': romanFigureList,
        'key': pieceKey
    }
    return analysisData
예제 #14
0
    def chfyChordAndLabel(self,
                          ignoreParts: int = 2,
                          tonicizationsRemainInEffect: bool = False):
        '''
        To use in the case of a partial analysis with chords and key information.

        Takes each successive chord and key/tonicization labelling lyric,
        works out the chord, and either
        returns that as data, or
        as appended to the score in question.

        Notes for the markup:
            changes of key remain in effect until the next marking, but
            changes of tonicizations don't by default (settable with tonicizationsRemainInEffect).

        That said, you may want to put in reminders of the prevailing key occasionally
        (after a tonicization, or indeed elsewhere);
        that's fine and doesn't make any different to the analysis.
        '''

        self.deducedAnalysis = []

        reduction = deepcopy(self.score)
        for x in range(ignoreParts):
            reduction.remove(
                reduction.parts[0])  # Top parts of the original score

        self.chfyScore = reduction.stripTies().chordify()
        self.chfyScore.partName = 'Roman'
        chNotes = self.chfyScore.recurse().notes

        currentIndex = 0  # Index
        currentKey = 'FAKE KEY'  # Initialise empty for inclusion of the first key
        currentTonicization = None

        if not self.annotationsAndLocations:
            self.getAnnotationsAndLocations()

        keyData = self.annotationsAndLocations
        lenKeyData = len(keyData)

        for ch in chNotes:

            startKey = currentKey
            if not tonicizationsRemainInEffect:  # == False:
                currentTonicization = None  # To reset for each chord.

            # Key Changes and Tonicization
            if lenKeyData > currentIndex:  # Index from 0, len counts from 1. Gets all of keyData
                if [ch.measureNumber, ch.beat] == keyData[currentIndex][0:2]:
                    stringInQuestion = keyData[currentIndex][
                        2]  # Before changing to new current index
                    currentIndex += 1
                    if '/' in stringInQuestion:  # Then it's a local tonicization
                        currentTonicization = stringInQuestion[
                            1:]  # After the '/'
                        # TODO support e.g. '/g' as well as (and converting it to) relative ('/ii')
                    else:  # Then it's a an actual modulation
                        currentKey = stringInQuestion
                        currentTonicization = None  # Definitely reset for a key change
                    # TODO add a condition to support m3-4 = m1-2 style annotation
                    # TODO accept a roman.romanNumeral (not from chord)

            if not currentTonicization:
                rn = roman.romanNumeralFromChord(ch, key.Key(currentKey))
            else:  # currentTonicization
                localKey = getLocalKey(currentTonicization, currentKey)
                rn = roman.romanNumeralFromChord(
                    ch,
                    key.Key(localKey),
                    # sixthMinor=roman.Minor67Default.CAUTIONARY,
                    # seventhMinor=roman.Minor67Default.CAUTIONARY,
                )  # TODO: issues with sixth and seventh minor

            lyric = str(rn.figure)

            # Lyric modifications. Otherwise the lyric is unchanged
            if startKey != currentKey:
                lyric = currentKey + ': ' + lyric
            elif currentTonicization:
                lyric = lyric + stringInQuestion

            ch.lyric = lyric

            thisData = [ch.measureNumber, ch.beat, lyric]
            self.deducedAnalysis.append(thisData)
예제 #15
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-key',
                        help='run Krumhansl algorithm on a music file',
                        action="store_true")
    parser.add_argument('-rna',
                        help='run roman numeral analysis on a music file',
                        action="store_true")
    parser.add_argument('-rtc',
                        help='run real-time chord naming',
                        action="store_true")
    parser.add_argument('-out',
                        help='read a file and then write it out again',
                        action="store_true")
    args = parser.parse_args()

    if not (args.rtc):
        root = tk.Tk()
        root.withdraw()
        file_path = filedialog.askopenfilename()
        start = int(time.time())
        score = converter.parse(file_path)
        read = int(time.time())
        sys.stdout.write('file read in ' + str(read - start) + 'ms\n')

    if args.key or args.rna:
        key = analysis.discrete.analyzeStream(score, 'Krumhansl')
        keyTime = int(time.time())
        sys.stdout.write(
            str(key) + ' established in ' + str(keyTime - read) + 'ms\n')

    if args.rna:
        delim = ""
        chordFilter = stream.filters.ClassFilter('Chord')
        sIter = score.recurse().iter
        sIter.addFilter(chordFilter)

        for a in sIter:
            root = a.root()
            rn = roman.romanNumeralFromChord(a, key)
            sys.stdout.write(delim + str(rn.romanNumeralAlone))
            delim = " - "

        rnaTime = int(time.time())
        sys.stdout.write(' determined in ' + str(rnaTime - read) + 'ms\n')

    if args.out:
        score.write('abc', 'abcout.abc')
        score.write('midi', 'midiout.mid')
        score.write('musicxml', 'xmlout.xml')
        write = int(time.time())
        sys.stdout.write('file written in ' + str(write - read) + 'ms\n')

    if args.rtc:
        midi.init()
        controller = midi.Input(pygame.midi.get_default_input_id())
        c = chord.Chord()
        while True:
            if (controller.poll()):
                midi_event = controller.read(5)
                notePitch = midi_event[0][0][1]
                eventType = midi_event[0][0][0]
                n = note.Note(notePitch)
                if eventType == 144:
                    c.add(n)
                    sys.stdout.write(str(n) + '\n')
                    if c.isTriad():
                        sys.stdout.write(c.pitchedCommonName + '\n')

                if c.pitchedCommonName == 'A4-minor triad':
                    break

                if eventType == 128:
                    c.remove(n)
                    c = chord.Chord(c)
예제 #16
0
 def get_naive_chord_label(self, index):
     chord = self.chords[index]
     rn = roman.romanNumeralFromChord(chord, self.key)
     return rn.figure
예제 #17
0
def print_chords(chorale):
    chorale_key = chorale.analyze("key")
    chord_list = get_chords(chorale)
    for c in chord_list:
        rn = roman.romanNumeralFromChord(c, chorale_key)
        print(rn.figure)
예제 #18
0
bChords = b.chordify()

#adds chordify as another voice to show better
for c in bChords.flat:
    if 'Chord' not in c.classes:
        continue
    c.closedPosition(forceOctave=4, inPlace=True)

#b.measures(0,2).show()

stats = TransitionGraph()

#adds roman numerals at the bottom
for c in bChords.flat.getElementsByClass('Chord'):
    rn = roman.romanNumeralFromChord(c, key.Key('A'))
    stats.addNumeral(rn)
    c.addLyric(str(rn.figure))
#bChords.measures(0, 2).show()
bChords.show('text')



#prints the roman numerals, i.e. lyrics
for c in bChords.measures(0,2).flat:
    if 'Chord' not in c.classes:
        continue
    print c.lyric,
    
print "\n"
stats.printTransitions()
예제 #19
0
def music21_extract(p):
    """
    Takes in a Music21 score, and outputs dict
    """
    parts = []
    parts_times = []
    parts_delta_times = []
    parts_extras = []
    parts_time_signatures = []
    parts_key_signatures = []
    c = p.chordify()
    ks = p.parts[0].stream().flat.keySignature
    parts_roman_chords = []
    parts_chords = []
    for this_chord in c.recurse().getElementsByClass('Chord'):
        parts_chords.append(this_chord.fullName)
        #print(this_chord.measureNumber, this_chord.beatStr, this_chord)
        rn = roman.romanNumeralFromChord(this_chord, ks.asKey())
        parts_roman_chords.append(rn.figure)

    for i, pi in enumerate(p.parts):
        part = []
        part_time = []
        part_delta_time = []
        part_extras = []
        total_time = 0
        ts = pi.stream().flat.timeSignature
        ks = pi.stream().flat.keySignature
        if len(ks.alteredPitches) == 0:
            parts_key_signatures.append([0])
        else:
            parts_key_signatures.append([ks.sharps])
        parts_time_signatures.append((ts.numerator, ts.denominator))
        for n in pi.stream().flat.notesAndRests:
            if n.isRest:
                part.append(0)
            else:
                try:
                    part.append(n.midi)
                except AttributeError:
                    continue
            if n.tie is not None:
                if n.tie.type == "start":
                    part_extras.append(1)
                elif n.tie.type == "continue":
                    part_extras.append(2)
                elif n.tie.type == "stop":
                    part_extras.append(3)
                else:
                   print("another type of tie?")
                   from IPython import embed; embed(); raise ValueError()
            elif len(n.expressions) > 0:
                print("trill or fermata?")
                from IPython import embed; embed(); raise ValueError()
            else:
                part_extras.append(0)

            part_time.append(total_time + n.duration.quarterLength)
            total_time = part_time[-1]
            part_delta_time.append(n.duration.quarterLength)
        parts.append(part)
        parts_times.append(part_time)
        parts_delta_times.append(part_delta_time)
        parts_extras.append(part_extras)
    return {"parts": parts,
            "parts_times": parts_times,
            "parts_delta_times": parts_delta_times,
            "parts_extras": parts_extras,
            "parts_time_signatures": parts_time_signatures,
            "parts_key_signatures": parts_key_signatures,
            "parts_chords": parts_chords,
            "parts_roman_chords": parts_roman_chords}