
    3j                       d Z ddlm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 ej                  rddlmZ  G d	 d
e
j                        Z G d dej                         Zedk(  rddlZ ej&                  e       yy)z
This module contains classes for representing unpitched events such as percussion.
For backwards compatibility reasons, the module does not contain the actual
:class:`~music21.note.Unpitched` which is in the `note` module.
    )annotations)IterableN)common)chord)note)pitchc                       e Zd ZdZdZd fd	Z fdZd Zedd       Z	e	j                  dd       Z	d fdZedd	       Zej                  dd
       Z xZS )PercussionChorda  
    A representation of one or (normally) more than one unpitched object sharing a stem
    and treated like a "chord."  It may also contain standard notes (pitches) for cases
    such as a percussionist playing a cymbal and marimba at the same time.

    It is a :class:`~music21.chord.ChordBase` and `:class:`~music21.note.NotRest` subclass
    that is NOT a :class:`~music21.chord.Chord` because one or more
    notes is an :class:`~music21.note.Unpitched`
    object.

    >>> vibraslapNote = note.Unpitched(displayName='D4', storedInstrument=instrument.Vibraslap())
    >>> pChord = percussion.PercussionChord([vibraslapNote, note.Note('E5')])
    >>> pChord
    <music21.percussion.PercussionChord [Vibraslap E5]>

    >>> pChord.isChord
    False

    A PercussionChord has "notes," just like anything deriving from ChordBase.  Some of these
    are Unpitched objects.

    >>> pChord.notes
    (<music21.note.Unpitched 'Vibraslap'>, <music21.note.Note E>)

    The same notes can also be assigned to another PercussionChord:

    >>> pChord2 = percussion.PercussionChord()
    >>> pChord2.notes = pChord.notes
    >>> pChord2.notes
    (<music21.note.Unpitched 'Vibraslap'>, <music21.note.Note E>)

    Don't attempt setting anything but Note or Unpitched objects as notes:

    >>> pChord2.notes = [note.Rest()]
    Traceback (most recent call last):
    TypeError: every element of notes must be a note.Note or note.Unpitched object

    **Equality**

    Two PercussionChord objects are equal if their notes are equal *and in the same
    order* (this is different from Chord, but necessary because we cannot compare
    based just on pitch equality)

    >>> pChord == pChord2
    True
    >>> pChord3 = percussion.PercussionChord([note.Unpitched('D4')])
    >>> pChord == pChord3
    False

    OMIT_FROM_DOCS

    See the repr of an empty percussion chord:

    >>> percussion.PercussionChord()
    <music21.percussion.PercussionChord object at 0x...>

    This is in OMIT
    Fc                X    t         |   |      }|j                  D ]	  }||_         |S )N)memo)super__deepcopy___notes_chordAttached)selfr   newn	__class__s       ?/DATA/.local/lib/python3.12/site-packages/music21/percussion.pyr   zPercussionChord.__deepcopy__]   s0    g""-A"A 
    c                    t         |   |      syt        | j                  |j                        D ]  \  }}||k7  s y y)zP
        Returns True if all the notes are equal and in the same order.
        FT)r   __eq__zipnotes)r   othermy_nother_nr   s       r   r   zPercussionChord.__eq__c   s@     w~e$ U[[9MD'w : r   c                    t        |       dz	  S )N   )idr   s    r   __hash__zPercussionChord.__hash__o   s    $x1}r   c                ,    t        | j                        S Ntupler   r!   s    r   r   zPercussionChord.notesr   s    T[[!!r   c                    t        j                  |      st        d      t        d |D              st        d      | j                  j                          | j                  |       y)zH
        Sets notes to an iterable of Note or Unpitched objects
        z"notes must be set with an iterablec              3  p   K   | ].  }t        |t        j                  t        j                  f       0 y wr$   )
isinstancer   	UnpitchedNote).0r   s     r   	<genexpr>z(PercussionChord.notes.<locals>.<genexpr>}   s%     Px!:a$..$))!<=xs   46zCevery element of notes must be a note.Note or note.Unpitched objectN)r   
isIterable	TypeErrorallr   clearadd)r   newNotess     r   r   zPercussionChord.notesv   sT    
   *@AAPxPPabbr   c                   | j                   st        | 	         S g }| j                   D ]  }t        |t        j
                        r|j                  |j                         9t        |t        j                        sT|j                  r/|j                  t        |j                  j                               |j                  d|j                   d        ddj                  |      z   dz   S )Nz
unpitched[][ )r   r   _reprInternalr)   r   r+   appendnameWithOctaver*   storedInstrumentstrinstrumentNamedisplayNamejoin)r   allNotesthisNoter   s      r   r8   zPercussionChord._reprInternal   s    zz7(**

H(DII. 7 78Hdnn5,,OOC(A(A(P(P$QROOj1E1E0Fa$HI # SXXh''#--r   c                >    t        d | j                  D              }|S )aQ  
        Get or set a list or tuple of all Pitch objects in this PercussionChord.

        Unpitched members (that at most have only display pitches) are ignored.

        >>> pChord = percussion.PercussionChord([note.Unpitched(displayName='D4'), note.Note('E5')])
        >>> pChord.pitches
        (<music21.pitch.Pitch E5>,)

        >>> pChord.pitches = [60]
        >>> pChord.pitches
        (<music21.pitch.Pitch C4>,)

        Notice that setting pitches has now just cleared any existing notes, pitched or unpitched:

        >>> pChord.notes
        (<music21.note.Note C>,)
        c              3  j   K   | ]+  }t        |t        j                        s|j                   - y wr$   )r)   r   r+   r   )r,   	components     r   r-   z*PercussionChord.pitches.<locals>.<genexpr>   s)      1^-8	JyRVR[R[<\IOO[s   33r%   )r   pitchess     r   rE   zPercussionChord.pitches   s'    ( ,1 1^-1[[1^ ,^r   c                |    g | _         |D ]0  }| j                   j                  t        j                  |             2 y r$   )r   r9   r   r+   )r   valueps      r   rE   zPercussionChord.pitches   s-    AKKtyy|, r   r$   )returnztuple[note.NotRest, ...])r3   z$Iterable[note.Unpitched | note.Note]rI   None)rI   r<   )rI   ztuple[pitch.Pitch, ...])rG   zt.Iterable[pitch.Pitch]rI   rJ   )__name__
__module____qualname____doc__isChordr   r   r"   propertyr   setterr8   rE   __classcell__)r   s   @r   r
   r
       s|    9t G
 " " \\	 	."  . ^^- -r   r
   c                      e Zd Zy)TestN)rK   rL   rM    r   r   rT   rT      s    r   rT   __main__)rN   
__future__r   collections.abcr   typingtunittestmusic21r   r   r   TYPE_CHECKINGr   	ChordBaser
   TestCaserT   rK   mainTestrU   r   r   <module>ra      st   
 # $      ??Q-eoo Q-h	8 	 zGT r   