Ejemplo n.º 1
0
def findPotentialPassingTones(show=True):
    g = corpus.parse("gloria")
    gcn = g.parts["cantus"].measures(1, 126).flat.notesAndRests

    gcn[0].lyric = ""
    gcn[-1].lyric = ""
    for i in range(1, len(gcn) - 1):
        prev = gcn[i - 1]
        cur = gcn[i]
        next = gcn[i + 1]  # @ReservedAssignment

        cur.lyric = ""

        if "Rest" in prev.classes or "Rest" in cur.classes or "Rest" in next.classes:
            continue

        int1 = interval.notesToInterval(prev, cur)
        if int1.isStep is False:
            continue

        int2 = interval.notesToInterval(cur, next)
        if int2.isStep is False:
            continue

        cma = cur.beatStrength
        if cma < 1 and cma <= prev.beatStrength and cma <= next.beatStrength:

            if int1.direction == int2.direction:
                cur.lyric = "pt"  # neighbor tone
            else:
                cur.lyric = "nt"  # passing tone
    if show:
        g.parts["cantus"].show()
Ejemplo n.º 2
0
def capuaRuleOne(srcStream):
    '''
    Applies Nicolaus de Capua's first rule to the given srcStream, i.e. if a line descends
    a major second then ascends back to the original note, the major second is
    made into a minor second. Also copies the relevant accidentals into
    `Note.editorial.misc["saved-accidental"]` and changes `Note.editorial.color`
    for rule 1 (blue green blue).
    
    The relevant Rule number is also stored in `Note.editorial.misc['capua_rule_number']` which
    can be got out by OR-ing this.
    
    Returns the number of notes that were changed (not counting notes whose colors were changed).    
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if (n1.isRest or n2.isRest or n3.isRest):
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if (n1.pitch.accidental is not None
                or n3.pitch.accidental is not None):
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        ## e.g. G, F, G => G, F#, G
        if i1.directedName == "M-2" and \
           i2.directedName == "M2":
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_ONE
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_ONE
            if (n2.pitch.accidental is not None
                    and n2.pitch.accidental.name == "flat"):
                n2.editorial.misc["saved-accidental"] = n2.pitch.accidental
                n2.pitch.accidental = None
                n2.editorial.ficta = pitch.Accidental("natural")
                n2.editorial.misc["capua-ficta"] = pitch.Accidental("natural")
                n1.editorial.color = "blue"
                n2.editorial.color = "forestGreen"
                n3.editorial.color = "blue"
            else:
                n2.editorial.ficta = pitch.Accidental("sharp")
                n2.editorial.misc["capua-ficta"] = pitch.Accidental("sharp")
                n1.editorial.color = "blue"
                n2.editorial.color = "ForestGreen"
                n3.editorial.color = "blue"

    return numChanged
Ejemplo n.º 3
0
def capuaRuleFourB(srcStream):
    '''
    See capuaRuleOne for precise instructions.
    
    Applies more probable interpretation of Capua's fourth rule to the given
    srcStream, i.e. if a descending minor third is followed by a descending major
    second, the intervals will be changed to a major third followed by a minor
    second. Also copies any relevant accidental to note.editorial.misc under
    "saved-accidental" and changes note.editorial.color for rule 4 (orange
    green orange).
    
    returns the number of times a note was changed.
    '''
    numChanged = 0
    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if n1.isRest or \
           n2.isRest or \
           n3.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if n1.accidental is not None or \
           n3.accidental is not None:
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        # e.g., D F G => D F# G  or G Bb C => G B C
        if i1.directedName  == "m3" and \
           i2.directedName  == "M2":
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_FOUR_B
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_FOUR_B
            if (n2.accidental is not None and n2.accidental.name == "flat"):
                n2.editorial.misc["saved-accidental"] = n2.accidental
                n2.accidental = None
                n2.editorial.ficta = pitch.Accidental("natural")
                n2.editorial.misc["capua-ficta"] = pitch.Accidental("natural")
                n1.editorial.color = "orange"
                n2.editorial.color = "green"
                n3.editorial.color = "orange"
            else:
                n2.editorial.ficta = pitch.Accidental("sharp")
                n2.editorial.misc["capua-ficta"] = pitch.Accidental("sharp")
                n1.editorial.color = "orange"
                n2.editorial.color = "green"
                n3.editorial.color = "orange"

    return numChanged
Ejemplo n.º 4
0
def capuaRuleTwo(srcStream):
    """
    See capuaRuleOne for precise instructions.
    
    Applies Capua's second rule to the given srcStream, i.e. if four notes are
    ascending with the pattern M2 m2 M2, the intervals shall be made M2 M2 m2.
    Also changes note.editorial.color for rule 2 (purple purple green purple).
    
    returns the number of times any note was changed
    """
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn) - 3):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]
        n4 = ssn[i + 3]

        if n1.isRest or n2.isRest or n3.isRest or n4.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)
        i3 = interval.notesToInterval(n3, n4)

        if n1.accidental is not None or n2.accidental is not None or n4.accidental is not None:
            continue

        ### never seems to improve things...
        if n3.step == "A" or n3.step == "D":
            continue

        # e.g., D E F G => D E F# G
        #    or F A Bb C => F A B C
        if i1.directedName == "M2" and i2.directedName == "m2" and i3.directedName == "M2":
            numChanged += 1
            if "capua" in n3.editorial.misc:
                n3.editorial.misc["capua_rule_number"] += RULE_TWO
            else:
                n3.editorial.misc["capua_rule_number"] = RULE_TWO

            if n3.accidental is not None and n3.accidental.name == "flat":
                n3.editorial.misc["saved-accidental"] = n3.accidental
                n3.accidental = None
                n3.editorial.ficta = pitch.Accidental("natural")
                n3.editorial.misc["capua-ficta"] = pitch.Accidental("natural")
                n1.editorial.color = "purple"
                n2.editorial.color = "purple"
                n3.editorial.color = "ForestGreen"
                n4.editorial.color = "purple"
            else:
                n3.editorial.ficta = pitch.Accidental("sharp")
                n3.editorial.misc["capua-ficta"] = pitch.Accidental("sharp")
                n1.editorial.color = "purple"
                n2.editorial.color = "purple"
                n3.editorial.color = "ForestGreen"
                n4.editorial.color = "purple"

    return numChanged
Ejemplo n.º 5
0
Archivo: capua.py Proyecto: EQ4/music21
def capuaRuleFourB(srcStream):
    '''
    See capuaRuleOne for precise instructions.
    
    Applies more probable interpretation of Capua's fourth rule to the given
    srcStream, i.e. if a descending minor third is followed by a descending major
    second, the intervals will be changed to a major third followed by a minor
    second. Also copies any relevant accidental to note.editorial.misc under
    "saved-accidental" and changes note.editorial.color for rule 4 (orange
    green orange).
    
    returns the number of times a note was changed.
    '''
    numChanged = 0
    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn)-2):
        n1 = ssn[i]
        n2 = ssn[i+1]
        n3 = ssn[i+2]

        if n1.isRest or \
           n2.isRest or \
           n3.isRest:
            continue

        i1 = interval.notesToInterval(n1,n2)
        i2 = interval.notesToInterval(n2,n3)

        if n1.pitch.accidental is not None or \
           n3.pitch.accidental is not None:
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        # e.g., D F G => D F# G  or G Bb C => G B C
        if i1.directedName  == "m3" and \
           i2.directedName  == "M2":
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_FOUR_B
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_FOUR_B
            if (n2.pitch.accidental is not None and n2.pitch.accidental.name == "flat"):
                n2.editorial.misc["saved-accidental"] = n2.pitch.accidental
                n2.pitch.accidental = None
                n2.editorial.ficta = pitch.Accidental("natural")
                n2.editorial.misc["capua-ficta"] = pitch.Accidental("natural")
                n1.editorial.color = "orange"
                n2.editorial.color = "green"
                n3.editorial.color = "orange"
            else:
                n2.editorial.ficta = pitch.Accidental("sharp")
                n2.editorial.misc["capua-ficta"] = pitch.Accidental("sharp")
                n1.editorial.color = "orange"
                n2.editorial.color = "green"
                n3.editorial.color = "orange"

    return numChanged
Ejemplo n.º 6
0
def findPotentialPassingTones(show=True):
    g = corpus.parse('gloria')
    gcn = g.parts['cantus'].measures(1, 126).flat.notesAndRests

    gcn[0].lyric = ""
    gcn[-1].lyric = ""
    for i in range(1, len(gcn) - 1):
        prev = gcn[i - 1]
        cur = gcn[i]
        nextN = gcn[i + 1]

        cur.lyric = ""

        if ("Rest" in prev.classes or "Rest" in cur.classes
                or "Rest" in nextN.classes):
            continue

        int1 = interval.notesToInterval(prev, cur)
        if int1.isStep is False:
            continue

        int2 = interval.notesToInterval(cur, nextN)
        if int2.isStep is False:
            continue

        cma = cur.beatStrength
        if (cma < 1 and cma <= prev.beatStrength
                and cma <= nextN.beatStrength):

            if int1.direction == int2.direction:
                cur.lyric = 'pt'  # neighbor tone
            else:
                cur.lyric = 'nt'  # passing tone
    if show:
        g.parts['cantus'].show()
Ejemplo n.º 7
0
def capuaRuleOne(srcStream):
    '''
    Applies Nicolaus de Capua's first rule to the given srcStream, i.e. if a line descends
    a major second then ascends back to the original note, the major second is
    made into a minor second. Also copies the relevant accidentals into
    `Note.editorial.misc["saved-accidental"]` and changes `Note.style.color`
    for rule 1 (blue green blue).

    The relevant Rule number is also stored in `Note.editorial.misc['capua_rule_number']` which
    can be got out by OR-ing this.

    Returns the number of notes that were changed (not counting notes whose colors were changed).
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if (n1.isRest or n2.isRest or n3.isRest):
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if (n1.pitch.accidental is not None
                or n3.pitch.accidental is not None):
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        ## e.g. G, F, G => G, F#, G
        if (i1.directedName == "M-2"
                and i2.directedName == "M2"):
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_ONE
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_ONE
            if (n2.pitch.accidental is not None and n2.pitch.accidental.name == "flat"):
                n2.editorial.misc["saved-accidental"] = n2.pitch.accidental
                n2.pitch.accidental = None
                n2.editorial.ficta = pitch.Accidental("natural")
                n2.editorial.misc["capua-ficta"] = pitch.Accidental("natural")
                n1.style.color = "blue"
                n2.style.color = "forestGreen"
                n3.style.color = "blue"
            else:
                n2.editorial.ficta = pitch.Accidental("sharp")
                n2.editorial.misc["capua-ficta"] = pitch.Accidental("sharp")
                n1.style.color = "blue"
                n2.style.color = "ForestGreen"
                n3.style.color = "blue"

    return numChanged
Ejemplo n.º 8
0
 def isParallelUnison(self, note11, note12, note21, note22):
     '''Given four notes, assuming the first pair sounds at the same time and
     the second pair sounds at the same time, returns True if the two
     harmonic intervals are P8 and False otherwise.'''
     interval1 = interval.notesToInterval(note11, note21)
     interval2 = interval.notesToInterval(note12, note22)
     if interval1.name == interval2.name == "P1": return True
     else: return False
Ejemplo n.º 9
0
def capuaRuleOne(srcStream):
    '''
    Applies Nicolaus de Capua's first rule to the given srcStream, i.e. if a line descends
    a major second then ascends back to the original note, the major second is
    made into a minor second. Also copies the relevant accidentals into
    `Note.editorial.savedAccidental` and changes `Note.style.color`
    for rule 1 (blue green blue).

    The relevant Rule number is also stored in `Note.editorial.capuaRuleNumber']` which
    can be got out by OR-ing this.

    Returns the number of notes that were changed (not counting notes whose colors were changed).
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if n1.isRest or n2.isRest or n3.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if (n1.pitch.accidental is not None
                or n3.pitch.accidental is not None):
            continue

        # never seems to improve things...
        if n2.step == 'A' or n2.step == 'D':
            continue

        # e.g. G, F, G => G, F#, G
        if (i1.directedName == 'M-2' and i2.directedName == 'M2'):
            numChanged += 1
            if 'capuaRuleNumber' in n2.editorial:
                n2.editorial.capuaRuleNumber += RULE_ONE
            else:
                n2.editorial.capuaRuleNumber = RULE_ONE
            if n2.pitch.accidental is not None and n2.pitch.accidental.name == 'flat':
                n2.editorial.savedAccidental = n2.pitch.accidental
                n2.pitch.accidental = None
                n2.editorial.ficta = pitch.Accidental('natural')
                n2.editorial.capuaFicta = pitch.Accidental('natural')
                n1.style.color = 'blue'
                n2.style.color = 'forestGreen'
                n3.style.color = 'blue'
            else:
                n2.editorial.ficta = pitch.Accidental('sharp')
                n2.editorial.capuaFicta = pitch.Accidental('sharp')
                n1.style.color = 'blue'
                n2.style.color = 'ForestGreen'
                n3.style.color = 'blue'

    return numChanged
Ejemplo n.º 10
0
def capuaRuleFourB(srcStream):
    '''
    See capuaRuleOne for precise instructions.

    Applies more probable interpretation of Capua's fourth rule to the given
    srcStream, i.e. if a descending minor third is followed by a descending major
    second, the intervals will be changed to a major third followed by a minor
    second. Also copies any relevant accidental to note.editorial.savedAccidental
    and changes note.style.color for rule 4 (orange
    green orange).

    returns the number of times a note was changed.
    '''
    numChanged = 0
    ssn = srcStream.flat.notesAndRests
    for i in range(len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if n1.isRest or n2.isRest or n3.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if (n1.pitch.accidental is not None
                or n3.pitch.accidental is not None):
            continue

        # never seems to improve things...
        if n2.step == 'A' or n2.step == 'D':
            continue

        # e.g., D F G => D F# G  or G Bb C => G B C
        if i1.directedName == 'm3' and i2.directedName == 'M2':
            numChanged += 1
            if 'capuaRuleNumber' in n2.editorial:
                n2.editorial.capuaRuleNumber += RULE_FOUR_B
            else:
                n2.editorial.capuaRuleNumber = RULE_FOUR_B
            if n2.pitch.accidental is not None and n2.pitch.accidental.name == 'flat':
                n2.editorial.savedAccidental = n2.pitch.accidental
                n2.pitch.accidental = None
                n2.editorial.ficta = pitch.Accidental('natural')
                n2.editorial.capuaFicta = pitch.Accidental('natural')
                n1.style.color = 'orange'
                n2.style.color = 'green'
                n3.style.color = 'orange'
            else:
                n2.editorial.ficta = pitch.Accidental('sharp')
                n2.editorial.capuaFicta = pitch.Accidental('sharp')
                n1.style.color = 'orange'
                n2.style.color = 'green'
                n3.style.color = 'orange'

    return numChanged
Ejemplo n.º 11
0
def capuaRuleOne(srcStream):
    '''Applies Nicolaus de Capua's first rule to the given srcStream, i.e. if a line descends
    a major second then ascends back to the original note, the major second is
    made into a minor second. Also copies the relevant accidentals into
    note.editorial.misc under "saved-accidental" and changes note.editorial.color
    for rule 1 (blue green blue).
    
    Returns the number of changes.    
    '''
    numChanged = 0
    
    ssn = srcStream.notes
    for i in range(0, len(ssn)-2):
        n1 = ssn[i]
        n2 = ssn[i+1]
        n3 = ssn[i+2]

        if n1.isRest or \
           n2.isRest or \
           n3.isRest:
            continue
        
        i1 = notesToInterval(n1,n2)
        i2 = notesToInterval(n2,n3)

        if n1.accidental is not None or \
           n3.accidental is not None:
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        ## e.g. G, F, G => G, F#, G
        if i1.directedName == "M-2" and \
           i2.directedName == "M2":
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_ONE
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_ONE
            if (n2.accidental is not None and n2.accidental.name == "flat"):
                n2.editorial.misc["saved-accidental"] = n2.accidental
                n2.accidental = None
                n2.editorial.ficta = Accidental("natural")
                n2.editorial.misc["capua-ficta"] = Accidental("natural")
                n1.editorial.color = "blue"
                n2.editorial.color = "forestGreen"
                n3.editorial.color = "blue"
            else:
                n2.editorial.ficta = Accidental("sharp")
                n2.editorial.misc["capua-ficta"] = Accidental("sharp")
                n1.editorial.color = "blue"
                n2.editorial.color = "ForestGreen"
                n3.editorial.color = "blue"

    return numChanged
Ejemplo n.º 12
0
def capuaRuleFourA(srcStream):
    '''
    See capuaRuleOne for precise instructions.

    Applies one interpretation of Capua's fourth rule to the given srcStream,
    i.e. if a descending minor third is followed by a descending major second,
    the intervals will be changed to a major third followed by a minor second.
    Also changes note.editorial.color for rule 4 (orange green orange).
    
    returns the number of notes that were changed

    This rule is a less likely interpretation of the ambiguous rule 4, thus
    applyCapuaToStream uses capuaRuleFourB instead.
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if n1.isRest or \
           n2.isRest or \
           n3.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if n1.accidental is not None or \
           n2.accidental is not None or \
           n3.accidental is not None:
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        # e.g., D B A => D Bb A
        if i1.directedName  == "m-3" and \
           i2.directedName  == "M-2":
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_FOUR_A
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_FOUR_A
            n2.editorial.ficta = pitch.Accidental("flat")
            n2.editorial.misc["capua-ficta"] = pitch.Accidental("flat")
            n1.editorial.color = "orange"
            n2.editorial.color = "ForestGreen"
            n3.editorial.color = "orange"

    return numChanged
Ejemplo n.º 13
0
Archivo: capua.py Proyecto: EQ4/music21
def capuaRuleFourA(srcStream):
    '''
    See capuaRuleOne for precise instructions.

    Applies one interpretation of Capua's fourth rule to the given srcStream,
    i.e. if a descending minor third is followed by a descending major second,
    the intervals will be changed to a major third followed by a minor second.
    Also changes note.editorial.color for rule 4 (orange green orange).
    
    returns the number of notes that were changed

    This rule is a less likely interpretation of the ambiguous rule 4, thus
    applyCapuaToStream uses capuaRuleFourB instead.
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn)-2):
        n1 = ssn[i]
        n2 = ssn[i+1]
        n3 = ssn[i+2]

        if n1.isRest or \
           n2.isRest or \
           n3.isRest:
            continue
        
        i1 = interval.notesToInterval(n1,n2)
        i2 = interval.notesToInterval(n2,n3)

        if n1.pitch.accidental is not None or \
           n2.pitch.accidental is not None or \
           n3.pitch.accidental is not None:
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        # e.g., D B A => D Bb A
        if i1.directedName  == "m-3" and \
           i2.directedName  == "M-2":
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_FOUR_A
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_FOUR_A
            n2.editorial.ficta = pitch.Accidental("flat")
            n2.editorial.misc["capua-ficta"] = pitch.Accidental("flat")
            n1.editorial.color = "orange"
            n2.editorial.color = "ForestGreen"
            n3.editorial.color = "orange"

    return numChanged
Ejemplo n.º 14
0
def capuaRuleThree(srcStream):
    '''
    See capuaRuleOne for precise instructions.
    
    Applies Capua's third rule to the given srcStream, i.e. if there is a
    descending major third followed by an ascending major second, the second
    note will be made a half-step higher so that there is a descending minor
    third followed by an ascending minor second. Also changes
    note.editorial.color for rule 3 (pink green pink).
    
    returns the number of times a note was changed
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if n1.isRest or \
           n2.isRest or \
           n3.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if n1.accidental is not None or \
           n2.accidental is not None or \
           n3.accidental is not None:
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        # e.g., E C D => E C# D
        if i1.directedName  == "M-3" and \
           i2.directedName  == "M2":
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_THREE
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_THREE
            n2.editorial.ficta = pitch.Accidental("sharp")
            n2.editorial.misc["capua-ficta"] = pitch.Accidental("sharp")
            n1.editorial.color = "DeepPink"
            n2.editorial.color = "ForestGreen"
            n3.editorial.color = "DeepPink"

    return numChanged
Ejemplo n.º 15
0
Archivo: capua.py Proyecto: EQ4/music21
def capuaRuleThree(srcStream):
    '''
    See capuaRuleOne for precise instructions.
    
    Applies Capua's third rule to the given srcStream, i.e. if there is a
    descending major third followed by an ascending major second, the second
    note will be made a half-step higher so that there is a descending minor
    third followed by an ascending minor second. Also changes
    note.editorial.color for rule 3 (pink green pink).
    
    returns the number of times a note was changed
    '''
    numChanged = 0
    
    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn)-2):
        n1 = ssn[i]
        n2 = ssn[i+1]
        n3 = ssn[i+2]

        if n1.isRest or \
           n2.isRest or \
           n3.isRest:
            continue
        
        i1 = interval.notesToInterval(n1,n2)
        i2 = interval.notesToInterval(n2,n3)

        if n1.pitch.accidental is not None or \
           n2.pitch.accidental is not None or \
           n3.pitch.accidental is not None:
            continue

        ### never seems to improve things...
        if n2.step == "A" or n2.step == "D":
            continue

        # e.g., E C D => E C# D
        if i1.directedName  == "M-3" and \
           i2.directedName  == "M2":
            numChanged += 1
            if ("capua" in n2.editorial.misc):
                n2.editorial.misc['capua_rule_number'] += RULE_THREE
            else:
                n2.editorial.misc['capua_rule_number'] = RULE_THREE
            n2.editorial.ficta = pitch.Accidental("sharp")
            n2.editorial.misc["capua-ficta"] = pitch.Accidental("sharp")
            n1.editorial.color = "DeepPink"
            n2.editorial.color = "ForestGreen"
            n3.editorial.color = "DeepPink"

    return numChanged
Ejemplo n.º 16
0
def capuaRuleFourA(srcStream):
    '''
    See capuaRuleOne for precise instructions.

    Applies one interpretation of Capua's fourth rule to the given srcStream,
    i.e. if a descending minor third is followed by a descending major second,
    the intervals will be changed to a major third followed by a minor second.
    Also changes note.style.color for rule 4 (orange green orange).

    returns the number of notes that were changed

    This rule is a less likely interpretation of the ambiguous rule 4, thus
    applyCapuaToStream uses capuaRuleFourB instead.
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if n1.isRest or n2.isRest or n3.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if (n1.pitch.accidental is not None or n2.pitch.accidental is not None
                or n3.pitch.accidental is not None):
            continue

        # never seems to improve things...
        if n2.step == 'A' or n2.step == 'D':
            continue

        # e.g., D B A => D Bb A
        if i1.directedName == 'm-3' and i2.directedName == 'M-2':
            numChanged += 1
            if 'capuaRuleNumber' in n2.editorial:
                n2.editorial.capuaRuleNumber += RULE_FOUR_A
            else:
                n2.editorial.capuaRuleNumber = RULE_FOUR_A
            n2.editorial.ficta = pitch.Accidental('flat')
            n2.editorial.capuaFicta = pitch.Accidental('flat')
            n1.style.color = 'orange'
            n2.style.color = 'ForestGreen'
            n3.style.color = 'orange'

    return numChanged
Ejemplo n.º 17
0
def capuaRuleThree(srcStream):
    '''
    See capuaRuleOne for precise instructions.

    Applies Capua's third rule to the given srcStream, i.e. if there is a
    descending major third followed by an ascending major second, the second
    note will be made a half-step higher so that there is a descending minor
    third followed by an ascending minor second. Also changes
    note.style.color for rule 3 (pink green pink).

    returns the number of times a note was changed
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(len(ssn) - 2):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]

        if n1.isRest or n2.isRest or n3.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)

        if (n1.pitch.accidental is not None or n2.pitch.accidental is not None
                or n3.pitch.accidental is not None):
            continue

        # never seems to improve things...
        if n2.step == 'A' or n2.step == 'D':
            continue

        # e.g., E C D => E C# D
        if (i1.directedName == 'M-3' and i2.directedName == 'M2'):
            numChanged += 1
            if 'capuaRuleNumber' in n2.editorial:
                n2.editorial.capuaRuleNumber += RULE_THREE
            else:
                n2.editorial.capuaRuleNumber = RULE_THREE
            n2.editorial.ficta = pitch.Accidental('sharp')
            n2.editorial.capuaFicta = pitch.Accidental('sharp')
            n1.style.color = 'DeepPink'
            n2.style.color = 'ForestGreen'
            n3.style.color = 'DeepPink'

    return numChanged
Ejemplo n.º 18
0
def searchForIntervals(notesStr):
    '''
    notesStr is the same as above.  Now however we check to see
    if the generic intervals are the same, rather than the note names.
    Useful if the clef is missing.
    '''
    notesArr = notesStr.split()
    noteObjArr = []
    for tN in notesArr:
        tNObj = note.Note()
        tNObj.name = tN[0]
        tNObj.octave = int(tN[1])
        noteObjArr.append(tNObj)

    interObjArr = []
    for i in range(len(noteObjArr) - 1):
        int1 = interval.notesToInterval(noteObjArr[i], noteObjArr[i + 1])
        interObjArr.append(int1)
    #print interObjArr

    searcher1 = IntervalSearcher(interObjArr)
    ballataObj = cadencebook.BallataSheet()

    streamOpus = stream.Opus()

    for thisWork in ballataObj:
        print(thisWork.title)
        for thisCadence in thisWork.snippets:
            if thisCadence is None:
                continue
            for i in range(len(thisCadence.parts)):
                colorFound(searcher1, thisCadence, streamOpus, thisWork, i)

    if any(streamOpus):
        streamOpus.show('lily.png')
Ejemplo n.º 19
0
 def getDominant(self):
     interval1to5 = interval.notesToInterval(self.tonic, self.pitchFromScaleDegree(5))
     if interval1to5.specificName != "Perfect":
         print(interval1to5.diatonicType)
         raise ScaleException("This scale has no Dominant (Locrian perhaps?)")
     else:
         return self.pitchFromScaleDegree(5)
Ejemplo n.º 20
0
def resolves(voice, resolve_interval):
    """Given a voice starting with the note that must resolve, checks whether it resolves according to the provided resolveInterval integer

    >>> from music21 import note, stream
    >>> voice = stream.Part()
    >>> for current_note in map(note.Note, ['f4', 'e4', 'f4']):
    ...     voice.append(current_note)
    >>> resolves(voice, -2)
    True
    >>> resolves(voice, 2)
    False
    """
    if len(voice) < 2:
        return True

    first_note = voice[0]
    for note in voice[1:]:
        current_interval = interval.notesToInterval(first_note, note)
        if current_interval.generic.directed == resolve_interval:
            return True
        # returns false if the resolve interval is wrong or there a chromatic step in the wrong direction
        if current_interval.generic.directed != 1 or resolve_interval * current_interval.chromatic.directed < 0:
            return

    return True
 def transposed_to(
     self,
     pitch: Pitch = Pitch()) -> Tuple['SpotifyChord', Optional[Interval]]:
     if self.is_no_chord():
         return self, None
     tr_int = interval.notesToInterval(self.root, pitch)
     return self.transposed_by(tr_int), tr_int
Ejemplo n.º 22
0
def searchForIntervals(notesStr):
    '''
    notesStr is the same as above.  Now however we check to see
    if the generic intervals are the same, rather than the note names.
    Useful if the clef is missing.
    '''
    notesArr = notesStr.split()
    noteObjArr = []
    for tN in notesArr:
        tNObj = note.Note()
        tNObj.name = tN[0]
        tNObj.octave = int(tN[1])
        noteObjArr.append(tNObj)

    interObjArr = []
    for i in range(len(noteObjArr) - 1):
        int1 = interval.notesToInterval(noteObjArr[i], noteObjArr[i + 1])
        interObjArr.append(int1)
    #print interObjArr

    searcher1 = IntervalSearcher(interObjArr)
    ballataObj  = cadencebook.BallataSheet()

    streamOpus = stream.Opus()

    for thisWork in ballataObj:
        print(thisWork.title)
        for thisCadence in thisWork.snippets:
            if thisCadence is None:
                continue
            for i in range(len(thisCadence.parts)):
                colorFound(searcher1, thisCadence, streamOpus, thisWork, i)

    if any(streamOpus):
        streamOpus.show('lily.png')
Ejemplo n.º 23
0
 def generateFirstSpecies(self, stream1, minorScale):
     '''Given a stream (the cantus firmus) and the stream's key in the
     form of a MinorScale object, generates a stream of first species
     counterpoint that follows the rules of 21M.301.'''
     # DOES NOT YET CHECK FOR TOO MANY THIRDS/SIXTHS IN A ROW,
     # DOES NOT YET RAISE LEADING TONES, AND DOES NOT CHECK FOR NOODLING.
     stream2 = Stream([])
     firstNote = stream1.notes[0]
     choices = [interval.transposeNote(firstNote, "P1"),\
                interval.transposeNote(firstNote, "P5"),\
                interval.transposeNote(firstNote, "P8")]
     note1 = random.choice(choices)
     note1.duration = firstNote.duration
     stream2.append(note1)
     afterLeap = False
     for i in range(1, len(stream1.notes)):
         prevFirmus = stream1.notes[i-1]
         currFirmus = stream1.notes[i]
         prevNote = stream2.notes[i-1]
         choices = self.generateValidNotes(prevFirmus, currFirmus, prevNote, afterLeap, minorScale)
         if len(choices) == 0:
             raise ModalCounterpointException("Sorry, please try again")
         newNote = random.choice(choices)
         newNote.duration = currFirmus.duration
         stream2.append(newNote)
         int = interval.notesToInterval(prevNote, newNote)
         if int.generic.undirected > 3: afterLeap = True
         else: afterLeap = False
     return stream2
Ejemplo n.º 24
0
 def isHiddenFifth(self, note11, note12, note21, note22):
     '''Given four notes, assuming the first pair sounds at the same time and
     the second pair sounds at the same time, returns True if there is a
     hidden fifth and false otherwise.'''
     interval1 = interval.notesToInterval(note11, note21)
     interval2 = interval.notesToInterval(note12, note22)
     interval3 = interval.notesToInterval(note11, note12)
     interval4 = interval.notesToInterval(note21, note22)
     if interval3.direction > 0 and interval4.direction > 0:
         if interval2.name == "P5" and not interval1.name == "P5": return True
         else: return False
     elif interval3.direction < 0 and interval4.direction < 0:
         if interval2.name == "P5" and not interval1.name == "P5": return True
         else: return False
     elif interval3.direction == interval4.direction == 0: return False
     return False
Ejemplo n.º 25
0
def generateTripletBlues(blRealization=None, numRepeats=5):  # 12/8
    '''
    Turns whole notes in twelve bar blues bass line to triplet blues bass line. Takes
    in numRepeats, which is the number of times to repeat the bass line. Also, takes in a
    realization of :meth:`~music21.figuredBass.examples.twelveBarBlues`. If none is provided,
    a default realization with :attr:`~music21.figuredBass.rules.Rules.forbidVoiceOverlap`
    set to False and :attr:`~music21.figuredBass.rules.Rules.partMovementLimits` set to
    [(1, 4), (2, 12), (3, 12)] is used.

    >>> from music21.figuredBass import examples
    >>> #_DOCS_SHOW examples.generateTripletBlues(numRepeats=1).show()

    .. image:: images/figuredBass/fbExamples_tripletBlues.*
        :width: 700
    '''
    from music21 import converter
    from music21 import stream
    from music21 import interval
    from music21 import meter
    if blRealization is None:
        bluesLine = twelveBarBlues()
        fbRules = rules.Rules()
        fbRules.partMovementLimits = [(1, 4), (2, 12), (3, 12)]
        fbRules.forbidVoiceOverlap = False
        blRealization = bluesLine.realize(fbRules)

    sampleScore = blRealization.generateRandomRealizations(numRepeats)
    tripletBassLine = converter.parse(
        "tinynotation: BB-4 BB-8 D4 D8 F4 F8 A-8 G8 F8", makeNotation=False)

    newBassLine = stream.Part()
    for n in sampleScore[1].notes:
        i = interval.notesToInterval(tripletBassLine[0], n)
        tp = tripletBassLine.transpose(i)
        for lyr in n.lyrics:
            tp.notes.first().addLyric(lyr.text)
        for m in tp.notes:
            newBassLine.append(m)

    newTopLine = stream.Part()
    for sampleChord in sampleScore[0].notes:
        sampleChordCopy = copy.deepcopy(sampleChord)
        sampleChordCopy.quarterLength = 6.0
        newTopLine.append(sampleChordCopy)

    newScore = stream.Score()
    newScore.append(meter.TimeSignature("12/8"))  # Time signature
    newScore.append(sampleScore[1][1])  # Key signature
    newScore.insert(0, newTopLine)
    newScore.insert(0, newBassLine)
    return newScore
Ejemplo n.º 26
0
    def countMelodicIntervals(self, sStream, found=None, ignoreDirection=True, 
        ignoreUnison=True):
        '''
        Find all unique melodic intervals in this Stream. 

        If `found` is provided as a dictionary, this dictionary will be used to store Intervals, and counts of Intervals already found will be incremented.
        '''
        # note that Stream.findConsecutiveNotes() and Stream.melodicIntervals()
        # offer similar approaches, but return Streams and manage offsets and durations, components not needed here
    
        if found == None:
            found = {}

        # if this has parts, need to move through each at a time
        if sStream.hasPartLikeStreams():
            procList = [s for s in sStream.getElementsByClass('Stream')]
        else: # assume a single list of notes
            procList = [sStream]

        for p in procList:
            # get only Notes for now, skipping rests and chords
            noteStream = p.stripTies(inPlace=False).getElementsByClass('Note')
            #noteStream.show()
            for i, n in enumerate(noteStream):
                if i <= len(noteStream) - 2:
                    nNext = noteStream[i+1]
                else:
                    nNext = None

                if nNext is not None:
                    #environLocal.printDebug(['creating interval from notes:', n, nNext, i])
                    i = interval.notesToInterval(n, nNext)
                    if ignoreUnison: # will apply to enharmonic eq unisons
                        if i.chromatic.semitones == 0:
                            continue
                    if ignoreDirection:
                        if i.chromatic.semitones < 0:
                            i = i.reverse()
                    # must use directed name for cases where ignoreDirection
                    # is false
                    if i.directedName not in found.keys():
                        found[i.directedName] = [i, 1]
                    else:
                        found[i.directedName][1] += 1 # increment counter
                        
#         def compare(x, y):
#             return abs(x.chromatic.semitones) - abs(y.chromatic.semitones)
#         found.sort(cmp=compare)

        return found
Ejemplo n.º 27
0
def findPotentialPassingTones(show=True):
    g = corpus.parse('gloria')
    gcn = g.parts['cantus'].measures(1,126).flat.notesAndRests

    gcn[0].lyric = ""
    gcn[-1].lyric = ""
    for i in range(1, len(gcn) - 1):
        prev = gcn[i-1]
        cur  = gcn[i]
        nextN = gcn[i+1]  
        
        cur.lyric = ""
        
        if ("Rest" in prev.classes or 
            "Rest" in cur.classes or 
            "Rest" in nextN.classes):
            continue
        
        int1 = interval.notesToInterval(prev, cur)
        if int1.isStep is False:
            continue
        
        int2 = interval.notesToInterval(cur, nextN)
        if int2.isStep is False:
            continue
            
        cma = cur.beatStrength 
        if (cma < 1 and 
            cma <= prev.beatStrength and
            cma <= nextN.beatStrength): 

            if int1.direction == int2.direction:
                cur.lyric = 'pt' # neighbor tone
            else:
                cur.lyric = 'nt' # passing tone
    if show:   
        g.parts['cantus'].show()
Ejemplo n.º 28
0
def searchForIntervals(notesStr):
    '''
    notesStr is the same as above.  Now however we check to see
    if the generic intervals are the same, rather than the note names.
    Useful if the clef is missing.
    '''
    notesArr = notesStr.split()
    noteObjArr = []
    for tN in notesArr:
        tNObj = note.Note()
        tNObj.name = tN[0]
        tNObj.octave = int(tN[1])
        noteObjArr.append(tNObj)

    interObjArr = []
    for i in range(len(noteObjArr) - 1):
        int1 = interval.notesToInterval(noteObjArr[i], noteObjArr[i + 1])
        interObjArr.append(int1)
    #print interObjArr

    searcher1 = IntervalSearcher(interObjArr)
    ballataObj = cadencebook.BallataSheet()

    streamOpus = stream.Opus()

    for thisWork in ballataObj:
        print(thisWork.title)
        for thisCadence in thisWork.snippets:
            if thisCadence is None:
                continue
            for i in range(len(thisCadence.parts)):
                if searcher1.compareToStream(
                        thisCadence.parts[i].flat) is True:
                    notesStr = ""
                    for thisNote in thisCadence.parts[i].flat.notesAndRests:
                        #thisNote.editorial.color = "blue"
                        if thisNote.isRest is False:
                            notesStr += thisNote.nameWithOctave + " "
                        else:
                            notesStr += "r "
                    streamOpus.insert(0, thisCadence)
                    #                    streamLily += "\\score {" + \
                    #                            "<< \\time " + str(thisCadence.timeSig) + \
                    #                            "\n \\new Staff {" + str(thisCadence.parts[i].lily) + "} >>" + \
                    #                            thisCadence.header() + "\n}\n"
                    print(u"In piece %r found in stream %d: %s" %
                          (thisWork.title, i, notesStr))
    if len(streamOpus) > 0:
        streamOpus.show('lily.png')
Ejemplo n.º 29
0
def ch1_writing_II_A(show=True, *arguments, **keywords):
    '''p. 7

    Compose a melody using whole and half steps in any musical style.

    This technique uses a random walk of whole or half steps with direction 
    choices determined by whether the present note is above or below the 
    target end.
    '''
    import random
    from music21 import stream, expressions, pitch

    dirWeight = [-1, 1] # start with an even distribution
    s = stream.Stream()

    nStart = note.Note('g4')
    n = copy.deepcopy(nStart)

    while True:
#        n.quarterLength = random.choice([.25, .5, 1])
        n.duration.type = random.choice(['16th', 'eighth', 'quarter'])
        s.append(n)
        # if we have written more than fifteen notes 
        # and the last notes matches the first pitch class, then end.
        if len(s) > 4 and n.pitch.pitchClass == nStart.pitch.pitchClass:
            n.expressions.append(expressions.Fermata())
            break
        if len(s) > 30: # emergency break in case the piece is too long
            break
        direction = random.choice(dirWeight)
        if direction == 1:
            i = random.choice(['w', 'h'])
        else:
            i = random.choice(['w-', 'h-'])
        try:
            n = n.transpose(i)
        except pitch.AccidentalException:
            break # end b/c our transposition have exceeded accidental range
        
        iSpread = interval.notesToInterval(nStart, n)
        if iSpread.direction == -1: # we are below our target, favor upward
            dirWeight = [-1, 1, 1]
        if iSpread.direction == 1: # we are above our target, favor down
            dirWeight = [-1, -1, 1]

    if show:
        s.show()
    else:
        unused_post = musicxml.m21ToString.fromMusic21Object(s)
Ejemplo n.º 30
0
def generateTripletBlues(blRealization=None, numRepeats=5):  # 12/8
    """
    Turns whole notes in twelve bar blues bass line to triplet blues bass line. Takes
    in numRepeats, which is the number of times to repeat the bass line. Also, takes in a 
    realization of :meth:`~music21.figuredBass.examples.twelveBarBlues`. If none is provided, 
    a default realization with :attr:`~music21.figuredBass.rules.Rules.forbidVoiceOverlap`
    set to False and :attr:`~music21.figuredBass.rules.Rules.partMovementLimits` set to
    [(1,4),(2,12),(3,12)] is used.

    >>> from music21.figuredBass import examples
    >>> #_DOCS_SHOW examples.generateTripletBlues(numRepeats = 1).show()

    .. image:: images/figuredBass/fbExamples_tripletBlues.*
        :width: 700   
    """
    from music21 import tinyNotation, stream, interval, meter

    if blRealization == None:
        bluesLine = twelveBarBlues()
        fbRules = rules.Rules()
        fbRules.partMovementLimits = [(1, 4), (2, 12), (3, 12)]
        fbRules.forbidVoiceOverlap = False
        blRealization = bluesLine.realize(fbRules)
        sampleScore = blRealization.generateRandomRealizations(numRepeats)

    tripletBassLine = tinyNotation.TinyNotationStream("BB-4 BB-8 D4 D8 F4 F8 A-8 G8 F8")

    newBassLine = stream.Part()
    for n in sampleScore[1].notes:
        i = interval.notesToInterval(tripletBassLine[0], n)
        tp = tripletBassLine.transpose(i)
        for lyr in n.lyrics:
            tp.notes[0].addLyric(lyr.text)
        for m in tp.notes:
            newBassLine.append(m)

    newTopLine = stream.Part()
    for sampleChord in sampleScore[0].notes:
        sampleChordCopy = copy.deepcopy(sampleChord)
        sampleChordCopy.quarterLength = 6.0
        newTopLine.append(sampleChordCopy)

    newScore = stream.Score()
    newScore.append(meter.TimeSignature("12/8"))  # Time signature
    newScore.append(sampleScore[1][1])  # Key signature
    newScore.insert(0, newTopLine)
    newScore.insert(0, newBassLine)
    return newScore
Ejemplo n.º 31
0
def searchForIntervals(notesStr):
    '''
    notesStr is the same as above.  Now however we check to see
    if the generic intervals are the same, rather than the note names.
    Useful if the clef is missing.
    '''
    notesArr = notesStr.split()
    noteObjArr = []
    for tN in notesArr:
        tNObj = note.Note()
        tNObj.name = tN[0]
        tNObj.octave = int(tN[1])
        noteObjArr.append(tNObj)
    
    interObjArr = []
    for i in range(len(noteObjArr) - 1):
        int1 = interval.notesToInterval(noteObjArr[i], noteObjArr[i+1])
        interObjArr.append(int1)
    #print interObjArr

    searcher1 = IntervalSearcher(interObjArr) 
    ballataObj  = cadencebook.BallataSheet()

    streamOpus = stream.Opus()

    for thisWork in ballataObj:
        print(thisWork.title)
        for thisCadence in thisWork.snippets:
            if thisCadence is None:
                continue
            for i in range(len(thisCadence.parts)):
                if searcher1.compareToStream(thisCadence.parts[i].flat) is True:
                    notesStr = ""
                    for thisNote in thisCadence.parts[i].flat.notesAndRests:
                        #thisNote.editorial.color = "blue"
                        if thisNote.isRest is False:
                            notesStr += thisNote.nameWithOctave + " "
                        else:
                            notesStr += "r "
                    streamOpus.insert(0, thisCadence)
#                    streamLily += "\\score {" + \
#                            "<< \\time " + str(thisCadence.timeSig) + \
#                            "\n \\new Staff {" + str(thisCadence.parts[i].lily) + "} >>" + \
#                            thisCadence.header() + "\n}\n"
                    print(u"In piece %r found in stream %d: %s" % (thisWork.title, i, notesStr))
    if len(streamOpus) > 0:
        streamOpus.show('lily.png')
Ejemplo n.º 32
0
def corpusFindMelodicSevenths(show=True):
    # find and display melodic sevenths
    import os
    from music21.analysis import discrete

    mid = discrete.MelodicIntervalDiversity()
    groupEast = corpus.search('shanxi', field='locale')
    groupWest = corpus.search('niederlande', field='locale')

    found = []
    for unused_name, group in [('shanxi', groupEast),
                               ('niederlande', groupWest)]:
        for fp, n in group:
            s = converter.parse(fp, number=n)
            intervalDict = mid.countMelodicIntervals(s)

            for key in sorted(intervalDict.keys()):
                if key in ['m7', 'M7']:
                    found.append([fp, n, s])

    results = stream.Stream()
    for fp, num, s in found:
        environLocal.printDebug(['working with found', fp, num])
        # this assumes these are all monophonic
        noteStream = s.flat.getElementsByClass('Note')
        for i, n in enumerate(noteStream):
            if i <= len(noteStream) - 2:
                nNext = noteStream[i + 1]
            else:
                nNext = None

            if nNext is not None:
                #environLocal.printDebug(['creating interval from notes:', n, nNext, i])
                i = interval.notesToInterval(n, nNext)
                environLocal.printDebug(['got interval', i.name])
                if i.name in ['m7', 'M7']:
                    #n.addLyric(s.metadata.title)
                    junk, fn = os.path.split(fp)
                    n.addLyric('%s: %s' % (fn, num))

                    m = noteStream.extractContext(
                        n, 1, 2, forceOutputClass=stream.Measure)
                    m.makeAccidentals()
                    m.timeSignature = m.bestTimeSignature()
                    results.append(m)
    if show == True:
        results.show()
Ejemplo n.º 33
0
def ch1_basic_I_B(show=True, *arguments, **keywords):
    """
    p2.
    given 2 pitches, mark on a keyboard their positions and mark 
    intervals as W for whole step and H for half step, otherwise N
    """
    pitches = [("a#", "b"), ("b-", "c#"), ("g-", "a"), ("d-", "c##"), ("f", "e"), ("f#", "e")]
    for i, j in pitches:
        n1 = note.Note(i)
        n2 = note.Note(j)
        i1 = interval.notesToInterval(n1, n2)
        if i1.intervalClass == 1:  # by interval class
            unused_mark = "H"
        elif i1.intervalClass == 2:
            unused_mark = "W"
        else:
            unused_mark = "N"
Ejemplo n.º 34
0
def generateBoogieVamp(blRealization=None, numRepeats=5):
    '''
    Turns whole notes in twelve bar blues bass line to blues boogie woogie bass line. Takes
    in numRepeats, which is the number of times to repeat the bass line. Also, takes in a
    realization of :meth:`~music21.figuredBass.examples.twelveBarBlues`. If none is provided,
    a default realization with :attr:`~music21.figuredBass.rules.Rules.forbidVoiceOverlap`
    set to False and :attr:`~music21.figuredBass.rules.Rules.partMovementLimits` set to
    [(1, 4), (2, 12), (3, 12)] is used.

    >>> from music21.figuredBass import examples
    >>> #_DOCS_SHOW examples.generateBoogieVamp(numRepeats=1).show()

    .. image:: images/figuredBass/fbExamples_boogieVamp.*
        :width: 700
    '''
    from music21 import converter
    from music21 import stream
    from music21 import interval
    if blRealization is None:
        bluesLine = twelveBarBlues()
        fbRules = rules.Rules()
        fbRules.partMovementLimits = [(1, 4), (2, 12), (3, 12)]
        fbRules.forbidVoiceOverlap = False
        blRealization = bluesLine.realize(fbRules)

    sampleScore = blRealization.generateRandomRealizations(numRepeats)
    boogieBassLine = converter.parse(
        "tinynotation: BB-8. D16 F8. G16 A-8. G16 F8. D16", makeNotation=False)

    newBassLine = stream.Part()
    newBassLine.append(sampleScore[1][0])  # Time signature
    newBassLine.append(sampleScore[1][1])  # Key signature

    for n in sampleScore[1].notes:
        i = interval.notesToInterval(boogieBassLine[0], n)
        tp = boogieBassLine.transpose(i)
        for lyr in n.lyrics:
            tp.notes.first().addLyric(lyr.text)
        for m in tp.notes:
            newBassLine.append(m)

    newScore = stream.Score()
    newScore.insert(0, sampleScore[0])
    newScore.insert(newBassLine)

    return newScore
Ejemplo n.º 35
0
def corpusFindMelodicSevenths(show = True):
    # find and display melodic sevenths
    import os
    from music21.analysis import discrete

    mid = discrete.MelodicIntervalDiversity()
    groupEast = corpus.search('shanxi', field='locale')
    groupWest = corpus.search('niederlande', field='locale') 

    found = []
    for unused_name, group in [('shanxi', groupEast), ('niederlande', groupWest)]:
        for fp, n in group:
            s = converter.parse(fp, number=n)
            intervalDict = mid.countMelodicIntervals(s)
        
            for key in sorted(intervalDict.keys()):
                if key in ['m7', 'M7']:
                    found.append([fp, n, s])
                   
    results = stream.Stream()
    for fp, num, s in found: 
        environLocal.printDebug(['working with found', fp, num])
        # this assumes these are all monophonic
        noteStream = s.flat.getElementsByClass('Note')
        for i, n in enumerate(noteStream):
            if i <= len(noteStream) - 2:
                nNext = noteStream[i+1]
            else:
                nNext = None

            if nNext is not None:
                #environLocal.printDebug(['creating interval from notes:', n, nNext, i])
                i = interval.notesToInterval(n, nNext)
                environLocal.printDebug(['got interval', i.name])
                if i.name in ['m7', 'M7']:
                    #n.addLyric(s.metadata.title)
                    junk, fn = os.path.split(fp)
                    n.addLyric('%s: %s' % (fn, num))

                    m = noteStream.extractContext(n, 1, 2, forceOutputClass=stream.Measure)
                    m.makeAccidentals()
                    m.timeSignature = m.bestTimeSignature()
                    results.append(m)
    if show == True:
        results.show()
Ejemplo n.º 36
0
def ch1_basic_I_B(show=True, *arguments, **keywords):
    '''
    p2.
    given 2 pitches, mark on a keyboard their positions and mark 
    intervals as W for whole step and H for half step, otherwise N
    '''
    pitches = [('a#', 'b'), ('b-', 'c#'), ('g-', 'a'), ('d-', 'c##'), 
               ('f', 'e'), ('f#', 'e')]
    for i,j in pitches:
        n1 = note.Note(i)
        n2 = note.Note(j)
        i1 = interval.notesToInterval(n1, n2)
        if i1.intervalClass == 1: # by interval class
            unused_mark = "H"
        elif i1.intervalClass == 2:
            unused_mark = "W"
        else:
            unused_mark = "N"
Ejemplo n.º 37
0
def generateBoogieVamp(blRealization=None, numRepeats=5):
    """
    Turns whole notes in twelve bar blues bass line to blues boogie woogie bass line. Takes
    in numRepeats, which is the number of times to repeat the bass line. Also, takes in a 
    realization of :meth:`~music21.figuredBass.examples.twelveBarBlues`. If none is provided, 
    a default realization with :attr:`~music21.figuredBass.rules.Rules.forbidVoiceOverlap`
    set to False and :attr:`~music21.figuredBass.rules.Rules.partMovementLimits` set to
    [(1,4),(2,12),(3,12)] is used.     

    >>> from music21.figuredBass import examples
    >>> #_DOCS_SHOW examples.generateBoogieVamp(numRepeats = 1).show()
    
    .. image:: images/figuredBass/fbExamples_boogieVamp.*
        :width: 700   
    """
    from music21 import tinyNotation, stream, interval

    if blRealization == None:
        bluesLine = twelveBarBlues()
        fbRules = rules.Rules()
        fbRules.partMovementLimits = [(1, 4), (2, 12), (3, 12)]
        fbRules.forbidVoiceOverlap = False
        blRealization = bluesLine.realize(fbRules)
        sampleScore = blRealization.generateRandomRealizations(numRepeats)

    boogieBassLine = tinyNotation.TinyNotationStream("BB-8. D16 F8. G16 A-8. G16 F8. D16")

    newBassLine = stream.Part()
    newBassLine.append(sampleScore[1][0])  # Time signature
    newBassLine.append(sampleScore[1][1])  # Key signature

    for n in sampleScore[1].notes:
        i = interval.notesToInterval(boogieBassLine[0], n)
        tp = boogieBassLine.transpose(i)
        for lyr in n.lyrics:
            tp.notes[0].addLyric(lyr.text)
        for m in tp.notes:
            newBassLine.append(m)

    newScore = stream.Score()
    newScore.insert(0, sampleScore[0])
    newScore.insert(newBassLine)

    return newScore
Ejemplo n.º 38
0
def construct_music21(musicobject):
    """Export a music21 stream from the given musicobject."""
    if type(musicobject) == Tone:
        if isinstance(musicobject.frequency, float):
            n = note.Note()
            difference = frequency_to_semitone(musicobject.frequency)
            n.transpose(difference, inPlace=True)
        elif musicobject.frequency == '_':
            n = note.Rest()
        else:
            n = note.Note()
            n.pitch.name = musicobject.frequency
        n.duration.quarterLength = musicobject.duration
        return n

    if type(musicobject) == Group:
        compound = stream.Stream()
        for sequence in musicobject.sequences:
            s = stream.Stream()
            for element in sequence:
                s.append(construct_music21(element))
            compound.insert(0, s)
        return compound.flat

    if type(musicobject) == Transformed:
        subject = construct_music21(musicobject.subject)
        T = musicobject.transformation

        # Apply duration transformation
        if type(musicobject.subject) == Tone:
            subject.duration = duration.Duration(subject.duration.quarterLength * T.duration)
        else:
            subject.scaleDurations(T.duration)
            subject.scaleOffsets(T.duration)

        # Apply frequency transformation
        if isinstance(T.frequency, float):
            difference = frequency_to_semitone(T.frequency)
        else:
            difference = interval.notesToInterval(note.Note('c4'), note.Note(T.frequency))
        subject.transpose(difference, inPlace=True)

        return subject
Ejemplo n.º 39
0
def searchForIntervals(notesStr):
    '''notesStr is the same as above.  Now however we check to see
    if the generic intervals are the same, rather than the note names.
    Useful if the clef is missing.
    '''
    notesArr = notesStr.split()
    noteObjArr = []
    for tN in notesArr:
        tNObj = Note()
        tNObj.name = tN[0]
        tNObj.octave = int(tN[1])
        noteObjArr.append(tNObj)
    
    interObjArr = []
    for i in range(len(noteObjArr) - 1):
        int1 = interval.notesToInterval(noteObjArr[i], noteObjArr[i+1])
        interObjArr.append(int1)
    #print interObjArr

    searcher1 = IntervalSearcher(interObjArr) 
    ballataObj  = cadencebook.BallataSheet()
    streamLily = ""

    for thisWork in ballataObj:
        for thisCadence in thisWork.snippets:
            if (thisCadence is None):
                continue
            for i in range(len(thisCadence.parts)):
                if searcher1.compareToStream(thisCadence.parts[i].flat) is True:
                    notesList = ""
                    for thisNote in thisCadence.parts[i].flat.notes:
                        notesList += thisNote.name + " "
                        #thisNote.editorial.color = "blue"
                    streamLily += "\\score {" + \
                            "<< \\time " + str(thisCadence.timeSig) + \
                            "\n \\new Staff {" + str(thisCadence.parts[i].lily) + "} >>" + \
                            str(thisCadence.header()) + "\n}\n"
                    print("In piece %r found in stream %d: %s" % (thisWork.title, i, notesList))

    if streamLily:
        print(streamLily)
        lily.lilyString.LilyString(streamLily).showPDF()
Ejemplo n.º 40
0
def check_augmented_seconds(voice):
    """Raises an error if the interval between two notes in a voice
    is an augmented second.

    >>> from music21 import note, stream
    >>> soprano = stream.Part(map(note.Note, ['D5', 'E-5', 'F#5']))
    >>> bass = stream.Part(map(note.Note, ['B-2', 'G2', 'A2']))
    >>> check_augmented_seconds(soprano)
    Traceback (most recent call last):
    ...
    errors.AugmentedSecondError: Found augmented second at index 2
    >>> check_augmented_seconds(bass)
    """
    previous_note = None
    for i, current_note in enumerate(voice):
        if i > 0:
            test_interval = interval.notesToInterval(previous_note, current_note)
            if test_interval.name == "A2":
                raise AugmentedSecondError(i)
        previous_note = current_note
def base40ActualInterval(base40NumA, base40NumB):
    '''
    Calculates a music21 Interval between two Base40 pitch
    numbers, as calculated using the music21.interval module.

    Raises a Base40 Exception if (a) Either of the Base40 pitch
    numbers does not correspond to a pitch name or (b) If
    an unusual interval is encountered that can't be handled
    by music21.


    >>> musedata.base40.base40ActualInterval(163, 191)
    <music21.interval.Interval m6>
    >>> musedata.base40.base40ActualInterval(186, 174) #Descending M3
    <music21.interval.Interval M-3>
    >>> musedata.base40.base40ActualInterval(1, 5)
    <music21.interval.Interval AAAA1>
    >>> musedata.base40.base40ActualInterval(1, 3)
    <music21.interval.Interval AA1>
    >>> musedata.base40.base40ActualInterval(2, 6)
    Traceback (most recent call last):
    music21.musedata.base40.Base40Exception: Pitch name not assigned to this Base40 number 6

    OMIT_FROM_DOCS
    >>> musedata.base40.base40ActualInterval(12, 6)
    Traceback (most recent call last):
    music21.musedata.base40.Base40Exception: Pitch name not assigned to this Base40 number 12
    '''
    pitchA = base40ToPitch(base40NumA)
    pitchB = base40ToPitch(base40NumB)

    noteA = note.Note()
    noteA.pitch = pitchA
    noteB = note.Note()
    noteB.pitch = pitchB

    try:
        return interval.notesToInterval(noteA, noteB)
    except IndexError:
        raise Base40Exception(
            'Unusual interval- Limitation of music21.interval')
Ejemplo n.º 42
0
def iqRootsAndPercentage(analysisStream):
    totalDuration = analysisStream.duration.quarterLength
    romMerged = analysisStream.flat.stripTies()
    major = ""
    minor = ""
    active = 'minor'
    for element in romMerged:
        if "RomanNumeral" in element.classes:
            #distanceToTonicInSemis = int((element.root().ps -
            #    pitch.Pitch(element.scale.tonic).ps) % 12)
            elementLetter = str(element.root().name)

            ## leave El
            if element.quality == 'minor' or element.quality == 'diminished':
                elementLetter = elementLetter.lower()
            elif element.quality == 'other':
                rootScaleDegree = element.scale.getScaleDegreeFromPitch(
                    element.root())
                if rootScaleDegree:
                    thirdPitch = element.scale.pitchFromDegree(
                        (rootScaleDegree + 2) % 7)
                    int1 = interval.notesToInterval(element.root(), thirdPitch)
                    if int1.intervalClass == 3:
                        elementLetter = elementLetter.lower()
                else:
                    pass
            longString = elementLetter + " (" + str(
                int(element.duration.quarterLength * 10000 / totalDuration) /
                100) + ") "
            if active == 'major':
                major += longString
            else:
                minor += longString
        elif "Key" in element.classes:
            if element.mode == 'major':
                active = 'major'
                major += "\n" + element.tonic + " " + element.mode + " "
            else:
                active = 'minor'
                minor += "\n" + element.tonic + " " + element.mode + " "
    return (major, minor)
Ejemplo n.º 43
0
def base40ActualInterval(base40NumA, base40NumB):
    '''
    Calculates a music21 Interval between two Base40 pitch
    numbers, as calculated using the music21.interval module.

    Raises a Base40 Exception if (a) Either of the Base40 pitch
    numbers does not correspond to a pitch name or (b) If
    an unusual interval is encountered that can't be handled
    by music21.

    >>> from music21 import *
    >>> base40ActualInterval(163,191)
    <music21.interval.Interval m6>
    >>> base40ActualInterval(186,174) #Descending M3
    <music21.interval.Interval M-3> 
    >>> base40ActualInterval(1,5)
    <music21.interval.Interval AAAA1>
    >>> base40ActualInterval(1,3)
    <music21.interval.Interval AA1>
    >>> base40ActualInterval(2,6)
    Traceback (most recent call last):
    Base40Exception: Pitch name not assigned to this Base40 number 6

    OMIT_FROM_DOCS
    >>> base40ActualInterval(12,6)
    Traceback (most recent call last):
    Base40Exception: Pitch name not assigned to this Base40 number 12
    '''
    pitchA = base40ToPitch(base40NumA)
    pitchB = base40ToPitch(base40NumB)

    noteA = note.Note()
    noteA.pitch = pitchA
    noteB = note.Note()
    noteB.pitch = pitchB
    
    try:
        return interval.notesToInterval(noteA,noteB)
    except IndexError:
        raise Base40Exception('Unusual interval- Limitation of music21.interval')
Ejemplo n.º 44
0
def iqRootsAndPercentage(analysisStream):
    totalDuration = analysisStream.duration.quarterLength
    romMerged = analysisStream.flat.stripTies()
    major = ""
    minor = ""
    active = 'minor'
    for element in romMerged:
        if "RomanNumeral" in element.classes:
            #distanceToTonicInSemis = int((element.root().ps -
            #    pitch.Pitch(element.scale.tonic).ps) % 12)
            elementLetter = str(element.root().name)

            ## leave El
            if element.quality == 'minor' or element.quality == 'diminished':
                elementLetter = elementLetter.lower()
            elif element.quality == 'other':
                rootScaleDegree = element.scale.getScaleDegreeFromPitch(element.root())
                if rootScaleDegree:
                    thirdPitch = element.scale.pitchFromDegree((rootScaleDegree + 2) % 7)
                    int1 = interval.notesToInterval(element.root(), thirdPitch)
                    if int1.intervalClass == 3:
                        elementLetter = elementLetter.lower()
                else:
                    pass
            longString = elementLetter + " (" + str(int(
                                element.duration.quarterLength * 10000 / totalDuration)
                                                    / 100) + ") "
            if active == 'major':
                major += longString
            else:
                minor += longString
        elif "Key" in element.classes:
            if element.mode == 'major':
                active = 'major'
                major += "\n" + element.tonic + " " + element.mode + " "
            else:
                active = 'minor'
                minor += "\n" + element.tonic + " " + element.mode + " "
    return (major, minor)
Ejemplo n.º 45
0
 def isValidStep(self, note11, note12):
     '''Determines if the melodic interval between two given notes is "legal"
     according to 21M.301 rules of counterpoint.'''
     interval1 = interval.notesToInterval(note11, note12)
     if interval1.diatonic.name in self.legalMelodicIntervals: return True
     else: return False
Ejemplo n.º 46
0
    def generateValidNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, minorScale):
        '''Helper function for generateFirstSpecies; gets a list of possible
        next notes based on valid melodic intervals, then checks each one so
        that parallel/hidden fifths/octaves, voice crossing, and invalid
        harmonies are prevented. Adds extra weight to notes that would create
        contrary motion.'''
        print currFirmus.name
        valid = []
        bottomInt = interval.notesToInterval(prevFirmus, currFirmus)
        if bottomInt.direction < 0: ascending = True
        else: ascending = False

        n1 = interval.transposeNote(prevNote, "m2")
        n2 = interval.transposeNote(prevNote, "M2")
        n3 = interval.transposeNote(prevNote, "m3")
        n4 = interval.transposeNote(prevNote, "M3")
        n5 = interval.transposeNote(prevNote, "P4")
        n6 = interval.transposeNote(prevNote, "P5")
        if afterLeap: possible = [n1, n2, n3, n4]
        else: possible = [n1, n2, n3, n4, n5, n6]
        possible.extend(possible)

        n7 = interval.transposeNote(prevNote, "m-2")
        n8 = interval.transposeNote(prevNote, "M-2")
        n9 = interval.transposeNote(prevNote, "m-3")
        n10 = interval.transposeNote(prevNote, "M-3")
        n11 = interval.transposeNote(prevNote, "P-4")
        n12 = interval.transposeNote(prevNote, "P-5")
        if afterLeap: possible.extend([n7, n8, n9, n10])
        else: possible.extend([n7, n8, n9, n10, n11, n12])
        print "possible: ", [note1.name for note1 in possible]
        
        for note1 in possible:
            try: validHarmony = self.isValidHarmony(note1, currFirmus)
            except: validHarmony = False

#            vlq = VoiceLeadingQuartet(prevNote, prevFirmus, note1, currFirmus)
#            par5 = vlq.parallelFifth()
#            par8 = vlq.parallelOctave()
#            hid5 = vlq.hiddenFifth()
#            hid8 = vlq.hiddenOctave()
#            par1 = vlq.parallelUnison()
            
            try: par5 = self.isParallelFifth(prevNote, note1, prevFirmus, currFirmus)
            except: par5 = True
            try: par8 = self.isParallelOctave(prevNote, note1, prevFirmus, currFirmus)
            except: par8 = True
            try: hid5 = self.isHiddenFifth(prevNote, note1, prevFirmus, currFirmus)
            except: hid5 = True
            try: hid8 = self.isHiddenOctave(prevNote, note1, prevFirmus, currFirmus)
            except: hid8 = True
            try: par1 = self.isParallelUnison(prevNote, note1, prevFirmus, currFirmus)
            except: par1 = True
            try:
                distance = interval.notesToInterval(currFirmus, note1)
                if distance.direction < 0: crossing = True
                else: crossing = False
            except: crossing = True
            goodNotes = minorScale.getConcreteMelodicMinorScale()
            goodNames = [note2.name for note2 in goodNotes]
            if validHarmony and (not par5) and (not par8) and (not hid5) and\
               (not hid8) and (not par1) and (not crossing):
                if note1.name in goodNames:
                    print "adding: ", note1.name, note1.octave
                    valid.append(note1)
        print
        return valid
Ejemplo n.º 47
0
def intervals(notes):
    return [notesToInterval(notes[0], y).semiSimpleName for y in notes[1:]]
Ejemplo n.º 48
0
def capuaRuleTwo(srcStream):
    '''
    See capuaRuleOne for precise instructions.

    Applies Capua's second rule to the given srcStream, i.e. if four notes are
    ascending with the pattern M2 m2 M2, the intervals shall be made M2 M2 m2.
    Also changes note.style.color for rule 2 (purple purple green purple).

    returns the number of times any note was changed
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(len(ssn) - 3):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]
        n4 = ssn[i + 3]

        if (n1.isRest or n2.isRest or n3.isRest or n4.isRest):
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)
        i3 = interval.notesToInterval(n3, n4)

        if (n1.pitch.accidental is not None or n2.pitch.accidental is not None
                or n4.pitch.accidental is not None):
            continue

        # never seems to improve things...
        if n3.step == 'A' or n3.step == 'D':
            continue

        # e.g., D E F G => D E F# G
        #    or F A Bb C => F A B C
        if (i1.directedName == 'M2' and i2.directedName == 'm2'
                and i3.directedName == 'M2'):
            numChanged += 1
            if 'capuaRuleNumber' in n3.editorial:
                n3.editorial.capuaRuleNumber += RULE_TWO
            else:
                n3.editorial.capuaRuleNumber = RULE_TWO

            if n3.pitch.accidental is not None and n3.pitch.accidental.name == 'flat':
                n3.editorial.savedAccidental = n3.pitch.accidental
                n3.pitch.accidental = None
                n3.editorial.ficta = pitch.Accidental('natural')
                n3.editorial.capuaFicta = pitch.Accidental('natural')
                n1.style.color = 'purple'
                n2.style.color = 'purple'
                n3.style.color = 'ForestGreen'
                n4.style.color = 'purple'
            else:
                n3.editorial.ficta = pitch.Accidental('sharp')
                n3.editorial.capuaFicta = pitch.Accidental('sharp')
                n1.style.color = 'purple'
                n2.style.color = 'purple'
                n3.style.color = 'ForestGreen'
                n4.style.color = 'purple'

    return numChanged
Ejemplo n.º 49
0
def capuaRuleTwo(srcStream):
    '''
    See capuaRuleOne for precise instructions.
    
    Applies Capua's second rule to the given srcStream, i.e. if four notes are
    ascending with the pattern M2 m2 M2, the intervals shall be made M2 M2 m2.
    Also changes note.editorial.color for rule 2 (purple purple green purple).
    
    returns the number of times any note was changed
    '''
    numChanged = 0

    ssn = srcStream.flat.notesAndRests
    for i in range(0, len(ssn) - 3):
        n1 = ssn[i]
        n2 = ssn[i + 1]
        n3 = ssn[i + 2]
        n4 = ssn[i + 3]

        if n1.isRest or \
           n2.isRest or \
           n3.isRest or \
           n4.isRest:
            continue

        i1 = interval.notesToInterval(n1, n2)
        i2 = interval.notesToInterval(n2, n3)
        i3 = interval.notesToInterval(n3, n4)

        if n1.accidental is not None or \
           n2.accidental is not None or \
           n4.accidental is not None:
            continue

        ### never seems to improve things...
        if n3.step == "A" or n3.step == "D":
            continue

        # e.g., D E F G => D E F# G
        #    or F A Bb C => F A B C
        if i1.directedName == "M2" and \
           i2.directedName == "m2" and \
           i3.directedName == "M2":
            numChanged += 1
            if ("capua" in n3.editorial.misc):
                n3.editorial.misc['capua_rule_number'] += RULE_TWO
            else:
                n3.editorial.misc['capua_rule_number'] = RULE_TWO

            if (n3.accidental is not None and n3.accidental.name == "flat"):
                n3.editorial.misc["saved-accidental"] = n3.accidental
                n3.accidental = None
                n3.editorial.ficta = pitch.Accidental("natural")
                n3.editorial.misc["capua-ficta"] = pitch.Accidental("natural")
                n1.editorial.color = "purple"
                n2.editorial.color = "purple"
                n3.editorial.color = "ForestGreen"
                n4.editorial.color = "purple"
            else:
                n3.editorial.ficta = pitch.Accidental("sharp")
                n3.editorial.misc["capua-ficta"] = pitch.Accidental("sharp")
                n1.editorial.color = "purple"
                n2.editorial.color = "purple"
                n3.editorial.color = "ForestGreen"
                n4.editorial.color = "purple"

    return numChanged
Ejemplo n.º 50
0
def findPhraseBoundaries(book=4, madrigal=12):
    filename = 'monteverdi/madrigal.%s.%s' % (book, madrigal)
    sc = corpus.parse(filename + '.xml')
    analysis = corpus.parse(filename + '.rntxt')
    analysisFlat = analysis.flat.stripTies().getElementsByClass(
        roman.RomanNumeral)

    phraseScoresByOffset = {}

    for p in sc.parts:
        partNotes = p.flat.stripTies(matchByPitch=True).notesAndRests
        #thisPartPhraseScores = [] # keeps track of the likelihood that a phrase boundary is after note i
        for i in range(
                2,
                len(partNotes) - 2
        ):  # start on the third note and stop searching on the third to last note...
            thisScore = 0
            twoNotesBack = partNotes[i - 2]
            previousNote = partNotes[i - 1]
            thisNote = partNotes[i]
            nextNote = partNotes[i + 1]
            nextAfterThatNote = partNotes[i + 2]

            phraseOffset = nextNote.offset
            if phraseOffset in phraseScoresByOffset:
                existingScore = phraseScoresByOffset[phraseOffset]
            else:
                phraseScoresByOffset[phraseOffset] = 0
                existingScore = 0

            if thisNote.isRest == True:
                continue

            if nextNote.isRest == True:
                thisScore = thisScore + 10
            else:
                intervalToNextNote = interval.notesToInterval(
                    thisNote, nextNote)
                if intervalToNextNote.chromatic.undirected >= 6:  # a tritone or bigger
                    thisScore = thisScore + 10
            if (thisNote.quarterLength > previousNote.quarterLength) and \
                (thisNote.quarterLength > nextNote.quarterLength):
                thisScore = thisScore + 10
            if (thisNote.quarterLength > previousNote.quarterLength) and \
                (thisNote.quarterLength > twoNotesBack.quarterLength) and \
                (nextNote.quarterLength > nextAfterThatNote.quarterLength):
                thisScore = thisScore + 10

            previousNoteAnalysis = analysisFlat.getElementAtOrBefore(
                previousNote.offset)
            thisNoteAnalysis = analysisFlat.getElementAtOrBefore(
                thisNote.offset)

            if (previousNoteAnalysis.romanNumeral == 'V'
                    and thisNoteAnalysis.romanNumeral.upper() == 'I'):
                thisScore = thisScore + 11
            elif (previousNoteAnalysis.romanNumeral.upper() == 'II'
                  and thisNoteAnalysis.romanNumeral.upper() == 'I'):
                thisScore = thisScore + 6

            if thisNote.lyric is not None and thisNote.lyric.endswith('.'):
                thisScore = thisScore + 15  # would be higher but our lyrics data is bad.

            phraseScoresByOffset[phraseOffset] = existingScore + thisScore

    flattenedBass = sc.parts[-1].flat.notesAndRests
    for thisOffset in sorted(phraseScoresByOffset.keys()):
        psbo = phraseScoresByOffset[thisOffset]
        if psbo > 0:
            print(thisOffset, psbo)
            relevantNote = flattenedBass.getElementAtOrBefore(thisOffset - 0.1)
            if hasattr(relevantNote, 'score'):
                print("adjusting score from %d to %d for note in measure %d" %
                      (relevantNote.score, relevantNote.score + psbo,
                       relevantNote.measureNumber))
                relevantNote.score += psbo
            else:
                relevantNote.score = psbo
    for n in flattenedBass:
        if hasattr(n, 'score'):
            n.lyric = str(n.score)

    sc.show()