示例#1
0
    def testOrnamentA(self):
        from music21 import expressions
        from music21 import chord
        s = stream.Stream()
        s.repeatAppend(note.Note(), 4)
        s.repeatAppend(chord.Chord(['c4', 'g5']), 4)

        #s.insert(4, expressions.Trill())
        s.notes[3].expressions.append(expressions.Trill())
        s.notes[2].expressions.append(expressions.Mordent())
        s.notes[1].expressions.append(expressions.InvertedMordent())

        s.notes[6].expressions.append(expressions.Trill())
        s.notes[7].expressions.append(expressions.Mordent())
        s.notes[5].expressions.append(expressions.InvertedMordent())

        raw = fromMusic21Object(s)
        #s.show()

        self.assertEqual(raw.count('<trill-mark'), 2)
        self.assertEqual(raw.count('<ornaments>'), 6)
        self.assertEqual(raw.count('<inverted-mordent/>'), 2)
        self.assertEqual(raw.count('<mordent/>'), 2)
示例#2
0
        def createNachschlagTrillMeasure():
            '''
            Returns a dictionary with the following keys

            returnDict = {
                "name": string,
                "midi": measure stream,
                "omr": measure stream,
                "expected": measure stream,
            }
            '''
            noteDuration = duration.Duration('quarter')
            trillDuration = duration.Duration(.125)

            n0 = note.Note("E")
            n0.duration = noteDuration

            tn1 = note.Note("E")
            tn1.duration = trillDuration
            tn2 = note.Note("F")
            tn2.duration = trillDuration
            tn3 = note.Note("D")
            tn3.duration = trillDuration
            firstHalfTrill = [tn1, tn2, deepcopy(tn1), deepcopy(tn2)]
            secondHalfTrill = [deepcopy(tn1), deepcopy(tn2), deepcopy(tn1), tn3]
            expandedTrill = firstHalfTrill + secondHalfTrill

            midiMeasure = stream.Measure()
            midiMeasure.append(expandedTrill)
            omrMeasure = stream.Measure()
            omrMeasure.append(n0)

            nachschlagTrill = expressions.Trill()
            nachschlagTrill.nachschlag = True
            nachschlagTrill.quarterLength = trillDuration.quarterLength
            expectedFixedOmrMeasure = stream.Measure()
            noteWithTrill = deepcopy(n0)
            noteWithTrill.expressions.append(deepcopy(nachschlagTrill))
            expectedFixedOmrMeasure.append(noteWithTrill)

            returnDict = {
                "name": "Nachschlag Trill",
                "midi": midiMeasure,
                "omr": omrMeasure,
                "expected": expectedFixedOmrMeasure,
            }

            return returnDict
示例#3
0
        def createMeasureWithTrillAlready():
            '''
            Returns a dictionary with the following keys

            returnDict = {
                "name": string,
                "midi": measure stream,
                "omr": measure stream,
                "expected": measure stream,
            }
            '''
            noteDuration = duration.Duration('quarter')
            trillDuration = duration.Duration(.125)

            noteWithTrill = note.Note("F")
            noteWithTrill.duration = noteDuration
            trill = expressions.Trill()
            trill.quarterLength = trillDuration.quarterLength
            noteWithTrill.expressions.append(trill)

            tn1 = note.Note("F")
            tn1.duration = trillDuration
            tn2 = note.Note("G")
            tn2.duration = trillDuration
            expandedTrill = [tn1, tn2, deepcopy(tn1), deepcopy(tn2)]

            midiMeasure = stream.Measure()
            midiMeasure.append(expandedTrill)
            omrMeasure = stream.Measure()
            omrMeasure.append(noteWithTrill)

            returnDict = {
                "name": "OMR with Trill Notation",
                "midi": midiMeasure,
                "omr": omrMeasure,
                "expected": deepcopy(omrMeasure),
            }
            return returnDict
示例#4
0
        def createMeasureWithTrillAlready():
            '''
            Returns a dictionary with the following keys

            returnDict = {
                'name': string,
                'midi': measure stream,
                'omr': measure stream,
                'expected': measure stream,
            }
            '''
            noteDuration = duration.Duration('quarter')
            trillDuration = duration.Duration(.125)

            noteWithTrill = note.Note('F')
            noteWithTrill.duration = noteDuration
            trill = expressions.Trill()
            trill.quarterLength = trillDuration.quarterLength
            noteWithTrill.expressions.append(trill)

            tn1 = note.Note('F')
            tn1.duration = trillDuration
            tn2 = note.Note('G')
            tn2.duration = trillDuration
            expandedTrill = [tn1, tn2, deepcopy(tn1), deepcopy(tn2)]

            midiMeasure = stream.Measure()
            midiMeasure.append(expandedTrill)
            omrMeasure = stream.Measure()
            omrMeasure.append(noteWithTrill)

            returnDict = {
                'name': 'OMR with Trill Notation',
                'midi': midiMeasure,
                'omr': omrMeasure,
                'expected': deepcopy(omrMeasure),
            }
            return returnDict
示例#5
0
        def createDoubleTrillMeasure():
            '''
            Returns a dictionary with the following keys

            returnDict = {
                "name": string,
                "midi": measure stream,
                "omr": measure stream,
                "expected": measure stream,
            }
            '''
            noteDuration = duration.Duration('quarter')

            # GAGA Trill
            trill1NoteDuration = duration.Duration(.25)
            n0 = note.Note("G")
            n0.duration = noteDuration
            n1 = note.Note("G")
            n1.duration = trill1NoteDuration
            n2 = note.Note("A")
            n2.duration = trill1NoteDuration
            trill1 = [n1, n2, deepcopy(n1), deepcopy(n2)]  # GAGA

            # CBCB Trill
            trill2NoteDuration = duration.Duration(.0625)
            n3 = note.Note("B3")  # omr
            n3.duration = noteDuration
            n4 = note.Note("B3")
            n4.duration = trill2NoteDuration
            n5 = note.Note("C")
            n5.duration = trill2NoteDuration
            trill2 = [n5, n4, deepcopy(n5), deepcopy(n4),
                      deepcopy(n5), deepcopy(n4), deepcopy(n5), deepcopy(n4)]

            midiMeasure = stream.Measure()
            midiMeasure.append(trill1)
            midiMeasure.append(trill2)

            omrMeasure = stream.Measure()
            omrMeasure.append([n0, n3])

            expectedFixedOmrMeasure = stream.Measure()
            n0WithTrill = deepcopy(n0)
            n0Trill = expressions.Trill()
            n0Trill.size = interval.Interval('m-2')
            n0Trill.quarterLength = trill1NoteDuration.quarterLength
            n0WithTrill.expressions.append(n0Trill)
            n1WithTrill = deepcopy(n3)
            n1Trill = expressions.Trill()
            n1Trill.size = interval.Interval('M2')
            n1Trill.quarterLength = trill2NoteDuration.quarterLength
            n1WithTrill.expressions.append(n0Trill)
            expectedFixedOmrMeasure.append([n0WithTrill, n1WithTrill])

            returnDict = {
                "name": "Double Trill Measure",
                "midi": midiMeasure,
                "omr": omrMeasure,
                "expected": expectedFixedOmrMeasure,
            }
            return returnDict
示例#6
0
    def recognize(self, busyNotes, simpleNotes=None) -> Union[bool, expressions.Trill]:
        '''
        Tries to identify the busy notes as a trill.

        When simple notes is provided, tries to identify busy notes
        as the trill shortened by simple notes.
        Currently only supports one simple note in simple notes.

        Only when checkNachschlag is true, allows last few notes to break trill rules.

        Trill interval size is interval between busy notes.

        Returns: False if not possible or the Trill Expression
        '''
        # Enough notes to trill
        if len(busyNotes) <= 2:
            return False

        # Oscillation pitches
        n1 = busyNotes[0]
        n2 = busyNotes[1]

        if not n1.isNote or not n2.isNote:
            return False

        if abs(n1.pitch.midi - n2.pitch.midi) > self.acceptableInterval:
            return False

        twoNoteOscillation = True
        i = 0
        for i in range(len(busyNotes)):
            noteConsidering = busyNotes[i]
            if not noteConsidering.isNote:
                return False
            if i % 2 == 0 and noteConsidering.pitch != n1.pitch:
                twoNoteOscillation = False
                break
            elif i % 2 != 0 and noteConsidering.pitch != n2.pitch:
                twoNoteOscillation = False
                break

        isNachschlag = False
        if twoNoteOscillation:
            pass
        elif not self.checkNachschlag:
            return False
        else:
            lengthOk = len(busyNotes) >= self.minimumLengthForNachschlag
            notTooMuchNachschlag = i >= len(busyNotes) / 2
            if lengthOk and notTooMuchNachschlag:
                isNachschlag = True
            else:
                return False

        # set up trill
        trill = expressions.Trill()
        trill.quarterLength = self.calculateOrnamentNoteQl(busyNotes, simpleNotes)
        if isNachschlag:
            trill.nachschlag = True

        if not simpleNotes:
            trill.size = interval.Interval(noteStart=n1, noteEnd=n2)
            return trill

        # currently ignore other notes in simpleNotes
        simpleNote = simpleNotes[0]

        # enharmonic invariant checker
        if not(simpleNote.pitch.midi == n1.pitch.midi or simpleNote.pitch.midi == n2.pitch.midi):
            return False

        endNote = n2
        startNote = n1
        if simpleNote.pitch.midi == n2.pitch.midi:
            endNote = n1
            startNote = n2
        distance = interval.Interval(noteStart=startNote, noteEnd=endNote)
        trill.size = distance
        return trill
示例#7
0
    def testRecognizeTrill(self):
        # set up the experiment
        testConditions = []

        n1Duration = duration.Duration('quarter')
        t1NumNotes = 4
        t1UpInterval = interval.Interval('M2')
        t1DownInterval = interval.Interval('M-2')
        n1Lower = note.Note('G')
        n1Lower.duration = n1Duration
        n1Upper = note.Note('A')
        n1Upper.duration = n1Duration
        t1 = expressions.Trill()
        t1NoteDuration = calculateTrillNoteDuration(t1NumNotes, n1Duration)
        t1.quarterLength = t1NoteDuration
        t1Notes = t1.realize(n1Lower)[0]  # GAGA
        t1NotesWithRest = deepcopy(t1Notes)  # GA_A
        r1 = note.Rest()
        r1.duration = duration.Duration(t1NoteDuration)
        t1NotesWithRest[2] = r1
        testConditions.append(
            _TestCondition(
                name='even whole step trill up without simple note',
                busyNotes=t1Notes,
                isOrnament=True,
                ornamentSize=t1UpInterval)
        )
        testConditions.append(
            _TestCondition(
                name='even whole step trill up from simple note',
                busyNotes=t1Notes,
                simpleNotes=[n1Lower],
                isOrnament=True,
                ornamentSize=t1UpInterval)
        )
        testConditions.append(
            _TestCondition(
                name='even whole step trill up to simple note',
                busyNotes=t1Notes,
                simpleNotes=[n1Upper],
                isOrnament=True,
                ornamentSize=t1DownInterval)
        )
        testConditions.append(
            _TestCondition(
                name='valid trill up to enharmonic simple note',
                busyNotes=t1Notes,
                simpleNotes=[note.Note('G##')],  # A
                isOrnament=True,
                ornamentSize=t1DownInterval)
        )
        testConditions.append(
            _TestCondition(
                name='valid trill but not with simple note',
                busyNotes=t1Notes,
                simpleNotes=[note.Note('E')],
                isOrnament=False)
        )
        testConditions.append(
            _TestCondition(
                name='invalid trill has rest inside',
                busyNotes=t1NotesWithRest,
                isOrnament=False)
        )

        n2Duration = duration.Duration('half')
        t2NumNotes = 5
        t2UpInterval = interval.Interval('m2')
        t2DownInterval = interval.Interval('m-2')
        n2Lower = note.Note('G#')
        n2Lower.duration = n2Duration
        n2Upper = note.Note('A')
        n2Upper.duration = n2Duration
        t2NoteDuration = duration.Duration(calculateTrillNoteDuration(t2NumNotes, n2Duration))
        t2n1 = note.Note('A')  # trill2note1
        t2n1.duration = t2NoteDuration
        t2n2 = note.Note('G#')
        t2n2.duration = t2NoteDuration
        t2Notes = stream.Stream()  # A G# A G# A
        t2Notes.append([t2n1, t2n2, deepcopy(t2n1), deepcopy(t2n2), deepcopy(t2n1)])
        testConditions.append(
            _TestCondition(
                name='odd half step trill down without simple note',
                busyNotes=t2Notes,
                isOrnament=True,
                ornamentSize=t2DownInterval)
        )
        testConditions.append(
            _TestCondition(
                name='odd half step trill down to simple note',
                busyNotes=t2Notes,
                simpleNotes=[n2Lower],
                isOrnament=True,
                ornamentSize=t2UpInterval)
        )
        testConditions.append(
            _TestCondition(
                name='odd trill down from simple note',
                busyNotes=t2Notes,
                simpleNotes=[n2Upper],
                isOrnament=True,
                ornamentSize=t2DownInterval)
        )

        n3Duration = duration.Duration('quarter')
        t3NumNotes = 8
        t3UpInterval = interval.Interval('m2')
        t3DownInterval = interval.Interval('m-2')
        n3 = note.Note('B')
        n3.duration = n3Duration
        t3NoteDuration = duration.Duration(calculateTrillNoteDuration(t3NumNotes, n3Duration))
        t3n1 = note.Note('C5')
        t3n1.duration = t3NoteDuration
        t3n2 = note.Note('B')
        t3n2.duration = t3NoteDuration
        nachschlagN1 = note.Note('D5')
        nachschlagN1.duration = t3NoteDuration
        nachschlagN2 = note.Note('E5')
        nachschlagN2.duration = t3NoteDuration
        nachschlagN3 = note.Note('F5')
        nachschlagN3.duration = t3NoteDuration
        t3Notes = stream.Stream()  # CBCBCDEF
        t3Notes.append(
            [t3n1, t3n2, deepcopy(t3n1), deepcopy(t3n2), deepcopy(t3n1),
            nachschlagN1, nachschlagN2, nachschlagN3]
        )

        testConditions.append(
            _TestCondition(
                name='Nachschlag trill when not checking for nachschlag',
                busyNotes=t3Notes,
                isOrnament=False)
        )
        testConditions.append(
            _TestCondition(
                name='Nachschlag trill when checking for nachschlag',
                busyNotes=t3Notes,
                isNachschlag=True,
                isOrnament=True,
                ornamentSize=t3DownInterval)
        )
        testConditions.append(
            _TestCondition(
                name='Nachschlag trill when checking for nachschlag up to simple note',
                busyNotes=t3Notes,
                simpleNotes=[n3],
                isNachschlag=True,
                isOrnament=True,
                ornamentSize=t3UpInterval)
        )

        t4Duration = duration.Duration('eighth')
        t4n1 = note.Note('A')
        t4n1.duration = t4Duration
        t4n2 = note.Note('G')
        t4n2.duration = t4Duration
        testConditions.append(
            _TestCondition(
                name='One note not a trill',
                busyNotes=[t4n1],
                isOrnament=False)
        )
        testConditions.append(
            _TestCondition(
                name='Two notes not a trill',
                busyNotes=[t4n1, t4n2],
                isOrnament=False)
        )

        t5NoteDuration = duration.Duration('eighth')
        t5n1 = note.Note('A')  # trill2note1
        t5n1.duration = t5NoteDuration
        t5n2 = note.Note('C')
        t5n2.duration = t5NoteDuration
        t5Notes = stream.Stream()  # A C A C
        t5Notes.append([t5n1, t5n2, deepcopy(t5n1), deepcopy(t5n2)])
        testConditions.append(
            _TestCondition(
                name='Too big of oscillating interval to be trill',
                busyNotes=t5Notes,
                isOrnament=False)
        )

        t6NoteDuration = duration.Duration('eighth')
        t6n1 = note.Note('F')  # trill2note1
        t6n1.duration = t6NoteDuration
        t6n2 = note.Note('E')
        t6n2.duration = t6NoteDuration
        t6n3 = note.Note('G')
        t6n3.duration = t2NoteDuration
        t5Notes = stream.Stream()  # F E F G
        t5Notes.append([t6n1, t6n2, deepcopy(t6n1), t6n3])
        testConditions.append(
            _TestCondition(
                name='Right interval but not oscillating between same notes',
                busyNotes=t5Notes,
                isOrnament=False)
        )

        # run test
        for cond in testConditions:
            trillRecognizer = TrillRecognizer()
            if cond.isNachschlag:
                trillRecognizer.checkNachschlag = True

            if cond.simpleNotes:
                trill = trillRecognizer.recognize(cond.busyNotes, simpleNotes=cond.simpleNotes)
            else:
                trill = trillRecognizer.recognize(cond.busyNotes)

            if cond.isOrnament:
                self.assertIsInstance(trill, expressions.Trill, cond.name)
                # ensure trill is correct
                self.assertEqual(trill.nachschlag, cond.isNachschlag, cond.name)
                if cond.ornamentSize:
                    self.assertEqual(trill.size, cond.ornamentSize, cond.name)
            else:
                self.assertFalse(trill, cond.name)