A beta version of a complete .capx to music21 converter.

Currently only handles one <voice> per <staff> and does not deal with Slurs, Dynamics, Ornamentation, etc.

Does not handle pickup notes, which are defined simply with an early barline (same as incomplete bars at the end).


class music21.capella.fromCapellaXML.CapellaImporter

Object for importing .capx, CapellaXML files into music21 (from which they can be converted to musicxml, MIDI, lilypond, etc.

Note that Capella stores files closer to their printed versions – that is to say, Systems enclose all the parts for that system and have new clefs etc.

CapellaImporter methods


return a Accidental object from an <alter> tag.

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> alter = ci.domElementFromText('<alter step="-1"/>')
>>> ci.accidentalFromAlter(alter)
<accidental flat>

The only known display type is “suppress”

>>> alter = ci.domElementFromText('<alter step="2" display="suppress"/>')
>>> acc = ci.accidentalFromAlter(alter)
>>> acc
<accidental double-sharp>
>>> acc.displayType

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 Barline or 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)    
[< style=final>]
>>> repeatTag = ci.domElementFromText('<barline type="repEndBegin"/>')
>>> ci.barlineListFromBarline(repeatTag)    
[< direction=end>, < direction=start>]

returns a Note or Chord from a chordElement – a Note is returned if the <chord> has one <head> element, a Chord is returned if there are multiple <head> elements.

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> chordElement = ci.domElementFromText(
...     '<chord><duration base="1/1"/><heads><head pitch="G4"/></heads></chord>')
>>> n = ci.chordOrNoteFromChord(chordElement)
>>> n
<music21.note.Note G>
>>> n.duration
<music21.duration.Duration 4.0>

This one is an actual chord

>>> chordElement = ci.domElementFromText(
...        '<chord><duration base="1/8"/>' + 
...        '<heads><head pitch="G4"/><head pitch="A5"/></heads></chord>')
>>> c = ci.chordOrNoteFromChord(chordElement)
>>> c
<music21.chord.Chord G3 A4>
>>> c.duration
<music21.duration.Duration 0.5>

TODO: test Lyrics


returns a Clef object or subclass from a <clefSign> tag.

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> clefSign = ci.domElementFromText('<clefSign clef="treble"/>')
>>> ci.clefFromClefSign(clefSign)
>>> clefSign = ci.domElementFromText('<clefSign clef="G2-"/>')
>>> ci.clefFromClefSign(clefSign)
>>> clefSign = ci.domElementFromText('<clefSign clef="F1+"/>')
>>> clefObject = ci.clefFromClefSign(clefSign)
>>> clefObject
>>> clefObject.sign
>>> clefObject.line
>>> clefObject.octaveChange

Utility method, especially for the documentation examples/tests, which uses xml.etree.ElementTree to parse the string and returns its root object.

Not used by the main parser

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> funnyTag = ci.domElementFromText(
...    '<funny yes="definitely"><greg/>hi<greg><ha>ha</ha>' + 
...    '<greg type="embedded"/></greg></funny>')
>>> funnyTag
<Element 'funny' at 0x...>

iter searches recursively

>>> len(list(funnyTag.iter('greg')))

findall does not:

>>> len(funnyTag.findall('greg'))
>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> durationTag = ci.domElementFromText('<duration base="1/32" dots="1"/>')
>>> d = ci.durationFromDuration(durationTag)
>>> d
<music21.duration.Duration 0.1875>
>>> d.type
>>> d.dots
>>> durationTag2 = ci.domElementFromText(
...      '<duration base="1/4"><tuplet count="3"/></duration>')
>>> d2 = ci.durationFromDuration(durationTag2)
>>> d2
<music21.duration.Duration 2/3>
>>> d2.type
>>> d2.tuplets
(<music21.duration.Tuplet 3/2/eighth>,)

Does not handle noDuration=’true’, display, churchStyle on rest durations


Returns a KeySignature object from a keySign tag.

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> keySign = ci.domElementFromText('<keySign fifths="-1"/>')
>>> ci.keySignatureFromKeySign(keySign)
<music21.key.KeySignature of 1 flat>

returns a Lyric object from a <verse> tag

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> verse = ci.domElementFromText('<verse i="0" hyphen="true">di&quot;</verse>')
>>> ci.lyricFromVerse(verse)
<music21.note.Lyric number=1 syllabic=begin text="di"">

Does not yet support ‘align’ attribute

if the text is empty, returns None


returns a list of Lyric objects from a <lyric> tag

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> lyricEl = ci.domElementFromText(
...      '<lyric><verse i="0" hyphen="true">di</verse>' + 
...      '<verse i="1">man,</verse><verse i="2">frau,</verse></lyric>')
>>> ci.lyricListFromLyric(lyricEl)
[<music21.note.Lyric number=1 syllabic=begin text="di">, 
 <music21.note.Lyric number=2 syllabic=single text="man,">, 
 <music21.note.Lyric number=3 syllabic=single text="frau,">]

return a Note object from a <head> element. This will become part of Chord._notes if there are multiple, but in any case, it needs to be a Note not a Pitch for now, because it could have Tie information

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> headElement = ci.domElementFromText(
...      '<head pitch="B7"><alter step="-1"/><tie end="true"/></head>')
>>> n = ci.noteFromHead(headElement)
>>> n
<music21.note.Note B->
>>> n.octave # capella octaves are one higher than written
>>> n.tie
<music21.tie.Tie stop>

returns a list of Note elements for each <head> in <heads>

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> headsElement = ci.domElementFromText(
...    '<heads><head pitch="B7"><alter step="-1"/></head><head pitch="C2"/></heads>')
>>> ci.notesFromHeads(headsElement)
[<music21.note.Note B->, <music21.note.Note C>]

Takes the string (or unicode string) in xmlText and parses it with xml.dom.minidom. Sets self.mainDom to the dom object and returns the dom object.


Take a Score object which is organized by Systems and return a new Score object which is organized by Parts.


Reads in a .capx file at filename, stores it as self.zipFilename, unzips it, extracts the score.xml embedded file, sets self.xmlText to the contents.

Returns self.xmlText


Returns a Rest object from a <rest> tag.

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> restElement = ci.domElementFromText('<rest><duration base="1/2"/></rest>')
>>> r = ci.restFromRest(restElement)
>>> r
<music21.note.Rest rest>
>>> r.duration.type
CapellaImporter.scoreFromFile(filename, systemScore=False)

main program: opens a file given by filename and returns a complete music21 Score from it.

If systemScore is True then it skips the step of making Parts from Systems and Measures within Parts.


not implemented

CapellaImporter.streamFromNoteObjects(noteObjectsElement, streamObj=None)

Converts a <noteObjects> tag into a Stream object which is returned. A Stream can be given as an optional argument, in which case the objects of this Stream are appended to this object.

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> noteObjectsString = r"""
...           <noteObjects>
...                <clefSign clef="G2-"/>
...                <keySign fifths="-1"/>
...                <chord>
...                    <duration base="1/2"/>
...                    <lyric>
...                        <verse i="0">das,</verse>
...                        <verse i="1">scherz,</verse>
...                    </lyric>
...                    <heads>
...                        <head pitch="G4"/>
...                    </heads>
...                </chord>
...                <chord>
...                    <duration base="1/2"/>
...                    <lyric>
...                        <verse i="0">so</verse>
...                        <verse i="1">der</verse>
...                    </lyric>
...                    <heads>
...                        <head pitch="A4"/>
...                    </heads>
...                </chord>
...                <barline type="end"/>
...            </noteObjects>
...            """
>>> noteObjectsElement = ci.domElementFromText(noteObjectsString)
>>> s = ci.streamFromNoteObjects(noteObjectsElement)
{0.0} <music21.clef.Treble8vbClef>
{0.0} <music21.key.KeySignature of 1 flat>
{0.0} <music21.note.Note G>
{2.0} <music21.note.Note A>
{4.0} < style=final>
>>> s.highestTime
CapellaImporter.systemFromSystem(systemElement, systemObj=None)

returns a System object from a <system> tag. The System object will contain Part objects which will have the notes, etc. contained in it.

TODO: Handle multiple <voices>

CapellaImporter.systemScoreFromScore(scoreElement, scoreObj=None)

returns an Score object from a <score> tag.

The Score object is not a standard music21 Score object which contains parts, then measures, then voices, but instead contains systems which optionally contain voices, which contain parts. No measures have yet been created.


returns a Tie element from a <tie> tag

if begin == ‘true’ then Tie.type = start

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> tieEl = ci.domElementFromText('<tie begin="true"/>')
>>> ci.tieFromTie(tieEl)
<music21.tie.Tie start>

if end == ‘true’ then Tie.type = stop

>>> tieEl = ci.domElementFromText('<tie end="true"/>')
>>> ci.tieFromTie(tieEl)
<music21.tie.Tie stop>

if begin == ‘true’ and end == ‘true’ then Tie.type = continue (is this right???)

>>> tieEl = ci.domElementFromText('<tie begin="true" end="true"/>')
>>> ci.tieFromTie(tieEl)
<music21.tie.Tie continue>

Returns a TimeSignature object from a timeSign tag.

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> timeSign = ci.domElementFromText('<timeSign time="4/4"/>')
>>> ci.timeSignatureFromTimeSign(timeSign)
<music21.meter.TimeSignature 4/4>
>>> timeSign = ci.domElementFromText('<timeSign time="infinite"/>')
>>> ci.timeSignatureFromTimeSign(timeSign) is None

Returns a Tuplet object from a <tuplet> tag.

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> tupletTag = ci.domElementFromText('<tuplet count="3"/>')
>>> ci.tupletFromTuplet(tupletTag)    
<music21.duration.Tuplet 3/2/eighth>

does not handle ‘tripartite’ = True