§
    ƒØj¥—  ã                  ó’  — d dl mZ d dlm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  G d„ d¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ de¦  «        Zdd„Z G d„ de¦  «        Z G d„ de¦  «        Z G d„ dej        ¦  «        Zedk    rd dlZ ej        e¦  «         dS dS )é    )Úannotations)ÚdeepcopyN)Úduration)Úexpressions)Úinterval)Únote)Úpitch)Ústream)Úaligner)ÚornamentRecognizerc                  ó$   — e Zd ZdZd„ Zd„ Zd„ ZdS )ÚOMRMidiFixerz�
    Base class for future fixers
    changes is a list of changes associated with the midiStream and omrStream,
    not a list of lists
    c                ó0   — || _         || _        || _        d S ©N)ÚchangesÚ
midiStreamÚ	omrStream)Úselfr   r   r   s       ú‘/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/music21/alpha/analysis/fixer.pyÚ__init__zOMRMidiFixer.__init__   s   € ØˆŒØ$ˆŒØ"ˆŒˆˆó    c                ó   — d S r   © )r   s    r   ÚfixzOMRMidiFixer.fix$   s   € Øˆr   c                ór   — t          |t          j        ¦  «        rt          |t          j        ¦  «        rdS dS )NTF)Ú
isinstancer   ÚNote©r   ÚmidiRefÚomrRefs      r   ÚcheckIfNoteInstancez OMRMidiFixer.checkIfNoteInstance'   s3   € Ý�g�tœyÑ)Ô)ð 	­j¸ÅÄÑ.KÔ.Kð 	Ø�4Øˆur   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r!   r   r   r   r   r      sK   € € € € € ðð ð
#ð #ð #ð
ð ð ðð ð ð ð r   r   c                  ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )ÚDeleteFixeraÏ  
    The DeleteFixer was designed to fit the specifications of the OpenScore project.
    The goal of the OpenScore project is to open-source music with open source software
    (like music21!). OpenScore will use a combination of computer and human power
    to digitize classical music scores and put them in the public domain. One idea is
    that software can identify wrong recognized notes in a scanned score and mark or
    delete the entire measure that that note is in and pass it off to a human corrector to
    re-transcribe the entire measure. The DeleteFixer could be the computer power in
    this method of score correction that OpenScore is using.

    CAUTION: this does really weird things still.
    c                óh  •— t          ¦   «                              ¦   «          | j        D ]ˆ\  }}}|                      ||¦  «        du rŒt	          |t
          j        ¦  «        r|t
          j        j        k    rŒO|                     t          j
        ¦  «        }| j                             |¦  «         Œ‰d S )NF)Úsuperr   r   r!   r   r   Ú	ChangeOpsÚNoChangeÚgetContextByClassr
   ÚMeasurer   Úremove)r   r   r    ÚopÚmÚ	__class__s        €r   r   zDeleteFixer.fix9   s¬   ø€ Ý‰Œ�Š‰ŒˆØ%)¤\ð 		%ð 		%Ñ!ˆW�f˜bØ×'Ò'¨°Ñ8Ô8¸EÐAÐAØõ ˜"�gÔ/Ñ0Ô0ð °R½7Ô;LÔ;UÒ5UÐ5UØà×(Ò(­¬Ñ8Ô8ˆAØŒN×!Ò! !Ñ$Ô$Ð$Ð$ð		%ð 		%r   )r"   r#   r$   r%   r   Ú__classcell__©r1   s   @r   r'   r'   ,   sB   ø€ € € € € ðð ð%ð %ð %ð %ð %ð %ð %ð %ð %r   r'   c                  óN   ‡ — e Zd ZdZˆ fd„Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
dd
„Zˆ xZS )ÚEnharmonicFixera/  
    Fixes incorrectly spelled enharmonics
    initialized with self.changes -- a list of tuples in this form:
    (MIDIReference, OMRReference, op)
    MIDIReference and OMRReference are actual note/rest/chord object in some stream
    op is a ChangeOp that relates the two references

    TEST 1, no changes in OMR stream

    >>> omrStream1 = stream.Stream()
    >>> midiStream1 = stream.Stream()

    >>> omrNote1 = note.Note('A#4')
    >>> omrNote2 = note.Note('A#4')
    >>> midiNote1 = note.Note('B-4')
    >>> midiNote2 = note.Note('B-4')

    >>> omrStream1.append([omrNote1, omrNote2])
    >>> midiStream1.append([midiNote1, midiNote2])
    >>> subOp = alpha.analysis.aligner.ChangeOps.Substitution

    >>> ct1 = (midiNote1, omrNote1, subOp)
    >>> ct2 = (midiNote2, omrNote2, subOp)
    >>> changes1 = [ct1, ct2]

    >>> fixer1 = alpha.analysis.fixer.EnharmonicFixer(changes1, None, None)
    >>> fixer1.fix()
    >>> omrStream1[0]
    <music21.note.Note A#>
    >>> omrStream1[1]
    <music21.note.Note A#>

    TEST 2, no changes in OMR stream

    >>> omrStream2 = stream.Stream()
    >>> midiStream2 = stream.Stream()

    >>> omr2Note1 = note.Note('A#4')
    >>> omr2Note2 = note.Note('A#4')
    >>> midi2Note1 = note.Note('A#4')
    >>> midi2Note2 = note.Note('A#4')

    >>> omrStream2.append([omr2Note1, omr2Note2])
    >>> midiStream2.append([midi2Note1, midi2Note2])
    >>> ncOp = alpha.analysis.aligner.ChangeOps.NoChange

    >>> ct2_1 = (midi2Note1, omr2Note1, ncOp)
    >>> ct2_2 = (midi2Note2, omr2Note2, ncOp)
    >>> changes2 = [ct2_1, ct2_2]

    >>> fixer2 = alpha.analysis.fixer.EnharmonicFixer(changes2, None, None)
    >>> fixer2.fix()
    >>> omrStream2[0]
    <music21.note.Note A#>
    >>> omrStream1[1]
    <music21.note.Note A#>

    TEST 3 (case 1)

    >>> midiNote3 = note.Note('A4')
    >>> omrNote3 = note.Note('An4')

    >>> subOp = alpha.analysis.aligner.ChangeOps.Substitution

    >>> ct3 = (midiNote3, omrNote3, subOp)
    >>> changes3 = [ct3]
    >>> omrNote3.pitch.accidental
    <music21.pitch.Accidental natural>
    >>> fixer3 = alpha.analysis.fixer.EnharmonicFixer(changes3, None, None)
    >>> fixer3.fix()
    >>> omrNote3.pitch.accidental

    TEST 4 (case 2-1) e.g MIDI = g#, ground truth = a-, OMR = an

    >>> midiNote4 = note.Note('G#4')
    >>> omrNote4 = note.Note('An4')

    >>> subOp = alpha.analysis.aligner.ChangeOps.Substitution

    >>> ct4 = (midiNote4, omrNote4, subOp)
    >>> changes4 = [ct4]
    >>> omrNote4.pitch.accidental
    <music21.pitch.Accidental natural>
    >>> fixer4 = alpha.analysis.fixer.EnharmonicFixer(changes4, None, None)
    >>> fixer4.fix()
    >>> omrNote4.pitch.accidental
    <music21.pitch.Accidental flat>

    TEST 5 (case 2-2) e.g midi = g-, gt = f#, omr = fn

    >>> midiNote5 = note.Note('G-4')
    >>> omrNote5 = note.Note('Fn4')

    >>> subOp = alpha.analysis.aligner.ChangeOps.Substitution

    >>> ct5 = (midiNote5, omrNote5, subOp)
    >>> changes5 = [ct5]
    >>> omrNote5.pitch.accidental
    <music21.pitch.Accidental natural>
    >>> fixer5 = alpha.analysis.fixer.EnharmonicFixer(changes5, None, None)
    >>> fixer5.fix()
    >>> omrNote5.pitch.accidental
    <music21.pitch.Accidental sharp>

    TEST 6.1 (case 3) e.g. midi = g#, gt = g#, omr = gn or omr = g-

    >>> midiNote6_1 = note.Note('G#4')
    >>> midiNote6_2 = note.Note('G#4')
    >>> omrNote6_1 = note.Note('Gn4')
    >>> omrNote6_2 = note.Note('G-4')

    >>> subOp6_1 = alpha.analysis.aligner.ChangeOps.Substitution
    >>> subOp6_2 = alpha.analysis.aligner.ChangeOps.Substitution
    >>> ct6_1 = (midiNote6_1, omrNote6_1, subOp6_1)
    >>> ct6_2 = (midiNote6_2, omrNote6_2, subOp6_2)
    >>> changes6 = [ct6_1, ct6_2]

    >>> omrNote6_1.pitch.accidental
    <music21.pitch.Accidental natural>
    >>> omrNote6_2.pitch.accidental
    <music21.pitch.Accidental flat>
    >>> fixer6 = alpha.analysis.fixer.EnharmonicFixer(changes6, None, None)
    >>> fixer6.fix()
    >>> omrNote6_1.pitch.accidental
    <music21.pitch.Accidental sharp>
    >>> omrNote6_2.pitch.accidental
    <music21.pitch.Accidental sharp>

    TEST 7 (case 4-1, 4-2) notes are on different step, off by an interval of 2:
    * 4-1: e.g. midi = g#, gt = a-, omr = a#
    * 4-2: e.g. midi = a-, gt = g#, omr = g-

    >>> midiNote7_1 = note.Note('G#4')
    >>> omrNote7_1 = note.Note('A#4')

    >>> midiNote7_2 = note.Note('A-4')
    >>> omrNote7_2 = note.Note('G-4')

    >>> subOp7_1 = alpha.analysis.aligner.ChangeOps.Substitution
    >>> subOp7_2 = alpha.analysis.aligner.ChangeOps.Substitution
    >>> ct7_1 = (midiNote7_1, omrNote7_1, subOp7_1)
    >>> ct7_2 = (midiNote7_2, omrNote7_2, subOp7_2)
    >>> changes7 = [ct7_1, ct7_2]

    >>> omrNote7_1.pitch.accidental
    <music21.pitch.Accidental sharp>
    >>> omrNote7_2.pitch.accidental
    <music21.pitch.Accidental flat>
    >>> fixer7 = alpha.analysis.fixer.EnharmonicFixer(changes7, None, None)
    >>> fixer7.fix()

    >>> omrNote7_1.pitch.step
    'A'
    >>> omrNote7_1.pitch.accidental
    <music21.pitch.Accidental flat>

    >>> omrNote7_2.pitch.step
    'G'
    >>> omrNote7_2.pitch.accidental
    <music21.pitch.Accidental sharp>
    c                ó’  •— t          ¦   «                              ¦   «          | j        D �]œ\  }}}d|j        _        |                      ||¦  «        du rŒ,t          |t          j        ¦  «        r|t          j        j	        k    rŒ\|  
                    ||d¬¦  «        rŒu|                      |¦  «        �r|                      ||¦  «        rd|j        _        Œ®|j        |j        k    rd|j                             t!          j        d¦  «        ¦  «                             |j        ¦  «        rt          j        d¦  «        |j        _        �Œ"|j        |j        k     rb|j                             t!          j        d¦  «        ¦  «                             |j        ¦  «        rt          j        d	¦  «        |j        _        �Œ–|                      |¦  «        rQ|                      ||¦  «        r;|                      |¦  «        r|j        j        |j        _        �Œîd|j        _        �Œü|                      |¦  «        �rC|                      ||¦  «        �r,|j        |j        k    r†|j        j        t          j        d	¦  «        k    rb|j                             t!          j        d
¦  «        ¦  «                             |j        ¦  «        rt          j        d¦  «        |j        _        �Œ¿|j        |j        k     r„|j        j        t          j        d¦  «        k    rb|j                             t!          j        d¦  «        ¦  «                             |j        ¦  «        rt          j        d	¦  «        |j        _        �ŒU|j        |j        k    r7|                      |¦  «        r"|                      ||¦  «        r|j        |_        �ŒždS )z[
        Fixes the enharmonic errors in the OMR by changing the pitch of the note.
        ÚblackFé   )ÚsetIntNéÿÿÿÿÚflaté   Úsharpéþÿÿÿé   )r)   r   r   ÚstyleÚcolorr!   r   r   r*   r+   ÚintervalTooBigÚ	hasNatAccÚisEnharmonicr	   Ú
accidentalÚ	transposer   ÚIntervalÚ
AccidentalÚhasSharpFlatAccÚstepEqÚhasAccÚ	stepNotEq)r   r   r    r/   r1   s       €r   r   zEnharmonicFixer.fixè   sm  ø€ õ 	‰Œ�Š‰ŒˆØ%)¤\ð A	-ñ A	-Ñ!ˆW�f˜bØ!(ˆFŒLÔà×'Ò'¨°Ñ8Ô8¸EÐAÐAØõ ˜"�gÔ/Ñ0Ô0ð °R½7Ô;LÔ;UÒ5UÐ5UØð ×"Ò" 7¨F¸1Ð"Ñ=Ô=ð Øà�~Š~˜fÑ%Ô%ñ 3-Ø×$Ò$ W¨fÑ5Ô5ð PØ.2�F”LÔ+Ð+ð ”| g¤mÒ3Ð3Ø!œ<×1Ò1µ(Ô2CÀBÑ2GÔ2Gñ 4ô 4ß4@²LÀÄÑ4OÔ4OðOå6;Ô6FÀvÑ6NÔ6N˜FœLÔ3ùð
  œ¨¬Ò5Ð5Ø!œ<×1Ò1µ(Ô2CÀAÑ2FÔ2Fñ 4ô 4ß4@²LÀÄÑ4OÔ4OðPå6;Ô6FÀwÑ6OÔ6O˜FœLÔ3ùð ×%Ò% fÑ-Ô-ð -°$·+²+¸gÀvÑ2NÔ2Nð -Ø—;’;˜vÑ&Ô&ð 3Ø.5¬mÔ.F�F”LÔ+Ñ+à.2�F”LÔ+Ñ+à×%Ò% fÑ-Ô-ñ -°$·.².ÀÈ&Ñ2QÔ2Qñ -ð ”< '¤-Ò/Ð/Ø”|Ô.µ%Ô2BÀ7Ñ2KÔ2KÒKÐKØ!œ<×1Ò1µ(Ô2CÀBÑ2GÔ2Gñ 4ô 4ß4@²LÀÄÑ4OÔ4OðOå6;Ô6FÀvÑ6NÔ6N˜FœLÔ3ùð ”\ G¤MÒ1Ð1Ø”|Ô.µ%Ô2BÀ6Ñ2JÔ2JÒJÐJØ!œ<×1Ò1µ(Ô2CÀAÑ2FÔ2Fñ 4ô 4ß4@²LÀÄÑ4OÔ4OðPå6;Ô6FÀwÑ6OÔ6O˜FœLÔ3ùð ”, '¤-Ò/Ð/Ø×,Ò,¨WÑ5Ô5ð 0àŸš G¨VÑ4Ô4ð 0ð  'œ}�”ùðCA	-ð A	-r   c                ó@   — |j                              |j         ¦  «        S )zZ
        Returns True if the omrRef is enharmonic to the midiRef, False otherwise
        )r	   rD   r   s      r   rD   zEnharmonicFixer.isEnharmonic1  s   € ð Œ}×)Ò)¨&¬,Ñ7Ô7Ð7r   c                ó   — |j         j        duS )zO
        Returns True if the omrRef has an accidental, False otherwise
        N)r	   rE   ©r   r    s     r   rK   zEnharmonicFixer.hasAcc7  s   € ð Œ|Ô&¨dÐ2Ð2r   c                óV   — |                       |¦  «        o|j        j        j        dk    S )zV
        Returns True if the omrRef has a natural accidental, False otherwise
        Únatural©rK   r	   rE   ÚnamerO   s     r   rC   zEnharmonicFixer.hasNatAcc=  ó(   € ð �{Š{˜6Ñ"Ô"ÐP v¤|Ô'>Ô'CÀyÒ'PÐPr   c                óV   — |                       |¦  «        o|j        j        j        dk    S )z\
        Returns True if the omrRef has a sharp or flat accidental, False otherwise
        rQ   rR   rO   s     r   rI   zEnharmonicFixer.hasSharpFlatAccC  rT   r   c                ó"   — |j         |j         k    S )zF
        Returns True if the steps are equal, False otherwise
        ©Ústepr   s      r   rJ   zEnharmonicFixer.stepEqI  ó   € ð Œ|˜vœ{Ò*Ð*r   c                ó"   — |j         |j         k    S )zJ
        Returns True if the steps are not equal, False otherwise
        rW   r   s      r   rL   zEnharmonicFixer.stepNotEqO  rY   r   r8   c                óF   — t          j        ||¦  «        j        |k    rdS dS )z¨
        Returns True if the intervalClass between the two notes is greater than setInt.

        Note that intervalClass and not actual interval size is used.
        TF)r   ÚnotesToChromaticÚintervalClass)r   r   r    r9   s       r   rB   zEnharmonicFixer.intervalTooBigU  s)   € õ Ô$ W¨fÑ5Ô5ÔCÀfÒLÐLØ�4Øˆur   )r8   )r"   r#   r$   r%   r   rD   rK   rC   rI   rJ   rL   rB   r2   r3   s   @r   r5   r5   F   s¿   ø€ € € € € ð`ð `ðBF-ð F-ð F-ð F-ð F-ðR8ð 8ð 8ð3ð 3ð 3ðQð Qð QðQð Qð Qð+ð +ð +ð+ð +ð +ðð ð ð ð ð ð ð r   r5   c                  óJ   ‡ — e Zd ZdZdˆ fd„	Zdd„Zddœdd„Zdddœdd„Zˆ xZS )ÚOrnamentFixera<  
    Fixes missed ornaments in OMR using expanded ornaments in MIDI
    initialized with self.changes -- a list of tuples in this form:
    (MIDIReference, OMRReference, op)
    MIDIReference and OMRReference are actual note/rest/chord object in some stream
    op is a ChangeOp that relates the two references

    recognizers can be a single recognizer or list of recognizers,
    but self.recognizers is always a list.
    recognizers take in stream of busy notes and optional stream of simple note(s)
    and return False or an instance of the ornament recognized
    Úbluec                ó¦   •— t          ¦   «                              |||¦  «         t          |t          ¦  «        s	|g| _        n|| _        || _        d S r   )r)   r   r   ÚlistÚrecognizersÚmarkChangeColor)r   r   r   r   rc   rd   r1   s         €r   r   zOrnamentFixer.__init__l  sT   ø€ Ý‰Œ×Ò˜ *¨iÑ8Ô8Ð8Ý˜+¥tÑ,Ô,ð 	+Ø +˜}ˆDÔÐà*ˆDÔØ.ˆÔÐÐr   Úreturnúexpressions.Ornament | Nonec                óT   — | j         D ]}|                     ||¬¦  «        }|r|c S Œ dS )a?  
        Finds an ornament in busyNotes based from simpleNote
        using provided recognizers.

        :param busyNotes: stream of notes
        :param simpleNotes: stream of notes

        Tries the recognizers in order, returning the result of the first
        one to successfully recognize an ornament.
        )ÚsimpleNotesN)rc   Ú	recognize)r   Ú	busyNotesrh   ÚrÚornaments        r   ÚfindOrnamentzOrnamentFixer.findOrnamentt  sF   € ð Ô!ð 	 ð 	 ˆAØ—{’{ 9¸+�{ÑFÔFˆHØð  Ø���ð àˆtr   F©ÚshowÚselectedNoteú	note.Noterl   úexpressions.OrnamentÚboolc               ó    — t          d„ |j        D ¦   «         ¦  «        s/|j                             |¦  «         |r| j        |j        _        dS dS )a‡  
        Adds the ornament to the selectedNote when selectedNote has no ornaments already.

        * selectedNote: Note.note to add ornament to
        * ornament: Expressions.ornament to add to note
        * show: True when note should be colored blue

        Returns True if added successfully, or False if there was already an
        ornament on the note and it wasn't added.
        c              3  óJ   K  — | ]}t          |t          j        ¦  «        V — Œd S r   )r   r   ÚOrnament)Ú.0Úes     r   ú	<genexpr>z,OrnamentFixer.addOrnament.<locals>.<genexpr>”  s/   è è € ÐYÐY¸1•:˜a¥Ô!5Ñ6Ô6ÐYÐYÐYÐYÐYÐYr   TF)Úanyr   Úappendrd   r@   rA   )r   rp   rl   ro   s       r   ÚaddOrnamentzOrnamentFixer.addOrnament…  s^   € õ ÐYÐYÀÔ@XÐYÑYÔYÑYÔYð 	ØÔ$×+Ò+¨HÑ5Ô5Ð5Øð @Ø+/Ô+?�Ô"Ô(Ø�4Øˆur   T)ro   ÚinPlaceúOMRMidiFixer | Nonec               óî  — | j         }d}g }g }|sYt          | j        ¦  «        }t          | j        ¦  «        }t	          j        ||¬¦  «        }|                     ¦   «          |j         }|D ]±\  }	}
}|t          j        j        u s|t          j        j	        u rŒ-|
|v rŒ2t          |	|
j        ¦  «        }d}|D ]
}||v rd} nŒ|rŒY|                      |t          |
¦  «        g¦  «        }|r2||z  }|                     |
¦  «         |                      |
||¬¦  «         Œ²|r2| j                             ¦   «          | j                             ¦   «          |s"|� t!          |j         |j        |j        ¦  «        S dS )zò
        Corrects missed ornaments in omrStream according to midiStream
        :param show: Whether to show results
        :param inPlace: Whether to make changes to own omr stream or
        return a new OrnamentFixer with changes
        N©ÚsourceStreamÚtargetStreamFTrn   )r   r   r   r   r   ÚStreamAlignerÚalignr*   r+   ÚDeletionÚgetNotesWithinDurationr   rm   r{   r|   ro   Ú
TrillFixerr‚   r�   )r   ro   r}   r   ÚsaÚomrNotesLabeledOrnamentÚ midiNotesAlreadyFixedForOrnamentÚomrStreamCopyÚmidiStreamCopyÚmidiNoteRefÚ
omrNoteRefÚchangerj   ÚbusyNoteAlreadyUsedÚbusyNoteÚornamentFounds                   r   r   zOrnamentFixer.fix›  sË  € ð ”,ˆØ)-ˆØ"$ÐØ+-Ð(àð 	!Ý$ T¤^Ñ4Ô4ˆMÝ% d¤oÑ6Ô6ˆNÝÔ&°MÐP^Ð_Ñ_Ô_ˆBØ�HŠH‰JŒJˆJØ”jˆGà/6ð 	Gð 	GÑ+ˆK˜ Và�Ô*Ô3Ð3Ð3°vÅÔARÔA[Ð7[Ð7[Øð Ð4Ð4Ð4ØÝ.¨{¸JÔ<OÑPÔPˆIØ"'ÐØ%ð ð �ØÐ?Ð?Ð?Ø*.Ð'Ø�Eð @ð #ð Øð !×-Ò-¨i½(À:Ñ:NÔ:NÐ9OÑPÔPˆMð ð GØ0°IÑ=Ð0Ø'×.Ò.¨zÑ:Ô:Ð:Ø× Ò  ¨]ÀÐ ÑFÔFÐFøàð 	#ØŒN×ÒÑ!Ô!Ð!ØŒO× Ò Ñ"Ô"Ð"àð 	˜2˜>å˜bœj¨"¬/¸2¼?ÑKÔKÐKà�4r   )r`   )re   rf   )rp   rq   rl   rr   re   rs   )re   r~   )	r"   r#   r$   r%   r   rm   r|   r   r2   r3   s   @r   r_   r_   _  s£   ø€ € € € € ðð ð/ð /ð /ð /ð /ð /ðð ð ð ð* ð	ð ð ð ð ð ð,  ¨ð 5ð 5ð 5ð 5ð 5ð 5ð 5ð 5ð 5ð 5r   r_   c                óâ  — |r|| _         t          j        ¦   «         }| j        j        |j        k    r|S |j        | j        j        z
  }|                      dd¬¦  «        }|                     t          | ¦  «        ¦  «         |rl||j        j        k    r\|}|                     dd¬¦  «        }||j        j        z  }|                     t          |¦  «        ¦  «         |r||j        j        k    °\|S )a—  
    Returns maximal stream of deepcopies of notes, rests, and chords following
    (and including) startingNote which occupy no more than totalDuration combined.

    * startingGeneralNote is a GeneralNote (could be a note, rest, or chord)
    * totalDuration is a duration
    * referenceStream is optionally a stream which the startingGeneralNote's
        active site should be set to when provided
    ÚGeneralNoteT)ÚactiveSiteOnly)Ú
activeSiter
   ÚStreamr   ÚquarterLengthÚnextr{   r   )ÚstartingGeneralNoteÚtotalDurationÚreferenceStreamÚnotesÚdurationQlLeftÚnextGeneralNoteÚcurrentGeneralNotes          r   r†   r†   Ò  s  € ð ð 9Ø)8ÐÔ&åŒM‰OŒO€Eð Ô#Ô1°MÔ4OÒOÐOØˆà"Ô0Ð3FÔ3OÔ3]Ñ]€NØ)×.Ò.¨}ÈTÐ.ÑRÔR€OØ	‡L‚L•Ð-Ñ.Ô.Ñ/Ô/Ð/à
ð 3˜n°Ô0HÔ0VÒVÐVØ,ÐØ,×1Ò1°-ÐPTÐ1ÑUÔUˆàÐ,Ô5ÔCÑCˆØ�Š•XÐ0Ñ1Ô1Ñ2Ô2Ð2ð ð 3˜n°Ô0HÔ0VÒVÐVð €Lr   c                  ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )r‡   a9  
    Fixes missed trills in OMR using expanded ornaments in MIDI.
    initialized with self.changes -- a list of tuples in this form:
    (MIDIReference, OMRReference, op)
    MIDIReference and OMRReference are actual note/rest/chord object in some stream
    op is a ChangeOp that relates the two references
    c                ó²   •— t          j        ¦   «         }t          j        ¦   «         }d|_        ||g}t          ¦   «                              ||||¦  «         d S )NT)r   ÚTrillRecognizerÚcheckNachschlagr)   r   )r   r   r   r   ÚdefaultOrnamentRecognizerÚnachschlagOrnamentRecognizerrc   r1   s          €r   r   zTrillFixer.__init__ú  sY   ø€ Ý$6Ô$FÑ$HÔ$HÐ!Ý'9Ô'IÑ'KÔ'KÐ$Ø7;Ð$Ô4Ø0Ð2NÐOˆÝ‰Œ×Ò˜ *¨i¸ÑEÔEÐEÐEÐEr   ©r"   r#   r$   r%   r   r2   r3   s   @r   r‡   r‡   ò  sK   ø€ € € € € ðð ðFð Fð Fð Fð Fð Fð Fð Fð Fr   r‡   c                  ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )Ú	TurnFixeraG  
    Fixes missed turns/inverted turns in OMR using expanded ornaments in MIDI.
    initialized with self.changes -- a list of tuples in this form:
    (MIDIReference, OMRReference, op)
    MIDIReference and OMRReference are actual note/rest/chord object in some stream
    op is a ChangeOp that relates the two references
    c                óv   •— t          j        ¦   «         }t          ¦   «                              ||||¦  «         d S r   )r   ÚTurnRecognizerr)   r   )r   r   r   r   Ú
recognizerr1   s        €r   r   zTurnFixer.__init__	  s5   ø€ Ý'Ô6Ñ8Ô8ˆ
Ý‰Œ×Ò˜ *¨i¸ÑDÔDÐDÐDÐDr   r§   r3   s   @r   r©   r©     sK   ø€ € € € € ðð ðEð Eð Eð Eð Eð Eð Eð Eð Er   r©   c                  ó2   — e Zd Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ ZdS )ÚTestc                óB   — ddl m}  || t          ¦   «         ¦  «         d S )Nr   )ÚtestCopyAll)Úmusic21.test.commonTestr°   Úglobals)r   r°   s     r   ÚtestCopyAndDeepcopyzTest.testCopyAndDeepcopy  s0   € Ø7Ð7Ð7Ð7Ð7Ð7Øˆ�D�'™)œ)Ñ$Ô$Ð$Ð$Ð$r   c                ó¬  — t          |¦  «        t          |¦  «        k    rd}d|fS t          t          |¦  «        ¦  «        D ]�}t          ||         j        ¦  «        t          ||         j        ¦  «        k    r(d|› d||         j        › d||         j        › d�}d|fc S ||         ||         k    rd|› d||         › d||         › d�}d|fc S Œ‘d	S )
a  
        Returns a tuple of (bool, reason) where the first element is
        whether the measures are equal and the second (`reason`) is a string
        explaining why they are unequal.

        Reason is an empty string if the measures are equal.
        znot equal lengthFzExpressions z
 unequal (z != ú)z	Elements z are unequal ()TÚ )ÚlenÚranger   )r   Úm1Úm2ÚmsgÚis        r   ÚmeasuresEqualzTest.measuresEqual  s  € õ ˆr‰7Œ7•c˜"‘g”gÒÐØ$ˆCØ˜#�:ÐÝ•s˜2‘w”w‘”ð 	"ð 	"ˆAÝ�2�a”5Ô$Ñ%Ô%­¨R°¬UÔ->Ñ)?Ô)?Ò?Ð?Ø] QÐ]Ð]°"°Q´%Ô2CÐ]Ð]ÈÈAÌÔIZÐ]Ð]Ð]�Ø˜c�zÐ!Ð!Ð!Ø�!Œu˜˜1œŠ~ˆ~ØF !ÐFÐF°2°a´5ÐFÐF¸bÀ¼eÐFÐFÐF�Ø˜c�zÐ!Ð!Ð!ð ð ˆxr   c                óž  — |d         }|d         }|d         }|d         }t          j        ||¬¦  «        }|                     ¦   «          t          |¦  «        }d}	|                      |                      ||j        ¦  «        d         |	¦  «          ||j        |j        |j        ¦  «        }
d}	|                      |                      ||j        ¦  «        d         |	¦  «         |
 	                    d	¬
¦  «        }d}	|                      ||j        ¦  «        \  }}|                      |||	z   |z   ¦  «         d}	|                      ||
j
        ¦  «        \  }}|                      |||	z   |z   ¦  «         d}	|                      |j
        |¦  «        \  }}|                      |||	z   |z   ¦  «         |
 	                    d¬
¦  «        }|                      ||¦  «         d}	|                      ||
j
        ¦  «        \  }}|                      |||	z   |z   ¦  «         d}	|                      ||¦  «        \  }}|                      |||	z   |z   ¦  «         dS )a  
        testCase is a dictionary with the following keys

        returnDict = {
            'name': string,
            'midi': measure stream,
            'omr': measure stream,
            'expected': fixed measure stream,
        }

        testFixer is an OMRMidiFixer
        ÚomrÚmidiÚexpectedrS   r€   z5Expect no changes from creating and aligning aligner.r   z&Expect no changes from creating fixer.F)r}   zB. Expect no changes to aligner source stream, but unequal because z=. Expect no changes to fixer omr stream, but unequal because z8. Appropriate changes in new fixer, but unequal because Tz<. Expect changes in fixer's omr stream, but unequal because z=. Expect changes in original omr stream, but unequal because N)r   rƒ   r„   r   Ú
assertTruer½   r�   r   r‚   r   r   ÚassertIsNone)r   ÚtestCaseÚ	testFixerr¿   rÀ   ÚexpectedOmrÚtestingNamerˆ   ÚomrCopyÚassertionCheckÚfixerÚnotInPlaceResultÚisEqualÚreasonÚfixerInPlaceResults                  r   ÚcheckFixerHelperzTest.checkFixerHelper&  sT  € ð �uŒoˆØ˜ÔˆØ˜zÔ*ˆØ˜vÔ&ˆõ Ô"°À$ÐGÑGÔGˆØ
�Š‰
Œ
ˆ
Ý˜3‘-”-ˆØPˆØ�Š˜×*Ò*¨7°B´OÑDÔDÀQÔGÈÑXÔXÐXð �	˜"œ* b¤o°r´ÑGÔGˆØAˆØ�Š˜×*Ò*¨7°B´OÑDÔDÀQÔGÈÑXÔXÐXð !Ÿ9š9¨U˜9Ñ3Ô3Ðà]ˆØ×,Ò,¨W°b´oÑFÔF‰ˆ�Ø�Š˜ ¨~Ñ!=ÀÑ!FÑGÔGÐGàXˆØ×,Ò,¨W°e´oÑFÔF‰ˆ�Ø�Š˜ ¨~Ñ!=ÀÑ!FÑGÔGÐGàSˆØ×,Ò,Ð-=Ô-GÈÑUÔU‰ˆ�Ø�Š˜ ¨~Ñ!=ÀÑ!FÑGÔGÐGð #ŸYšY¨t˜YÑ4Ô4ÐØ×ÒÐ,¨kÑ:Ô:Ð:àWˆØ×,Ò,¨[¸%¼/ÑJÔJ‰ˆ�Ø�Š˜ ¨~Ñ!=ÀÑ!FÑGÔGÐGàXˆØ×,Ò,¨[¸#Ñ>Ô>‰ˆ�Ø�Š˜ ¨~Ñ!=ÀÑ!FÑGÔGÐGÐGÐGr   c                óX	  — t          j        d¦  «        }t          j        d¦  «        |_        t	          j        ¦   «         }|                     |¦  «         t          |t          j        d¦  «        ¦  «        }|                      |t          j        ¦  «         |  	                    |gt          |j        ¦  «        d¦  «         t          |t          j        d¦  «        ¦  «        }|  	                    |gt          |j        ¦  «        d¦  «         t          |t          j        d¦  «        ¦  «        }|  	                    g t          |j        ¦  «        d¦  «         t	          j        ¦   «         }t          j        d¦  «        }t          j        d¦  «        |_        t          j        d	¦  «        }t          j        d¦  «        |_        |                     |||g¦  «         t          |t          j        d¦  «        ¦  «        }|  	                    |gt          |j        ¦  «        d¦  «         t          |t          j        d¦  «        ¦  «        }|  	                    |||gt          |j        ¦  «        d
¦  «         t          |t          j        d¦  «        ¦  «        }|  	                    |||gt          |j        ¦  «        d¦  «         t          |t          j        d¦  «        ¦  «        }|  	                    ||gt          |j        ¦  «        d¦  «         t          |t          j        d¦  «        ¦  «        }|  	                    ||gt          |j        ¦  «        d¦  «         t          |t          j        d¦  «        |¬¦  «        }|  	                    |gt          |j        ¦  «        d¦  «         t	          j        ¦   «         }d|_        t          j        ¦   «         }t          j        d¦  «        |_        |                     ||g¦  «         t          |t          j        d¦  «        ¦  «        }d}	|  	                    ||gt          |j        ¦  «        |	¦  «         t          |t          j        d¦  «        |¬¦  «        }|  	                    |||gt          |j        ¦  «        d¦  «         d S )NÚCÚquarterz$starting note occupies full durationÚhalfz'starting note occupies partial durationÚeighthzstarting note too longÚDÚEzall notes fill up full durationÚwholez"all notes fill up partial durationg      ø?z some notes fill up full durationg      ü?z#some notes fill up partial duration)rœ   z(partial fill up from reference stream m1Úm3z#note and rest fill up full durationz fill up from reference stream m2)r   r   r   ÚDurationr
   r—   r{   r†   ÚassertIsInstanceÚassertListEqualrb   r�   r-   ÚidÚRestÚnotesAndRests)
r   Ún1r¹   Úresultrº   Ún2Ún3rØ   Úr1r»   s
             r   ÚtestGetNotesWithinDurationzTest.testGetNotesWithinDuration_  sÝ  € ÝŒY�s‰^Œ^ˆÝÔ'¨	Ñ2Ô2ˆŒÝŒ]‰_Œ_ˆØ
�	Š	�"‰Œˆå'¨­HÔ,=¸iÑ,HÔ,HÑIÔIˆØ×Ò˜f¥f¤mÑ4Ô4Ð4Ø×Ò˜b˜T¥4¨¬Ñ#5Ô#5Ð7]Ñ^Ô^Ð^å'¨­HÔ,=¸fÑ,EÔ,EÑFÔFˆØ×Ò˜b˜T¥4¨¬Ñ#5Ô#5Ð7`ÑaÔaÐaå'¨­HÔ,=¸hÑ,GÔ,GÑHÔHˆØ×Ò˜R¥ f¤lÑ!3Ô!3Ð5MÑNÔNÐNåŒ^ÑÔˆÝŒY�s‰^Œ^ˆÝÔ'¨Ñ1Ô1ˆŒÝŒY�s‰^Œ^ˆÝÔ'¨Ñ1Ô1ˆŒØ
�	Š	�2�r˜2�,ÑÔÐå'¨­HÔ,=¸iÑ,HÔ,HÑIÔIˆØ×Ò˜b˜T¥4¨¬Ñ#5Ô#5Ð7]Ñ^Ô^Ð^å'¨­HÔ,=¸fÑ,EÔ,EÑFÔFˆØ×Ò˜b " b˜\­4°´Ñ+=Ô+=Ð?`ÑaÔaÐaå'¨­HÔ,=¸gÑ,FÔ,FÑGÔGˆØ×Ò˜b " b˜\­4°´Ñ+=Ô+=Ð?cÑdÔdÐdå'¨­HÔ,=¸cÑ,BÔ,BÑCÔCˆØ×Ò˜b "˜X¥t¨F¬LÑ'9Ô'9Ð;]Ñ^Ô^Ð^å'¨­HÔ,=¸dÑ,CÔ,CÑDÔDˆØ×Ò˜b "˜X¥t¨F¬LÑ'9Ô'9Ð;`ÑaÔaÐaõ (¨­HÔ,=¸fÑ,EÔ,EÐWYÐZÑZÔZˆØ×Ò˜b˜T¥4¨¬Ñ#5Ô#5Ð7aÑbÔbÐbåŒ^ÑÔˆØˆŒÝŒY‰[Œ[ˆÝÔ'¨	Ñ2Ô2ˆŒØ
�	Š	�2�r�(ÑÔÐÝ'¨­HÔ,=¸fÑ,EÔ,EÑFÔFˆØ3ˆØ×Ò˜b "˜X¥t¨FÔ,@Ñ'AÔ'AÀ3ÑGÔGÐGõ (¨­HÔ,=¸fÑ,EÔ,EÐWYÐZÑZÔZˆØ×Ò˜b " b˜\­4°´Ñ+=Ô+=Ð?aÑbÔbÐbÐbÐbr   c                óÂ   — d„ }d„ }d„ }d„ }d„ } |¦   «          |¦   «          |¦   «          |¦   «          |¦   «         g}|D ]}|                       |t          ¦  «         Œd S )Nc            
     óf  — t          j        d¦  «        } t          j        d¦  «        }t          j        d¦  «        }| |_         t          j        d¦  «        }||_         t          j        d¦  «        }||_         ||t	          |¦  «        t	          |¦  «        g}t          j        d¦  «        }t          j        d¦  «        }| |_         t          j        d¦  «        }||_         t          j        d¦  «        }	||	_         |	|t	          |	¦  «        t	          |¦  «        t	          |	¦  «        t	          |¦  «        t	          |	¦  «        t	          |¦  «        g}
t          j        ¦   «         }|                     |¦  «         |                     |
¦  «         t          j        ¦   «         }|                     ||g¦  «         t          j        ¦   «         }t	          |¦  «        }t          j	        ¦   «         }t          j        d¦  «        |_        |j        |_        |j                             |¦  «         t	          |¦  «        }t          j	        ¦   «         }t          j        d	¦  «        |_        |j        |_        |j                             |¦  «         |                     ||g¦  «         d
|||dœ}|S )á  
            Returns a dictionary with the following keys

            returnDict = {
                'name': string,
                'midi': measure stream,
                'omr': measure stream,
                'expected': measure stream,
            }
            rÒ   ç      Ð?ÚGÚAg      °?ÚB3rÑ   zm-2ÚM2zDouble Trill Measure©rS   rÀ   r¿   rÁ   )r   rÙ   r   r   r   r
   r-   r{   r   ÚTrillr   rG   Úsizer˜   )ÚnoteDurationÚtrill1NoteDurationÚn0rß   rá   Útrill1Útrill2NoteDurationrâ   Ún4Ún5Útrill2ÚmidiMeasureÚ
omrMeasureÚexpectedFixedOmrMeasureÚn0WithTrillÚn0TrillÚn1WithTrillÚn1TrillÚ
returnDicts                      r   ÚcreateDoubleTrillMeasurez5Test.testTrillFixer.<locals>.createDoubleTrillMeasure—  sI  € õ $Ô,¨YÑ7Ô7ˆLõ "*Ô!2°3Ñ!7Ô!7ÐÝ”˜3‘”ˆBØ&ˆBŒKÝ”˜3‘”ˆBØ,ˆBŒKÝ”˜3‘”ˆBØ,ˆBŒKØ˜"�h r™lœl­H°R©L¬LÐ9ˆFõ "*Ô!2°5Ñ!9Ô!9ÐÝ”˜4‘”ˆBØ&ˆBŒKÝ”˜4‘”ˆBØ,ˆBŒKÝ”˜3‘”ˆBØ,ˆBŒKØ˜"�h r™lœl­H°R©L¬LÝ˜r‘l”l¥H¨R¡L¤Lµ(¸2±,´,ÅÈÁÄðNˆFõ !œ.Ñ*Ô*ˆKØ×Ò˜vÑ&Ô&Ð&Ø×Ò˜vÑ&Ô&Ð&åœÑ)Ô)ˆJØ×Ò˜r 2˜hÑ'Ô'Ð'å&,¤nÑ&6Ô&6Ð#Ý" 2™,œ,ˆKÝ!Ô'Ñ)Ô)ˆGÝ#Ô,¨UÑ3Ô3ˆGŒLØ$6Ô$DˆGÔ!ØÔ#×*Ò*¨7Ñ3Ô3Ð3Ý" 2™,œ,ˆKÝ!Ô'Ñ)Ô)ˆGÝ#Ô,¨TÑ2Ô2ˆGŒLØ$6Ô$DˆGÔ!ØÔ#×*Ò*¨7Ñ3Ô3Ð3Ø#×*Ò*¨K¸Ð+EÑFÔFÐFð /Ø#Ø!Ø3ð	ð ˆJð Ðr   c                 ó   — t          j        d¦  «        } t          j        d¦  «        }| |_         t          j        d¦  «        }t          j        d¦  «        |_         t          j        d¦  «        }t          j        d¦  «        |_         ||t	          |¦  «        t	          |¦  «        g}t          j        ¦   «         }|                     |¦  «         t          j        ¦   «         }|                     |¦  «         d||t	          |¦  «        dœ}|S )rç   rÒ   rÑ   rè   rê   z*Non-Trill Measure Wrong Oscillate Intervalrí   ©r   rÙ   r   r   r   r
   r-   r{   ©rð   rò   rß   rá   ÚnonTrillrø   rù   rÿ   s           r   ÚcreateWrongTrillMeasurez4Test.testTrillFixer.<locals>.createWrongTrillMeasureÕ  sí   € õ $Ô,¨YÑ7Ô7ˆLå”˜3‘”ˆBØ&ˆBŒKÝ”˜3‘”ˆBÝ"Ô+¨CÑ0Ô0ˆBŒKÝ”˜3‘”ˆBÝ"Ô+¨CÑ0Ô0ˆBŒKà˜B¥¨¡¤­h°r©l¬lÐ;ˆHå œ.Ñ*Ô*ˆKØ×Ò˜xÑ(Ô(Ð(ÝœÑ)Ô)ˆJØ×Ò˜bÑ!Ô!Ð!ð EØ#Ø!Ý$ ZÑ0Ô0ð	ð ˆJð Ðr   c                 ó   — t          j        d¦  «        } t          j        d¦  «        }| |_         t          j        d¦  «        }t          j        d¦  «        |_         t          j        d¦  «        }t          j        d¦  «        |_         ||t	          |¦  «        t	          |¦  «        g}t          j        ¦   «         }|                     |¦  «         t          j        ¦   «         }|                     |¦  «         d||t	          |¦  «        dœ}|S )rç   rÒ   rê   rÑ   rè   rÕ   zNon-Trill Measure Wrong Notesrí   r  r  s           r   ÚcreateNonTrillMeasurez2Test.testTrillFixer.<locals>.createNonTrillMeasureø  sì   € õ $Ô,¨YÑ7Ô7ˆLå”˜3‘”ˆBØ&ˆBŒKÝ”˜3‘”ˆBÝ"Ô+¨CÑ0Ô0ˆBŒKÝ”˜3‘”ˆBÝ"Ô+¨CÑ0Ô0ˆBŒKà˜B¥¨¡¤­h°r©l¬lÐ;ˆHå œ.Ñ*Ô*ˆKØ×Ò˜xÑ(Ô(Ð(ÝœÑ)Ô)ˆJØ×Ò˜bÑ!Ô!Ð!ð 8Ø#Ø!Ý$ ZÑ0Ô0ð	ð ˆJð Ðr   c                 óˆ  — t          j        d¦  «        } t          j        d¦  «        }t          j        d¦  «        }| |_         t          j        d¦  «        }||_         t          j        d¦  «        }||_         t          j        d¦  «        }||_         ||t	          |¦  «        t	          |¦  «        g}t	          |¦  «        t	          |¦  «        t	          |¦  «        |g}||z   }t          j        ¦   «         }	|	                     |¦  «         t          j        ¦   «         }
|
                     |¦  «         t          j	        ¦   «         }d|_
        |j        |_        t          j        ¦   «         }t	          |¦  «        }|j                             t	          |¦  «        ¦  «         |                     |¦  «         d|	|
|dœ}|S )	rç   rÒ   ç      À?rÖ   ÚFrÕ   TzNachschlag Trillrí   )r   rÙ   r   r   r   r
   r-   r{   r   rî   Ú
nachschlagr˜   )rð   ÚtrillDurationrò   Útn1Útn2Útn3ÚfirstHalfTrillÚsecondHalfTrillÚexpandedTrillrø   rù   ÚnachschlagTrillrú   ÚnoteWithTrillrÿ   s                  r   ÚcreateNachschlagTrillMeasurez9Test.testTrillFixer.<locals>.createNachschlagTrillMeasure  s‰  € õ $Ô,¨YÑ7Ô7ˆLÝ$Ô-¨dÑ3Ô3ˆMå”˜3‘”ˆBØ&ˆBŒKå”)˜C‘.”.ˆCØ(ˆCŒLÝ”)˜C‘.”.ˆCØ(ˆCŒLÝ”)˜C‘.”.ˆCØ(ˆCŒLØ! 3­°©¬µxÀ±}´}ÐEˆNÝ'¨™}œ}­h°s©m¬m½XÀc¹]¼]ÈCÐPˆOØ*¨_Ñ<ˆMå œ.Ñ*Ô*ˆKØ×Ò˜}Ñ-Ô-Ð-ÝœÑ)Ô)ˆJØ×Ò˜bÑ!Ô!Ð!å)Ô/Ñ1Ô1ˆOØ)-ˆOÔ&Ø,9Ô,GˆOÔ)Ý&,¤nÑ&6Ô&6Ð#Ý$ R™LœLˆMØÔ%×,Ò,­X°oÑ-FÔ-FÑGÔGÐGØ#×*Ò*¨=Ñ9Ô9Ð9ð +Ø#Ø!Ø3ð	ð ˆJð Ðr   c                 ór  — t          j        d¦  «        } t          j        d¦  «        }t          j        d¦  «        }| |_         t	          j        ¦   «         }|j        |_        |j                             |¦  «         t          j        d¦  «        }||_         t          j        d¦  «        }||_         ||t          |¦  «        t          |¦  «        g}t          j
        ¦   «         }|                     |¦  «         t          j
        ¦   «         }|                     |¦  «         d||t          |¦  «        dœ}	|	S )rç   rÒ   r	  r
  ré   zOMR with Trill Notationrí   )r   rÙ   r   r   r   rî   r˜   r{   r   r
   r-   )
rð   r  r  Útrillr  r  r  rø   rù   rÿ   s
             r   ÚcreateMeasureWithTrillAlreadyz:Test.testTrillFixer.<locals>.createMeasureWithTrillAlreadyM  s  € õ $Ô,¨YÑ7Ô7ˆLÝ$Ô-¨dÑ3Ô3ˆMå œI c™NœNˆMØ%1ˆMÔ"ÝÔ%Ñ'Ô'ˆEØ"/Ô"=ˆEÔØÔ%×,Ò,¨UÑ3Ô3Ð3å”)˜C‘.”.ˆCØ(ˆCŒLÝ”)˜C‘.”.ˆCØ(ˆCŒLØ  #¥x°¡}¤}µh¸s±m´mÐDˆMå œ.Ñ*Ô*ˆKØ×Ò˜}Ñ-Ô-Ð-ÝœÑ)Ô)ˆJØ×Ò˜mÑ,Ô,Ð,ð 2Ø#Ø!Ý$ ZÑ0Ô0ð	ð ˆJð Ðr   )rÏ   r‡   )r   r   r  r  r  r  ÚtestConditionsrÄ   s           r   ÚtestTrillFixerzTest.testTrillFixer–  sË   € ð<	ð <	ð <	ð|!	ð !	ð !	ðF"	ð "	ð "	ðH/	ð /	ð /	ðb%	ð %	ð %	ðP %Ð$Ñ&Ô&Ø#Ð#Ñ%Ô%Ø!Ð!Ñ#Ô#Ø(Ð(Ñ*Ô*Ø)Ð)Ñ+Ô+ð
ˆð 'ð 	8ð 	8ˆHØ×!Ò! (­JÑ7Ô7Ð7Ð7ð	8ð 	8r   c                ó’   — d„ }d„ }d„ } |¦   «          |¦   «          |¦   «         g}|D ]}|                       |t          ¦  «         Œd S )Nc                 ón  — t          j        ¦   «         } t          j        d¦  «        }t	          j        d¦  «        |_        |                      |¦  «         t          j        ¦   «         }t          |¦  «        }|j	                             t          j
        ¦   «         ¦  «         |                     |¦  «         t          j        ¦   «         }t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        g}|                     |¦  «         d|| |dœ}|S )rç   r
  r×   ré   rÖ   zSingle Turn Measurerí   )r
   r-   r   r   r   rÙ   r{   r—   r   r   ÚTurn)rù   ÚomrNoterú   ÚexpectedOmrNoterø   Úturnrÿ   s          r   ÚcreateSingleTurnMeasurez3Test.testTurnFixer.<locals>.createSingleTurnMeasure€  s  € õ  œÑ)Ô)ˆJÝ”i ‘n”nˆGÝ'Ô0°Ñ9Ô9ˆGÔØ×Ò˜gÑ&Ô&Ð&å&,¤m¡o¤oÐ#Ý& wÑ/Ô/ˆOØÔ'×.Ò.­{Ô/?Ñ/AÔ/AÑBÔBÐBØ#×*Ò*¨?Ñ;Ô;Ð;å œ.Ñ*Ô*ˆKÝ”I˜c‘N”N¥D¤I¨c¡N¤NµD´I¸c±N´NÅDÄIÈcÁNÄNÐSˆDØ×Ò˜tÑ$Ô$Ð$ð .Ø#Ø!Ø3ð	ð ˆJð Ðr   c                 ó`  — t          j        ¦   «         } t          j        d¦  «        }t          j        d¦  «        }t          j        d¦  «        }|                      |||g¦  «         t          j        ¦   «         }t          |¦  «        }|j                             t          j        ¦   «         ¦  «         t          |¦  «        }|j                             t          j        ¦   «         ¦  «         |                     |t          |¦  «        |g¦  «         t          j        ¦   «         }t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        g}t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        g}	|D ]}
t          j
        d¦  «        |
_	        Œ|	D ]}
t          j
        d¦  «        |
_	        Œ|                     g |¢t          |¦  «        ‘|	¢¦  «         d	|| |d
œ}|S )rç   zB-ré   rê   ÚC5zG#zA#ÚBrè   z>Inverted turns with accidentals separated By non-ornament Noterí   )r
   r-   r   r   r{   r—   r   r   ÚInvertedTurnr   rÙ   )rù   ÚomrNote1Ú
middleNoteÚomrNote2rú   ÚexpectOmrNote1ÚexpectOmrNote2rø   Úturn1Úturn2Únrÿ   s               r   ÚcreateDoubleInvertedTurnMeasurez;Test.testTurnFixer.<locals>.createDoubleInvertedTurnMeasure¡  sß  € õ  œÑ)Ô)ˆJÝ”y ‘”ˆHÝœ 3™œˆJÝ”y ‘”ˆHØ×Ò˜x¨°XÐ>Ñ?Ô?Ð?õ '-¤m¡o¤oÐ#Ý% hÑ/Ô/ˆNØÔ&×-Ò-­kÔ.FÑ.HÔ.HÑIÔIÐIÝ% hÑ/Ô/ˆNØÔ&×-Ò-­kÔ.FÑ.HÔ.HÑIÔIÐIØ#×*Ò*¨N½HÀZÑ<PÔ<PÐR`Ð+aÑbÔbÐbå œ.Ñ*Ô*ˆKÝ”Y˜s‘^”^¥T¤Y¨t¡_¤_µd´iÀ±o´oÅtÄyÐQUÁÄÐWˆEÝ”Y˜t‘_”_¥d¤i°¡o¤oµt´yÀ±~´~ÅtÄyÐQUÁÄÐWˆEØð 4ð 4�Ý%Ô.¨sÑ3Ô3�”
�
Øð 4ð 4�Ý%Ô.¨sÑ3Ô3�”
�
Ø×ÒÐE ÐE­°Ñ(<Ô(<ÐE¸uÐEÑFÔFÐFð YØ#Ø!Ø3ð	ð ˆJð Ðr   c                 óÄ  — t          j        ¦   «         } t          j        d¦  «        }t	          j        d¦  «        |_        |                      |¦  «         t          j        ¦   «         }t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        t          j        d¦  «        g}|                     |¦  «         d|| t          | ¦  «        dœ}|S )rç   rê   r×   r$  ré   r
  zNon-Turn Measurerí   )r
   r-   r   r   r   rÙ   r{   r   )rù   r  rø   r   rÿ   s        r   ÚcreateNonTurnMeasurez0Test.testTurnFixer.<locals>.createNonTurnMeasureË  s¾   € õ  œÑ)Ô)ˆJÝ”i ‘n”nˆGÝ'Ô0°Ñ9Ô9ˆGÔØ×Ò˜gÑ&Ô&Ð&å œ.Ñ*Ô*ˆKÝ”I˜c‘N”N¥D¤I¨c¡N¤NµD´I¸c±N´NÅDÄIÈcÁNÄNÐSˆDØ×Ò˜tÑ$Ô$Ð$ð +Ø#Ø!Ý$ ZÑ0Ô0ð	ð ˆJð Ðr   )rÏ   r©   )r   r!  r.  r0  r  rÄ   s         r   ÚtestTurnFixerzTest.testTurnFixer  s’   € ð	ð 	ð 	ðB(	ð (	ð (	ðT	ð 	ð 	ð8 2Ð1Ñ3Ô3Ø9Ð9Ñ;Ô;Ø.Ð.Ñ0Ô0ð2ˆð 'ð 	7ð 	7ˆHØ×!Ò! (­IÑ6Ô6Ð6Ð6ð	7ð 	7r   N)	r"   r#   r$   r³   r½   rÏ   rä   r  r1  r   r   r   r®   r®     s   € € € € € ð%ð %ð %ðð ð ð(7Hð 7Hð 7Hðr5cð 5cð 5cðng8ð g8ð g8ðRm7ð m7ð m7ð m7ð m7r   r®   Ú__main__r   )Ú
__future__r   Úcopyr   ÚunittestÚmusic21r   r   r   r   r	   r
   Úmusic21.alpha.analysisr   r   r   r'   r5   r_   r†   r‡   r©   ÚTestCaser®   r"   ÚmainTestr   r   r   ú<module>r:     sb  ðð #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ð Ð Ø €€€à Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à *Ð *Ð *Ð *Ð *Ð *Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5ðð ð ð ð ñ ô ð ð&%ð %ð %ð %ð %�,ñ %ô %ð %ð4Wð Wð Wð Wð W�lñ Wô Wð Wðrqð qð qð qð q�Lñ qô qð qðfð ð ð ð@Fð Fð Fð Fð F�ñ Fô Fð Fð
Eð 
Eð 
Eð 
Eð 
E�ñ 
Eô 
Eð 
Eð_7ð _7ð _7ð _7ð _7ˆ8Ôñ _7ô _7ð _7ðD ˆzÒÐØ€N€N€NØ€GÔ�TÑÔÐÐÐð Ðr   