def testJoinPartStaffsE(self):
        '''
        Measure numbers existing only in certain PartStaffs: don't collapse together
        '''
        from music21 import corpus
        from music21 import layout
        sch = corpus.parse('schoenberg/opus19', 2)

        s = stream.Score()
        ps1 = stream.PartStaff()
        ps2 = stream.PartStaff()
        s.append(ps1)
        s.append(ps2)
        s.insert(0, layout.StaffGroup([ps1, ps2]))
        m1 = sch.parts[0].measure(1)  # RH
        m2 = sch.parts[1].measure(2)  # LH
        m3 = sch.parts[0].measure(3)  # RH
        ps1.append(m1)
        ps1.append(m3)
        ps2.insert(m1.offset, m2)
        root = self.getET(s)
        m1tag, m2tag, m3tag = root.findall('part/measure')
        self.assertEqual({staff.text
                          for staff in m1tag.findall('note/staff')}, {'1'})
        self.assertEqual({staff.text
                          for staff in m2tag.findall('note/staff')}, {'2'})
        self.assertEqual({staff.text
                          for staff in m3tag.findall('note/staff')}, {'1'})
Beispiel #2
0
    def testMultipleInstrumentsPiano(self):
        ps1 = stream.PartStaff([
            stream.Measure(
                [instrument.ElectricPiano(),
                 note.Note(type='whole')]),
            stream.Measure(
                [instrument.ElectricOrgan(),
                 note.Note(type='whole')]),
            stream.Measure([instrument.Piano(),
                            note.Note(type='whole')]),
        ])
        ps2 = stream.PartStaff([
            stream.Measure([instrument.Vocalist(),
                            note.Note(type='whole')]),
            stream.Measure([note.Note(type='whole')]),
            stream.Measure([note.Note(type='whole')]),
        ])
        sg = layout.StaffGroup([ps1, ps2])
        s = stream.Score([ps1, ps2, sg])
        scEx = ScoreExporter(s)
        tree = scEx.parse()

        self.assertEqual(
            [el.text for el in tree.findall('.//instrument-name')],
            ['Electric Piano', 'Voice', 'Electric Organ', 'Piano'])
        self.assertEqual(len(tree.findall('.//measure/note/instrument')), 6)
 def testJoinPartStaffsB(self):
     '''
     Gapful first PartStaff, ensure <backup> in second PartStaff correct
     '''
     from music21 import layout
     from music21 import note
     s = stream.Score()
     ps1 = stream.PartStaff()
     ps1.insert(0, note.Note())
     # Gap
     ps1.insert(3, note.Note())
     ps2 = stream.PartStaff()
     ps2.insert(0, note.Note())
     s.append(ps1)
     s.append(ps2)
     s.insert(0, layout.StaffGroup([ps1, ps2]))
     root = self.getET(s)
     notes = root.findall('.//note')
     forward = root.find('.//forward')
     backup = root.find('.//backup')
     amountToBackup = (
         int(notes[0].find('duration').text)
         + int(forward.find('duration').text)
         + int(notes[1].find('duration').text)
     )
     self.assertEqual(int(backup.find('duration').text), amountToBackup)
Beispiel #4
0
    def testJoinPartStaffsH(self):
        '''
        Overlapping PartStaffs cannot be guaranteed to export correctly,
        so they fall back to the old export paradigm (no joinable groups).
        '''
        from music21 import musicxml

        ps1 = stream.PartStaff(stream.Measure())
        ps2 = stream.PartStaff(stream.Measure())
        ps3 = stream.PartStaff(stream.Measure())
        sg1 = StaffGroup([ps1, ps2])
        sg2 = StaffGroup([ps1, ps3])
        s = stream.Score([ps1, ps2, ps3, sg1, sg2])

        SX = musicxml.m21ToXml.ScoreExporter(s)
        SX.scorePreliminaries()
        with self.assertWarns(MusicXMLWarning):
            SX.parsePartlikeScore()
            self.assertEqual(SX.joinableGroups(), [])
 def testJoinPartStaffsC(self):
     '''
     First PartStaff longer than second
     '''
     from music21 import layout
     from music21 import note
     s = stream.Score()
     ps1 = stream.PartStaff()
     ps1.repeatAppend(note.Note(), 8)
     ps1.makeNotation(inPlace=True)  # makeNotation to freeze notation
     s.insert(0, ps1)
     ps2 = stream.PartStaff()
     ps2.repeatAppend(note.Note(), 4)
     ps2.makeNotation(inPlace=True)  # makeNotation to freeze notation
     s.insert(0, ps2)
     s.insert(0, layout.StaffGroup([ps1, ps2]))
     root = self.getET(s)
     measures = root.findall('.//measure')
     notes = root.findall('.//note')
     self.assertEqual(len(measures), 2)
     self.assertEqual(len(notes), 12)
    def testMeterChanges(self):
        from music21 import layout
        from music21 import meter
        from music21 import note

        ps1 = stream.PartStaff()
        ps2 = stream.PartStaff()
        sg = layout.StaffGroup([ps1, ps2])
        s = stream.Score([ps1, ps2, sg])
        for ps in ps1, ps2:
            ps.insert(0, meter.TimeSignature('3/1'))
            ps.repeatAppend(note.Note(type='whole'), 6)
            ps.makeNotation(inPlace=True)  # makes measures
            ps[stream.Measure][1].insert(meter.TimeSignature('4/1'))

        root = self.getET(s)
        # Just two <attributes> tags, a 3/1 in measure 1 and a 4/1 in measure 2
        self.assertEqual(len(root.findall('part/measure/attributes/time')), 2)

        # Edge cases -- no expectation of correctness, just don't crash
        ps1[stream.Measure].last().number = 0  # was measure 2
        root = self.getET(s)
        self.assertEqual(len(root.findall('part/measure/attributes/time')), 3)
 def testJoinPartStaffsD(self):
     '''
     Same example as testJoinPartStaffsC but switch the hands:
     second PartStaff longer than first
     '''
     from music21 import layout
     from music21 import note
     s = stream.Score()
     ps1 = stream.PartStaff()
     ps1.repeatAppend(note.Note(), 8)
     ps1.makeNotation(inPlace=True)  # makeNotation to freeze notation
     ps2 = stream.PartStaff()
     ps2.repeatAppend(note.Note(), 4)
     ps2.makeNotation(inPlace=True)  # makeNotation to freeze notation
     s.insert(0, ps2)
     s.insert(0, ps1)
     s.insert(0, layout.StaffGroup([ps2, ps1]))
     root = self.getET(s)
     measures = root.findall('.//measure')
     notes = root.findall('.//note')
     # from music21.musicxml.helpers import dump
     # dump(root)
     self.assertEqual(len(measures), 2)
     self.assertEqual(len(notes), 12)
    def realize(self):
        # Would make sense to insert parts in __init__ but breaks music21 when writing
        for _i in range(2):
            self.insert(0, stream.PartStaff())

        halfnote_chances = {
            len(self.possible_chords) - 1: 0.9,
            len(self.possible_chords) - 2: 0.65,
            len(self.possible_chords) - 3: 0.65,
        }
        past_halfnotes = 0

        for i, poss_chord in enumerate(
                self.possible_chords):  # For each chord in the composition
            b = choice(poss_chord.b_pitches)
            t = choice(poss_chord.filter_t(b))
            a = choice(poss_chord.filter_a(b, t))
            s = choice(poss_chord.filter_s(b, t, a))

            current_chord_treb = chord.Chord([a, s])
            current_chord_bass = chord.Chord([b, t])

            # Calculate duration offset from beginneing b/c Stream.append() cannot always get it right
            extra_offset_treb = extra_offset_bass = 0 + past_halfnotes

            if i in halfnote_chances:  # If the current chord may become a half note
                if random() < halfnote_chances[i]:
                    current_chord_bass.duration.type = "half"
                    current_chord_treb.duration.type = "half"
                    past_halfnotes += 1
            elif random(
            ) < 0.2 and i > 0:  # If this chord is not a potential half note dotted-quarter/eigth
                current_chord_treb.duration.quarterLength -= 0.5
                self.elements[0][i - 1].duration.quarterLength += 0.5
                extra_offset_treb += 0.5
            # elif random() < 0.15 and i > 0:  # Bass eigth/dotted-quarter
            #     current_chord_bass.duration.quarterLength += 0.5
            #     self.elements[1][i-1].duration.quarterLength -= 0.5
            #     extra_offset_bass -= 0.5

            self.elements[0].insert(i + extra_offset_treb, current_chord_treb)
            self.elements[1].insert(i + extra_offset_bass, current_chord_bass)