Пример #1
0
def chord_texture(token_seq, duration=1):
    for token in token_seq:
        if token[0] == REST_WORD:
            yield note.Rest()
        elif token[0] in (START_WORD, END_WORD):
            yield bar.Barline('double')
        else:
            yield chord.Chord(set(token), quarterLength=duration)
Пример #2
0
def makeRowScore(data: Optional = None,
                 write: bool = False,
                 title: Optional[str] = 'Rows_in_the_Repertoire'):
    """
    Makes a score setting out any number of rows in musical notation,
    annotated with labelled pitch classes and work metadata (title, composer etc).

    Note: unlike the rest of this repository, this requires an external music21: library
    """

    from music21 import bar, expressions, layout, metadata, meter, serial, stream

    score = stream.Score()
    part = stream.Part()
    part.insert(0, meter.TimeSignature('12/4'))  # Not essential
    count = 1

    if not data:
        jsonPath = os.path.join('.', 'Repertoire_Anthology', 'rows_in_the_repertoire.json')
        with open(jsonPath) as jsonFile:
            data = json.load(jsonFile)

    for d in data:  # dict
        entry = data[d]
        m = stream.Measure(number=count)
        count += 1
        row = serial.pcToToneRow(entry['P0'])

        for x in row.notes:
            x.stemDirection = 'none'
            x.lyric = x.pitch.pitchClass
            m.insert(x.offset, x)

        text = f"{entry['Composer']}: {entry['Work']}, {entry['Year']}"  # ", {entry['P0']}"
        m.insert(0, expressions.TextExpression(text))
        part.append(m)

    score.append(part)

    # Layout
    for thisMeasure in score.parts[0].getElementsByClass('Measure'):
        thisMeasure.insert(bar.Barline(type='final', location='right'))
        thisMeasure.insert(layout.SystemLayout(isNew=True))

    # Metadata
    score.insert(0, metadata.Metadata())
    score.metadata.composer = 'Various composers and analysts, compiled by Mark Gotham'
    score.metadata.title = title

    if write:
        w = os.path.join('.', 'Repertoire_Anthology', title + '.mxl')
        score.write(fmt='mxl', fp=w)
    else:
        return score
Пример #3
0
def exShenker():
    import copy
    from music21 import corpus, stream, scale, bar, layout
    # wtc no 1
    src = corpus.parse('bwv846')
    #src.show()

    melodicSrc = src.parts[0]
    measureTemplate = copy.deepcopy(melodicSrc.getElementsByClass('Measure'))
    for i, m in enumerate(measureTemplate):
        m.removeByClass(['GeneralNote'])
        m.number = i + 1

    # this stream has triple bar lines, clefs, etc
    chords = src.flat.makeChords(minimumWindowSize=2)

    analysis = stream.Score()
    chordReduction = copy.deepcopy(measureTemplate)
    for i, m in enumerate(chordReduction.getElementsByClass('Measure')):
        mNotes = src.flat.getElementsByOffset(m.offset,
                                              m.offset +
                                              m.barDuration.quarterLength,
                                              includeEndBoundary=False)
        mNotes.makeChords(minimumWindowSize=4, inPlace=True)
        c = mNotes.flat.notes[0]
        c.duration.type = 'whole'
        m.append(c)
        m.rightBarline = bar.Barline('regular')
    # add parts

    scaleCMajor = scale.MajorScale('c')

    #measureNumber, chordNumberOrNone, scaleDegree, octaveDisplay,
    #    durationTypeDisplay, textDisplay
    manifest = [
        (1, None, 3, 5, 'whole', '3'),
        (24, None, 2, 5, 'whole', '2'),
        (35, None, 1, 5, 'whole', '1'),
    ]
    analysis1 = chordsToAnalysis(chordReduction, manifest, scaleCMajor)

    manifest = [
        (1, None, 1, 4, 'whole', 'I'),
        (24, None, 5, 3, 'whole', 'V'),
        (31, None, 4, 4, 'quarter', '--7'),
        (35, None, 1, 4, 'whole', 'I'),
    ]
    analysis2 = chordsToAnalysis(chordReduction, manifest, scaleCMajor)

    analysis.insert(0, analysis1)
    analysis.insert(0, analysis2)
    analysis.insert(0, chordReduction)
    analysis.show()
Пример #4
0
def melody_texture(token_seq, duration=0.25, use_last=False):
    for token in token_seq:
        if token[0] == REST_WORD:
            yield note.Rest()
        elif token[0] in (START_WORD, END_WORD):
            yield bar.Barline('double')
        else:
            if use_last:
                yield (note.Note(token[-1], quarterLength=duration))
            else:
                for elem in token:
                    yield (note.Note(elem, quarterLength=duration))
Пример #5
0
def chordsToAnalysis(chordStream, manifest, scale):
    '''
    manifest is a list of tuples in the following form:
    (measureNumber, chordNumberOrNone, scaleDegree, octaveDisplay, durationTypeDisplay)
    '''
    from music21 import note, bar

    chordMeasures = chordStream.getElementsByClass('Measure')
    measureTemplate = copy.deepcopy(chordMeasures)
    for i, m in enumerate(measureTemplate):
        m.removeByClass(['GeneralNote'])
        # assuming we have measure numbers

    for (measureNumber, chordNumberOrNone, scaleDegree, octaveDisplay,
         durationTypeDisplay, textDisplay) in manifest:
        # assume measures are in order; replace with different method
        m = chordMeasures[measureNumber - 1]
        mPost = measureTemplate[measureNumber - 1]
        if chordNumberOrNone is None:
            c = m.notes[0]
        else:
            c = m.notes[chordNumberOrNone - 1]  # assume counting from 1

        pTarget = scale.pitchFromDegree(scaleDegree)
        match = False
        p = None
        for p in c.pitches:
            if p.name == pTarget.name:
                match = True
                break
        if not match:
            print('no scale degree found in specified chord', p, pTarget)
        pTarget.octave = octaveDisplay
        n = note.Note(pTarget)
        if durationTypeDisplay in ['whole']:
            n.noteheadFill = False
        else:
            n.noteheadFill = True
        n.stemDirection = 'noStem'
        n.addLyric(textDisplay)
        mPost.insert(c.getOffsetBySite(m), n)

    # fill with rests
    for m in measureTemplate:
        m.rightBarline = bar.Barline('none')
        # need to hide rests
        if len(m.notes) == 0:
            r = note.Rest(quarterLength=4)
            r.hideObjectOnPrint = True
            m.append(r)

    return measureTemplate
 def test_note_beat_strength_indexer_2(self):
     # When the part has no Note or Rest objects in it
     expected = pandas.DataFrame({'0': pandas.Series()})
     test_part = stream.Part()
     # add stuff to the test_part
     for i in range(1000):
         add_me = clef.BassClef()
         add_me.offset = i
         test_part.append(add_me)
         add_me = bar.Barline()
         add_me.offset = i
         test_part.append(add_me)  # finished adding stuff to the test_part
     ip = IndexedPiece()
     ip.metadata('parts', expected.columns)
     ip._analyses['part_streams'] = [test_part]  # supply part_streams.
     actual = ip._get_beat_strength()['meter.NoteBeatStrengthIndexer']
     self.assertTrue(actual.equals(expected))
Пример #7
0
 def test_note_rest_indexer_2(self):
     # When the part has no Note or Rest objects in it. Really this is a test for the methods between
     # _get_part_streams() and _get_noterest().
     expected = pandas.DataFrame({'Part 1': pandas.Series()})
     test_part = stream.Part()
     # add stuff to the test_part
     for i in range(1000):
         add_me = clef.BassClef()
         add_me.offset = i
         test_part.append(add_me)
         add_me = bar.Barline()
         add_me.offset = i
         test_part.append(add_me)
     ip = IndexedPiece()
     ip._analyses['part_streams'] = [test_part]
     ip.metadata('parts', _find_part_names(ip._analyses['part_streams']))
     actual = ip.get('noterest')['noterest.NoteRestIndexer']
     self.assertTrue(actual.equals(expected))
Пример #8
0
 def test_duration_indexer_2(self):
     # When the part has no Note or Rest objects in it
     expected = pandas.DataFrame({'0': pandas.Series()})
     expected.columns = pandas.MultiIndex.from_product([
         ('meter.DurationIndexer', ), ('0', )
     ])
     test_part = stream.Part()
     # add stuff to the test_part
     for i in range(10):
         add_me = clef.BassClef()
         add_me.offset = i
         test_part.append(add_me)
         add_me = bar.Barline()
         add_me.offset = i
         test_part.append(add_me)
     test_part = [test_part]  # finished adding stuff to the test_part
     dur_indexer = meter.DurationIndexer(expected, test_part)
     actual = dur_indexer.run()
     self.assertTrue(actual.equals(expected))
Пример #9
0
    def barlineListFromBarline(self, barlineElement):
        '''
        Indication that the barline at this point should be something other than normal.
        
        Capella does not indicate measure breaks or barline breaks normally, so the only barlines
        that are indicated are unusual ones.
        
        Returns a LIST of :class:`~music21.bar.Barline` or :class:`~music21.bar.Repeat` objects
        because the `repEndBegin` type requires two `bar.Repeat` objects to encode in `music21`. 
        
        
        >>> ci = capella.fromCapellaXML.CapellaImporter()
        >>> barlineTag = ci.domElementFromText('<barline type="end"/>')
        >>> ci.barlineListFromBarline(barlineTag)    
        [<music21.bar.Barline style=final>]

        >>> repeatTag = ci.domElementFromText('<barline type="repEndBegin"/>')
        >>> ci.barlineListFromBarline(repeatTag)    
        [<music21.bar.Repeat direction=end>, <music21.bar.Repeat direction=start>]

        '''
        barlineList = []
        hasRepeatEnd = False
        if 'type' in barlineElement._attrs:
            barlineType = barlineElement._attrs['type'].value
            if barlineType.startswith('rep'):  # begins with rep
                if barlineType in self.barlineMap:
                    repeatType = self.barlineMap[barlineType]
                    if repeatType.find('end') > -1:
                        barlineList.append(bar.Repeat('end'))
                        hasRepeatEnd = True
                    if repeatType.find('start') > -1:
                        startRep = bar.Repeat('start')
                        if hasRepeatEnd is True:
                            startRep.priority = 1
                        barlineList.append(startRep)
            else:
                if barlineType in self.barlineMap:
                    barlineList.append(
                        bar.Barline(self.barlineMap[barlineType]))

        return barlineList
Пример #10
0
 def test_barline_to_lily_12(self):
     # error
     bee_ell = bar.Barline('regular')
     bee_ell._style = u'marmalade sun for everyone'  # pylint: disable=W0212
     self.assertRaises(problems.UnidentifiedObjectError,
                       functions.barline_to_lily, bee_ell)
Пример #11
0
 def test_barline_to_lily_11(self):
     bee_ell = bar.Barline('none')
     expected = u'\\bar ""'
     self.assertEqual(functions.barline_to_lily(bee_ell), expected)
Пример #12
0
 def test_barline_to_lily_10(self):
     bee_ell = bar.Barline('short')
     expected = u"\\bar \"'\""
     self.assertEqual(functions.barline_to_lily(bee_ell), expected)
Пример #13
0
 def test_barline_to_lily_8(self):
     bee_ell = bar.Barline('heavy-heavy')
     expected = u'\\bar ".|."'
     self.assertEqual(functions.barline_to_lily(bee_ell), expected)
Пример #14
0
 def test_barline_to_lily_6(self):
     bee_ell = bar.Barline('final')
     expected = u'\\bar "|."'
     self.assertEqual(functions.barline_to_lily(bee_ell), expected)
Пример #15
0
 def test_barline_to_lily_5(self):
     bee_ell = bar.Barline('double')
     expected = u'\\bar "||"'
     self.assertEqual(functions.barline_to_lily(bee_ell), expected)
Пример #16
0
 def test_barline_to_lily_3(self):
     bee_ell = bar.Barline('dashed')
     expected = u'\\bar "dashed"'
     self.assertEqual(functions.barline_to_lily(bee_ell), expected)
Пример #17
0
    def convertM21(self, outVote, arrError, ground):
        errorColor = "#ff0000"
        missingColor = "#00ff00"
        #         sOut=stream.Stream()
        sOut = stream.Score()
        sPart = stream.Part()
        measureIndex = 1
        measure = stream.Measure()
        measure.number = measureIndex
        indexS = 0

        for symbol in outVote:
            mytie = ""
            realDuration = None
            s = symbol
            isError = False
            isMissing = False
            if (len(ground) > indexS):
                sGround = ground[indexS]

            if (indexS in arrError):
                isError = True
                if s == "*":
                    s = sGround
                    isMissing = True

            if isinstance(s, list):
                s = s[0]
            if s.find('TS:') != -1:
                ts = meter.TimeSignature(s[3:])
                if isError:
                    ts.color = errorColor
                if isMissing:
                    ts.color = missingColor
                measure.append(ts)
            if s.find('KS:') != -1:
                k = key.KeySignature(int(s[3:]))
                if isError:
                    k.color = errorColor
                if isMissing:
                    k.color = missingColor
                measure.append(k)
            if s.find('CL:') != -1:
                c = clef.clefFromString(str(s[3:]))
                if isError:
                    c.color = errorColor
                if isMissing:
                    c.color = missingColor
                measure.append(c)
            if s.find('N:') != -1:
                try:
                    if isinstance(symbol, list):
                        realDuration = symbol[1]
                        mytie = symbol[2]

                    sep = s.index("_")
                    duration = s[sep + 1:]
                    #                     if realDuration!=None:
                    #                         duration=realDuration
                    if (float(duration) > 0):
                        n = note.Note(s[2:sep], quarterLength=float(duration))
                        if isError:
                            n.color = errorColor
                        if isMissing:
                            n.color = missingColor
                        if mytie != "":
                            n.tie = tie.Tie(mytie)
                        measure.append(n)
                except:
                    print "error" + s

            if s.find('R:') != -1:
                try:
                    if isinstance(symbol, list):
                        realDuration = symbol[1]
                        mytie = symbol[2]
                    duration = s[2:]
                    #                     if realDuration!=None:
                    #                         duration=realDuration
                    n = note.Rest(quarterLength=float(duration))
                    if isError:
                        n.color = errorColor
                    if isMissing:
                        n.color = missingColor
                    measure.append(n)
                except:
                    print "error" + s

            if s.find('C:') != -1:
                notes = s.split("[:")
                cPitch = []
                for n in notes:
                    if n != 'C:':
                        sep = n.index("_")
                        duration = n[sep + 1:]
                        pitch = n[0:sep]
                        cPitch.append(pitch)
                c = chord.Chord(cPitch)
                c.duration.quarterLength = float(duration)
                if isError:
                    c.color = errorColor
                if isMissing:
                    c.color = missingColor
                measure.append(c)
            if s.find('!') != -1:

                if isinstance(symbol, list):
                    barType = symbol[1]
                    barRepeat = symbol[2]
                    if barType != "":
                        mybartype = bar.styleToMusicXMLBarStyle(barType)
                        myBar = bar.Barline(style=mybartype)
                        measure.rightBarline = myBar

                    if barRepeat != "":
                        myBar = bar.Repeat(direction=barRepeat)
                        if barRepeat == "start":
                            measure.leftBarline = myBar
                        if barRepeat == "end":
                            measure.rightBarline = myBar
                sPart.append(measure)
                measureIndex += 1
                measure = stream.Measure()
                measure.number = measureIndex
            indexS += 1

        sOut.append(sPart)
        return sOut
Пример #18
0
def partPari(show = True):
    '''
    generate the score of Arvo Pärt's "Pari Intervallo" algorithmically
    using music21.scale.ConcreteScale() to simulate Tintinabulation.
    '''
    s = stream.Score()
    cminor = key.Key('c')
    #real Paert
    main = converter.parse("tinynotation: 4/4 E-1 C D E- F G F E- D C D E- G A- F G E- F G F E- D F G c B- c G A- B- c B- A- B- G c e- d c d c B- A- G F E- F G c E- F G E- D E- F E- D C E- G F E- C F E- D C E- D C D C~ C")
    
    # fake Paert
    #main = converter.parse("E-1 F G A- G F c d e- G A- F E- D d e- c B- A- c d A- G F G F A- B- A- c d A- B- c B- A- G F G F E-~ E-", '4/4')
    main.__class__ = stream.Part
    main.transpose('P8', inPlace=True)
    main.insert(0, cminor)
    main.insert(0, instrument.Recorder())
    bass = copy.deepcopy(main.flat)
    for n in bass.notes:
        n.pitch.diatonicNoteNum = n.pitch.diatonicNoteNum - 9
        if (n.pitch.step == 'A' or n.pitch.step == 'B') and n.pitch.octave == 2:
            n.accidental = pitch.Accidental('natural')
        else:
            n.accidental = cminor.accidentalByStep(n.step)
        if n.offset == (2-1) * 4 or n.offset == (74-1) * 4:
            n.pitch = pitch.Pitch("C3") # exceptions to rule
        elif n.offset == (73 - 1) * 4:
            n.tie = None
            n.pitch = pitch.Pitch("C3") 
    top = copy.deepcopy(main.flat)
    main.insert(0, clef.Treble8vbClef())
    middle = copy.deepcopy(main.flat)
    
    
    cMinorArpeg = scale.ConcreteScale(pitches = ["C2","E-2","G2"])
    # dummy test on other data
    #myA = pitch.Pitch("A2")
    #myA.microtone = -15
    #cMinorArpeg = scale.ConcreteScale(pitches = ["C2", "E`2", "F~2", myA])
    
    lastNote = top.notes[-1]
    top.remove(lastNote)
    for n in top:
        if 'Note' in n.classes:
            n.pitch = cMinorArpeg.next(n.pitch, stepSize=2)
            if n.offset != (73-1)*4.0:  # m. 73 is different
                n.duration.quarterLength = 3.0
                top.insert(n.offset + 3, note.Rest())
            else:
                n.duration.quarterLength = 6.0
                n.tie = None
    r1 = note.Rest(type = 'half')
    top.insertAndShift(0, r1)
    top.getElementsByClass(key.Key)[0].setOffsetBySite(top, 0)
    lastNote = middle.notes[-1]
    middle.remove(lastNote)
   
    for n in middle:
        if 'Note' in n.classes:
            n.pitch = cMinorArpeg.next(n.pitch, direction=scale.DIRECTION_DESCENDING, stepSize=2)
            if n.offset != (73-1)*4.0:  # m. 73 is different
                n.duration.quarterLength = 3.0
                middle.insert(n.offset + 3, note.Rest())
            else:
                n.duration.quarterLength = 5.0
                n.tie = None
    r2 = note.Rest(quarterLength = 3.0)
    middle.insertAndShift(0, r2)    
    middle.getElementsByClass(key.Key)[0].setOffsetBySite(middle, 0)

    ttied = top.makeMeasures().makeTies(inPlace=False)
    mtied = middle.makeMeasures().makeTies(inPlace=False)
    bass.makeMeasures(inPlace = True)
    main.makeMeasures(inPlace = True)
    
    s.insert(0, ttied)
    s.insert(0, main)
    s.insert(0, mtied)
    s.insert(0, bass)
    
    for p in s.parts:
        p.getElementsByClass(stream.Measure)[-1].rightBarline = bar.Barline('final')

    if show == True:
        s.show()
Пример #19
0
    def createBarlines(self, attributes):
        r'''
        Translates bar lines into music21.
        
        
        

        >>> nwt = noteworthy.translate.NoteworthyTranslator()
        >>> nwt.currentPart = stream.Part()
        >>> nwt.currentMeasure = stream.Measure() 
        >>> nwt.createBarlines({"Style":"MasterRepeatOpen"})
        >>> nwt.currentMeasure
        <music21.stream.Measure 0 offset=0.0>        
        >>> nwt.currentMeasure.leftBarline
        <music21.bar.Repeat direction=start> 
        
        '''
        self.activeAccidentals = {}

        if 'Style' not in attributes:
            # pure barline
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            return
        
        style = attributes['Style']
        
        if style == "MasterRepeatOpen":
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            self.currentMeasure.leftBarline = bar.Repeat(direction='start')
    
        elif style == "MasterRepeatClose":
            self.currentMeasure.rightBarline = bar.Repeat(direction='end')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            
        elif style == "LocalRepeatOpen":
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            self.currentMeasure.leftBarline = bar.Repeat(direction='start')
            
        elif style == "LocalRepeatClose":
            self.currentMeasure.rightBarline = bar.Repeat(direction='end')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            
        elif style == "Double":
            self.currentMeasure.rightBarline = bar.Barline('double')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()    
            
        elif style == "SectionOpen":
            self.currentMeasure.rightBarline = bar.Barline('heavy-light')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()    
        elif style == "SectionClose":
            self.currentMeasure.rightBarline = bar.Barline('final')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()    
        else:
            raise NoteworthyTranslateException('cannot find a style %s in our list' % style)
Пример #20
0
def toPart(volpianoText, *, breaksToLayout=False):
    # noinspection PyShadowingNames
    '''
    Returns a music21 Part from volpiano text.

    >>> veniSancti = volpiano.toPart('1---c--d---f--d---ed--c--d---f'
    ...                              + '---g--h--j---hgf--g--h---')
    >>> veniSancti.show('text')
    {0.0} <music21.stream.Measure 0 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.note.Note C>
        {1.0} <music21.note.Note D>
        {2.0} <music21.note.Note F>
        {3.0} <music21.note.Note D>
        {4.0} <music21.note.Note E>
        {5.0} <music21.note.Note D>
        {6.0} <music21.volpiano.Neume <music21.note.Note E><music21.note.Note D>>
        {6.0} <music21.note.Note C>
        {7.0} <music21.note.Note D>
        {8.0} <music21.note.Note F>
        {9.0} <music21.note.Note G>
        {10.0} <music21.note.Note A>
        {11.0} <music21.note.Note B>
        {12.0} <music21.note.Note A>
        {13.0} <music21.note.Note G>
        {14.0} <music21.note.Note F>
        {15.0} <music21.volpiano.Neume <music21.note.Note A><music21.note.Note G>>
        {15.0} <music21.note.Note G>
        {16.0} <music21.note.Note A>

    Clefs!

    >>> clefTest = volpiano.toPart('1---c--2---c')
    >>> clefTest.show('text')
    {0.0} <music21.stream.Measure 0 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.note.Note C>
        {1.0} <music21.clef.BassClef>
        {1.0} <music21.note.Note E>
    >>> for n in clefTest.recurse().notes:
    ...     n.nameWithOctave
    'C4'
    'E2'

    Flats and Naturals:

    >>> accTest = volpiano.toPart('1---e--we--e--We--e')
    >>> [n.name for n in accTest.recurse().notes]
    ['E', 'E-', 'E-', 'E', 'E']

    Breaks and barlines

    >>> breakTest = volpiano.toPart('1---e-7-e-77-e-777-e-3-e-4')
    >>> breakTest.show('text')
    {0.0} <music21.stream.Measure 0 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.note.Note E>
        {1.0} <music21.volpiano.LineBreak object at 0x105250fd0>
        {1.0} <music21.note.Note E>
        {2.0} <music21.volpiano.PageBreak object at 0x105262128>
        {2.0} <music21.note.Note E>
        {3.0} <music21.volpiano.ColumnBreak object at 0x105262240>
        {3.0} <music21.note.Note E>
        {4.0} <music21.bar.Barline type=regular>
    {4.0} <music21.stream.Measure 0 offset=4.0>
        {0.0} <music21.note.Note E>
        {1.0} <music21.bar.Barline type=double>


    As layout objects using breaksToLayout=True

    >>> breakTest = volpiano.toPart('1---e-7-e-77-e-777-e-3-e-4', breaksToLayout=True)
    >>> breakTest.show('text')
    {0.0} <music21.stream.Measure 0 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.note.Note E>
        {1.0} <music21.layout.SystemLayout>
        {1.0} <music21.note.Note E>
        {2.0} <music21.layout.PageLayout>
        {2.0} <music21.note.Note E>
        {3.0} <music21.volpiano.ColumnBreak object at 0x105262240>
        {3.0} <music21.note.Note E>
        {4.0} <music21.bar.Barline type=regular>
    {4.0} <music21.stream.Measure 0 offset=4.0>
        {0.0} <music21.note.Note E>
        {1.0} <music21.bar.Barline type=double>


    Liquescence test:

    >>> breakTest = volpiano.toPart('1---e-E-')
    >>> breakTest.recurse().notes[0].editorial.liquescence
    False
    >>> breakTest.recurse().notes[0].notehead
    'normal'
    >>> breakTest.recurse().notes[1].editorial.liquescence
    True
    >>> breakTest.recurse().notes[1].notehead
    'x'

    Changed in v5.7 -- corrected spelling of liquescence.
    '''
    p = stream.Part()
    m = stream.Measure()

    currentMeasure = m
    currentNeumeSpanner = None
    noteThatWouldGoInSpanner = None
    lastClef = clef.TrebleClef()
    continuousNumberOfBreakTokens = 0

    bIsFlat = False
    eIsFlat = False

    for token in volpianoText:
        if token == '7':
            continuousNumberOfBreakTokens += 1
            continue
        elif continuousNumberOfBreakTokens > 0:
            if not breaksToLayout:  # default
                breakClass = classByNumBreakTokens[
                    continuousNumberOfBreakTokens]
                breakToken = breakClass()  # pylint: disable=not-callable
            else:
                breakClass = classByNumBreakTokensLayout[
                    continuousNumberOfBreakTokens]
                if continuousNumberOfBreakTokens < 3:
                    breakToken = breakClass(isNew=True)  # pylint: disable=not-callable
                else:
                    breakToken = breakClass()  # pylint: disable=not-callable

            currentMeasure.append(breakToken)

        continuousNumberOfBreakTokens = 0

        if token == '-':
            noteThatWouldGoInSpanner = None
            if currentNeumeSpanner:
                currentMeasure.append(currentNeumeSpanner)
                currentNeumeSpanner = None
            continue

        if token in '1234':
            noteThatWouldGoInSpanner = None
            currentNeumeSpanner = None

        if token in '12':
            if token == '1':
                c = clef.TrebleClef()
            else:
                c = clef.BassClef()

            lastClef = c
            m.append(c)

        elif token in '34':
            bl = bar.Barline()
            if token == '4':
                bl.type = 'double'
            m.rightBarline = bl
            p.append(m)
            m = stream.Measure()

        elif token in normalPitches or token in liquescentPitches:
            n = note.Note()
            n.stemDirection = 'noStem'

            if token in normalPitches:
                distanceFromLowestLine = normalPitches.index(token) - 5
                n.editorial.liquescence = False
            else:
                distanceFromLowestLine = liquescentPitches.index(token) - 5
                n.notehead = 'x'
                n.editorial.liquescence = True

            clefLowestLine = lastClef.lowestLine
            diatonicNoteNum = clefLowestLine + distanceFromLowestLine

            n.pitch.diatonicNoteNum = diatonicNoteNum
            if n.pitch.step == 'B' and bIsFlat:
                n.pitch.accidental = pitch.Accidental('flat')
            elif n.pitch.step == 'E' and eIsFlat:
                n.pitch.accidental = pitch.Accidental('flat')

            m.append(n)

            if noteThatWouldGoInSpanner is not None:
                currentNeumeSpanner = Neume([noteThatWouldGoInSpanner, n])
                noteThatWouldGoInSpanner = None
            else:
                noteThatWouldGoInSpanner = n

        elif token in accidentalTokens:
            if token.lower() in eflatTokens and token in naturalTokens:
                eIsFlat = False
            elif token.lower() in bflatTokens and token in naturalTokens:
                bIsFlat = False
            elif token.lower() in eflatTokens and token in flatTokens:
                eIsFlat = True
            elif token.lower() in bflatTokens and token in flatTokens:
                bIsFlat = True
            else:  # pragma: no cover
                raise VolpianoException('Unknown accidental: ' + token +
                                        ': Should not happen')

    if continuousNumberOfBreakTokens > 0:
        breakClass = classByNumBreakTokens[continuousNumberOfBreakTokens]
        breakToken = breakClass()  # pylint: disable=not-callable
        currentMeasure.append(breakToken)

    if m:
        p.append(m)

    return p