
    rh                   P   % S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSK	J
r
  SSK	Jr  SSK	Jr  SSK	Jr  SSK	Jr  SS	K	Jr  SS
K	Jr  SSK	Jr  SSK	Jr  SSK	Jr  SSK	Jr  \R*                  " S5      r\R.                  " SSS9r\R.                  " SSS9r\R4                  (       a  SSKJr  \R:                  " / SS/ SQ/4PSSSS//4PSSSS //4PS!S"S#S$//4PS%S&S'S(//4PS)S*S+S,//4PS-S./ S/Q/4PS0S1S2S3//4PS4S5S6S7//4PS8S9/ S:Q/4PS;S<S=S>//4PS?S@SASB//4PSCSDSE//4PSFSGSH//4PSISJSKSL//4PSMSNSOSP//4PSQSRSSST//4PSUSVSWSX//4PSYSZS[S\//4PS]S^S_S`//4PSaSb/ ScQ/4PSdSeSf//4PSgShSi//4PSjSkSlSm//4PSnSoSpSq//4PSrSsStSu//4PSvSwSxSy//4PSzS{S|S}//4PS~SSS//4PSSSS//4PSSSS//4PSSS//4PSSSS//4PSSSS//4PSSSS//4PSSSS//4PSSSS//4PSSSS//4PSSSS//4PSSS//4PSSS//4PSSSS//4PSSSS//4PSSS//4PSSSS//4PSSSS//4PSSSS//4PSSS//4PSSS//4PSSS//4P5      rS%S-S;S.r " S S\R@                  5      r! " S S\RD                  5      r# " S S\R@                  5      r$ " S S\RJ                  5      r&S r'S r(SSS jjr)SS jr*S r+S r,S r-S r.0 r/S\0S'    " S S\#5      r1 " S S\15      r2S r3 " S S\Rh                  5      r5 " S S\Rh                  5      r6\#\)\1\&/r7\8S:X  a  SSK	r	\	Rr                  " \55        gg)z
An object representation of harmony, a subclass of chord, as encountered as chord symbols or
roman numerals, or other chord representations with a defined root.
    )annotationsN)base)chord)common)duration)environment)exceptions21)interval)key)pitch)prebase)styleharmonyTChordSymbol)boundNCTNoChordrealizerScalemajorz1,3,5) Mmajminorz1,-3,5mmin	augmentedz1,3,#5+aug
diminishedz1,-3,-5dimodominant-seventhz1,3,5,-77dom7major-seventhz1,3,5,7maj7M7zminor-major-seventhz1,-3,5,7)mM7zm#7minmaj7minor-seventhz	1,-3,5,-7m7min7zaugmented-major-seventhz1,3,#5,7z+M7augmaj7augmented-seventhz	1,3,#5,-7)z7+z+7aug7zhalf-diminished-seventhz
1,-3,-5,-7u   ø7m7b5diminished-seventhz1,-3,-5,--7o7dim7zseventh-flat-fivez	1,3,-5,-7dom7dim5zmajor-sixthz1,3,5,66zminor-sixthz1,-3,5,6m6min6major-ninthz	1,3,5,7,9M9Maj9dominant-ninthz
1,3,5,-7,99dom9zminor-major-ninthz
1,-3,5,7,9mM9minmaj9minor-ninthz1,-3,5,-7,9m9min9zaugmented-major-ninthz
1,3,#5,7,9z+M9augmaj9zaugmented-dominant-ninthz1,3,#5,-7,9)z9#5z+9aug9zhalf-diminished-ninthz1,-3,-5,-7,9u   ø9zhalf-diminished-minor-ninthz1,-3,-5,-7,-9   øb9zdiminished-ninthz1,-3,-5,--7,9o9dim9zdiminished-minor-ninthz1,-3,-5,--7,-9ob9dimb9dominant-11thz1,3,5,-7,9,1111dom11
major-11thz1,3,5,7,9,11M11Maj11zminor-major-11thz1,-3,5,7,9,11mM11minmaj11
minor-11thz1,-3,5,-7,9,11m11min11zaugmented-major-11thz1,3,#5,7,9,11z+M11augmaj11zaugmented-11thz1,3,#5,-7,9,11z+11aug11zhalf-diminished-11thz1,-3,-5,-7,9,11u   ø11zdiminished-11thz1,-3,-5,--7,9,11o11dim11
major-13thz1,3,5,7,9,11,13M13Maj13dominant-13thz1,3,5,-7,9,11,1313dom13zminor-major-13thz1,-3,5,7,9,11,13mM13minmaj13
minor-13thz1,-3,5,-7,9,11,13m13min13zaugmented-major-13thz1,3,#5,7,9,11,13z+M13augmaj13zaugmented-dominant-13thz1,3,#5,-7,9,11,13z+13aug13zhalf-diminished-13thz1,-3,-5,-7,9,11,13u   ø13zsuspended-secondz1,2,5sus2suspended-fourthz1,4,5sussus4zsuspended-fourth-seventhz1,4,5,-77sus7sus4
Neapolitanz	1,-2,3,-5N6Italianz1,#4,-6zIt+6ItFrenchz	1,2,#4,-6zFr+6FrGermanz
1,-3,#4,-6zGr+6Gerpedal1powerz1,5Tristanz
1,#4,#6,#9tristan)dominantmajor-minorhalf-diminishedc                      \ rS rSrSrg)HarmonyException    N__name__
__module____qualname____firstlineno____static_attributes__r       I/home/james-whalen/.local/lib/python3.13/site-packages/music21/harmony.pyr   r          r   r   c                    ^  \ rS rSrSr\R                  R                  S-
  r\R                  r
     S         SU 4S jjjrS rS rS r S       SS	 jjr\S
 5       r\R$                  S 5       r\S 5       r\R$                  S 5       r\S 5       r\R$                  S 5       r\S 5       r\R$                  S 5       rSS.S jrS rS rSrU =r$ )Harmony   a  
Harmony objects in music21 are a special type of chord - they retain all
the same functionality as a chord (and inherit from chord directly),
although they have special representations symbolically. They contain a
figure representation, a shorthand, for the actual pitches they contain.
This shorthand is commonly used on musical scores rather than writing out
the chord pitches. Thus, each harmony object has an attribute,
self.writeAsChord that dictates whether the object will be written to a
score as a chord (with pitches realized) or with just the
figure (as in Chord Symbols).

Most users should start with the ChordSymbol class or the RomanNumeral
class.  The Harmony object is primarily a base object for defining other
sorts of objects:

>>> c6 = harmony.ChordSymbol('C/E')
>>> c6
<music21.harmony.ChordSymbol C/E>

By default, Harmony objects just float above the score and are a sort of
analytical object.  To make them also count as pitches in a score, use
`writeAsChord=True`

>>> c6.writeAsChord = True
>>> c6
<music21.harmony.ChordSymbol C/E: E G C>

Or individual components can be specified:

>>> c6_again = harmony.ChordSymbol(root='C', bass='E', kind='major')
>>> c6_again
<music21.harmony.ChordSymbol C/E>

It is also possible to instantiate an empty Harmony object and
then set components later, but this is an advanced and delicate operation:

>>> h = harmony.ChordSymbol()
>>> h.root('B-3')
>>> h.bass('D', allow_add=True)
>>> h.inversion(1, transposeOnSet=False)
>>> h.addChordStepModification(harmony.ChordStepModification('add', 4))
>>> h
<music21.harmony.ChordSymbol B-/D add 4>

>>> h = harmony.ChordSymbol('C7/E')
>>> h.root()
<music21.pitch.Pitch C4>

>>> h.bass()
<music21.pitch.Pitch E3>

>>> h.inversion()
1

>>> h.isSeventh()
True

>>> [str(p) for p in h.pitches]
['E3', 'G3', 'B-3', 'C4']

>>> sus = harmony.ChordSymbol('Dsus4')
>>> sus.root()
<music21.pitch.Pitch D3>

Accepts a keyword 'updatePitches'. By default, it
is `True`, but can be set to `False` to initialize faster if pitches are not needed.
   Tc                  > [         TU ]  " S0 UD6  SU l        S U l        / U l        / U l        S U l        U R                  X#S9  Xl        U R                  (       a  U R                  5         SU R                  ;  a-  SU R                  ;   a  U R                  U R                  S   SS9  U(       aA  U R                  (       d   SU R                  ;   d  SU R                  ;   a  U R                  5         U R                  X#US9  g )	NFrootbassr   r   T	allow_addr   r   	inversionr   )super__init___writeAsChord_romanchordStepModifications_degreesList_key_updateFromParameters_figure_parseFigure
_overridesr   _updatePitches)selffigurer   r   r   updatePitcheskeywords	__class__s          r   r   Harmony.__init__   s     	$8$" CE#')	"""8 << (Vt-FIIdoof-I>LL00!""9"Mr   c                    U R                   nU R                  (       a=  US-  nUSR                  U R                   Vs/ s H  o"R                  PM     sn5      -  nU$ s  snf )Nz:  )r   writeAsChordjoinpitchesname)r   summaryps      r   _reprInternalHarmony._reprInternal  sO    ++tOGsxx >A >??G !?s   A
c                    gzB
subclass this in extensions (protected in TypeScript/Java speak)
Nr   r   s    r   r   Harmony._parseFigure       	r   c                    gr   r   r   s    r   r   Harmony._updatePitches  r   r   c                   U(       aP  [        U[        5      (       a;  [        R                  " U5      nU R	                  [
        R                  " USS95        OUb  U R	                  U5        Ub  U R                  USS9  U(       aO  [        U[        5      (       a:  [        R                  " U5      nU R                  [
        R                  " USS9SS9  gUb  U R                  USS9  gg)a  
This method must be called twice, once before the pitches
are rendered, and once after. This is because after the pitches
are rendered, the root() and bass() become reset by the chord class,
but we want the objects to retain their initial root, bass, and inversion.
   )octaveNTtransposeOnSetr   )	
isinstancestrr   cleanedFlatNotationr   r   Pitchr   r   )r   r   r   r   s       r   r   Harmony._updateFromParameters  s     JtS))--d3DIIekk$q12IIdO  NN9TN: JtS))--d3DIIekk$q1TIBIIddI+ r   c                T    U R                   c  U R                  5       $ U R                   $ )a  
Get or set the figure of the harmony object. The figure is the
character (string) representation of the object. For example, 'I',
'CM', '3#'.

When you instantiate a harmony object, if you pass in a figure it
is stored internally and returned when you access the figure
property. If you don't instantiate the object with a figure, this
property calls :meth:`music21.harmony.Harmony.findFigure` method which
deduces the figure provided other information about the object,
especially the chord.

If the pitches of the harmony object have been modified after being
instantiated, call :meth:`music21.harmony.Harmony.findFigure` to deduce the
new figure.

>>> h = harmony.ChordSymbol('CM')
>>> h.figure
'CM'

>>> harmony.ChordSymbol(root='C', bass='A', kind='minor').figure
'Cm/A'

>>> h.bass(note.Note('E'))
>>> h.figure
'CM'

OMIT_FROM_DOCS

Fixed storing deduced figures by avoiding duplicate chordStepModifications:

>>> h = harmony.ChordSymbol('CM7omit5')
>>> h.addChordStepModification(harmony.ChordStepModification(modType='add', degree=4))
>>> h.findFigure()
'Cmaj7 subtract 5 add 4'

>>> h.figure
'CM7omit5'

>>> h.figure = h.findFigure()
>>> h.figure
'Cmaj7 subtract 5 add 4'
)r   
findFigurer   s    r   r   Harmony.figure6  s&    Z <<??$$<<r   c                t    Xl         U R                   (       a!  U R                  5         U R                  5         g g N)r   r   r   )r   values     r   r   r   h  s+    <<! r   c                    U R                   $ )a  
Gets or sets the current Key (or Scale object) associated with this
Harmony object.

For a given RomanNumeral object. Each sub-classed harmony object
may treat this property differently, for example Roman Numeral
objects update the pitches when the key is changed, but chord
symbol objects do not and the key provides more information about
the musical context from where the harmony object was extracted.

>>> r1 = roman.RomanNumeral('V')
>>> r1.pitches
(<music21.pitch.Pitch G4>, <music21.pitch.Pitch B4>, <music21.pitch.Pitch D5>)

>>> r1.key = key.Key('A')
>>> r1.pitches
(<music21.pitch.Pitch E5>, <music21.pitch.Pitch G#5>, <music21.pitch.Pitch B5>)

Changing the key for a ChordSymbol object does nothing to its pitches, since it's
not dependent on key:

>>> h1 = harmony.ChordSymbol('D-m11')
>>> [str(p) for p in h1.pitches]
['D-2', 'F-2', 'A-2', 'C-3', 'E-3', 'G-3']

>>> h1.key = 'CM'  # = C-Major
>>> [str(p) for p in h1.pitches]
['D-2', 'F-2', 'A-2', 'C-3', 'E-3', 'G-3']


But it should change the .romanNumeral object:

>>> y = harmony.ChordSymbol('F')
>>> y.key is None
True
>>> y.romanNumeral
<music21.roman.RomanNumeral I in F major>
>>> y.key = key.Key('C')
>>> y.romanNumeral
<music21.roman.RomanNumeral IV in C major>
)r   r   s    r   r   Harmony.keyo  s    V yyr   c                    [        U[        5      (       a  [        R                  " U5      U l        g Xl        S U l        g r   )r   r   r   Keyr   r   )r   
keyOrScales     r   r   r     s+    j#&&
+DI"IDKr   c                   U R                   c  SSKJn  U R                  (       d  UR	                  5       $ U R
                  nSU l        U R                  c:  UR                  U [        R                  " U R                  5       5      5      U l         O UR                  X R                  5      U l         X l        U R                   $ )a,  
Get or set the romanNumeral numeral function of the Harmony as a
:class:`~music21.romanNumeral.RomanNumeral` object. String
representations accepted by RomanNumeral are also accepted.

>>> h = harmony.ChordSymbol('Dmaj7')
>>> h.romanNumeral
<music21.roman.RomanNumeral I7 in D major>

>>> h.romanNumeral = 'III7'
>>> h.romanNumeral
<music21.roman.RomanNumeral III7>

>>> h.romanNumeral.key = key.Key('B')
>>> h.romanNumeral
<music21.roman.RomanNumeral III7 in B major>

>>> h.romanNumeral = roman.RomanNumeral('IV7', 'A')
>>> h.romanNumeral
<music21.roman.RomanNumeral IV7 in A major>

>>> h = harmony.ChordSymbol('B-/D')
>>> h.romanNumeral
<music21.roman.RomanNumeral I6 in B- major>

OMIT_FROM_DOCS

Empty ChordSymbol = empty RomanNumeral:

>>> harmony.ChordSymbol().romanNumeral
<music21.roman.RomanNumeral>
r   romanT)r   music21r   r   RomanNumeralr   r   r   romanNumeralFromChordr   r   )r   r   storedWriteAsChords      r   romanNumeralHarmony.romanNumeral  s    F ;;%<<))++ "&!3!3 $Dxx#99$		@TU#99$I!3{{r   c                    [        US5      (       a  SUR                  ;   a  Xl        g SSKJn   UR                  U5      U l        g ! [        R                   a     Of = f[        SU 35      e)Nclassesr   r   r   z!not a valid pitch specification: )	hasattrr   r   r   r   r   r	   Music21Exceptionr   )r   r   r   s      r   r   r     sj    5)$$5==)HK!	,,U3DK,, 		!B5'JKKs   A AAc                    U R                   $ )aO  
Boolean attribute of all harmony objects that specifies how this
object will be written to the rendered output (such as musicxml). If `True`
(default for romanNumerals), the chord with pitches is written. If
False (default for ChordSymbols) the harmony symbol is written.
For `NoChord` objects, writeAsChord means to write as a rest.
)r   r   s    r   r   Harmony.writeAsChord  s     !!!r   c                    Xl         U(       a7  U R                  R                  S:X  a  [        R                  " S5      U l        g g g )Nr   r   )r   r   quarterLengthDuration)r   vals     r   r   r     s7     
 4==..!3$--a0DM 43r   r   c                   [        U[        5      (       d  [        SU 35      eXR                  ;  a  U R                  R	                  U5        U(       a  U R                  5         gg)a  
Add a harmony degree specification to this Harmony as a
:class:`~music21.harmony.ChordStepModification` object.

>>> hd = harmony.ChordStepModification('add', 4)
>>> h = harmony.ChordSymbol()
>>> h.addChordStepModification(hd)
>>> h.addChordStepModification('juicy')
Traceback (most recent call last):
music21.harmony.HarmonyException: cannot add this object as a degree: juicy

Alteration will also impact the pitches,
if the keyword argument updatePitches is given as True

>>> h = harmony.ChordSymbol('C')
>>> mod = harmony.ChordStepModification('alter', 5, -1)
>>> h.addChordStepModification(mod, updatePitches=True)
>>> h.pitches
(<music21.pitch.Pitch C3>, <music21.pitch.Pitch E3>, <music21.pitch.Pitch G-3>)

* Changed in v7: updatePitches is True by default
z$cannot add this object as a degree: N)r   ChordStepModificationr   r   appendr   )r   degreer   s      r   addChordStepModification Harmony.addChordStepModification  sc    . &"788 #6vh?A A 444''..v6! r   c                    g)NzNo Figure Representationr   r   s    r   r   Harmony.findFigure  s    )r   c                    U R                   $ )z'
Return all harmony degrees as a list.
)r   r   s    r   getChordStepModifications!Harmony.getChordStepModifications  s     ***r   )r   r   r   r   r   r   r   r   )NNNNT)
r   
str | Noner   str | pitch.Pitch | Noner   r   r   
int | Noner   boolr   )r   r   r   r   r   r   returnNone)r   r   r   r   __doc__r   Music21ObjectclassSortOrderr   	TextStyle_styleClassr   r   r   r   r   propertyr   setterr   r   r   r   r   r   r   __classcell__r   s   @r   r   r      s   BH ''66:N//K
 %).2.2'+'++N!+N++N ,+N %	+N
 !%+N +N^ #	,", #, 	,
 
,> /  / b ]]" " * *X 	ZZ  / /b 
L 
L " " 1 1 AE  "D*+ +r   r   c                      \ rS rSrSrg)ChordStepModificationExceptioni)  r   Nr   r   r   r   r   r   )  r   r   r   c                      \ rS rSrSrSSS jjrS rS r\S 5       r	\	R                  S 5       r	\S	 5       r\R                  S
 5       r\S 5       r\R                  S 5       rSrg)r   i/  a  
ChordStepModification objects define the specification of harmony degree
alterations, subtractions, or additions, used in
:class:`~music21.harmony.Harmony` objects, which includes
harmony.ChordSymbol objects (and will include harmony.RomanNumeral
objects).

- degree-value element: indicates degree in chord, positive integers only
- degree-alter: indicates semitone alteration of degree, positive and
  negative integers only
- degree-type: add, alter, or subtract
    - if `add`: degree-alter is relative to a dominant chord (major and
      perfect intervals except for a minor seventh)
    - if `alter` or `subtract`: degree-alter is relative to degree already in
      the chord based on its kind element

>>> hd = harmony.ChordStepModification('add', 4)
>>> hd
<music21.harmony.ChordStepModification modType=add
    degree=4 interval=<music21.interval.Interval P1>>

>>> hd = harmony.ChordStepModification('alter', 3, 1)
>>> hd
<music21.harmony.ChordStepModification modType=alter
    degree=3 interval=<music21.interval.Interval A1>>
Nc                    S U l         U   S U l        Ub  Xl        Ub  X l        Ub  X0l        g [        R
                  " S5      U l        g )NP1)_modType_degreemodTyper   r
   Interval)r   r  r   intervalObjs       r   r   ChordStepModification.__init__e  sF    "&!%"L K"'M$--d3DMr   c                T    SU R                    SU R                   SU R                   3$ )NzmodType=z degree=z
 interval=)r  r   r
   r   s    r   r   #ChordStepModification._reprInternalu  s'    $,,x}Jt}}oVVr   c                    [        U[        5      =(       aY    U R                  UR                  :H  =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ r   )r   r   r  r   r
   )r   others     r   __eq__ChordStepModification.__eq__x  sS    u34 0-0u||+0 /		
r   c                    U R                   $ )a2  
Returns or sets an integer specifying the scale degree
that this ChordStepModification alters.

>>> hd = harmony.ChordStepModification()
>>> hd.degree = 3
>>> hd.degree
3

>>> hd.degree = 'juicy'
Traceback (most recent call last):
music21.harmony.ChordStepModificationException: not a valid degree: juicy
)r  r   s    r   r   ChordStepModification.degree  s     ||r   c                |    Ub,  [         R                  " U5      (       a  [        U5      U l        g [	        SU 35      e)Nznot a valid degree: )r   isNumintr  r   r   exprs     r   r   r    s;    T 2 2t9DL,"4&)+ 	+r   c                    U R                   $ )a{  
Get or set the alteration of this degree as a
:class:`~music21.interval.Interval` object, generally
as a type of ascending or descending augmented unison.

>>> hd = harmony.ChordStepModification()
>>> hd.interval = 1
>>> hd.interval
<music21.interval.Interval A1>

>>> hd.interval = -2
>>> hd.interval
<music21.interval.Interval AA-1>

>>> hd.interval = 0
>>> hd.interval
<music21.interval.Interval P1>

>>> hd.interval = interval.Interval('m3')
>>> hd.interval
<music21.interval.Interval m3>

More than 3 half step alteration gets
an interval that isn't a prime.

>>> hd.interval = -4
>>> hd.interval
<music21.interval.Interval M-3>
)	_intervalr   s    r   r
   ChordStepModification.interval  s    > ~~r   c                8   US;   a  S U l         g [        U[        R                  5      (       a  Xl         g [	        U5      nUS::  a:  US:X  a  SnOSU-  nUS-  nUS:  a  US-  n[        R                  " U5      U l         g [        R                  " U5      U l         g )Nr   r   r   Parw   -)r  r   r
   r  abs)r   r   numAsaStrs       r   r
   r    s    G!DNx0011"N JEzA:D;D19CKD!)!2!24!8!)!2!25!9r   c                    U R                   $ )ag  
Get or set the ChordStepModification modification type, where
permitted types are the strings add, subtract, or alter.

>>> hd = harmony.ChordStepModification()
>>> hd.modType = 'add'
>>> hd.modType
'add'

>>> hd.modType = 'juicy'
Traceback (most recent call last):
music21.harmony.ChordStepModificationException: not a valid degree modification type: juicy
)r  r   s    r   r  ChordStepModification.modType  s     }}r   c                    Ub?  [        U[        5      (       a*  UR                  5       S;   a  UR                  5       U l        g [	        SU 35      e)N)addsubtractalterz&not a valid degree modification type: )r   r   lowerr  r   r  s     r   r  r     sJ    
4 5 5zz|;; $

,4TF;= 	=r   )r  r  r  r   r
   r  )NNNr   r   )r   r   r   r   r   r   r   r  r   r   r   r
   r  r   r   r   r   r   r   /  s    j4 W
    ]]+ +  @ __: :*    ^^= =r   r   c                    X/[         U '   g)a{  
Add a new chord symbol:

>>> harmony.addNewChordSymbol('BethChord', '1,3,-6,#9', ['MH', 'beth'])
>>> [str(p) for p in harmony.ChordSymbol('BMH').pitches]
['B2', 'C##3', 'D#3', 'G3']

>>> harmony.ChordSymbol('Cbeth').pitches
(<music21.pitch.Pitch C3>, <music21.pitch.Pitch D#3>,
 <music21.pitch.Pitch E3>, <music21.pitch.Pitch A-3>)

>>> harmony.ChordSymbol('C-beth').pitches
(<music21.pitch.Pitch C-3>, <music21.pitch.Pitch D3>,
 <music21.pitch.Pitch E-3>, <music21.pitch.Pitch A--3>)

OMIT_FROM_DOCS

>>> harmony.ChordSymbol(root='Cb', kind='BethChord').pitches
(<music21.pitch.Pitch C-3>, <music21.pitch.Pitch D3>,
 <music21.pitch.Pitch E-3>, <music21.pitch.Pitch A--3>)

>>> harmony.ChordSymbol(root='C-', kind='BethChord').pitches
(<music21.pitch.Pitch C-3>, <music21.pitch.Pitch D3>,
 <music21.pitch.Pitch E-3>, <music21.pitch.Pitch A--3>)

>>> harmony.removeChordSymbols('BethChord')
NCHORD_TYPES)chordTypeNamefbNotationStringAbbreviationLists      r   addNewChordSymbolr-    s    : #3!EKr   c                <    [         U    S   R                  SU5        g)aq  
Change the current Abbreviation used for a certain
:class:`music21.harmony.ChordSymbol` chord type

>>> harmony.getCurrentAbbreviationFor('minor')
'm'

>>> harmony.changeAbbreviationFor('minor', 'min')
>>> harmony.getCurrentAbbreviationFor('minor')
'min'

OMIT_FROM_DOCS

>>> harmony.changeAbbreviationFor('minor', 'm')  # must change it back for the rest of doctests
r   r   N)r)  insert)	chordTypechangeTos     r   changeAbbreviationForr2    s      	1$$Q1r   c                :   U R                   (       d  g U R                  5         [        U R                   5      S:X  aC  U(       a  U R                  5       R                  S-   S4$ U R                  5       R                  S-   $ U R                  S5      nU R                  S5      nU R                  S5      nU R                  S5      nU R                  S	5      nU R                  S
5      nUn	Un
UnSS jnS=pU R                  5       nU R                  5       nS n[         GHx  n[        U5      n[        U5      nU" UU5      n[        R                  " U5      (       d  U/n[        R                  " U5      (       d  M^  [        U5      S:X  a*  U(       a#  U" X44U5      (       a  U(       a	  UnUS   nM  M  M  [        U5      S:X  a"  U(       a  U" X4U4U5      (       a	  UnUS   nM  M  [        U5      S	:X  a1  U(       a*  U(       d#  U(       d  U" X4XV4USS9(       a
  UnUS   nGM  GM  [        U5      S:X  a+  U(       a$  U(       d  U" X4XVU4USS9(       a
  UnUS   nGM?  GMB  [        U5      S
:X  d  GMT  U(       d  GM^  U" X4XVXx4USS9(       d  GMq  UnUS   nGM{     U(       Gd,  Sn[         GH  n[        U5      n[        U5      nU" UU5      n[        R                  " U5      (       d  U/n[        R                  " U5      (       d  M^  UR                  SS5      R                  SS5      nUR!                  S5      nU Vs/ s H  n[#        U5      PM     nnUR%                  5         XXXXgUS.	n/ nU H  nUS:w  d  M  UR'                  UU   5        M!     U" UU5      (       d  M  U[        U5      :  d  GM  [        U5      nUnUS   nGM"     U(       Ga  U R)                  5       (       a  US:X  aA  U R                  U R+                  5       5        SnSnU R                  5       R                  U-   nOYU R                  5       R                  U-   S-   U R+                  5       R                  -   nOU R                  5       R                  U-   n[-        U5      R                    Vs1 s H  nUR                  iM     nnU R                    Vs1 s H  nUR                  iM     nnUR/                  U5      (       da  UR1                  U5      n UR1                  U5      n!U (       a  US-  nU  H  n"UU"S-   -  nM     U!(       a  US-  nU! H  nUUS-   -  nM     USS nOSnU(       a  UU4$ U$ ! [         a  n[        [	        U5      5      UeSnAff = fs  snf s  snf s  snf )u/  
Analyze the given chord, and attempt to describe its pitches using a
standard chord symbol figure.

The pitches of the chord are analyzed based on intervals, and compared to
standard triads, sevenths, ninths, elevenths, and thirteenth chords. The
type of chord therefore is determined if it matches (given certain
guidelines documented below) and the figure is returned. There is no
standard "chord symbol" notation, so a typical notation is used that can be
easily modified if desired by changing a dictionary in the source code.

Set includeChordType to true (default is False) to return a tuple, the
first element being the figure and the second element the identified chord
type.

>>> harmony.chordSymbolFigureFromChord(chord.Chord(['C3', 'E3', 'G3']))
'C'

THIRDS

>>> c = chord.Chord(['C3', 'E3', 'G3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('C', 'major')

>>> c = chord.Chord(['B-3', 'D-4', 'F4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('B-m', 'minor')

>>> c = chord.Chord(['F#3', 'A#3', 'C##4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('F#+', 'augmented')

>>> c = chord.Chord(['C3', 'E-3', 'G-3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Cdim', 'diminished')

SEVENTHS

>>> c = chord.Chord(['E-3', 'G3', 'B-3', 'D-4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('E-7', 'dominant-seventh')

>>> c = chord.Chord(['C3', 'E3', 'G3', 'B3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Cmaj7', 'major-seventh')

>>> c = chord.Chord(['F#3', 'A3', 'C#4', 'E#4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('F#mM7', 'minor-major-seventh')

>>> c = chord.Chord(['F3', 'A-3', 'C4', 'E-4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Fm7', 'minor-seventh')

>>> c = chord.Chord(['F3', 'A3', 'C#4', 'E4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('F+M7', 'augmented-major-seventh')

>>> c = chord.Chord(['C3', 'E3', 'G#3', 'B-3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('C7+', 'augmented-seventh')

>>> c = chord.Chord(['G3', 'B-3', 'D-4', 'F4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Gø7', 'half-diminished-seventh')

>>> c = chord.Chord(['C3', 'E-3', 'G-3', 'B--3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Co7', 'diminished-seventh')

>>> c = chord.Chord(['B-3', 'D4', 'F-4', 'A-4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('B-dom7dim5', 'seventh-flat-five')

NINTHS

>>> c = chord.Chord(['C3', 'E3', 'G3', 'B3', 'D3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('CM9', 'major-ninth')

>>> c = chord.Chord(['B-3', 'D4', 'F4', 'A-4', 'C4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('B-9', 'dominant-ninth')

>>> c = chord.Chord(['E-3', 'G-3', 'B-3', 'D4', 'F3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('E-mM9', 'minor-major-ninth')

>>> c = chord.Chord(['C3', 'E-3', 'G3', 'B-3', 'D3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Cm9', 'minor-ninth')

>>> c = chord.Chord(['F#3', 'A#3', 'C##4', 'E#4', 'G#3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('F#+M9', 'augmented-major-ninth')

>>> c = chord.Chord(['G3', 'B3', 'D#4', 'F4', 'A3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('G9#5', 'augmented-dominant-ninth')

>>> c = chord.Chord(['C3', 'E-3', 'G-3', 'B-3', 'D3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Cø9', 'half-diminished-ninth')

>>> c = chord.Chord(['B-3', 'D-4', 'F-4', 'A-4', 'C-4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('B-øb9', 'half-diminished-minor-ninth')

>>> c = chord.Chord(['C3', 'E-3', 'G-3', 'B--3', 'D3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Co9', 'diminished-ninth')

>>> c = chord.Chord(['F3', 'A-3', 'C-4', 'E--4', 'G-3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Fob9', 'diminished-minor-ninth')

This harmony can either be CmaddD or Csus2addE-. music21 prefers the former.
Change the ordering of harmony.CHORD_TYPES to switch the preference. From Bach BWV380

>>> c = chord.Chord(['C3', 'D4', 'G4', 'E-5'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('CmaddD', 'minor')


ELEVENTHS

>>> c = chord.Chord(['E-3', 'G3', 'B-3', 'D-4', 'F3', 'A-3'] )
>>> harmony.chordSymbolFigureFromChord(c, True)
('E-11', 'dominant-11th')

>>> c = chord.Chord(['G3', 'B3', 'D4', 'F#4', 'A3', 'C4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('GM11', 'major-11th')

>>> c = chord.Chord(['C3', 'E-3', 'G3', 'B3', 'D3', 'F3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('CmM11', 'minor-major-11th')

>>> c = chord.Chord(['F#3', 'A3', 'C#4', 'E4', 'G#3', 'B3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('F#m11', 'minor-11th')

>>> c = chord.Chord(['B-3', 'D4', 'F#4', 'A4', 'C4', 'E-4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('B-+M11', 'augmented-major-11th')

>>> c = chord.Chord(['F3', 'A3', 'C#4', 'E-4', 'G3', 'B-3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('F+11', 'augmented-11th')

>>> c = chord.Chord(['G3', 'B-3', 'D-4', 'F4', 'A3', 'C4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Gø11', 'half-diminished-11th')

>>> c = chord.Chord(['E-3', 'G-3', 'B--3', 'D--4', 'F3', 'A-3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('E-o11', 'diminished-11th')

THIRTEENTHS

These are so tricky: music21 needs to be told what the root is in these cases
all tests here are 'C' chords, but any root will work:

>>> c = chord.Chord(['C3', 'E3', 'G3', 'B3', 'D4', 'F4', 'A4'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('CM13', 'major-13th')

>>> c = chord.Chord(['C3', 'E3', 'G3', 'B-3', 'D4', 'F4', 'A4'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('C13', 'dominant-13th')

>>> c = chord.Chord(['C3', 'E-3', 'G3', 'B3', 'D4', 'F4', 'A4'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('CmM13', 'minor-major-13th')

>>> c = chord.Chord(['C3', 'E-3', 'G3', 'B-3', 'D4', 'F4', 'A4'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('Cm13', 'minor-13th')

>>> c = chord.Chord(['C3', 'E3', 'G#3', 'B3', 'D4', 'F4', 'A4'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('C+M13', 'augmented-major-13th')

>>> c = chord.Chord(['C3', 'E3', 'G#3', 'B-3', 'D4', 'F4', 'A4'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('C+13', 'augmented-dominant-13th')

>>> c = chord.Chord(['C3', 'E-3', 'G-3', 'B-3', 'D4', 'F4', 'A4'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('Cø13', 'half-diminished-13th')

Pop chords are typically not always "strictly" spelled and often certain degrees
are omitted. Therefore, the following common chord omissions are permitted
and the chord will still be identified correctly:

* triads: none
* seventh chords: none
* ninth chords: fifth
* eleventh chords: third and/or fifth
* thirteenth chords: fifth, eleventh, ninth

This chord could be minor 7th with a C4, but because this 5th is not present,
it is not identified.

>>> c = chord.Chord(['F3', 'A-3', 'E-4'])
>>> harmony.chordSymbolFigureFromChord(c)
'Chord Symbol Cannot Be Identified'

Removing the fifth G3  (fifth of chord)

>>> c = chord.Chord(['C3', 'E3',  'B3', 'D3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('CM9', 'major-ninth')

Chord with G3 and B-3 removed (3rd & 5th of chord)

>>> c = chord.Chord(['E-3', 'D-4', 'F3', 'A-3'] )

Without a 3rd and 5th, root() algorithm can't locate the root,
so we must tell it the root (or write an algorithm that assumes the root is the
lowest note if the root can't be found)

>>> c.root('E-3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('E-11', 'dominant-11th')

Inversions are supported, and indicated with a '/' between the root, type-string, and bass

>>> c = chord.Chord([ 'G#3', 'B-3', 'C4', 'E4',])
>>> harmony.chordSymbolFigureFromChord(c, True)
('C7+/G#', 'augmented-seventh')

>>> c = chord.Chord(['G#2', 'B2', 'F#3', 'A3', 'C#4', 'E4'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('F#m11/G#', 'minor-11th')

if the algorithm matches the chord, but omissions or subtractions are present,
the chord symbol attempts to indicate this (although there is no standard way of doing
this so the notation might be different from what you're familiar with).

An example of using this algorithm for identifying chords "in the wild":

>>> score = corpus.parse('bach/bwv380')
>>> excerpt = score.measures(2, 3)
>>> chfy = excerpt.chordify()
>>> for c in chfy.flatten().getElementsByClass(chord.Chord):
...   print(harmony.chordSymbolFigureFromChord(c))
B-7
E-maj7/B-
B-7
Chord Symbol Cannot Be Identified
B-7
E-
B-
Chord Symbol Cannot Be Identified
B-/D
B-7
CmaddD
Cm/D
E-+M7/D
Cm/E-
F7

Notice, however, that this excerpt contains many embellishment and non-harmonic tones,
so an algorithm to truly identify the chord symbols must be as complex as any harmonic
analysis algorithm, which this is not, so innately this method is flawed.

And for the sake of completeness, unique chords supported by musicxml that
this method can still successfully identify. Notice that the root must
often be specified for this method to work.

>>> c = chord.Chord(['C3', 'D3', 'G3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Csus2', 'suspended-second')
>>> c.root()
<music21.pitch.Pitch C3>
>>> c.bass()
<music21.pitch.Pitch C3>


>>> c = chord.Chord(['C3', 'F3', 'G3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Csus', 'suspended-fourth')
>>> c.root()
<music21.pitch.Pitch C3>
>>> c.inversion()
0

>>> c = chord.Chord(['C3', 'D-3', 'E3', 'G-3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('CN6', 'Neapolitan')

>>> c = chord.Chord(['C3', 'F#3', 'A-3'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('CIt+6', 'Italian')

>>> c = chord.Chord(['C3', 'D3', 'F#3', 'A-3'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('CFr+6', 'French')

>>> c = chord.Chord(['C3', 'E-3', 'F#3', 'A-3'])
>>> c.root('C3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('CGr+6', 'German')

>>> eflat = chord.Chord(['E-3'])
>>> harmony.chordSymbolFigureFromChord(eflat, True)
('E-pedal', 'pedal')

>>> c = chord.Chord(['C3', 'G3'])
>>> harmony.chordSymbolFigureFromChord(c, True)
('Cpower', 'power')

>>> c = chord.Chord(['F3', 'G#3', 'B3', 'D#4'] )
>>> c.root('F3')
>>> harmony.chordSymbolFigureFromChord(c, True)
('Ftristan', 'Tristan')

This algorithm works as follows:

1. chord is analyzed for root (using chord's root() )
   if the root cannot be determined, error is raised
   be aware that the root() method determines the root based on which note has
   the most thirds above it
   this is not a consistent way to determine the root of 13th chords, for example
2. a chord vector is extracted from the chord
    using  :meth:`music21.chord.Chord.semitonesFromChordStep`
    this vector extracts the following degrees: (2, 3, 4, 5, 6, 7, 9, 11, and 13)
3. this vector is converted to fbNotationString (in the form of chord step,
    and a '-' or '#' to indicate semitone distance)
4. the fbNotationString is matched against the CHORD_TYPES dictionary in this harmony module,
    although certain subtractions are permitted for example a 9th chord will
    still be identified correctly even if it is missing the 5th
5. the type with the most identical matches is used, and if no type matches,
    "Chord Type Cannot Be Identified" is returned
6. the output format for the chord symbol figure is the chord's root,
    the chord type's Abbreviation (saved in CHORD_TYPES dictionary),
    a '/' if the chord is in an inversion, and the chord's bass

The chord symbol nomenclature is not entirely standardized. There are several
ways to write each abbreviation.

For example, an augmented triad might be symbolized with '+' or 'aug'.
Thus, by default the returned symbol is the first (element 0) in the CHORD_TYPES list.
For example (Eb minor eleventh chord, second inversion):

    root + chord-type-str + '/' + bass = 'E-min11/B-'

Users who wish to change these defaults can simply change that
entry in the CHORD_TYPES dictionary.

>>> harmony.chordSymbolFigureFromChord(chord.Chord(['C2', 'E2', 'G2']))
'C'

>>> harmony.changeAbbreviationFor('major', 'maj')
>>> harmony.chordSymbolFigureFromChord(chord.Chord(['C2', 'E2', 'G2']))
'Cmaj'

OMIT_FROM_DOCS

>>> harmony.changeAbbreviationFor('major', '')

r   Nr   rv   r                  c                   [        U5      nU[        U 5      :  a  gUS:  a"  U S   US   :w  a  SU;   a  US   S:X  a  U S   b  gUS:  a"  U S   US   :w  a  SU;   a  US   S:X  a  U S   b  gUS:  a"  U S   US   :w  a  SU;   a  US   S	:X  a  U S   b  gUS:  a"  U S   US   :w  a  S
U;   a  US   S:X  a  U S   b  gUS:  a"  U S   US   :w  a  S	U;   a  US   S:X  a  U S   b  gUS:  a"  U S   US   :w  a  SU;   a  US   S
:X  a  U S   b  gg)a,  
inChord is the chord the user submits to analyze,
givenChordNum is the chord type that the method is currently looking at
to determine if it could be a match for inChord

the corresponding semitones are compared, and if they do not match it is determined
whether this is a permitted omission, etc.

Fr   r   r   r7  r6  r4  r5     	   r8     T)len)inChordNumsgivenChordNumspermittedOmissionsr   s       r   compare+chordSymbolFigureFromChord.<locals>.compare  sw    s;6k!nq(99,,1Ba1G"1~16k!nq(99,,1Ba1G"1~16k!nq(99,,1Bb1H"1~16k!nq(99,,1Ba1G"1~16k!nq(99--.2Cq2H"1~16k!nq(99--.2Cq2H"1~1r   c           
     v   SSSSSSSSSS.	n/ nU [         ;   a	  [         U    n U [        ;   a  UR                  S5       Hx  nUS	:X  a  M  S
U;   a  UR                  S
5      S-  nOUR                  S5      n[	        UR                  S
S5      R                  SS5      5      nUR                  X&   U-   5        Mz     U$ )Nr7  r5  r:  r6  r4  r;  )	r   r4  r5  r;  r:  r<  r6  r7  r8  ,rw   r  #r   )CHORD_ALIASESr)  splitcountr  replacer   )	innerKind
fbNotationtypesinner_chordDegreescharaltr   s          r    convertFBNotationStringToDegreesDchordSymbolFigureFromChord.<locals>.convertFBNotationStringToDegrees  s     

  %%i0I#"((-3;$;**S/B.C**S/CT\\#r2::3CD"))%-#*=> . "!r   r   )r4  )r@  )r   r4  )r4  r:  r;  r  rF  rD  )	r6  r   r7  r4  r8  r5  r;  r:  r<  rh   rj   ri   /r"  omitrE  !Chord Symbol Cannot Be Identified)r   )r   r   	Exceptionr   r   r=  r   semitonesFromChordStepisTriad	isSeventhr)  !getAbbreviationListGivenChordTypegetNotationStringGivenChordTyper   
isListLikerJ  rH  r  sortr   r   r   r   
issuperset
difference)#inChordincludeChordTypeed3d5d7d9d11d13d2d4d6rA  kindStrkindrX  rY  rQ  	chordKindchordKindStrr+  chordDegreesnumberOfMatchedDegreessdegreesxdata	toComparecsr   perfect	inPitches	additionssubtractionsr  s#                                      r   chordSymbolFigureFromChordr|  #  s-   l ??. 7??q LLN'''17;;<<>&&00		'	'	*B		'	'	*B		'	'	*B		'	'	*B

(
(
+C

(
(
+C	B	B	B&P GooG!!#I": ![	8C:9E7	CST  ..(>L\**< A%'B8\22w$D*1oG 8?2 \"a'IBB<66$D*1oG 7 \"a'Bs3BB+\dS$D*1oG T \"a'CBBC0,SYZ$D*1oG [ \"a'CCBBC5|Xbcc$D*1oG7 !: !"$I<YGL>yI;IGWXL$$\22 ,~  ..$,,S"5==c2F''#,+237a3q673rRVYZ	 AAv!((a1 ! 9l33-L0AA14\1B.(".q/1 %4 & W\\^,)\\^((72\\^((72S87<<>;N;NN$$w.B#.r?#:#:;#:a166#:;%,__5_QVV_	5!!),,!,,W5I"--i8Le"A1s7OB #f%A1s7OB &CRB0Dz	m  .s1v&A-.L 48 <5s)   U' ?V"VV'
V1VVc                P    [        [        U 5      5      nU R                  Ul        U$ )a;  
Get the :class:`~music21.harmony.chordSymbol` object from the chord, using
:meth:`music21.harmony.Harmony.chordSymbolFigureFromChord`

>>> c = chord.Chord(['D3', 'F3', 'A4', 'B-5'])
>>> symbol = harmony.chordSymbolFromChord(c)
>>> symbol
<music21.harmony.ChordSymbol B-maj7/D>
>>> c.pitches == symbol.pitches
True
)r   r|  r   )r`  rw  s     r   chordSymbolFromChordr~  W  s$     
/8	9BBJIr   c                    [         U    S   $ )z
Get the Abbreviation list (all allowed Abbreviations that map to this
:class:`music21.harmony.ChordSymbol` object):

>>> harmony.getAbbreviationListGivenChordType('minor-major-13th')
['mM13', 'minmaj13']

r   r(  r0  s    r   rZ  rZ  h       y!!$$r   c                    [        U 5      S   $ )z
Return the current Abbreviation for a given
:class:`music21.harmony.ChordSymbol` chordType:

>>> harmony.getCurrentAbbreviationFor('dominant-seventh')
'7'

r   )rZ  r  s    r   getCurrentAbbreviationForr  t  s     -Y7::r   c                    [         U    S   $ )z
Get the notation string (fb-notation style) associated with this
:class:`music21.harmony.ChordSymbol` chordType

>>> harmony.getNotationStringGivenChordType('German')
'1,-3,#4,-6'

r   r(  r  s    r   r[  r[    r  r   c                    [         U 	 g)z~
Remove the given chord type from the CHORD_TYPES dictionary, so it
can no longer be identified or parsed by harmony methods.
Nr(  r  s    r   removeChordSymbolsr    s    
 	Ir   z5dict[tuple[str, str], realizerScale.FiguredBassScale]realizerScaleCachec                     ^  \ rS rSrSr      S       SU 4S jjjrS r    SS jrSS jrS r	S r
S	 rS
 rSS jrS rS rS rSS.SU 4S jjjrSrU =r$ )r   i  a  
Class representing the Chord Symbols commonly found on lead sheets.
Chord Symbol objects can be instantiated one of two main ways:

1. when music xml is parsed by the music21 converter, xml Chord Symbol tags
   are interpreted as Chord Symbol objects with a root and kind attribute.
   If bass is not specified, the bass is assumed to be the root

2. by creating a chord symbol object with music21 by passing in the
   expression commonly found on leadsheets. Due to the relative diversity
   of lead sheet chord syntax, not all expressions are supported. Consult
   the examples for the supported syntax, or email us for help.

All :class:`~music21.harmony.ChordSymbol` inherit from
:class:`~music21.chord.Chord` so you can consider these objects as chords,
although they have a unique representation in a score. ChordSymbols, unlike
chords, by default appear as chord symbols in a score and have duration of
0.

To obtain the chord representation of the `ChordSymbol` in the score, change
:attr:`~music21.harmony.Harmony.writeAsChord` to True. Unless otherwise
specified, the duration of this chord object will become 1.0. If you have a
leadsheet, run :func:`music21.harmony.realizeChordSymbolDurations` on the
stream to assign the correct (according to offsets) duration to each
harmony object.)

The music xml-based approach to instantiating Chord Symbol objects:

>>> cs = harmony.ChordSymbol(kind='minor', kindStr='m', root='C', bass='E-')
>>> cs
<music21.harmony.ChordSymbol Cm/E->

>>> cs.chordKind
'minor'

>>> cs.root()
<music21.pitch.Pitch C4>

>>> cs.bass()
<music21.pitch.Pitch E-3>

The second approach to creating a Chord Symbol object, by
passing a regular expression (this list is not exhaustive):

>>> symbols = ['', 'm', '+', 'dim', '7',
...            'M7', 'm7', 'dim7', '7+', 'm7b5',  # half-diminished
...            'mM7', '6', 'm6', '9', 'Maj9', 'm9',
...            '11', 'Maj11', 'm11', '13',
...            'Maj13', 'm13', 'sus2', 'sus4',
...            'N6', 'It+6', 'Fr+6', 'Gr+6', 'pedal',
...            'power', 'tristan', '/E', 'm7/E-', 'add2',
...            '7omit3',]
>>> for s in symbols:
...     chordSymbolName = 'C' + s
...     h = harmony.ChordSymbol(chordSymbolName)
...     pitchNames = [str(p) for p in h.pitches]
...     print('%-10s%s' % (chordSymbolName, '[' + (', '.join(pitchNames)) + ']'))
C         [C3, E3, G3]
Cm        [C3, E-3, G3]
C+        [C3, E3, G#3]
Cdim      [C3, E-3, G-3]
C7        [C3, E3, G3, B-3]
CM7       [C3, E3, G3, B3]
Cm7       [C3, E-3, G3, B-3]
Cdim7     [C3, E-3, G-3, B--3]
C7+       [C3, E3, G#3, B-3]
Cm7b5     [C3, E-3, G-3, B-3]
CmM7      [C3, E-3, G3, B3]
C6        [C3, E3, G3, A3]
Cm6       [C3, E-3, G3, A3]
C9        [C3, E3, G3, B-3, D4]
CMaj9     [C3, E3, G3, B3, D4]
Cm9       [C3, E-3, G3, B-3, D4]
C11       [C2, E2, G2, B-2, D3, F3]
CMaj11    [C2, E2, G2, B2, D3, F3]
Cm11      [C2, E-2, G2, B-2, D3, F3]
C13       [C2, E2, G2, B-2, D3, F3, A3]
CMaj13    [C2, E2, G2, B2, D3, F3, A3]
Cm13      [C2, E-2, G2, B-2, D3, F3, A3]
Csus2     [C3, D3, G3]
Csus4     [C3, F3, G3]
CN6       [C3, D-3, E3, G-3]
CIt+6     [C3, F#3, A-3]
CFr+6     [C3, D3, F#3, A-3]
CGr+6     [C3, E-3, F#3, A-3]
Cpedal    [C3]
Cpower    [C3, G3]
Ctristan  [C3, D#3, F#3, A#3]
C/E       [E3, G3, C4]
Cm7/E-    [E-3, G3, B-3, C4]
Cadd2     [C3, D3, E3, G3]
C7omit3   [C3, G3, B-3]

You can also create a Chord Symbol by writing out each degree,
and any alterations to that degree:

You must explicitly indicate EACH degree (a triad is NOT necessarily implied)

>>> [str(p) for p in harmony.ChordSymbol('C35b7b9#11b13').pitches]
['C2', 'E2', 'G2', 'D-3', 'F#3', 'A-3', 'B-3']

>>> [str(p) for p in harmony.ChordSymbol('C35911').pitches]
['C2', 'E2', 'G2', 'D3', 'F3']

to prevent ambiguity in notation and in accordance with the rest of music21,
if a root or bass is flat, the '-' must be used, and NOT 'b'. However, alterations and chord
abbreviations are specified normally with the 'b' and '#' signs.

>>> dFlat = harmony.ChordSymbol('D-35')
>>> [str(p) for p in dFlat.pitches]
['D-3', 'F3', 'A-3']

>>> [str(p) for p in harmony.ChordSymbol('Db35').pitches]
['D3', 'F3', 'A3']

(Note that this would be much better expressed just as 'Dm'.)

>>> [str(p) for p in harmony.ChordSymbol('D,35b7b9#11b13').pitches]
['D2', 'F#2', 'A2', 'E-3', 'G#3', 'B-3', 'C4']

>>> harmony.ChordSymbol('Am').pitches
(<music21.pitch.Pitch A2>, <music21.pitch.Pitch C3>, <music21.pitch.Pitch E3>)

>>> harmony.ChordSymbol('A-m').pitches
(<music21.pitch.Pitch A-2>, <music21.pitch.Pitch C-3>, <music21.pitch.Pitch E-3>)

>>> harmony.ChordSymbol('A-m').pitches
(<music21.pitch.Pitch A-2>, <music21.pitch.Pitch C-3>, <music21.pitch.Pitch E-3>)

>>> harmony.ChordSymbol('F-dim7').pitches
(<music21.pitch.Pitch F-2>, <music21.pitch.Pitch A--2>,
 <music21.pitch.Pitch C--3>, <music21.pitch.Pitch E---3>)

Thanks to David Bolton for catching the bugs tested below:

>>> [str(p) for p in harmony.ChordSymbol('C3579').pitches]
['C2', 'E2', 'G2', 'D3', 'B3']

>>> [str(p) for p in harmony.ChordSymbol('C35b79').pitches]
['C2', 'E2', 'G2', 'D3', 'B-3']

>>> [str(p) for p in harmony.ChordSymbol('C357b9').pitches]
['C2', 'E2', 'G2', 'D-3', 'B3']

When bass is not in chord:

>>> cs = harmony.ChordSymbol(root='E', bass='C', kind='diminished-seventh')

>>> [str(p) for p in cs.pitches]
['C2', 'E3', 'G3', 'B-3', 'D-4']

>>> cs.figure
'Eo7/C'

And now, and example of parsing in the wild:

>>> s = corpus.parse('leadsheet/fosterBrownHair')
>>> initialSymbols = s.flatten().getElementsByClass(harmony.ChordSymbol)[0:5]
>>> [[str(c.name) for c in c.pitches] for c in initialSymbols]
[['F', 'A', 'C'], ['B-', 'D', 'F'], ['F', 'A', 'C'], ['C', 'E', 'G'], ['F', 'A', 'C']]


Test creating an empty chordSymbol:

>>> cs = harmony.ChordSymbol()
>>> cs
<music21.harmony.ChordSymbol>
>>> cs.root('E-')
>>> cs.bass('B-', allow_add=True)

important: we are not asking for transposition, merely specifying the inversion that
the chord should be read in (transposeOnSet = False)

>>> cs.inversion(2, transposeOnSet=False)

>>> cs.romanNumeral = 'I64'
>>> cs.chordKind = 'major'
>>> cs.chordKindStr = 'M'
>>> cs
<music21.harmony.ChordSymbol E-/B->
c                   > XPl         X`l        [        TU ]  " U4X#US.UD6  SU;  a!  SU;  a  [        R
                  " S5      U l        U R                   (       d  U R                  (       a  U R                  5         g g )Nr   r   r   r   )rn  ro  r   r   r   r   r   )	r   r   r   r   r   rm  rl  r   r   s	           r   r   ChordSymbol.__init__T  sj     #WdWhWX%/*I$--a0DM>>T..! /r   c                T   [        U[        5      (       d  [        U5      n/ SQn/ SQn/ SQnU R                  U;   aD  [        R                  " US   R
                  [        US   R                  S-   5      -   5      US'   GOnU R                  U;   a  [        R                  " US   R
                  [        US   R                  S-   5      -   5      US'   [        R                  " US   R
                  [        US   R                  S-   5      -   5      US'   OU R                  U;   a  [        R                  " US   R
                  [        US   R                  S-   5      -   5      US'   [        R                  " US   R
                  [        US   R                  S-   5      -   5      US'   [        R                  " US   R
                  [        US   R                  S-   5      -   5      US'   OU$ [        R                  " U5      nUR                  5       n[        UR                  5      $ )Nr=   r:   rB   rL   rO   rT   r^   r[   rc   r   r   r4  )r   listrn  r   r   r   r   r   r   ChordsortDiatonicAscendingr   )r   r   ninths	eleventhsthirteenthscs         r   _adjustOctavesChordSymbol._adjustOctavesh  s   '4((7mG
 BA	C>>V#WQZ__s71:;L;Lq;P7Q%QRGAJ^^y(WQZ__s71:;L;Lq;P7Q%QRGAJWQZ__s71:;L;Lq;P7Q%QRGAJ^^{*WQZ__s71:;L;Lq;P7Q%QRGAJWQZ__s71:;L;Lq;P7Q%QRGAJWQZ__s71:;L;Lq;P7Q%QRGAJNKK ##%AIIr   c                  ^ ^^^	 SSK Jn  [        T5      mT R                  nUc  T$ T R	                  5       mUR                  T5      m	UUU	U 4S jnUU 4S jnUU 4S jnU HR  nUR                  S:X  a
  U" U5        M  UR                  S:X  a
  U" U5        M7  UR                  S:X  d  MI   U" U5        MT     T$ ! [         a    SUl        U" U5         Mt  f = f)	a  
degree-value element: indicates degree in chord, positive integers only

degree-alter: indicates semitone alteration of degree, positive and negative integers only

degree-type: `add`, `alter`, or `subtract`:
    if `add`:
        degree-alter is relative to a dominant chord (major and perfect
        intervals except for a minor seventh)
    if `alter` or `subtract`:
        degree-alter is relative to degree already in the chord based on its kind element


FROM XML DOCUMENTATION

The degree element is used to add, alter, or subtract
individual notes in the chord. The degree-value element
is a number indicating the degree of the chord (1 for
the root, 3 for third, etc). The degree-alter element
is like the alter element in notes: 1 for sharp, -1 for
flat, etc. The degree-type element can be `add`, `alter`, or
`subtract`. If the degree-type is `alter` or `subtract`, the
degree-alter is relative to the degree already in the
chord based on its kind element. If the degree-type is
`add`, the degree-alter is relative to a dominant chord
(major and perfect intervals except for a minor
seventh). The print-object attribute can be used to
keep the degree from printing separately when it has
already taken into account in the text attribute of
the kind element. The plus-minus attribute is used to
indicate if plus and minus symbols should be used
instead of sharp and flat symbols to display the degree
alteration; it is `no` by default. The degree-value and
degree-type text attributes specify how the value and
type of the degree should be displayed.

A harmony of kind "other" can be spelled explicitly by
using a series of degree elements together with a root.
r   )scalec                  > TR                  U R                  T5      nU R                  (       a  U R                  R                  S:w  as  U R                  S:X  aH  U R                  R                  S:  a.  TR                  b!  TR                  S:w  a  UR                  S5      nUR                  U R                  5      nU R                  S:  a  UR                  S-   Ul        TR                  n[        U R                  5      U;   aM  T HF  nTR                  U5      U R                  :X  d  M$  TR                  U5        TR                  U5        MH     gTR                  U5        g)zM
change the pitches list based on this chordStepModification, adding
a pitch
r   r5  Nr   rE  r   )pitchFromDegreer   r
   	semitonesrn  	transposer   r   r   getScaleDegreeFromPitchremover   )hDpitchToAppendrs  r   r   	rootPitchscr   s       r   typeAddDChordSymbol._adjustPitchesForChordStepModifications.<locals>.typeAdd  s   
 ..ryy)DM{{r{{449 IIN--12",$1$;$;B$?M - 7 7 DyyA~'4';';a'?$''G299~( A11!4		Aq)}5 !
 }-r   c                  > TR                   nU(       d  gSn[        TU5       H  u  p4UR                  SS5      nUR                  SS5      nUR                  SS5      nU R                  [	        U5      :X  d  MV  TR                  U5        SnTR                    H:  n[        U R                  5      U;   d  M  TR                   R                  U5          M     M     U(       d  [        SU R                   35      eg)	zO
change the pitches list based on this chordStepModification, removing a pitch
NFr  r   rF  ATDegree not in specified chord: )r   ziprJ  r   r  r  r   r   )r  rs  
pitchFoundr   r   degreeStringr   r   s         r   typeSubtractIChordSymbol._adjustPitchesForChordStepModifications.<locals>.typeSubtract  s     ''GJ '2	R0R0R099F+NN1%!%J(,(9(9ryy>\9 --44\B! ): 3 45bii[AC C r   c                d  > SnTR                   n[        TU5       Hr  u  p4UR                  SS5      nUR                  SS5      nUR                  SS5      nU R                  [	        U5      :X  d  MV  UR                  U R                  SS9nSnMt     U(       d  [        SU R                   35      eg	)
z
alter
Fr  r   rF  r  TinPlacer  N)r   r  rJ  r   r  r  r
   r   )r  r  rs  r   r   r   r   s        r   	typeAlterFChordSymbol._adjustPitchesForChordStepModifications.<locals>.typeAlter  s     J''G '2	R0R0R099F+BKK>A!%J 3" 45bii[AC C r   r"  r#  r$  )r   r  r  r   r   
MajorScaler  r   )
r   r   r  r   r  r  r  chordStepModificationr  r  s
   ``      @@r   '_adjustPitchesForChordStepModifications3ChordSymbol._adjustPitchesForChordStepModifications  s    T 	"w-!%!<!<!)NIIK	i(	. 	.p	C8	C: &<!$,,5-.&..*<23&..'9334 &<  6 349)1123s   +B99CCc                   SnSnUR                  U5      [        U5      -   nXS nUSS S:X  a  SnUSS nOUSS S:X  a  SnUSS nUSS R                  5       (       a  USS nUSS nO"US   R                  5       (       a
  US   nUSS nU(       a,  US	:X  a  S
nU R                  [	        U[        U5      U5      SS9  U$ )ao  
Removes and parses the first instance of a given `modType` such as
'add', 'alter', 'omit', or 'subtract'. Returns the unparsed remainder.

>>> cs = harmony.ChordSymbol()
>>> cs._parseAddAlterSubtract('add#9omit5', 'add')
'omit5'
>>> cs.chordStepModifications
[<music21.harmony.ChordStepModification
    modType=add degree=9 interval=<music21.interval.Interval A1>>]
r   r   Nr   brE  rF  r6  rT  r#  Fr   )indexr=  	isnumericr   r   r  )r   	remainingr  r   r$  
startIndexs         r   _parseAddAlterSubtract"ChordSymbol._parseAddAlterSubtract9  s     #//'2S\A
 k*	Ra=CE!!"Ir]c!E!!"IRa=""$$r]F!!"Iq\##%%q\F!!"I& $))%gs6{EBRW * Yr   c                   UnSU;   a  USUR                  S5       nSU;   a  USUR                  S5       nSU;   a  USUR                  S5       nSU;   a  USUR                  S5       nSU;   a=  XR                  S5      S-      R                  5       (       a  USUR                  S5       nSU;   aj  UR                  S5      [        U5      S-
  :  aI  XR                  S5      S-      R                  5       (       a   S	U;  a  S
U;  a  USUR                  S5       n[         H2  n[	        U5       H   nX:X  d  M
  X0l        U[        U5      S  s  s  $    M4     U$ )Nr"  r   r$  rT  r#  rF  r   r  rJ   rG   )r  isdigitr=  r)  rZ  rn  )r   sH
originalsHrn  
charStrings        r   _getKindFromShortHand!ChordSymbol._getKindFromShortHanda  sM   
B;Abhhuo&Bb=Abhhw'(BR<Abhhv&'BAbhhz*+B"9HHSMA-.6688Abhhsm$B2I"((3-#b'A+5xx}q()1133Ob(8Abhhsm$B$I?	J
#%.N%c"gh// K %
 r   c                :    U H  nUR                   S:  d  M    g   g)N   TFdiatonicNoteNumr   r   r   s      r   _hasPitchAboveC4ChordSymbol._hasPitchAboveC4x  "    A  2%  r   c                :    U H  nUR                   S:  d  M    g   g)Nr<  TFr  r  s      r   _hasPitchBelowA1ChordSymbol._hasPitchBelowA1~  r  r   c                    SnU R                   nU[        ;   a	  [        U   nU[        ;   a  [        U5      nOSnUR	                  SS5      nUR                  5       U l        U$ )z
returns NotationString of ChordSymbolObject which dictates which scale
degrees and how those scale degrees are altered in this chord.

>>> h = harmony.ChordSymbol('F-dim7')
>>> h._notationString()
'1,-3,-5,--7'
r   rD  r   )rn  rG  r)  r[  rJ  rH  r   )r   notationStringrm  rs  s       r   _notationStringChordSymbol._notationString  sa     ~~=  &D;<TBNN ((c2#MMOr   c                   U R                   S:X  a  gU R                   n[        R                  " SSU5      nSU;   aK  USUR                  S5       nUR	                  SS5      nUR	                  US5      nUR	                  SS5      nOb[        R
                  " SU5      nU(       a2  UR                  5       nUR	                  UR                  5       SS5      nO[        S	U S
3S-   5      eU(       a%  U R                  [        R                  " U5      5        [        R                  " SU5      nUnU(       aR  UR                  5       nUR	                  SS5      nU R                  USS9  UR	                  UR                  5       S5      nU R                  U5      nSnSn	U H  n
 [        UR                  U
5      U	5      n	M!     XiS nSnSnU(       aj  U[        U5      :  a[  U H=  nUS-  nUR!                  5       (       a  X-  nX;   d  M(  U R#                  X5      nSnSn  O   U(       a  U[        U5      :  a  M[  UR	                  SS5      nU H  n
X;   d  M
  USUR                  U
5       nM      SU;   d  SU;   a(  [        R$                  " S5      nUR'                  U5      nOU/n/ n/ nU H  nU(       d  M  UR	                  SS5      nUR	                  SS5      n [)        U5      nUS:  aj  SnSnSnU H\  nU(       dK  US:X  a   UR+                  UU   UUS-      -   5        SnO'US;   a  UU-   nOUU-   nUR+                  U5        SnOSnUS-   nM^     M  UR+                  U5        M     U H  nUR+                  U5        M     Un/ nU H  nUS:w  d  M  SU;   a  SUR-                  S5      -  nOUR-                  S5      n[        R                  " SU5      nU(       d  MW  UR+                  [)        UR                  5       5      U/5        M     U H!  u  nnU R/                  [1        SUU5      SS 9  M#     g! [         a     GM  f = f! [         a  n[        SU< S3S-   S-   5      UeSnAff = f)!z
Translate the figure string (regular expression) into a meaningful
Harmony object by identifying the root, bass, inversion, kind, and
kindStr.
rU  Nz\sr   rD  r   z[A-Ga-g][#-]*r   zChord z does not begin zwith a valid root note.z/[A-Ga-g][#-]*rS  Tr   )r"  r$  rT  r#  i  r  rF  z([b#]+[^b#]+)zInvalid chord abbreviation z; see z&music21.harmony.CHORD_TYPES for valid z)abbreviations or specify all alterations.   Frw   )r  rF  rE  z[1-9]+r"  r   )r   resubr  rJ  matchgroup
ValueErrorr   r   r   searchr   r  r   r=  isalphar  compilerH  r  r   rI  r   r   )r   prelimFigurer   stm1m2r  r   ALTER_TYPESsearchStart	alterTypesearchStringForAlterTypes	substringirO  splitteralterationsindexesaltCopy
itemStringjustIntsveskipNextr  itemrs  
alterationsemiToneAlterm3r   alterBys                                  r   r   ChordSymbol._parseFigure  s    ;;=={{vveR6,,"4"4S"9:D%%c2.BD"%B'//R8L*L9Bxxz!))"((*b!< 6,7G!H#<"= > > IIekk$'( YY(,7	88:D<<R(DIIddI+

288:r2I''	2:$I!)//)"<kJ % *3<)@!	'A4M0N,N1Q<<>>%I+040K0K11>- "IA 2 (A4M0N,N ZZR  %I,),- % "9r	zz/2H"..,K$K%J!))#r2H''R0Hx= "} 
&D#3;#NN:a=:a!e;L+LM'+H!Z/)3d):J)3d):J#NN:6)+J#(AA ' z*A &B DNN4  %JR*$$&)9)9#)>$>M$.$4$4S$9MYYy*52NNC
O]#CD &  'OFG))%eVW=U * T  '_  N   1"v>>?AB 	s*   "P;Q;
Q
	Q

Q3Q..Q3c                4   SU R                   ;  d  SU R                   ;  d  U R                  c  gSSKJn  U R                   S   R                  S4nU[
        ;   a
  [
        U   nO)UR                  " U R                   S   S5      nU[
        U'   SU R                   S   l        SU R                   S   l        U R                  5       (       a?  UR                  U R                   S   U R                  5       5      nUR                  S5        OQ/ nUR                  U R                   S   5        U R                   S   U;  a  UR                  U R                   S   5        U R                  U5      nU R                   S   R                  U R                   S   R                  :w  a[  U R                  5       nU R                  U5      (       d4  SnSU R                   S   l        UR                  U R                   S   5        OU R                  SS	S
9  SnU R                  U5      nUS;  a  USU  H3  nUR                  S-   Ul        US:  d  M  UR                  S-   Ul        M5     U H@  nUR                   U R                   S   R                   :  d  M,  UR                  S-   Ul        MB     U R#                  U5      (       a6  U H  nU=R                  S-  sl        M     U R#                  U5      (       a  M6  U R%                  U5      (       a6  U H  nU=R                  S-  sl        M     U R%                  U5      (       a  M6  ['        U5      U l        U R+                  SS9  U R-                  U R-                  5       SS9  U R/                  U R/                  5       5        g)a  
TODO: EXTREMELY SLOW!

Calculate the pitches in the chord symbol and update all associated
variables, including bass, root, inversion and chord:

>>> CS = harmony.ChordSymbol

>>> [str(pi) for pi in CS(root='C', bass='E', kind='major').pitches]
['E3', 'G3', 'C4']

>>> [str(pi) for pi in CS(root='C', bass='G', kind='major').pitches]
['G2', 'C3', 'E3']

>>> [str(pi) for pi in CS(root='C', kind='minor').pitches]
['C3', 'E-3', 'G3']

>>> [str(pi) for pi in CS(root='C', bass='B', kind='major-ninth').pitches]
['B2', 'C3', 'D3', 'E3', 'G3']

>>> [str(pi) for pi in CS(root='D', bass='F', kind='minor-seventh').pitches]
['F3', 'A3', 'C4', 'D4']

Note that this ChordSymbol creates what looks like a B- minor-seventh
chord in first inversion, but is considered to be a D- chord in root
position:

>>> dFlatMaj6 = CS('D-6')
>>> [str(pi) for pi in dFlatMaj6.pitches]
['D-3', 'F3', 'A-3', 'B-3']

>>> dFlatMaj6.root()
<music21.pitch.Pitch D-3>

>>> dFlatMaj6.inversion()
0

OMIT_FROM_DOCS

>>> CS('E7omit3').root().nameWithOctave
'E3'
>>> CS('E7omit5/G#').bass().nameWithOctave
'G#2'
>>> CS('E9omit5/G#').root().nameWithOctave
'E3'
>>> CS('E11omit3').root().nameWithOctave
'E2'
r   r   Nr   r   r   r   r6  Fr   )r   Nr   Tr  r   )r   rn  music21.figuredBassr   r   r  FiguredBassScaler   r  getSamplePitchespopr   r  r   inversionIsValidr  r  r  r  tupler   r  r   r   )r   r   scaleInitTuplefbScaler   inversionNumr   	thisPitchs           r   r   ChordSymbol._updatePitches  s
   b (F$//,IT^^Mc5 //&166@//(8G#44T__V5LgVG18~. *+&)*&!!..tv/FH\H\H^_GKKNGNN4??623v&g5tv67%%g.??6"''4??6+B+G+GG>>+L((66  $ 23'.tv67NN4N6L>>wGy(Q|,88a<!# xx!|AH	 - $$tv'>'N'NN xx!|AH  ##G,,$	  A%  % ##G,, ##G,,$	  A%  % ##G,, W~""4"0 			$))+	.		$))+r   c                f   U R                   (       d  U R                  (       Ga  U R                  5       c  [        SU 5      eU R                  5       R                  nU R                  nU[
        ;   a	  [
        U   nU[        ;   a  U[        U5      S   -  nU R                  5       bV  U R                  5       R                  U R                  5       R                  :w  a   USU R                  5       R                  -   -  nU R                    H  nUR                  b_  UR                  R                  nUS:  a  SnOSnU[        U5      -  nUSUR                  -   S-   U-   [        UR                  5      -   -  nMo  USUR                  -   S-   [        UR                  5      -   -  nM     U$ [        U 5      $ )a  
Return the chord symbol figure associated with this chord.

This method tries to deduce what information it can from the provided
pitches.

>>> h = harmony.ChordSymbol(root='F', bass='D-', kind='Neapolitan')
>>> h.figure
'FN6/D-'

Thanks to Norman Schmidt for code sample and helping fix a bug

>>> foster = corpus.parse('leadsheet/fosterBrownHair.xml')
>>> foster = foster.parts[0].getElementsByClass(stream.Measure)
>>> for m in foster[12:17]:
...   c = m.getElementsByClass(harmony.ChordSymbol)
...   if c:
...     ch = c[0].figure
...     print(ch.replace('-', 'b'))
...   else:
...     print('n.c.')
F
G7
C
C
C

Thanks to David Bolton for catching the bugs tested below:

>>> h1 = harmony.ChordSymbol('C7 b9')
>>> for x in h1.pitches:
...     x
...
<music21.pitch.Pitch C3>
<music21.pitch.Pitch E3>
<music21.pitch.Pitch G3>
<music21.pitch.Pitch B-3>
<music21.pitch.Pitch D-4>

>>> h2 = harmony.ChordSymbol('C/B- add 2')
>>> for x in h2.pitches:
...     x
...
<music21.pitch.Pitch B-2>
<music21.pitch.Pitch C3>
<music21.pitch.Pitch D3>
<music21.pitch.Pitch E3>
<music21.pitch.Pitch G3>

OMIT_FROM_DOCS

>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> elStr = (r'<harmony><root><root-step>C</root-step></root><kind>dominant</kind>' +
...           '<degree><degree-value>9</degree-value><degree-alter>-1</degree-alter>' +
...           '        <degree-type>add</degree-type></degree></harmony>')
>>> mxHarmony = EL(elStr)

>>> cs = MP.xmlToChordSymbol(mxHarmony)
>>> print(cs.figure)
C7 add b9

>>> cs.pitches
(<music21.pitch.Pitch C3>,
 <music21.pitch.Pitch E3>,
 <music21.pitch.Pitch G3>,
 <music21.pitch.Pitch B-3>,
 <music21.pitch.Pitch D-4>)

>>> elStr = (r'<harmony><root><root-step>C</root-step></root><kind>major</kind>' +
...           '<bass><bass-step>B</bass-step><bass-alter>-1</bass-alter></bass>' +
...           '<degree><degree-value>2</degree-value><degree-alter>0</degree-alter>' +
...           '        <degree-type>add</degree-type></degree></harmony>')
>>> mxHarmony = EL(elStr)

>>> cs = MP.xmlToChordSymbol(mxHarmony)
>>> print(cs.figure)
C/B- add 2

>>> cs.pitches
(<music21.pitch.Pitch B-2>,
 <music21.pitch.Pitch C3>,
 <music21.pitch.Pitch D3>,
 <music21.pitch.Pitch E3>,
 <music21.pitch.Pitch G3>)
z.Cannot find figure. No root to the chord foundr   rS  rF  r  r   )r   rn  r   r   r   rG  r)  rZ  r   r
   r  r  r  r   r   r|  )r   r   rm  csModnumAlterrr  prefixs          r   r   ChordSymbol.findFigure  sp   p &&$... yy{"&'WY]^^YY[%%F>>D}$$T*{";DA!DDyy{&99;##tyy{'7'77cDIIK$4$444F44>>-$~~77H!|X.FcEMM1C7&@3u||CTTTFcEMM1C7#ell:KKKF 5 M .d33r   c                   SnSnSnSnUS:X  a!  U R                   U;   d  U R                   U;   a  gUS:X  a1  U R                   U;   d   U R                   U;   d  U R                   U;   a  gUS:X  aA  U R                   U;   d0  U R                   U;   d   U R                   U;   d  U R                   U;   a  gUS	;   a  U R                   S
:w  a  gUc  gg)z
Returns true if the provided inversion exists for the given pitches of
the chord. If not, it returns false and the getPitches method then
appends the bass pitch to the chord.
)rr   rt   rp   rn   ry   r0   r3   r$   r}   r|   r'   r,   r  r  r  r4  Tr7  r   )r6  r   rv   F)rn  )r   r   seventhsr  r  r  s         r   r  ChordSymbol.inversionIsValid 	  s    



	


 >NNk)~~*!^NNi'~~,~~'!^NNh&~~'~~*~~,6!NNg-r   Fr  c               N   > [         TU ]  XS9nU(       d	  SUl        U$ SU l        g)aD  
Overrides :meth:`~music21.chord.Chord.transpose` so that this ChordSymbol's
`figure` is appropriately cleared afterward.

>>> cs = harmony.ChordSymbol('Am')
>>> cs.figure
'Am'
>>> cs.transpose(1)
<music21.harmony.ChordSymbol B-m>
>>> cs.transpose(5, inPlace=True)
>>> cs
<music21.harmony.ChordSymbol Dm>
>>> cs.figure
'Dm'
r  N)r   r  r   )r   r   r  postr   s       r   r  ChordSymbol.transpose]	  s0      w  8DKKDKr   )r   rn  ro  r   r   r   )NNNNr   r   )r   r   r   pitch.Pitch | str | Noner   r  r   r   )r   zt.Iterable[pitch.Pitch]r   zlist[pitch.Pitch])r  r   r  r   r   r   r&  )r   r   r   zT | None)r   r   r   r   r   r   r  r  r  r  r  r  r  r   r   r   r  r  r   r   r   s   @r   r   r     s    tr %).2.2'+"!"+" ," %	" "(:r.r	rh&P.2@TD@H{4z;z .3   r   c                     ^  \ rS rSrSr   S     SU 4S jjjrSSS.S jjrSSSS.S	 jjrS
 rSS.SS jjr	Sr
U =r$ )r   iv	  a  
Class representing a special 'no chord' ChordSymbol used to explicitly
encode absence of chords. This is especially useful to stop a chord
without playing another.

>>> from music21.harmony import ChordSymbol, NoChord
>>> s = stream.Score()
>>> s.repeatAppend(note.Note('C'), 4)
>>> s.append(ChordSymbol('C'))
>>> s.repeatAppend(note.Note('C'), 4)
>>> s.append(NoChord())
>>> s.repeatAppend(note.Note('C'), 4)
>>> s = s.makeMeasures()

See how the chordSymbol of C stops at offset 8 rather
than continuing, thanks to the NoChord object.

>>> s = harmony.realizeChordSymbolDurations(s)
>>> s.show('text', addEndTimes=True)
{0.0 - 0.0} <music21.clef.BassClef>
{0.0 - 0.0} <music21.meter.TimeSignature 4/4>
{0.0 - 1.0} <music21.note.Note C>
{1.0 - 2.0} <music21.note.Note C>
{2.0 - 3.0} <music21.note.Note C>
{3.0 - 4.0} <music21.note.Note C>
{4.0 - 8.0} <music21.harmony.ChordSymbol C>
{4.0 - 5.0} <music21.note.Note C>
{5.0 - 6.0} <music21.note.Note C>
{6.0 - 7.0} <music21.note.Note C>
{7.0 - 8.0} <music21.note.Note C>
{8.0 - 12.0} <music21.harmony.NoChord N.C.>
{8.0 - 9.0} <music21.note.Note C>
{9.0 - 10.0} <music21.note.Note C>
{10.0 - 11.0} <music21.note.Note C>
{11.0 - 12.0} <music21.note.Note C>
{12.0 - 12.0} <music21.bar.Barline type=final>

>>> c_major = s.getElementsByClass(ChordSymbol).first()
>>> c_major.duration
<music21.duration.Duration 4.0>
>>> c_major.offset
4.0

Other text than the default of 'N.C.' can be given:

>>> nc2 = NoChord('NC')
>>> nc2
<music21.harmony.NoChord NC>
>>> nc2.pitches
()

Note that even if the text is a valid chord abbreviation, no
pitches are generated.  This feature may be useful for adding
the appearance of ChordSymbols in a piece without having them
be realized.

>>> nc2 = NoChord('C7')
>>> nc2
<music21.harmony.NoChord C7>
>>> nc2.pitches
()
Nc                   > [         TU ]  " U4X#=(       d    U=(       d    SS.UD6  U R                  c  U R                  U l        g g )NN.C.)rm  rl  )r   r   r   ro  )r   r   rm  rl  r   r   s        r   r   NoChord.__init__	  sC     	\d4Ov4O\S[\<<,,DL  r   findc                   g r   r   )r   newrootr  s      r   r   NoChord.root	      r   F)r  r   c                   g r   r   )r   newbassr  r   s       r   r   NoChord.bass	  r  r   c                    g r   r   r   s    r   r   NoChord._parseFigure	  s    r   r  c               >    U(       d  [         R                  " U 5      $ g)z
Overrides :meth:`~music21.chord.Chord.transpose` to do nothing.

>>> nc = harmony.NoChord()
>>> nc.figure
'N.C.'
>>> nc.transpose(8, inPlace=True)
>>> nc.figure
'N.C.'
N)copydeepcopy)r   _valuer  s      r   r  NoChord.transpose	  s     ==&&r   )r   )NnoneN)r   r   rm  r   rl  r   r   )r   r   r   z
NCT | None)r   r   r   r   r   r   r   r   r   r  r   r   r   s   @r   r   r   v	  sh    =@   	
-
- 
- 	
- 
-   16  r   c                P   U R                  5       nUR                  [        5      R                  5       nSnSn[	        U5      S:  a  U H  nU(       a  SnUnM  UR                  U5      UR                  U5      -
  nXdR                  l        UR                  U5      [	        U5      S-
  :X  a-  UR                  UR                  U5      -
  UR                  l        UnM     U$ [	        U5      S:X  a5  UR                  UR                  US   5      -
  US   R                  l        U$ U $ )a	  
Returns music21 stream with duration attribute of chord symbols correctly
set. Duration of chord symbols is based on the surrounding chord symbols;
The chord symbol continues duration until another chord symbol is located
or the piece ends.

>>> s = stream.Score()
>>> s.append(harmony.ChordSymbol('C'))
>>> s.repeatAppend(note.Note('C'), 4)
>>> s.append(harmony.ChordSymbol('C'))
>>> s.repeatAppend(note.Note('C'), 4)
>>> s = s.makeMeasures()

>>> harmony.realizeChordSymbolDurations(s).show('text')
{0.0} <music21.clef.BassClef>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.harmony.ChordSymbol C>
{0.0} <music21.note.Note C>
{1.0} <music21.note.Note C>
{2.0} <music21.note.Note C>
{3.0} <music21.note.Note C>
{4.0} <music21.harmony.ChordSymbol C>
{4.0} <music21.note.Note C>
{5.0} <music21.note.Note C>
{6.0} <music21.note.Note C>
{7.0} <music21.note.Note C>
{8.0} <music21.bar.Barline type=final>

If only one chord symbol object is present:

>>> s = stream.Score()
>>> s.append(harmony.ChordSymbol('C'))
>>> s.repeatAppend(note.Note('C'), 4)
>>> s = s.makeMeasures()
>>> harmony.realizeChordSymbolDurations(s).show('text')
{0.0} <music21.clef.BassClef>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.harmony.ChordSymbol C>
{0.0} <music21.note.Note C>
{1.0} <music21.note.Note C>
{2.0} <music21.note.Note C>
{3.0} <music21.note.Note C>
{4.0} <music21.bar.Barline type=final>

If a ChordSymbol object exists followed by many notes, duration represents
all those notes (how else can the computer know to end the chord? if
there's no chord following it other than end the chord at the end of the
piece?).

>>> s = stream.Score()
>>> s.repeatAppend(note.Note('C'), 4)
>>> s.append(harmony.ChordSymbol('C'))
>>> s.repeatAppend(note.Note('C'), 8)
>>> s = s.makeMeasures()
>>> harmony.realizeChordSymbolDurations(s).show('text')
{0.0} <music21.clef.BassClef>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.note.Note C>
{1.0} <music21.note.Note C>
{2.0} <music21.note.Note C>
{3.0} <music21.note.Note C>
{4.0} <music21.harmony.ChordSymbol C>
{4.0} <music21.note.Note C>
{5.0} <music21.note.Note C>
{6.0} <music21.note.Note C>
{7.0} <music21.note.Note C>
{8.0} <music21.note.Note C>
{9.0} <music21.note.Note C>
{10.0} <music21.note.Note C>
{11.0} <music21.note.Note C>
{12.0} <music21.bar.Barline type=final>
TNr   Fr   )
flattengetElementsByClassr   streamr=  elementOffsetr   r   r  highestTime)piecepf
onlyChordsfirst	lastChordrw  qlDiffs          r   realizeChordSymbolDurationsr0  	  s   R 
B&&{3::<JEI
:B	))"-0@0@0KK39""0##B'C
Oa,?@02AQAQRTAU0UBKK-	  		ZA	/1~~@P@PQ[\]Q^@_/_
1,	r   c                      \ rS rSrS rS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rSr g) TestiF
  c                B   SSK Jn  UR                  S5      nU R                  [	        U5      S5        U R                  [	        UR
                  5      S5        U R                  [	        UR                  5       5      S5        U R                  UR                  5       5        g )Nr   r   Cmz <music21.harmony.ChordSymbol Cm>zO(<music21.pitch.Pitch C3>, <music21.pitch.Pitch E-3>, <music21.pitch.Pitch G3>)C3)	r   r   r   assertEqualr   r   r   
assertTrueisConsonantr   r   rw  s      r   testChordAttributesTest.testChordAttributesH
  sv    #  &R"DE

O]	_ 	RWWY.()r   c                    SSK Jn  UR                  5       nUR                  SS5      nUR	                  U5        U R                  [        UR                  5      S5        g )Nr   r4  r"  r7  r   )r   r   r   r   r   r7  r=  r   )r   r   hhds       r   	testBasicTest.testBasicR
  sL    #OO**5!4	""2&Q556:r   c                    SSK Jn  UR                  5       nUR                  S5        UR	                  SSS9  UR                  SSS	9  S
Ul        SUl        SUl        U R                  [        U5      S5        g )Nr   r4  zE-zB-Tr   r6  Fr   I64r   r   z#<music21.harmony.ChordSymbol E-/B->)r   r   r   r   r   r   r   rn  ro  r7  reprr:  s      r   testChordKindSettingTest.testChordKindSettingY
  sh    #  "

%
Qu-b#HIr   c                j    [         R                  " S5      n[        U5      nU R                  US5        g )N)zc##5ze#5zg#5zC##dim)r   r  r|  r7  )r   cisisdimfigs      r   testDoubleSharpsEtcTest.testDoubleSharpsEtcd
  s+    ;;56(2h'r   c                    [        S5      nUR                  5       nU R                  UR                  S5        UR	                  5       nU R                  UR                  S5        g )NzCm/E-C4E-3)r   r   r7  nameWithOctaver   )r   dr   r  s       r   testChordSymbolSetsBassOctave"Test.testChordSymbolSetsBassOctavej
  sN     vvx,,d3FFH))51r   c                   [        SSSSS9nU R                  UR                  5       S5        U R                  UR                  SS9R                  S5        U R                  UR                  SS9R                  S5        U R                  UR                  SS9R                  UR                  SS9R                  5        g)	zI
Test that bass is preserved even when both bass and inversion are given
FzA-r   r   )r   r   r   rm  Fr  N)r   r7  r   r   r   r   
assertLessr   )r   explicitFm6s     r   $testHarmonyPreservesInversionAndBass)Test.testHarmonyPreservesInversionAndBassq
  s     "sQ..0!4))u)5::DA))u)5::C@((e(4;;#((e(4;;	=r   c                   SSK Jn  SSK Jn  [        S5      nUR	                  S5      nUR                  S5      nUR                  SU5        UR                  SU5        U R                  UR                  S5      U5        [        S5      nUR	                  S5      nSUR                  l
        UR                  S5      nUR                  U5        UR                  U5        U R                  UR                  S5      U5        g)zs
This tests a former bug in getContextByClass
because ChordSymbol used to have the same `.classSortOrder`
as Note.
r   noter'  Cr   r   N)r   r[  r'  r   NoteMeasurer/  assertIsgetContextByClassr   r   r   )r   r[  r'  rw  nr   s         r   testClassSortOrderHarmonyTest.testClassSortOrderHarmony|
  s     	!"IIcNNN1	A	Ba))-8"= IIcN#$

 NN1		a))-8"=r   c                   SSK Jn  UR                  5       nU R                  SUR                  5        U R                  SUR
                  5        U R                  SUR                  5        UR                  S5      nU R                  SUR                  5        U R                  SUR
                  5        U R                  SUR                  5        UR                  S5      nU R                  SUR                  5        U R                  SUR
                  5        U R                  SUR                  5        UR                  SS9nU R                  SUR                  5        U R                  SUR
                  5        U R                  SUR                  5        UR                  SS	9nU R                  SUR                  5        U R                  SUR
                  5        U R                  SUR                  5        UR                  SSS	9nU R                  SUR                  5        U R                  SUR
                  5        U R                  SUR                  5        UR                  S
SSS9nU R                  SUR
                  5        U R                  SUR                  5        U R                  [        U5      S5        U R                  S[        UR                  5      5        U R                  UR                  5       5        U R                  UR                  5       5        UR                  5         U R                  S[        UR                  5      5        g )Nr   r4  r#  r  NCr   )rm  zNo Chord)rl  r]  E)r   r   rm  z<music21.harmony.NoChord N.C.>)r   r   r   r7  rn  ro  r   r   r=  r   assertIsNoner   r   r   )r   r   ncs      r   testNoChordTest.testNoChord
  s|   #__.1+__T".r/ryy)__V$.1+__&_).1+__Z_0.R__5RYY/__T:_6.R__5ryy)__#Cf_=1+R"BCC

O,"'')$"'')$
C

O,r   c                   SSK Jn  U R                  [        5       nUR	                  S5        S S S 5        U R                  [        WR                  5      S5        U R                  [        5       nUR	                  S5        S S S 5        U R                  [        UR                  5      S5        g ! , (       d  f       N= f! , (       d  f       NE= f)Nr   r4  zH-7z0Chord H-7 does not begin with a valid root note.Garg7zvInvalid chord abbreviation 'arg7'; see music21.harmony.CHORD_TYPES for valid abbreviations or specify all alterations.)r   r   assertRaisesr  r   r7  r   	exception)r   r   contexts      r   testInvalidRootsTest.testInvalidRoots
  s    #z*g& + 	!!">	

 z*g( + 	!!":	
 +* +*s   B00C0
B>
Cc                    SSK Jn  [        R                  " S5      nUR	                  U5      nU R                  UR                  S5        g )Nr   r4  )zA#r]  rg  rU  )r   r   r   r  r~  r7  r   )r   r   r  rw  s       r   testInvalidSymbolTest.testInvalidSymbol
  s9    #KK()))!,$GHr   c                   [        S5      nU R                  UR                   Vs/ s H  o"R                  PM     sn/ SQ5        [        S5      nU R                  UR                   Vs/ s H  o"R                  PM     sn/ SQ5        [        S5      nU R                  UR                   Vs/ s H  o"R                  PM     sn/ SQ5        g s  snf s  snf s  snf )NzFFr+6)rT  GBzD-dadd6)DzF#r  rx  atristan)r  zB#zD#zF##)r   r7  r   r   )r   rw  r   s      r   testRegexEdgeCasesTest.testRegexEdgeCases
  s    !"**5*Q&&*57LM!"**5*Q&&*57LM$"**5*Q&&*57OP	 655s   C(C+Cc                   SSK Jn  SSKJn  [	        S U 5       5      nUR
                  R                  5       nU" U5      nUR                  U5      n[        UR                  5      n	[        U5      n
U R                  X8R                  5        U R                  X9R                  5        U R                  X:R                  5        UR                  nU	R                  nU
R                  nU[        ;   a	  [        U   nU[        ;   a	  [        U   nU[        ;   a	  [        U   nU R                  X5        U R                  X5        U R                  UR                  5       U	R                  5       5        U R                  UR                  5       U
R                  5       5        U R                  UR                  5       U	R                  5       5        U R                  UR                  5       U
R                  5       5        g)z
Run a series of tests on the given chord.

xmlString: an XML harmony object

figure: the equivalent figure representation

pitches: the list of pitches of the chord
r   
fromstringmusicxmlc              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r   r   .0r   s     r   	<genexpr>&Test.runTestOnChord.<locals>.<genexpr>
       81A   #%N)xml.etree.ElementTreer  r   r  r  xmlToM21MeasureParserxmlToChordSymbolr   r   r7  r   rn  rG  r   r   )r   	xmlStringr   r   ELr  MP	mxHarmonycs1cs2cs3kind1kind2kind3s                 r   runTestOnChordTest.runTestOnChord
  sr    	;$888,,.yM	!!),#**%&!++.++.++.M!!%(EM!!%(EM!!%(E&&SXXZ0SXXZ0SXXZ0SXXZ0r   c                4    SnSnSnU R                  XU5        g )Na   
          <harmony>
            <root>
              <root-step>A</root-step>
            </root>
            <kind text="7">dominant</kind>
            <inversion>3</inversion>
            <bass>
              <bass-step>G</bass-step>
            </bass>
          </harmony>
          zA7/G)G2A2C#3E3r  r   r  r   r   s       r   testChordWithBassTest.testChordWithBass  s%    	 +Iw7r   c                   SnSn[        U5      nU R                  UR                  [        S U 5       5      5        SnSn[        U5      nU R                  UR                  [        S U 5       5      5        Sn[        S U 5       5      nU R                  U[        S	5      R                  5        U R                  U[        S
5      R                  5        Sn[        S U 5       5      nU R                  U[        S5      R                  5        Sn[        S U 5       5      nU R                  U[        S5      R                  5        g )N)r  r  B2D#3F3zG+9c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  2Test.testChordFlatSharpInFigure.<locals>.<genexpr>*       *K7a5;;q>>7r  )r  r  r  r  A3zG9#5c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  r  /  r  r  )r  r6  r  G#3c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  r  2  r  r  AmM7Aminmaj7)A1C2E2r  c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  r  6  r  r  zAm#7)r  F2r  B-3c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  r  :  r  r  	Csusaddb7)r   r7  r   r  )r   r   r   rw  s       r   testChordFlatSharpInFigureTest.testChordFlatSharpInFigure%  s   1 U*K7*K%KL1 U*K7*K%KL+888+f"5"="=>+j"9"A"AB+888+f"5"="=>+888+k":"B"BCr   c                4    SnSnSnU R                  XU5        g)z
This tests a bug where the root and bass were wrongly parsed,
since the matched root and bass were globally removed from figure,
and not only where matched.
a#  
          <harmony>
            <root>
              <root-step>E</root-step>
            </root>
            <kind text="7">dominant</kind>
            <bass>
              <bass-step>E</bass-step>
              <bass-alter>-1</bass-alter>
            </bass>
          </harmony>
        zE7/E-)zE-2r  r  B3D4Nr  r  s       r   testRootBassParsingTest.testRootBassParsing=  s%    	 2Iw7r   c                4    SnSnSnU R                  XU5        g)z
This tests a bug where the chord modification (add 2) was placed at a
wrong octave, resulting in a D bass instead of the proper E.
a  
          <harmony>
            <root>
              <root-step>C</root-step>
            </root>
            <kind>major</kind>
            <bass>
              <bass-step>E</bass-step>
            </bass>
            <degree>
              <degree-value>2</degree-value>
              <degree-alter>0</degree-alter>
              <degree-type text="add">add</degree-type>
            </degree>
          </harmony>
           z	C/E add 2r  G3rM  r  Nr  r  s       r   testChordStepBassTest.testChordStepBassU  s%    	  *Iw7r   c                   SSK Jn  SSKJn  Sn[	        S U 5       5      nSnUR
                  R                  5       nU" U5      nUR                  U5      n[        UR                  5      n[        S5      n	U R                  X7R                  5        U R                  X8R                  5        U R                  X9R                  5        g)	z
This tests a bug where the bass addition was considered as the fifth
inversion in suspended chords. Now, this is considered as a non-valid
inversion, and the bass is simply added before the root.
r   r  r  )r  D3r  r  c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  #Test.testSusBass.<locals>.<genexpr>z  r  r  a  
          <harmony>
            <root>
              <root-step>D</root-step>
            </root>
            <kind text="sus">suspended-fourth</kind>
            <bass>
              <bass-step>G</bass-step>
            </bass>
          </harmony>
         zDsus/GN)r  r  r   r  r  r  r  r  r   r   r7  r   
r   r  r  r   r  r  r  r  r  r  s
             r   testSusBassTest.testSusBassp  s     	;$*888
	 ,,.yM	!!),#**%(#++.++.++.r   c                   SSK Jn  SSKJn  Sn[	        S U 5       5      nSnUR
                  R                  5       nU" U5      nUR                  U5      n[        UR                  5      n[        S5      n	U R                  X7R                  5        U R                  X8R                  5        U R                  X9R                  5        U R                  SUR                  5       R                  5        g )	Nr   r  r  )rN  r  r  rM  c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  *Test.testBassNotInChord.<locals>.<genexpr>  r  r  z
          <harmony>
            <root>
              <root-step>C</root-step>
            </root>
            <kind text="">major</kind>
            <bass>
              <bass-step>E-</bass-step>
            </bass>
          </harmony>
         zC/E-rN  )r  r  r   r  r  r  r  r  r   r   r7  r   r   rO  r  s
             r   testBassNotInChordTest.testBassNotInChord  s    :$+888
	 ,,.yM	!!),#**%&!++.++.++. 	
 9 9:r   c                   SSK Jn  SSKJn  Sn[	        S U 5       5      nSnUR
                  R                  5       nU" U5      nUR                  U5      n[        UR                  5      n[        S5      n	U R                  SUR                  5       R                  5        U R                  X7R                  5        U R                  X8R                  5        U R                  X9R                  5        g )	Nr   r  r  r  c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  $Test.testSus2Bass.<locals>.<genexpr>  r  r  a  
          <harmony>
            <root>
              <root-step>C</root-step>
            </root>
            <kind text="sus2">suspended-second</kind>
            <bass>
              <bass-step>E</bass-step>
            </bass>
          </harmony>
       zCsus2/Er  )r  r  r   r  r  r  r  r  r   r   r7  r   rO  r   r  s
             r   testSus2BassTest.testSus2Bass  s    :$*888
	 ,,.yM	!!),#**%)$sxxz889++.++.++.r   c                4    SnSnSnU R                  XU5        g)z%
This tests a bug in _adjustOctaves.
z
        <harmony >
            <root>
              <root-step>D</root-step>
            </root>
            <kind text="min9">minor-ninth</kind>
        </harmony>
           )D2r  r  r6  r  Dm9Nr  )r   r  r   r   s       r   	testNinthTest.testNinth  s%    
	 1Iw7r   c                   SSK Jn  SSKJn  SnSn[	        S U 5       5      nUR
                  R                  5       nU" U5      nUR                  U5      n[        S5      nU R                  SUR                  5       5        U R                  SUR                  5       5        S	n[	        S
 U 5       5      nU R                  UR                  U5        U R                  UR                  U5        U R                  UR                  5       UR                  5       5        U R                  UR                  5       UR                  5       5        g )Nr   r  r  z
        <harmony>
          <root>
            <root-step>C</root-step>
          </root>
          <kind>major</kind>
          <inversion>1</inversion>
        </harmony>
        )r  r  r6  c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  %Test.testInversion.<locals>.<genexpr>  r  r  zC/Er   )r  r  rM  c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  r    r  r  )r  r  r   r  r  r  r  r  r   r7  r   r   r   r   )	r   r  r  r  r   r  r  r  r  s	            r   testInversionTest.testInversion  s    :$	 %888,,.yM	!!),% CMMO,CMMO,$888g.g.SXXZ0SXXZ0r   c                    [        SSS9nU R                  SUR                  5       5        U R                  S[        UR	                  5       5      5        U R                  S[        UR                  5       5      5        g )Nr]  rg  r   r   rM  r  )r   r7  r   r   r   r   )r   rw  s     r   testChordWithoutKindTest.testChordWithoutKind	  sX    c,BLLN+s2779~.s2779~.r   c                l   SnSnSnU R                  XU5        SnU R                  XU5        SnU R                  XU5        SnSnSnU R                  XU5        S	nU R                  XU5        [        S
5      nU R                  S[        UR                  5      5        SnSnSnU R                  XU5        g )Na1  
          <harmony>
            <root>
              <root-step>G</root-step>
            </root>
            <kind text="7alt">dominant</kind>
            <degree>
              <degree-value>5</degree-value>
              <degree-alter>0</degree-alter>
              <degree-type>subtract</degree-type>
            </degree>
            <degree>
              <degree-value>9</degree-value>
              <degree-alter>-1</degree-alter>
              <degree-type>add</degree-type>
            </degree>
            <degree>
              <degree-value>9</degree-value>
              <degree-alter>1</degree-alter>
              <degree-type>add</degree-type>
            </degree>
            <degree>
              <degree-value>11</degree-value>
              <degree-alter>1</degree-alter>
              <degree-type>add</degree-type>
            </degree>
            <degree>
              <degree-value>13</degree-value>
              <degree-alter>-1</degree-alter>
              <degree-type>add</degree-type>
            </degree>
          </harmony>
        z+G7 subtract 5 add b9 add #9 add #11 add b13)r  r  r  zA-3zA#3zC#4zE-4z&G7 subtract5 addb9 add#9 add#11 addb13z!G7subtract5addb9add#9add#11addb13ab  
            <harmony>
            <root>
              <root-step>C</root-step>
            </root>
            <kind text="7b9">dominant</kind>
            <degree>
              <degree-value>9</degree-value>
              <degree-alter>-1</degree-alter>
              <degree-type>add</degree-type>
            </degree>
          </harmony>
        zC7 b9)r6  r  r  r  zD-4z	C7 add b9zA7 alter #5zj(<music21.pitch.Pitch A2>, <music21.pitch.Pitch C#3>, <music21.pitch.Pitch E#3>, <music21.pitch.Pitch G3>)a  
          <harmony>
            <root>
              <root-step>A</root-step>
              </root>
            <kind>dominant</kind>
            <degree>
              <degree-value>5</degree-value>
              <degree-alter>1</degree-alter>
              <degree-type>alter</degree-type>
              </degree>
            <degree>
              <degree-value>9</degree-value>
              <degree-alter>1</degree-alter>
              <degree-type>add</degree-type>
              </degree>
            <degree>
              <degree-value>11</degree-value>
              <degree-alter>1</degree-alter>
              <degree-type>add</degree-type>
              </degree>
            </harmony>
        zA7 alter #5 add #9 add #11)r  r  zE#3r  zB#3zD#4)r  r   r7  r   r   )r   r  r   r   rw  s        r   testChordStepFromFigureTest.testChordStepFromFigure  s     	B ?@Iw79Iw74Iw7	 2Iw7Iw7 ' 569"**o	G	. .:Iw7r   c                |    [        S5      n[        S5      nU R                  UR                  UR                  5        g )NzF7 add 4 subtract 3F7sus4r   r7  r   r   ch1ch2s      r   testExpressSusUsingAlterations#Test.testExpressSusUsingAlterationsx  s/    /0(#ckk2r   c                |    [        S5      n[        S5      nU R                  UR                  UR                  5        g )NzCo omit5z
Cdim omit5r  r  s      r   testDoubledCharactersTest.testDoubledCharacters~  s.    *%,'ckk2r   c                X    Sn[        S U 5       5      nSnSnU R                  X#U5        g)z)
power chords should not have inversions
)r  r  r  c              3  N   #    U  H  n[         R                  " U5      v   M     g 7fr   r  r  s     r   r  #Test.x_testPower.<locals>.<genexpr>  r  r  z
          <harmony>
            <root>
              <root-step>A</root-step>
            </root>
            <kind text="5">power</kind>
            <bass>
              <bass-step>E</bass-step>
            </bass>
          </harmony>
        zApower/EN)r  r  )r   r   r  r   s       r   x_testPowerTest.x_testPower  s7     %888
	 Iw7r   c                   SSK Jn  SSK Jn  UR                  5       n[	        S5      nUR                  SUR                  SS95        UR                  SU5        [        U5        U R                  UR                  S5        g	)
z
Test an edge case where a Stream contains only one ChordSymbol
at the highest offset: should still have a nonzero duration
if there is a subsequent highest time.
r   rZ  r\  A7whole)typeg      ?g      @N)
r   r[  r'  r_  r   r/  r^  r0  r7  r   )r   r[  r'  r   rw  s        r   testSingleChordSymbolTest.testSingleChordSymbol  se     	!"NN	DII7I+,	b#A&))3/r   c                ~    [         R                  " S5      n[        USS9nU R                  UR                  U45        g )Nr6  F)r   r   )r   r   r   r7  r   )r   	bass_noter>  s      r   testUpdatePitchesFalseTest.testUpdatePitchesFalse  s2    KK%	%8YL1r   r   N)!r   r   r   r   r;  r@  rE  rJ  rQ  rW  rc  rj  rq  rt  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r   r2  r2  F
  s    *;	J(2	=>4*-X
*IQ*1X8&D08086!/F ;D/@8$ 1D/e8N338,0 2r   r2  c                  &    \ rS rSrS rS rS rSrg)TestExternali  c                    SSK Jn  SSK Jn  SSK Jn  UR	                  S5      nUR                  U5      nUR                  5       R                  UR                  5      nUR                  5       nU H  nSUl
        UR                  U5        M     g )Nr   r4  corpusr\  zleadSheet/fosterBrownHair.xmlF)r   r   r  r'  parser0  r%  r&  r   Streamr   r   )r   r   r  r'  testFilechordSymbolsrr  cSs           r   testReadInXMLTestExternal.testReadInXML  sr    #""<< ?@ 66x@'')<<W=P=PQMMOB#BOHHRL r   c                   SSK Jn  SSK Jn  SSK Jn  SSK Jn  UR                  S5      nUR                  U5      nUR                  5       R                  UR                  5      nUR                  5       nU H&  nSUl        UR                  UR                  U5        M(     UR                  SSS9  UR                  UR!                  S	S
95        UR                  5       R                  ["        R$                  5      n	g )Nr   r4  r  rZ  r\  z+demos/ComprehensiveChordSymbolsTestFile.xmlT)fillGapsr  r7  )r   )r   r   r  r[  r'  r  r0  r%  r&  r   r  r   r/  offset	makeRestsr   Restr   r  )
r   r   r  r[  r'  r  chordsrr  rt  unused_csChordss
             r   testChordRealization!TestExternal.testChordRealization  s    #" " << MN66x@!!#66w7J7JKMMOAAOHHQXXq!  	
T40	+,))+88Er   c                    / SQn/ SQnU HG  nU H>  n[         R                  5        H#  u  pVUS    H  nX4-   U-   n[        U5        M     M%     M@     MI     g )N)r  rx  r]  rz  rg  rT  rw  )r   r  rF  r   )r)  itemsr   )	r   notesmodrb  r   
unused_keyr   harmony_typesymbols	            r   testALLChordKindsTestExternal.testALLChordKinds  sW    3A'2'8'8':OJ(+A!"!5#F+ )/ (;  r   r   N)r   r   r   r   r  r  r  r   r   r   r   r  r    s    (F@	,r   r  __main__)F)r`  chord.Chord)r`  r   r   r   ):r   
__future__r   collectionsr  r  unittesttypingtr   r   r   r   r   r   r	   r
   r   r   r   r   EnvironmentenvironLocalTypeVarr   r   TYPE_CHECKINGr  r   OrderedDictr)  rG  r   r   r  r   r   ProtoM21Objectr   r-  r2  r|  r~  rZ  r  r[  r  r  __annotations__r   r   r0  TestCaser2  r  
_DOC_ORDERr   mainTestr   r   r   <module>r0     s   #   	              &&y1IIc'iiY'??1 %% >'w()*>'x#u&'>' 8c5\*+>' Is|,-	>' *sFo67>' y64.12>' Z)BCD>' {T6N34>' eY-? @A>' ;(<=>>' v ?@>' MD&>:;>' ;56>'" Y&'#>'$ Z$01%>'* [4.12+>', sFm45->'. <%);<=/>'0 ]T6N341>'2 |eY-?@A3>'4  -1F!GH5>'6 ~w787>'8 #_vh$?@9>': /D&>:;;>'<  05'2BCD=>'B w89C>'D NUG$456E>'F /FJ+?@AG>'H $ug&678I>'J o
/CDEK>'L (5'*:;<M>'N /&:;O>'P +eW-=>?Q>'V %w'789W>'X )D'?;<Y>'Z ,vz.BCD[>'\ '%)9:;]>'^ 06:2FGH_>'` !4ug6F GHa>'b 2VH=>c>'h 'F8,-i>'j 'E6?34k>'l  *vw.?!@Am>'n K$()o>'p VTN+,q>'r fd^,-s>'t vuo./u>'v sWIw>'x uwi !y>'z 	{+,{>' >D 0 5$=	|44 	
Y+ekk Y+~	\%B%B 	{=G22 {=BF@2&qh"	%	;	% MO I N
Y' Yxek eT`Lh	28 h	2V?,8$$ ?,z 1;@UV
 zT r   