Esempio n. 1
0
def _Rule_10(s: stave.Stave):
    """Éviter les marches d'harmonie"""
    for start in range(s.barNumber):
        for end in range(start, s.barNumber):

            motif = []
            for i in range(start, end + 1):
                for n in s.getBar(i):
                    motif.append(n)

            motif_bar_number = end - start + 1
            try:
                following = []
                for i in range(end + 1, motif_bar_number + end + 1):
                    for n in s.getBar(i):
                        following.append(n)
            except IndexError:
                break
            try:
                if tools.matchSequence(motif, following, s.scale):
                    msg = f"Sequence in {s.title}. It should be avoided"
                    if len(motif) == 1:
                        continue
                    if len(motif) <= 2:
                        error.warn(msg, motif, following)
                    else:
                        raise error.CompositionError(msg, motif, following)
            except ValueError:
                # It should be that the relative one is encountered, so no sequence here
                continue
Esempio n. 2
0
def rule_4(s: stave.Stave):
    """On doit commencer par une consonance parfaite (unisson, quinte ou douzième, octave ou quinzième) et finir par l'octave ou l'unisson
    """
    def nb_error(poss, posi, notes):
        if len(notes) != 2:
            raise error.CompositionError(
                f"Two notes are expected at the {poss} of the track",
                s.getBar(posi))

    # start
    notes = s.atFirstPos(0)
    nb_error("start", 0, notes)

    if not notes[0].pitch.isPerfectlyConsonantWith(notes[1].pitch):
        raise error.CompositionError(
            "The first two notes are not fully consonant.", s.getBar(0))

    # end
    notes = s.atFirstPos(s.lastFirstPos)
    nb_error("end", s.getBar(s.barNumber - 1), notes)

    if not notes[0].pitch.isInterval(1, 8, True).With(notes[1].pitch):
        raise error.CompositionError(
            "The last interval must be an unison or an octave.",
            s.getBar(s.barNumber - 1))
Esempio n. 3
0
def rule_23(s: stave.Stave):
    """La première et la dernière mesure sont obligatoirement harmonisées par l'accord de tonique à l'état fondamental"""
    c = chord.Chord(1, s.scale)
    for bar in (s.getBar(0), s.getBar(-1)):
        if not c.isInversion([*bar], 0):
            raise error.CompositionError(
                "First and last bar must be at the root position of the chord of the first degree",
                bar)
Esempio n. 4
0
def rule_26(s: stave.Stave):
    """La première et la dernière mesure sont obligatoirement harmonisées par l'accord de tonique à l'état fondamental"""
    tonic = chord.Chord(1, s.scale)
    for measure in (s.getBar(0), s.getBar(-1)):
        is_error = False
        try:
            if not tonic.isInversion([*measure], 0):
                is_error = True
        except ValueError:
            is_error = True

        if is_error:
            raise error.CompositionError(
                f"In {s.title}, the first bar or the last bar is not the tonic chord at root position",
                measure)
Esempio n. 5
0
def rule_22(cp: stave.Stave, cf: stave.Stave):
    """À l'avant dernière mesure, on emploiera la sixte majeure lorsque le chant donné sera à la basse et la tierce mineure suivie de l'octave ou de l'unisson lorsqu'il sera à la partie supérieure"""
    # is the cantus firmus above or beyond?
    cp_above = None
    for cpn, cfn in zip(cp.barIter(), cf.barIter()):
        cpn, cfn = [util.to_pitch(n[0]) for n in (cpn, cfn)]
        if cpn != cfn:
            cp_above = cpn.value.step > cfn.value.step
            break
    assert cp_above is not None

    # check the before last one bar
    cpn = util.to_pitch(cp.getBar(cp.barNumber - 2)[0])
    cfn = util.to_pitch(cf.getBar(cf.barNumber - 2)[0])
    cp = cp.copy()
    cp.extend(cf)
    before_last_bar = cp.getBar(cp.barNumber - 2)

    if cp_above and not cfn.isQualifiedInterval((6, "major")):
        raise error.CompositionError(
            "The before last interval must be a 6th major", before_last_bar)
    elif not cp_above and not cfn.isQualifiedInterval((3, "minor")):
        raise error.CompositionError(
            "The before last interval must be a 3rd minor", before_last_bar)
Esempio n. 6
0
def rule_14(s: stave.Stave):
    """Pour la fausse relation de triton, la règle est la même qu'en harmonie : la fausse relation de triton est défendue."""
    get_pitches = lambda b: sorted([util.to_pitch(x) for x in b],
                                   key=lambda x: x.value.semitone)

    old_high = None
    for i, bar in enumerate(s.barIter()):
        if len(bar) != 2:
            raise error.CompositionError("Two notes expected", bar)

        bass, high = get_pitches(bar)

        # check with last bar
        if old_high is not None and bass.isQualifiedInterval(
            (4, 'augmented')).With(old_high):
            raise error.CompositionError("False relation is forbidden", bar)
        # check with next bar
        if i + 1 < s.barNumber:
            next_bass, next_high = get_pitches(s.getBar(i + 1))
            if bass.isQualifiedInterval((4, 'augmented')).With(next_high):
                raise error.CompositionError("False relation is forbidden",
                                             bar)
        # prepare next iteration
        old_high = high