Beispiel #1
0
    def testBasicD(self):
        from music21 import stream, note, converter, spanner
        import copy

        s = stream.Stream()
        n1 = note.Note('d2', quarterLength=2.0)
        n2 = note.Note('e2', quarterLength=2.0)
        sp = spanner.Slur(n1, n2)

        s.append(n1)
        s.append(n2)
        s.append(sp)

        # the deepcopy is what creates the bug in the preservation of a weakref

        #temp = converter.freezeStr(s)

        sCopy = copy.deepcopy(s)
        temp = converter.freezeStr(sCopy)

        post = converter.thawStr(temp)
        self.assertEqual(len(post.notes), 2)
        self.assertEqual(str(post.notes[0].pitch), 'D2')
        spPost = post.spanners[0]
        self.assertEqual(spPost.getSpannedElements(), [
                         post.notes[0], post.notes[1]])
        self.assertEqual(spPost.getSpannedElementIds(), [
                         id(post.notes[0]), id(post.notes[1])])
Beispiel #2
0
    def testStreams02(self):

        # based on Stream.testAddSlurByMelisma(self):

        #from music21 import corpus, spanner
        nStart = None
        nEnd = None

        ex = corpus.parse('luca/gloria').parts['cantus'].measures(1, 11)
        exFlatNotes = ex.flat.notesAndRests.stream()
        nLast = exFlatNotes[-1]

        for i, n in enumerate(exFlatNotes):
            if i < len(exFlatNotes) - 1:
                nNext = exFlatNotes[i + 1]
            else:
                continue

            if n.lyrics:
                nStart = n
            # if next is a begin, then this is an end
            elif nStart is not None and nNext.lyrics and n.tie is None:
                nEnd = n
            elif nNext is nLast:
                nEnd = n
            if nStart is not None and nEnd is not None:
                nStart.addLyric(nStart.beatStr)
                ex.insert(spanner.Slur(nStart, nEnd))
                nStart = None
                nEnd = None

        for sp in ex.spanners.getElementsByClass('Slur'):
            #environLocal.printDebug(['sp', n.nameWithOctave, sp])
            n = sp.getFirst()
Beispiel #3
0
    def testFreezeThawWithSpanner(self):
        from music21 import stream, note, spanner
        s = stream.Stream()
        sDummy = stream.Stream()
        n = note.Note()
        sl1 = spanner.Slur([n])
        s.insert(0.0, sl1)
        s.insert(2.0, n)
        sDummy.insert(3.0, n)

        self.assertIs(s.spanners[0].getFirst(), s.notes[0])

        sf = StreamFreezer(s)
        out = sf.writeStr(fmt='jsonpickle')  # easier to read...

        del s
        del sDummy
        del n

        st = StreamThawer()
        st.openStr(out)
        outStream = st.stream
        self.assertEqual(len(outStream), 2)
        self.assertEqual(outStream.notes[0].offset, 2.0)
        self.assertIs(outStream.spanners[0].getFirst(), outStream.notes[0])
Beispiel #4
0
 def addSlur(self):
     """Adds a slur to the neumes notes"""
     notes = self.notes.elements
     if len(notes) > 1:
         slur = spanner.Slur(notes)
         slur.priority = -1
         self.insert(0, slur)
Beispiel #5
0
    def testSpannersWrite(self):
        p = converter.parse("tinynotation: 4/4 c4 d e f g a b c' b a g2")
        listNotes = list(p.recurse().notes)
        c = listNotes[0]
        d = listNotes[1]
        sl1 = spanner.Slur([c, d])
        p.insert(0.0, sl1)

        f = listNotes[3]
        g = listNotes[4]
        a = listNotes[5]
        sl2 = spanner.Slur([f, g, a])
        p.insert(0.0, sl2)

        c2 = listNotes[6]
        g2 = listNotes[-1]
        sl3 = spanner.Slur([c2, g2])
        p.insert(0.0, sl3)
        self.assertEqual(self.getXml(p).count('<slur '), 6)
Beispiel #6
0
    def setDurationForObject(self, generalNote, durationInfo):
        '''
        generalNote could be a Note, Chord, or Rest
        
        DurationInfo is a string like:
        
            Whole,Dotted,Slur
        
        '''
        from music21 import noteworthy
        dictionaries = noteworthy.dictionaries

        parts = durationInfo.split(',')
        lengthnote = parts[0]
        thisNoteIsSlurred = False
        durationObject = duration.Duration(
            dictionaries["dictionaryNoteLength"][lengthnote])

        for kk in parts:
            if kk == "Grace":
                #print "GRACE NOTE"
                # Now it doesn't work, the function for grace notes have to be added here
                environLocal.warn('skipping grace note')
                return
            elif kk == "Slur":
                #print "SLUR"
                if self.withinSlur is False:
                    self.beginningSlurNote = generalNote
                thisNoteIsSlurred = True
            elif kk == "Dotted":
                durationObject.dots = 1
            elif kk == "DblDotted":
                durationObject.dots = 2

            elif kk == "Triplet" or kk == "Triplet=First" or kk == "Triplet=End":
                tup = duration.Tuplet(3, 2, durationObject.type)
                durationObject.appendTuplet(tup)

        generalNote.duration = durationObject

        # if Slur
        if self.withinSlur is True and thisNoteIsSlurred is False:
            music21SlurObj = spanner.Slur(self.beginningSlurNote, generalNote)
            self.currentMeasure.append(music21SlurObj)
            self.withinSlur = False
        elif thisNoteIsSlurred is True:
            self.withinSlur = True
        else:
            self.withinSlur = False
Beispiel #7
0
    def testBasicF(self):
        from music21 import stream, note, converter, spanner

        s = stream.Score()
        s.repeatAppend(note.Note('G4'), 5)
        for i, syl in enumerate(['se-', 'ri-', 'al-', 'iz-', 'ing']):
            s.notes[i].addLyric(syl)
        s.append(spanner.Slur(s.notes[0], s.notes[-1]))

        # file writing
        #converter.freeze(s, fmt='pickle', fp='/_scratch/test.p')

        data = converter.freezeStr(s, fmt='pickle')
        sPost = converter.thawStr(data)
        self.assertEqual(len(sPost.notes), 5)
Beispiel #8
0
    def testSpannerSerializationOfNotesNotInPickle(self):
        '''
        test to see if spanners serialize properly if they
        contain notes not in the pickle...
        '''
        from music21 import stream, spanner, converter
        from music21 import note
        n1 = note.Note("D4")
        n2 = note.Note("E4")
        n3 = note.Note("F4")
        slur1 = spanner.Slur([n1, n2])
        s = stream.Part()
        s.insert(0, n3)
        s.insert(0, slur1)
        data = converter.freezeStr(s, fmt='pickle')

        unused_s2 = converter.thawStr(data)
Beispiel #9
0
    def testStreams01(self):
        '''
        Basic stream issues
        '''
        #from music21 import note, stream, clef, metadata, spanner

        #==== "fig-df02"
        # Storing, Ordering, and Timing Elements

        n1 = note.Note('g3', type='half')
        n2 = note.Note('d4', type='half')
        cf1 = clef.AltoClef()

        m1 = stream.Measure(number=1)
        m1.append([n1, n2])
        m1.insert(0, cf1)

        # the measure has three elements
        assert len(m1) == 3
        # the offset returned is the most-recently set
        assert n2.offset == 2.0
        # automatic sorting positions Clef first
        assert m1[0] == cf1
        # list-like indices follow sort order
        assert m1.index(n2) == 2
        # can find an element based on a given offset
        assert m1.getElementAtOrBefore(3) == n2

        n3 = note.Note('g#3', quarterLength=0.5)
        n4 = note.Note('d-4', quarterLength=3.5)

        m2 = stream.Measure(number=2)
        m2.append([n3, n4])

        # appended position is after n3
        assert n4.offset == .5
        assert m2.highestOffset == .5
        # can access objects on elements
        assert m2[1].duration.quarterLength == 3.5
        # the Stream duration is the highest offset + duration
        assert m2.duration.quarterLength == 4

        p1 = stream.Part()
        p1.append([m1, m2])

        # the part has 2 components
        assert len(p1) == 2
        # the Stream duration is the highest offset + durations
        assert p1.duration.quarterLength == 8
        # can access Notes from Part using multiple indices
        assert p1[1][0].pitch.nameWithOctave == 'G#3'

        s1 = stream.Score()
        s1.append(p1)
        md1 = metadata.Metadata(title='The music21 Stream')
        s1.insert(0, md1)
        # calling show by default renders musicxml output
        #s1.show()

        #==== "fig-df02" end

        #==== "fig-df03"
        # Positioning the Same Element in Multiple Containers
        # show positioning the same element in multiple containers
        # do not yet use a flat representation
        s2 = stream.Stream()
        s3 = stream.Stream()
        s2.insert(10, n2)
        s3.insert(40, n2)

        # the offset attribute returns the last assigned
        assert n2.offset == 40
        # we can provide a site to finde a location-specific offset
        assert n2.getOffsetBySite(m1) == 2.0
        assert n2.getOffsetBySite(s2) == 10
        # the None site provides a default offset
        assert set(n2.sites.get()) == set([None, m1, s2, s3])
        # the same instance is found in all Streams
        assert m1.hasElement(n2) == True
        assert s2.hasElement(n2) == True
        assert s3.hasElement(n2) == True

        # only offset is independent to each location
        n2.pitch.transpose('-M2', inPlace=True)
        assert s2[s2.index(n2)].nameWithOctave == 'C4'
        assert s3[s3.index(n2)].nameWithOctave == 'C4'
        assert m1[m1.index(n2)].nameWithOctave == 'C4'

        # the transposition is maintained in the original context
        #s1.show()

        #==== "fig-df03" end

        #==== "fig-df04"
        # Simultaneous Access to Hierarchical and Flat Representations
        #s1.flat.show('t')

        # lengths show the number of elements; indices are sequential
        s1Flat = s1.flat
        assert len(s1) == 2
        assert len(s1Flat) == 6
        assert s1Flat[4] == n3
        assert s1Flat[5] == n4

        # adding another Part to the Score results in a different flat representation
        n5 = note.Note('a#1', quarterLength=2.5)
        n6 = note.Note('b2', quarterLength=1.5)
        m4 = stream.Measure(number=2)
        m4.append([n5, n6])

        r1 = note.Rest(type='whole')
        cf2 = clef.bestClef(m4)  # = BassClef
        m3 = stream.Measure(number=1)
        m3.append([cf2, r1])

        p2 = stream.Part()
        p2.append([m3, m4])
        s1.insert(0, p2)

        assert 'BassClef' in cf2.classes

        # objects are sorted by offset
        s1Flat = s1.flat
        assert len(s1) == 3
        assert len(s1.flat) == 10
        assert s1Flat[6] == n3
        assert s1Flat[7] == n5
        assert s1Flat[8] == n4
        assert s1Flat[9] == n6

        # the F-sharp in m. 2 now as offsets for both flat non-flat sites
        assert n3.getOffsetBySite(m2) == 0
        assert n3.getOffsetBySite(s1Flat) == 4
        # the B in m. 2 now as offsets for both flat non-flat sites
        assert n6.getOffsetBySite(m4) == 2.5
        assert n6.getOffsetBySite(s1Flat) == 6.5

        #s1.show()

        #==== "fig-df04" end

        #==== "fig-df05"
        # Iterating and Filtering Elements by Class

        # get the Clef object, and report its sign, from Measure 1
        assert m1.getElementsByClass('Clef').stream()[0].sign == 'C'
        # collect into a list the sign of all clefs in the flat Score
        assert [cf.sign
                for cf in s1.flat.getElementsByClass('Clef')] == ['C', 'F']

        # collect the offsets Measures in the first part
        assert [e.offset for e in p1.elements] == [0.0, 4.0]
        # collect the offsets of Note in the first part flattened
        assert [e.offset
                for e in p1.flat.notesAndRests] == [0.0, 2.0, 4.0, 4.5]
        # collect the offsets of Notes in all parts flattened
        assert [e.offset for e in s1.flat.notesAndRests
                ] == [0.0, 0.0, 2.0, 4.0, 4.0, 4.5, 6.5]

        # get all pitch names
        match = []
        for e in s1.flat.getElementsByClass('Note').stream():
            match.append(e.pitch.nameWithOctave)
        assert match == ['G3', 'C4', 'G#3', 'A#1', 'D-4', 'B2']

        # collect all Notes and transpose up a perfect fifth
        for n in s1.flat.getElementsByClass('Note').stream():
            n.transpose('P5', inPlace=True)

        # check that all pitches are correctly transposed
        match = []
        for e in s1.flat.getElementsByClass('Note').stream():
            match.append(e.pitch.nameWithOctave)
        assert match == ['D4', 'G4', 'D#4', 'E#2', 'A-4', 'F#3']

        #s1.show()

        #==== "fig-df05" end

        #==== "fig-df06"
        # Searching by Locations and Contexts

        # a Note can always find a Clef
        self.assertIs(n4.getContextByClass('Clef'), cf1)
        # must search oldest sites first
        assert n6.getContextByClass('Clef',
                                    sortByCreationTime='reverse') == cf2

        #        # a Note can find their Measure number from a flat Part
        #        match = []
        #        for e in p1.flat.getElementsByClass('Note'):
        #            match.append(e.getContextByClass('Measure').number)
        #        assert match == [1, 1, 2, 2]

        # all Notes can find their Measure number from a flat Score
        match = []
        for e in s1.flat.notesAndRests:
            match.append([e.name, e.getContextByClass('Measure').number])
        assert match == [['D', 1], ['rest', 1], ['G', 1], ['D#', 2], ['E#', 2],
                         ['A-', 2], ['F#', 2]]
        #==== "fig-df06" end

        #==== "fig-df06"
        # Non-Hierarchical Object Associations
        #oldIds = []
        #for idKey in n1.sites.siteDict:
        #    print (idKey, n1.sites.siteDict[idKey].isDead)
        #    oldIds.append(idKey)
        #print("-------")

        # Spanners can be positioned in Parts or Measures
        sp1 = spanner.Slur([n1, n4])
        p1.append(sp1)
        sp2 = spanner.Slur([n5, n6])
        m4.insert(0, sp2)

        #print(id(sp1), id(sp1.spannerStorage), n1.sites.siteDict[id(sp1.spannerStorage)].isDead)
        #if id(sp1.spannerStorage) in oldIds:
        #    print ("******!!!!!!!!!*******")

        # Elements can report on what Spanner they belong to
        ss1 = n1.getSpannerSites()
        self.assertTrue(sp1 in ss1, (ss1, sp1))

        ss6 = n6.getSpannerSites()
        assert sp2 in ss6

        #         p1Flat = p1.flat
        #         assert sp1.getDurationSpanBySite(p1Flat) == [0.0, 8.0]
        #
        #         p2Flat = p2.flat
        #         assert sp2.getDurationSpanBySite(p2Flat) == [4.0, 8.0]

        #s1.show()
        #==== "fig-df06" end

        # additional tests
        self.assertEqual(m1.clef, cf1)