ï~~Proceedings of the International Computer Music Conference 2011, University of Huddersfield, UK, 31 July - 5 August 2011 # 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) m3 = stream.Measure(number=1) m3.append([cf2, rl]) rl = note.Rest(type='whole') cf2 = m3.bestClef() # cf2 is a BassClef m4 = stream.Measure(number=2) m4.append([n5, n6]) p2 = stream.Part() p2.append([m3, m4]) sl.insert(0, p2) # objects are sorted by offset slFlat = sl.flat assert len(sl) == 3 assert len(slFlat) == 10 assert slFlat[6] == n3 assert slFlat[7] == n5 assert slFlat[8] == n4 assert slFlat[9] == n6 # the B in m. 2 (=p2,m4) now has offsets for # both flat non-flat sites assert n6.getOffsetBySite(m4) == 2.5 assert n6.getOffsetBySite(slFlat) == 6.5 s1. show () i~i~iii!#........... Figure 6. Access to flat and non-flat representations, and adding and displaying an additional Part. 3.4. Iterating and Filtering Elements by Class The music21 system makes great use of subclassing and class definition to distinguish system components. Each clef and each ornament type, for example, are given unique class definitions. As all Music2lObjects can reside on Streams, it is often necessary to filter a Stream by class, return a new Stream with just the desired Music21Objects, and then process the results. As is typical in object-oriented languages, more general classes, inherited by subclasses, can be used for broader filters; specific class types or lists of classes can be used for more narrow filters. For example, a complex polyphonic work might contain nested Streams defining Parts, Measures, and Voices, and within these Measures have Clef, TimeSignature, Note, Rest, and Chord objects. If a user needs to find the distribution of pitch usage, or look for a specific pitch, iterating over all these elements is unnecessary. Instead, the getElementsByClass () method on the flat representation can be used, where a list of desired classes (Python names or strings) is given. The returned, independent Stream includes only the matching classes with offset positions transferred from the source. As with Python lists, the Stream can be iterated in standard loop syntax. Because calls to getElementsByClass ( [note.Note, chord.Chord]) are so common, the notes property on Streams provides quick access to a new Stream containing only Note and note-like entities. Figure 7 demonstrates applications of using getElementsByClass () and the notes property, iterating over various collected Music21Objects and gathering information or transforming objects. # get the Clef object, and report its sign, # from Measure 1 assert ml.getElementsByClass ('Clef') [0].sign == 'C' # collect into a list the sign of all clefs in # the flat Score assert [cf.sign for cf in sl.flat.getElementsByClass ('Clef')] == ['C', 'F'] # collect the offsets of Measures in the first # part assert [e.offset for e in pl.elements] == [0.0, 4.0] # collect the offsets of Notes in the first # part after flattening assert [e.offset for e in pl.flat.notes] == [0.0, 2.0, 4.0, 4.5] # get all pitch names match = [ ] for e in sl.flat.notes: match.append(e.pitch.nameWithOctave) assert match == ['G3', 'C4', 'G#3', 'A#1', 'D4', 'B2'] # collect all the Notes using the # getElementsByClass form and transpose them # up a perfect fifth for n in sl.flat.getElementsByClass('Note'): n.transpose('P5', inPlace=True) s. show () Â~r...'.............................................................................. Figure 7. Iterating and filtering a Stream by class, and then displaying the results of transposition applied to filtered Note objects. Similar to the Stream returned by the flat property, the Streams returned by getElementsByClass() and the notes property offer alternative "views" of the same Music21 Components. Figure 8, expanding the previous presentations, illustrates references of the same Music21Objects in multiple parallel Stream instances, each retaining relative but independent offset positions. With the frequent derivation of one Stream from an other, by usage of both the flat property as well as by getElementsByClass () and similar methds, it is useful 65
Top of page Top of page