
    3j7                    "   U d 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
 Z G d d      Z G d dej                        Z G d dej                        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)chord)DocOrder)clef)meter)stream)tiec                    t        j                         } t        j                  d      }t	        j
                  d      }d|_        t	        j
                  d      }t	        j
                  d      }||||fD ]  }| j                  |        | S )a8  
    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         M/DATA/.local/lib/python3.12/site-packages/music21/analysis/reduceChordsOld.pytestMeasureStream1r      st     	AE"A	]	#BB	]	#B	]	#BR_	 H    c                  N    e Zd Zd Z	 	 	 ddZddZd Zd Zd Zd Z	dd	Z
d
 Zy)ChordReducerc                z    d| _         | j                  | _        d| _        d | _        d | _        d | _        d | _        y )NF   )
printDebugqlbsmpConsonanceweightAlgorithm	maxChordspositionInMeasurenumberOfElementsInMeasure_lastPitchedObject_lastTs)selfs    r   __init__zChordReducer.__init__0   s?    #44!%)-& #'r   Nc                   ddl m} |j                  du r)|j                         j                  j                         }n|j                  j                         }| j                  ||      }t        |t        |            }t        ||j                  d      d| }|sW|j                         }	|j                  j                  |	_        |D ]  }
|j                  |
        |j                  d|	       |S ||d      }g }|D ]   }||   ||z  k\  r|j!                  |         n d}d}d}|D ]  }
t#        |
j$                  D ch c]  }|j&                   c}      }||v r||k7  r|#|
j(                  dk7  r|
j(                  }d|
_        n|	||_        d}|
}|
D ];  }d|_        |j,                  j.                  !d|j,                  j.                  _        = |}||
j                  z  }||
j                  z  }|j                  |
        |	||_        d}t3        dt        |            D ]r  }||   }
|
j(                  }|t5        |      z
  }t7        |d	      d
v s1||dz
     }|xj                  |z  c_        t5        |      |
_        |
xj                  |z  c_        t t9        |      D ]   }
|
j                  r|j                  |
       " |S c c}w )af  
        Takes a measure and reduces it to only one chord or `numChords` chords.

        >>> 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   tuplepitches
pitchClassoffsetr	   pitch
accidentaldisplayStatusrangeintroundlist)r(   
measureObj	numChordsr"   	trimBelowr+   mObjchordWeights
maxNChordsrr   maxChordWeighttrimmedMaxChordspcTuplescurrentGreedyChordcurrentGreedyChordPCscurrentGreedyChordNewLengthxpnicOffsetCurrentcOffsetSyncoplastCs                           r   reduceMeasureToNChordsz#ChordReducer.reduceMeasureToNChords;   s   , 	!%%%'--446D##**,D66t_M	3|#45	Ll.>.>MjyY
		A"mm99AOA KK1K%jm4"HH%))CC ''1  # " $&)#AQYY7Yq||Y78A$$.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 8s    K
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  

        >>> s = analysis.reduceChordsOld.testMeasureStream1().notes
        >>> cr = analysis.reduceChordsOld.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.5
        r   r.   )quarterLengthOnlyr$   r7   r%   	enumerater>   r?   r@   )r(   rI   r"   
presentPCsrY   r   rV   rW   s           r   r5   z'ChordReducer.computeMeasureChordWeights   s    H ""44O
!"),Z&j)DAq%&D"QYY7Yq||Y78A
" #
1qM_Q//M * "#)*& 8s   B
c                    |j                   S N)r   r(   r   s     r   r_   zChordReducer.quarterLengthOnly   s    r   c                4    |j                   |j                  z  S rc   )r   beatStrengthrd   s     r   quarterLengthBeatStrengthz&ChordReducer.quarterLengthBeatStrength   s    //r   c                t    | j                   | j                  dz
  k(  r|j                  S | j                  |      S )Nr/   )r$   r%   r   rg   rd   s     r   (quarterLengthBeatStrengthMeasurePositionz5ChordReducer.quarterLengthBeatStrengthMeasurePosition   s6    !!T%C%Ca%GG??"11!44r   c                .    d}| j                  |      |z  S )z8
        Everything from before plus consonance
        g      ?)ri   )r(   r   consonanceScores      r   r!   zChordReducer.qlbsmpConsonance   s     <<Q?/QQr   c                
   d}t        j                         }|j                  j                         }|s|S d| _        t        |j                  t         j                              }d| _        t        |      D ]  }|j                  |d      }	|	j                         j                  s|dk(  rn( n]| j                  |	||||      }
|j                  |
       | j                  skt!        |dd       |dz  dk(  s|dk7  st!        d        |j#                          |j                  t         j                        j                         }
|
r'|
j%                  dt'        j(                  |d	             |j+                  d
       |S )z;
        Return a multipart reduction of a stream.
        r   NT)indicesNotNumbers  )end   )allowTreble8vbinPlace)r   Partpartsfirstr&   r7   getElementsByClassr   r'   rE   measurerecursenotesAndRestsreduceThisMeasure
coreAppendr    printcoreElementsChangedr=   r   bestClefmakeNotation)r(   inStreamr#   closedPositionforceOctaverY   rW   p0lenMeasuresmIms              r   multiPartReductionzChordReducer.multiPartReduction   s>    KKM^^!!#H"&"//?@{#A!!!t!<B::<--6**2q)^[YQa"%r6Q;16"I $ 	
  0668HHQa=>	t$r   c                   t        j                         }||_        |j                         }| j	                  ||| j
                  d      }d }	d}
|D ]  }t        j                  |      }t        |t        j                        r@|dur<|dur|j                  |d       n|j                  d       |j                  d       |j                  |      }|	*t        ||
z
  d      dk7  r|	xj                  ||
z
  z  c_        |}	||j                  z   }
|j!                  ||d	        |j"                  j%                         j'                  t(        j*                        }|Rt        |j,                  j                  |
z
  d      dk7  r,|	xj                  |j,                  j                  |
z
  z  c_        |j/                          | j0                  )|d
   }| j0                  j2                  rT|j2                  rH| j0                  j4                  |j4                  k(  rt7        j8                  d      | j0                  _        n| j0                  j:                  r|j:                  rt=        | j0                        t=        |      k(  rwd}t?        t=        | j0                              D ].  }| j0                  j@                  |   |j@                  |   k7  s-d}0 |r$t7        j8                  d      | j0                  _        |d   | _        |j"                  j%                         jC                  t         j                        j%                         jD                  }|| jF                  k7  r!t        j                  |      |_"        || _#        |S )Ng333333?)r"   rK   r.   FT)r   rt   rs      )
ignoreSortr   start)$r   r   numberchordifyr]   r!   copydeepcopy
isinstancer   r   r   removeRedundantPitchesgetOffsetBySiterG   r   
coreInsertrv   rw   getContextByClassr   r   barDurationr   r&   isNoterB   r	   TieisChordr7   rE   r?   rx   timeSignaturer'   )r(   r   measureIndexr#   r   r   r   mIChordnewPartcLastcLastEndcElcElCopy	newOffset	tsContextfirstPitchedallSamepitchIsourceMeasureTss                      r   r|   zChordReducer.reduceThisMeasure  s   NN++---g.7>B>S>S8; . =
 CmmC(G#u{{+e0Ke+**{D*Q**4*8..t.<++G4I  X-q1S8''9x+??'E 7#8#88HLLG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/   Nr0   rc   )   FF)__name__
__module____qualname__r)   r]   r5   r_   rg   ri   r!   r   r|    r   r   r   r   /   s?    	 *+/3)-	]@5n05R F;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   )r(   r   r   r   r   r   s         r   testSimpleMeasurezTest.testSimpleMeasureG  s[    NN[['[['[['b"AHHQK r   N)r   r   r   r   r   r   r   r   r   E  s    r   r   c                      e Zd ZdZd Zy)TestExternalTc                   ddl m} |j                  d      j                  dd      }d}|r|j                  d   j                  t        j                        j                         j                  t        j                        }|rN|d   }|j                  d   j                  t        j                        j                         j                  |       |j                  d   j                  t        j                        j                         j                  dt        j                                t               }|j                  |d      }dd	l m} dd
l m}	 |j%                  d      }
|t&        j(                     D ]%  }|	j+                  ||
d      j,                  |_        ' |j                  d|       | j0                  r|j1                          y y )Nr   )corpuszPMFC_06_Giovanni-05_Donnar/      Tr   )r#   )r,   )romanG)preferSecondaryDominants)r1   r   parsemeasuresrv   rx   r   r   rw   r   Clefr<   r=   Treble8vbClefr   r   r,   r   Keyr   r   romanNumeralFromChordfigurelyricshow)r(   r   r   fixClef
startClefsclef1crrW   r,   r   cm	thisChords               r   testTrecentoMadrigalz!TestExternal.testTrecentoMadrigalS  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   N)r   r   r   r   r   r   r   r   r   r   P  s    D&r   r   r   
_DOC_ORDER__main__)__doc__
__future__r   r   unittestr1   r   music21.common.typesr   r   r   r   r	   r   r   TestCaser   r   r   __annotations__r   mainTestr   r   r   <module>r      s    #    )    ,T Tl	8 	)8$$ )\ 
H  zGT r   