
    rh7                    $   % S r SSKJ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
 r " S S5      r " S S\R                  5      r " S S\R                  5      r/ rS\S'   \S:X  a  SSKr\R*                  " \5        gg)zK
Automatically reduce a MeasureStack to a single chord or group of chords.
    )annotationsN)chord)DocOrder)clef)meter)stream)tiec                 &   [         R                  " 5       n [        R                  " S5      n[        R
                  " S5      nSUl        [        R
                  " S5      n[        R
                  " S5      nXX44 H  nU R                  U5        M     U $ )a  
returns a simple measure stream for testing:

>>> s = analysis.reduceChordsOld.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)stc1c2c3cs         Z/home/james-whalen/.local/lib/python3.13/site-packages/music21/analysis/reduceChordsOld.pytestMeasureStream1r      sp     	AE"A	]	#BB	]	#B	]	#BR_	 H    c                  \    \ rS rS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g)ChordReducer0   c                z    SU l         U R                  U l        SU l        S U l        S U l        S U l        S U l        g )NF   )
printDebugqlbsmpConsonanceweightAlgorithm	maxChordspositionInMeasurenumberOfElementsInMeasure_lastPitchedObject_lastTs)selfs    r   __init__ChordReducer.__init__1   s?    #44!%)-& #'r   Nc                N   SSK Jn  UR                  SL a)  UR                  5       R                  R                  5       nOUR                  R                  5       nU R                  Xc5      n[        U[        U5      5      n[        XwR                  SS9SU nU(       dY  UR                  5       n	UR                  R                  U	l        U H  n
UR                  U
5        M     UR                  SU	5        U$ XxS      n/ nU H   nX}   X-  :  a  UR!                  U5        M     O   SnSnSnU GH  n
U
R"                  (       a   [%        U
R&                  R(                  5      nO0[%        U
R*                   Vs1 s H  nUR(                  iM     sn5      nUU;   a  UU:w  a  Uc$  U
R,                  S:w  a  U
R,                  nSU
l        OUb	  UUl        SnU
nU
 H>  nSUl        UR&                  R0                  c  M#  SUR&                  R0                  l        M@     UnUU
R                  -  nM  UU
R                  -  nUR                  U
5        GM      Ub	  UUl        Sn[5        S[        U5      5       Hv  nUU   n
U
R,                  nU[7        U5      -
  n[9        US	5      S
;   d  M4  UUS-
     nU=R                  U-  sl        [7        U5      U
l        U
=R                  U-  sl        Mx     [;        U5       H'  n
U
R                  (       a  M  UR                  U
5        M)     U$ s  snf )a  

>>> s = analysis.reduceChordsOld.testMeasureStream1()
>>> cr = analysis.reduceChordsOld.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.chord.Chord C4 E4 G4 C5>
>>> newS.notes.first().quarterLength
4.0
r   )noteFT)keyreverseN           r    )      ?g      ?gZd;O?gT㥛 ?gX9v?)music21r-   isFlatflattennotesr   computeMeasureChordWeightsminlensortedgetRestdurationr   removeinsertr   isNotetuplepitch
pitchClasspitchesoffsetr	   
accidentaldisplayStatusrangeintroundlist)r)   
measureObj	numChordsr#   	trimBelowr-   mObjchordWeights
maxNChordsrr   maxChordWeighttrimmedMaxChordspcTuplescurrentGreedyChordcurrentGreedyChordPCscurrentGreedyChordNewLengthpxnicOffsetCurrentcOffsetSyncoplastCs                           r   reduceMeasureToNChords#ChordReducer.reduceMeasureToNChords<   s   * 	!%%%'--446D##**,D66tM	3|#45	L.>.>MjyY
		A"mm99AOA KK1K%m4"H%)CC ''1  # " $&)#Axx!'',,-;A1<<;<$$.C)C%-!((c/23((/"AH'37R&425/%&"A AEww))5;?**8  )*%+q>++q>+A- . )/J,*-' q#d)$AQAXXN*S-@@M]A&*MMQU##}4#~.=0 % dA???A  O <s   5L"
c                   Uc  U R                   n0 nSU l        [        U5      U l        [	        U5       H  u  pEX@l        UR
                  (       a   [        UR                  R                  5      nO/[        UR                   Vs1 s H  owR                  iM     sn5      nXc;  a  SX6'   X6==   U" U5      -  ss'   M     SU l        SU l        U$ s  snf )a  

>>> s = analysis.reduceChordsOld.testMeasureStream1().notes
>>> cr = analysis.reduceChordsOld.ChordReducer()
>>> cws = cr.computeMeasureChordWeights(s)
>>> for pcs in sorted(cws):
...     print("%18r  %2.1f" % (pcs, cws[pcs]))
     (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("%18r  %2.1f" % (pcs, cws[pcs]))
     (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("%18r  %2.1f" % (pcs, cws[pcs]))
     (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("%18r  %2.1f" % (pcs, cws[pcs]))
         (0, 4, 7)  3.0
     (0, 11, 4, 5)  0.5
r   r0   )
quarterLengthOnlyr%   r9   r&   	enumerater@   rA   rB   rC   rD   )r)   rL   r#   
presentPCsr\   r   rY   rZ   s           r   r7   'ChordReducer.computeMeasureChordWeights   s    H ""44O
!"),Z&j)DA%&"xx!'',,-;A<<;<" #
M_Q//M * "#)*& <s   C
c                    UR                   $ N)r   r)   r   s     r   rc   ChordReducer.quarterLengthOnly   s    r   c                4    UR                   UR                  -  $ rh   )r   beatStrengthri   s     r   quarterLengthBeatStrength&ChordReducer.quarterLengthBeatStrength   s    //r   c                v    U R                   U R                  S-
  :X  a  UR                  $ U R                  U5      $ )Nr1   )r%   r&   r   rm   ri   s     r   (quarterLengthBeatStrengthMeasurePosition5ChordReducer.quarterLengthBeatStrengthMeasurePosition   s6    !!T%C%Ca%GG??"11!44r   c                .    SnU R                  U5      U-  $ )z(
Everything from before plus consonance
g      ?)rp   )r)   r   consonanceScores      r   r"   ChordReducer.qlbsmpConsonance   s     <<Q?/QQr   c                *   Sn[         R                  " 5       nUR                  R                  5       nU(       d  U$ SU l        [        UR                  [         R                  5      5      nSU l        [        U5       H  nUR                  USS9n	U	R                  5       R                  (       d	  US:X  a  O&  OdU R                  XX#U5      n
UR                  U
5        U R                  (       d  Mr  [!        USSS9  US-  S:X  d  M  US:w  d  M  [!        S5        M     UR#                  5         UR                  [         R                  5      R                  5       n
U
(       a%  U
R%                  S[&        R(                  " USS	95        UR+                  SS
9  U$ )z+
Return a multipart reduction of a stream.
r   NT)indicesNotNumbers  )end   )allowTreble8vbinPlace)r   Partpartsfirstr'   r9   getElementsByClassr   r(   rH   measurerecursenotesAndRestsreduceThisMeasure
coreAppendr!   printcoreElementsChangedr?   r   bestClefmakeNotation)r)   inStreamr$   closedPositionforceOctaver\   rY   p0lenMeasuresmIms              r   multiPartReductionChordReducer.multiPartReduction   s<    KKM^^!!#H"&"//?@{#A!!!t!<B::<--6**2)[YQa"%r6Q;16"I $ 	
  0668HHQa=>	t$r   c                @   [         R                  " 5       nX&l        UR                  5       nU R	                  UUU R
                  SS9nS n	Sn
U H  n[        R                  " U5      n[        U[        R                  5      (       a9  USLa4  USLa  UR                  USS9  OUR                  SS9  UR                  SS9  UR                  U5      nU	b)  [        X-
  S5      S:w  a  U	=R                  X-
  -  sl        Un	XR                  -   n
UR!                  XSS	9  M     UR"                  R%                  5       R'                  [(        R*                  5      nUbS  [        UR,                  R                  U
-
  S5      S:w  a,  U	=R                  UR,                  R                  U
-
  -  sl        UR/                  5         U R0                  GbH  US
   nU R0                  R2                  (       a[  UR2                  (       aJ  U R0                  R4                  UR4                  :X  a%  [6        R8                  " S5      U R0                  l        OU R0                  R:                  (       a  UR:                  (       a  [=        U R0                  5      [=        U5      :X  a  Sn[?        [=        U R0                  5      5       H1  nU R0                  R@                  U   UR@                  U   :w  d  M/  SnM3     USL a%  [6        R8                  " S5      U R0                  l        US   U l        UR"                  R%                  5       RC                  [         R                  5      R%                  5       RD                  nUU RF                  :w  a"  [        R                  " U5      Ul"        UU l#        U$ )Ng333333?)r#   rN   r0   FT)r   r}   r|      )
ignoreSortr   start)$r   r   numberchordifyr`   r"   copydeepcopy
isinstancer   r   r   removeRedundantPitchesgetOffsetBySiterJ   r   
coreInsertr   r   getContextByClassr   r   barDurationr   r'   r@   rB   r	   TieisChordr9   rH   rD   r   timeSignaturer(   )r)   r   measureIndexr$   r   r   r   mIChordnewPartcLastcLastEndcElcElCopy	newOffset	tsContextfirstPitchedallSamepitchIsourceMeasureTss                      r   r   ChordReducer.reduceThisMeasure  s   NN++---g.7>B>S>S8; . =
 CmmC(G#u{{++e0Ke+**{D*Q**4*8..t.<++G4I  -q1S8''9+??'E #8#88HLLL=! $ HHNN$66u7J7JK	 Y**888CQG3N##y'<'<'J'JX'UU# 	
 "".Q4L&&--,2E2E**00L4F4FF25'''2BD++/((00\5I5It../3|3DD"G"'D,C,C(D"E22::6BlFZFZ[aFbb&+G #F $69ggg6F//3"#B%((..*==fnnMSSUccdll*"mmO<AO*DLr   )r'   r(   r$   r&   r%   r!   r#   )r1   Nr2   rh   )   FF)__name__
__module____qualname____firstlineno__r*   r`   r7   rc   rm   rp   r"   r   r   __static_attributes__ r   r   r   r   0   s?    	 *+/3)-	_D8t05R F;r   r   c                      \ rS rSrS rSrg)TestiK  c                    [         R                  " 5       n[        R                  " S5      nSUl        [        R                  " S5      n[        R                  " S5      nX#U4 H  nUR                  U5        M     g )Nr   r   r   )r   r   r   r   r   r   )r)   r   r   r   r   r   s         r   testSimpleMeasureTest.testSimpleMeasureM  sY    NN[['[['[['"AHHQK r   r   N)r   r   r   r   r   r   r   r   r   r   r   K  s    r   r   c                      \ rS rSrSrS rSrg)TestExternaliV  Tc                   SSK Jn  UR                  S5      R                  SS5      nSnU(       Ga	  UR                  S   R                  [        R                  5      R                  5       R                  [        R                  5      nU(       aN  US   nUR                  S   R                  [        R                  5      R                  5       R                  U5        UR                  S   R                  [        R                  5      R                  5       R                  S[        R                  " 5       5        [        5       nUR                  USS9nSS	K Jn  SS
K Jn	  UR%                  S5      n
U[&        R(                      H#  nU	R+                  UU
SS9R,                  Ul        M%     UR                  SU5        U R0                  (       a  UR1                  5         g g )Nr   )corpuszPMFC_06_Giovanni-05_Donnar1      Tr    )r$   )r.   )romanG)preferSecondaryDominants)r3   r   parsemeasuresr   r   r   r   r   r   Clefr>   r?   Treble8vbClefr   r   r.   r   Keyr   r   romanNumeralFromChordfigurelyricshow)r)   r   r   fixClef
startClefsclef1crrY   r.   r   cm	thisChords               r   testTrecentoMadrigal!TestExternal.testTrecentoMadrigalY  sj   " LL45>>q"E 66v~~ 99>ASASTXT]T]A^ "1
--fnn=CCELLUSGGAJ))&..9??AHHDL^L^L`a ^!!!q!1!WWS\5;;I#99):<SW : YY_Y_ O ( 	
A99FFH r   r   N)r   r   r   r   r   r   r   r   r   r   r   r   V  s    D&r   r   r   
_DOC_ORDER__main__)__doc__
__future__r   r   unittestr3   r   music21.common.typesr   r   r   r   r	   r   r   TestCaser   r   r   __annotations__r   mainTestr   r   r   <module>r      s    #    )    ,Y Yv	8 	)8$$ )\ 
H  zT r   