
    3j.{                       U d Z ddlmZ ddlZddlmZ ddlZddlZddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ  ej&                  d      Zd Z G d dej,                        Z G d d      Z G d dej2                        Z G d dej2                        Zg Zded<   edk(  rddlZ ej>                  e       yy)zK
Automatically reduce a MeasureStack to a single chord or group of chords.
    )annotationsN)Sequence)chord)DocOrder)exceptions21)environment)meter)note)pitch)stream)treereduceChordsc                    t        j                         } t        j                  d      }t	        j
                  d      }d|_        t	        j
                  d      }t	        j
                  d      }||||fD ]  }| j                  |        | S )a5  
    returns a simple measure stream for testing:

    >>> s = analysis.reduceChords.testMeasureStream1()
    >>> s.show('text')
    {0.0} <music21.meter.TimeSignature 4/4>
    {0.0} <music21.chord.Chord C4 E4 G4 C5>
    {2.0} <music21.chord.Chord C4 E4 F4 B4>
    {3.0} <music21.chord.Chord C4 E4 G4 C5>
    z4/4C4 E4 G4 C5       @C4 E4 F4 B4)r   Measurer	   TimeSignaturer   ChordquarterLengthappend)measuretimeSignaturechord1chord2chord3elements         J/DATA/.local/lib/python3.12/site-packages/music21/analysis/reduceChords.pytestMeasureStream1r   $   sv     nnG''.M[['FF[['F[['F!666:w ;N    c                      e Zd Zy)ChordReducerExceptionN)__name__
__module____qualname__ r    r   r"   r"   <   s    r    r"   c                      e Zd ZdZd Z	 	 	 	 ddZed        Zedd       Zd Z	d Z
d	 Z	 dd
Zd Zd Zd Zd Zd Zd Zd Z	 	 	 ddZd ZddZ	 	 	 ddZd Zd Zy)ChordReducerz
    A chord reducer.
    c                P    | j                   | _        d| _        d | _        d | _        y )N   )qlbsmpConsonanceweightAlgorithm	maxChordspositionInMeasurenumberOfElementsInMeasure)selfs    r   __init__zChordReducer.__init__C   s'    #44!%)-&r    Nc                &   t        |t        j                        st        d      |]t	        d |D              st        d      g }|D ].  }| j                  |j                        }|j                  |       0 t        |      }|]t	        d |D              st        d      g }|D ].  }| j                  |j                        }|j                  |       0 t        |      }t        j                  j                  |dt        j                  t        j                  f      }	| j!                  |	       | j#                  |	       | j%                  |	||       |	j'                         }
| j)                  |	|
       | j+                  |	|
d	
       | j)                  |	|
       | j-                  |	|
       | j+                  |	|
d
       | j)                  |	|
       | j-                  |	|
       t        j                         }dd l}|j1                         5  |j3                  dt4        j6                         t        j8                  j;                  |	|      }d d d        t        j<                         }j?                  t        j@                        D ]2  }| jC                  ||| jD                  d      }|j                  |       4 |j                  |       |r+|t        j                     D ]  }|jG                  dd        |S # 1 sw Y   xY w)Nz Must be called on a stream.Scorec              3  P   K   | ]  }t        |t        j                           y wN
isinstancer   r   .0xs     r   	<genexpr>z#ChordReducer.run.<locals>.<genexpr>S        K?az!U[[1?   $&z"All allowableChords must be Chordsc              3  P   K   | ]  }t        |t        j                           y wr4   r5   r7   s     r   r:   z#ChordReducer.run.<locals>.<genexpr>\   r;   r<   z"All forbiddenChords must be ChordsT)flatten	classList)	scoreTreeallowableChordsforbiddenChords      ?)duration      ?r   ignore)category)templateStream      ?)maximumNumberOfChordsr,   	trimBelow   )forceOctaveinPlace)$r6   r   Scorer"   all_getIntervalClassSetpitchesr   	frozensetr   
fromStreamasTimespansr
   Noter   r   removeZeroDurationTimespanssplitByBassremoveVerticalDissonancestoPartwiseTimespanTreesfillBassGapsremoveShortTimespansfillMeasureGapswarningscatch_warningssimplefilterr   Music21DeprecationWarningtoStream
chordifiedPartgetElementsByClassr   reduceMeasureToNChordsr+   closedPosition)r0   
inputScorerA   rg   rB   rJ   intervalClassSetsr9   intervalClassSetr@   partwiseTrees	reductionr^   chordifiedReductionchordifiedPartr   reducedMeasures                    r   runzChordReducer.runI   s    *fll3'(JKK&K?KK+,PQQ "$#'#<#<QYY#G !(()9: % ((9:O&K?KK+,PQQ "$#'#<#<QYY#G !(()9: % ((9:OOO//yy%++. 0 0	
 	((3#&&7F7F 	' 	H "99;)]3!!)]S!I)]3Y6!!)]S!I)]3Y6LLN	 	$$&!!(\5[5[!\"&--":":) #; # '  *==fnnMG!88&; $ 5 5	 9 N !!.1 N 	(u{{+  Q = , + '&s   ALLc                    | j                         j                         D ]X  \  }}t        |       |D ]  }t        d|        |j                         }|dk\  s:t        |       t	        j
                  d       y )N	   zmaximumOverlap is exceeded)rZ   itemsprintmaximumOverlapr   Music21Exception)r@   partsubtreetimespanoverlaps        r   _debugzChordReducer._debug   sp    &>>@FFHMD'$K#dH% $,,.G!|d"330  Ir    c                   t               }g }| D ]R  }t        |t        j                        r|j	                  |       /|j	                  t        j                  |             T t        |      D ]]  \  }}||dz   d D ]M  }t        t        |j                  |j                  z
              }|dz  }|dk\  rd|z
  }|j                  |       O _ d|v r|j                  d       t        |      S )z
        Return a frozenset of all the interval classes (1-6) in the given
        Sequence (list, tuple, etc.) of pitches or
        things like strings/ints that can be passed to the Pitch constructor.
        rs   N      r   )setr6   r   Pitchr   	enumerateintabspsaddremoverS   )
pitches_inresultrR   pir9   yinterval_ints           r   rQ   z!ChordReducer._getIntervalClassSet   s     5%'A!U[[)q!u{{1~.	  g&DAqQUV_"3qttadd{#34"1$#%#4L

<( % ' ;MM!  r    c              #  P  K   t        j                         }t        j                  t        j
                  t        j                  f}|j                         D ]L  }t        ||      s|j                  |       t        |      dk(  s0t        |       |j                          N y w)N   )collectionsdequer   r   r
   rV   Restr>   r6   r   lentuplepopleft)r0   inputStreamelementBuffer	prototyper   s        r   _iterateElementsPairwisez%ChordReducer._iterateElementsPairwise   s     #))+KKIIII
	
 #**,Ggy1  )=!Q&M**%%' -s   BB& B&c                   |j                  d      D ]Z  }|\  }}|j                  }|j                  }|j                  r|j                  s:|j                  |j                  k7  rT|j                  |j                  k(  rn|j	                  |      ra|j
                  D ]Q  }|j                  |       |j                  |j                        }|j                  |_	        |j                  |       S |j	                  |      s|j
                  D ]Z  }|j                  |j                  k  s|j                  |       |j                  |j                        }|j                  |       \ ] y)z9
        Aligns hockets between parts in `tree`.
        r   noffsetendTimeN)iterateVerticalitiesNwisepitchSetisConsonantmeasureNumberissubsetstartTimespansremoveTimespannewr   beatStrengthinsertr   )	r0   r@   verticalitiesverticalityOneverticalityTwopitchSetOnepitchSetTworz   newTimespans	            r   alignHocketszChordReducer.alignHockets   sT    '@@1@EM-:*NN(11K(11K"..)55++~/K/KK&&.*A*AA##K0 . = =H,,X6"*,,-44 #/ #K 0>/J/JK,$$[1 !> %%k2 . = =H''.*?*??!00:&.ll$2$9$9 '3 ' "((5 !>) Fr    c                   |j                  d      D ]i  }|\  }}|j                  r|j                  s"t        |j                        }t        |j                        }|d   j                  |d   j                  k7  rl|j                  |j                  k7  r|j                  |      }|j                         D ]  \  }}	t        |	      dk  rt        d |	D              s(|	d   j                  |	d   j                  k(  rH|	d   j                  |	d   j                  z   }
t        j                  |
      }|j                  |	       |	d   j                  ||	d   j                        }|j                  |        l y)a  
        Collapses arpeggios in `tree`.

        >>> m = stream.Measure([chord.Chord('C4 E4'), chord.Chord('C4 G4')])
        >>> cr = analysis.reduceChords.ChordReducer()
        >>> spans = m.asTimespans(classList=(note.NotRest,))
        >>> len(spans)
        2
        >>> cr.collapseArpeggios(spans)
        >>> len(spans)
        1

        OMIT_FROM_DOCS

        Ensure it doesn't crash without a class filter:

        >>> s = corpus.parse('beach')
        >>> cr2 = analysis.reduceChords.ChordReducer()
        >>> excerpt_tree = s.parts.first().asTimespans()
        >>> cr2.collapseArpeggios(excerpt_tree)
        >>> excerpt_tree
        <TimespanTree {163} (0.0 to 124.0) <music21.stream.Part Soprano I>>
        r   r   r   c              3  d   K   | ](  }t        |t        j                  j                         * y wr4   )r6   r   spansPitchedTimespanr7   s     r   r:   z1ChordReducer.collapseArpeggios.<locals>.<genexpr>*  s$     ]P\1Z4::+E+EFP\s   .0rs   )r   r   N)r   r   sortednameWithOctaver   unwrapVerticalitiesrt   r   rP   rR   r   r   removeTimespanListr   r   r   )r0   r@   r   onetwo
onePitches
twoPitcheshorizontalitiesunused_parttimespanListbothPitchessumChordmergeds                r   collapseArpeggioszChordReducer.collapseArpeggios   sg   0 '@@1@EM$HC<<s||-J-J!}++z!}/K/KK""c&7&77$ (;;MJO-<-B-B-D)\|$q(]P\]]!!_,,Q0G0GG*1o55Q8O8OO ;;{3,,\:%a,,$(O33 -    ( .E9 Fr    c                @   || j                   }i }d| _        t        |      | _        t	        |      D ]U  \  }}|| _        t        |j                  D ch c]  }|j                   c}      }||vrd||<   ||xx    ||      z  cc<   W d| _        d| _        |S c c}w )a  
        Compute measure chord weights:

        >>> s = analysis.reduceChords.testMeasureStream1().notes
        >>> cr = analysis.reduceChords.ChordReducer()
        >>> cws = cr.computeMeasureChordWeights(s)
        >>> for pcs in sorted(cws):
        ...     print(f'{pcs!r:18}  {cws[pcs]:2.1f}')
            (0, 4, 7)  3.0
        (0, 11, 4, 5)  1.0

        Add beatStrength:

        >>> cws = cr.computeMeasureChordWeights(s,
        ...     weightAlgorithm=cr.quarterLengthBeatStrength)
        >>> for pcs in sorted(cws):
        ...     print(f'{pcs!r:18}  {cws[pcs]:2.1f}')
            (0, 4, 7)  2.2
        (0, 11, 4, 5)  0.5

        Give extra weight to the last element in a measure:

        >>> cws = cr.computeMeasureChordWeights(s,
        ...     weightAlgorithm=cr.quarterLengthBeatStrengthMeasurePosition)
        >>> for pcs in sorted(cws):
        ...     print(f'{pcs!r:18}  {cws[pcs]:2.1f}')
            (0, 4, 7)  3.0
        (0, 11, 4, 5)  0.5

        Make consonance count a lot:

        >>> cws = cr.computeMeasureChordWeights(s,
        ...     weightAlgorithm=cr.qlbsmpConsonance)
        >>> for pcs in sorted(cws):
        ...     print(f'{pcs!r:18}  {cws[pcs]:2.1f}')
             (0, 4, 7)  3.0
         (0, 11, 4, 5)  0.1
        r           )quarterLengthOnlyr.   r   r/   r   r   rR   
pitchClass)r0   measureObjectr,   
presentPCsr   cr9   r   s           r   computeMeasureChordWeightsz'ChordReducer.computeMeasureChordWeights7  s    V ""44O
!"),]);&m,DAq%&D"QYY7Yq||Y78A
" #
1qM_Q//M - "#)*& 8s   B
c                *   fd}|j                         D ]  \  }}t        |      }t        j                  ||      D ]  \  }}t        |      }	||j                  |	d   j                  k  rD|j
                  j                  }
|j                  }j                  |	d         }||j                  |	d   j                  kD  rodt        |j                        z   dz   t        |	d   j                        z   dz   t        |      z   dz   t        |	      z   dz   t        |	d         z   }t        |       t        ||j                        }j                  |	d          |j                  |	d          |	d   j                  |      }|
|_        j                  |       |j                  |       ||	d<   |	d	   j                  |j                  k  rp|j                  }j                  |	d	          |j                  |	d	          |	d	   j                  |
      }j                  |       |j                  |       ||	d	<   t!        t#        |	      dz
        D ]  }|	|   |	|dz      }}|j$                  |j$                  k(  s|j                  |j                  k7  sC|j                  |j                  
      }||	|<   ||	|dz   <   j'                  ||f       |j'                  ||f       j                  |       |j                  |          y )Nc                R    j                  | j                        }|j                  S r4   )getVerticalityAtr   bassTimespan)rz   verticalityr@   s     r   	procedurez,ChordReducer.fillBassGaps.<locals>.procedurer  s#    #44X__EK+++r    r   z2Timespan offset errors: previousTimespan.endTime, z should be before z previousTimespan: z	 groups: z group[0]: r   r   rs   )rt   list	itertoolsgroupbyr   r   r   .findPreviousPitchedTimespanInSameStreamByClassr   strreprru   maxr   r   r   ranger   rR   r   )r0   r@   rk   r   r   ry   r   r   group_generatorgroupr   r   previousTimespanmsgr   r   r   timespanOnetimespanTwos    `                 r   r[   zChordReducer.fillBassGapsq  s   	, %2$7$7$9 K=L1:1B1B<QZ1[-o_-'&&q8#/#7#7#D#DL)00F'0'_'_a($ (3+33eAhooE T"%&6&>&>"?!@"6!79<U1X__9M!N #8!8 ;??O:P!Q #.	!. 15U	!<
 #0!0
 37uQx.!A   "#J!$V-=-E-E!F,,U1X6**584"'(,,f,"=K/;K,$$[1NN;/*E!H9$$|';';;*22G,,U2Y7**595"')-- ' #0 #K $$[1NN;/ +E"Is5zA~.A/4Qxq1uK#++{/B/BB*22k6H6HH&1ook>Q>Qo&R#.a'2a!e!44k;5OP22K3MN!((5{3 /[ 2\ %:r    c                   |j                         D ]2  \  }}t               }t               }t        j                  |d       D ]  \  }}t	        |      }	t        t        |	      dz
        D ]  }
|	|
   |	|
dz      }}|j                  |j                  k(  s|j                  |j                  k7  sC|j                  |j                        }||	|
<   ||	|
dz   <   |j                  |       |j                  |       |j                  |        |	d   j                  |	d   j                  k7  rS|	d   j                  |	d   j                        }d|_        |j                  |	d          |j                  |       ||	d<   |	d   j                  |	d   j                  k7  s]|	d   j                  |	d   j                        }|j                  |	d          |j                  |       ||	d<    |j                  |       |j!                  |       |j#                  |       |j!                  |       |j#                  |       5 y)	z/
        Fills measure gaps in `tree`.
        c                    | j                   S r4   )r   )r9   s    r   <lambda>z.ChordReducer.fillMeasureGaps.<locals>.<lambda>  s    1??r    rs   r   r   r   rE   r   N)rt   r   r   r   r   r   r   rR   r   r   r   r   parentOffsetr   parentEndTimedifference_updater   r   )r0   r@   rk   r   ry   toRemovetoInsertunused_measureNumberr   r   r   r   r   r   s                 r   r]   zChordReducer.fillMeasureGaps  s    %2$7$7$9 KuHuH9B9J9J2:5$o _-s5zA~.A/4Qxq1uK#++{/B/BB*22k6H6HH&1ook>Q>Qo&R#.a'2a!e [1 [1 [1 / 8??eAh&;&;;"'(,,eAh6K6K,"LK/2K,LLq*LL-*E!H9$$b	(?(??"')-- %b	 7 7 #0 #K LLr+LL- +E"I7:< &&x0X&((2NN8$&&x0K %:r    c                B   d }|j                         }||   }t        |      }t        j                  ||      D ]c  \  }}t        |      }t	        |      dk(  r |j                  |       |d   j                  |d   j                        }	|j                  |	       e y )Nc                :    | j                   }| j                  }||fS r4   )r   rR   )rz   r   rR   s      r   r   z3ChordReducer.fuseTimespansByPart.<locals>.procedure  s#    $22M&&G '))r    rs   r   r   r   )	rZ   r   r   r   r   r   r   r   r   )
r0   r@   rx   r   mappingry   r   
unused_keyr   r   s
             r   fuseTimespansByPartz ChordReducer.fuseTimespansByPart  s    	*
 335$-G}!*!2!2<!KJKE5zQ((/(,,b	)) ' K [) "Lr    c                    |j                         rdnd}| j                  | j                  dz
  k(  r|j                  }n| j	                  |      }||z  }|S )z8
        Everything from before plus consonance
        rE   g?rs   )r   r.   r/   r   (quarterLengthBeatStrengthMeasurePosition)r0   chordObjectconsonanceScoreweights       r   r+   zChordReducer.qlbsmpConsonance  sY     "-!8!8!:#!!T%C%Ca%GG ..FBB;OF/!r    c                8    |j                   |j                  z  }|S r4   )r   r   )r0   r   r   s      r   quarterLengthBeatStrengthz&ChordReducer.quarterLengthBeatStrength  s    **[-E-EEr    c                t    | j                   | j                  dz
  k(  r|j                  S | j                  |      S )Nrs   )r.   r/   r   r   r0   r   s     r   r   z5ChordReducer.quarterLengthBeatStrengthMeasurePosition  s8    !!T%C%Ca%GG,,,11+>>r    c                    |j                   S r4   )r   r   s     r   r   zChordReducer.quarterLengthOnly  s    (((r    c                    | j                  |j                         j                  |      }t        |t	        |            }t        ||j                  d      }|d| }|s[t        j                         }|j                  j                  |_
        |D ]  }	|j                  |	        |j                  d|       |S ||d      }
g }|D ]   }||   |
|z  k\  r|j                  |         n d}d}d}|j                  t        j                        D ]  }	t!        |	j"                  D ch c]  }|j$                   c}      }||v r||k7  r}|#|	j&                  dk7  r|	j&                  }d|	_        n|	||_
        d}|	}|	D ]4  }|j(                  j*                  d|j(                  j*                  _        6 |}||	j                  z  }||	j                  z  }|j                  |	        |||_
        t/        dt	        |            D ]r  }||   }	|	j&                  }|t1        |      z
  }t3        |d      dv s1||dz
     }|xj                  |z  c_
        t1        |      |	_        |	xj                  |z  c_
        t |S c c}w )	ae  
        Reduces measure to `n` chords:

        >>> s = analysis.reduceChords.testMeasureStream1()
        >>> cr = analysis.reduceChords.ChordReducer()

        Reduce to a maximum of 3 chords; though here we will only get one
        because the other chord is below the trimBelow threshold.

        >>> newS = cr.reduceMeasureToNChords(s, 3,
        ...     weightAlgorithm=cr.qlbsmpConsonance,
        ...     trimBelow=0.3)
        >>> newS.show('text')
        {0.0} <music21.meter.TimeSignature 4/4>
        {0.0} <music21.chord.Chord C4 E4 G4 C5>

        >>> newS[-1].quarterLength
        4.0
        T)keyreverseNr   r   rs   r*   )rI   g      ?gZd;O?gT㥛 ?gX9v?)r   r>   notesminr   r   getr
   r   rD   r   r   r   r   re   NotRestr   rR   r   r   r   
accidentaldisplayStatusr   r   round)r0   r   rJ   r,   rK   chordWeightssortedChordWeights
maxNChordsrr   maxChordWeighttrimmedMaxChordspcTuplescurrentGreedyChordcurrentGreedyChordPCscurrentGreedyChordNewLengthr9   r   r   r   cOffsetCurrentcOffsetSyncoplastCs                          r   rf   z#ChordReducer.reduceMeasureToNChords
  s   > 66!!#))
 !$$93|;L M#  

 ((>)>?
		A+44BBAO"$$Q' #  A&  %jm4"HH%))CC ''1	 #
 " $&)#11$,,?AQYY7Yq||Y78A$$.C)C%-!((c/23((/"AH'37R&425/%&"Aww))5;?**8  )*%+q>++q>+$$Q'' @( )/J, q#m,-Aa AXXN*S-@@M]A&*MM%a!e,##}4#~.=0 . C 8s   $I;
c                   |j                  d      D ]  }|j                  |      }|j                         D ]  \  }}|j                  s|j                  s|d   j
                  |d   j
                  k7  r?|d   j                  |d   j                        }|j                  |d   |d   f       |j                  |         y)zV
        Removes timespans containing passing and neighbor tones from `tree`.
        r*   r   r   rs   r   N)
r   r   rt   hasPassingTonehasNeighborToner   r   r   r   r   )r0   r@   r   r   r   horizontalityr   s          r   removeNonChordTonesz ChordReducer.removeNonChordTonesi  s     '@@1@EM';;MJO.=.C.C.E*]%44 - = ="1%33}Q7G7U7UU&q)--mA6F6N6N-O,,mA.>a@P-QR  ( /F Fr    c                   fd}|j                         D ]k  \  }}g }t        j                  ||      D ]'  \  }}	|\  }
}}t        |	      }	|sd}|	d   j                  |	d   j
                  k(  r!|	d   j                  |	d   j                  k(  rd}|:|	d   j                  |j                  k(  r|	d   j                  |j                  k(  rd}|r|t        j                         }|	D ]#  }||j                  xx   |j                  z  cc<   % |j                         d   \  }}|	D ]#  }|j                  |k7  s|j                  |       % |j                  |	       * j                  |       |j                  |       n y)a  
        Removes timespans in `tree` shorter than `duration`.

        Special treatment is given to groups of short timespans if they take up
        an entire measure. In that case, the timespans with the most common
        sets of pitches are kept.
        c                    | j                   }| j                  k  }j                  | j                        }|j                  }||j                  k  rd }|||fS r4   )r   r   r   r   r   )rz   r   proc_isShortr   proc_bassTimespanrD   r@   s        r   r   z4ChordReducer.removeShortTimespans.<locals>.procedure  sf    $22M#11H<L#44X__EK + 8 8 ,$22X=(,% ,0AAAr    Fr   r   TN)rt   r   r   r   r   r   r   r   r   CounterrR   r   most_commonr   extendr   )r0   r@   rk   rD   r   r   ry   timespansToRemover   r   r   isShortr   isEntireMeasurecountergroup_timespanbestPitchesunused_totalDurations    ` `              r   r\   z!ChordReducer.removeShortTimespansy  s   	B %2$7$7$9 K "'//C
U>A;$g|U"'8??eAh&;&;;Ry((E!H,B,BB*.+Qx,*=*== 9,,0D0DD.2O")113G*/ 6 67>;W;WW7 +08?8K8K8Ma8P5K!5*/)11[@-44^D +0 &,,U3- D. (():;&&'895 %:r    c                v   |j                         D ]  }d}|j                  }| j                  |      }|r||v rd}|j                         j	                         rd}|r||v rd}|rU|j                  }t        |      }	|j                  D ],  }
t        |
j                        |	k7  s|j                  |
       .  y)z
        Removes timespans in each dissonant verticality of `tree` whose pitches
        are above the lowest pitch in that verticality.
        FTN)	iterateVerticalitiesr   rQ   toChordr   r   r   rR   r   )r0   r@   rA   rB   r   r   rR   rj   r   lowestPitchrz   s              r   rY   z&ChordReducer.removeVerticalDissonances  s     %99;KK!**G#88A#3#F"""$002"#3#F#"++Hh-K'66x''(K7,,X6 7# <r    c                n    |D cg c]  }|j                   dk(  s| }}|j                  |       y c c}w )Nr   )r   r   )r0   r@   r9   zeroDurationTimespanss       r   rW   z(ChordReducer.removeZeroDurationTimespans  s7    ,5 NIqA9MI N$$%:; !Os   22c                    |j                         }|D ]  }| j                  ||        |j                         }|d   }||   }|j                         }|j	                  |       y )Nr   )allPartsr   rZ   
allOffsetssplitAt)r0   r@   partsrx   r   bassPartbassTreebassOffsetss           r   rX   zChordReducer.splitByBass  sg    ""$D$$Y5 33598$))++&r    )NFNr*   )r   z!Sequence[pitch.Pitch | str | int]returnzfrozenset[int]r4   )rs   NrI   )rC   )NNN)r#   r$   r%   __doc__r1   rp   staticmethodr|   rQ   r   r   r   r   r[   r]   r   r+   r   r   r   rf   r  r\   rY   rW   rX   r&   r    r   r(   r(   ?   s    . !  "#Od 
 
 ! !4( 6@B)N 8t>4@)1V*(?)  ]~) ,:` 	7><'r    r(   c                      e Zd Zd Zy)Testc                    t        j                         }t        j                  d      }d|_        t        j                  d      }t        j                  d      }|||fD ]  }|j                  |        y )Nr   r   r   )r   r   r   r   r   r   )r0   sc1c2c3r   s         r   testSimpleMeasurezTest.testSimpleMeasure  s[    NN[['[['[['b"AHHQK r    N)r#   r$   r%   r<  r&   r    r   r6  r6    s    r    r6  c                      e Zd ZdZd Zy)TestExternalTc                &   ddl m} |j                  d      j                  dd      }t	               }|j                  |t        j                  d      fdd d	      }|D ]  }|j                  d|        | j                  r|j                          y y )
Nr   )corpuszPMFC_06_Giovanni-05_Donnars   
   z	F#4 A4 C5Tr*   )rA   rg   rB   rJ   )
music21r@  parsemeasuresr(   rp   r   r   r   show)r0   r@  scorechordReducerrl   rx   s         r   testTrecentoMadrigalz!TestExternal.testTrecentoMadrigal  s    "89BB1bI $~ $$K(   "# % 
	 DLLD!  99JJL r    N)r#   r$   r%   rE  rH  r&   r    r   r>  r>    s    Dr    r>  r   
_DOC_ORDER__main__) r3  
__future__r   r   collections.abcr   r   unittestrB  r   music21.common.typesr   r   r   r	   r
   r   r   r   EnvironmentenvironLocalr   rw   r"   r(   TestCaser6  r>  rI  __annotations__r#   mainTestr&   r    r   <module>rT     s    #  $    )         '{&&~60	L99 	S
' S
'r
8 
 8$$  J 
H  zG\" r    