o
    OZh#z                     @   s  U d Z ddlmZ ddlZddlZddlmZmZmZm	Z	m
Z
mZmZmZ ddlZddlZdZdd Zdd	 Zd1d
dZd1ddZdd ZG dd dZe ZeG dd dZG dd dZd2deej fddZdeejeeejf f fddZG dd dZ dd  Z!d!d" Z"d#d$ Z#d3d&d'Z$e%d(krdZ&e
e' e(d)< z	e'ej)d* Z&W n e*y   dZ&Y nw d+ej)v sd,ej)v ree& n d-ej)v sd.ej)v ree& nd/ej)v sd0ej)v re  ne#  e+  dS dS )4z pygame.examples.midi

midi input, and a separate example of midi output.

By default it runs the output example.

python -m pygame.examples.midi --output
python -m pygame.examples.midi --input
python -m pygame.examples.midi --input
    )	dataclassN)AnyDictListLiteralOptionalSetTupleUnionZ	slategrayc                   C   s   t j  t  t j  d S N)pygamemidiinit_print_device_infoquit r   r   C/var/www/auris/lib/python3.10/site-packages/pygame/examples/midi.pyprint_device_info   s   
r   c                  C   s\   t tj D ]$} tj| }|\}}}}}d}|rd}|r d}td| ||||f  qd S )N z(input)z(output)z/%2i: interface :%s:, name :%s:, opened :%s:  %s)ranger   r   Z	get_countZget_device_infoprint)irZinterfnameinputoutputZopenedZin_outr   r   r   r      s   r   c           	      C   s   t   tj  t  | d u rtj }n| }td| d tj|}t j	d d}|rvtj
 }|D ] }|jt jfv rBd}|jt jfv rKd}|jtjjfv rWt| q7| rt|d}tj||j}|D ]}tj
| qk|s0~tj  d S )Nzusing input_id ::)   r   TF
   )pgr   r   r   r   Zget_default_input_idr   ZInputdisplayset_modeeventgettypeQUITKEYDOWNZMIDIINpollreadZmidis2events	device_idpostr   )	r)   Zinput_idr   ZgoingeventseZmidi_eventsZmidi_evsZm_er   r   r   
input_main0   s8   


r-   c                 C   s<  d}|}d}d}t tjtjtjtjtjtjtjtj	tj
tjtjtjtjtjtjtjtjtjtjtjtjtjtjtjg|}t  tj  t  | du rStj }n| }td| d tj |d}z1|!| t"||}tj#$|j%j&}	|	't( tj#)  t*|	+ }
|
't( g }|,|	|
| tj#-| t*|	+ }|.| tj/0tj1 d}t2 }	 tj/3 }|j4tj5kr|6|j7\}}}}|r||vr|8| |9|| |:| nd}n|j4tj;kr|r|<| |=| |>| d}nv|j4tj?krn~|j4tj@kr@|jAtjBkrnxz	||jA \}}W n
 tCy)   Y nLw ||vr?|8| |9|| |:| n5|j4tjDkruz	||jA \}}W n
 tCyZ   Y nw ||v ru||kru|=| |<|d |>| g }|,|	|
| tj#-| qW ~tjE  dS W ~tjE  dS ~tjE  w )a  Execute a musical keyboard example for the Church Organ instrument

    This is a piano keyboard example, with a two octave keyboard, starting at
    note F3. Left mouse down over a key starts a note, left up stops it. The
    notes are also mapped to the computer keyboard keys, assuming an American
    English PC keyboard (sorry everyone else, but I don't know if I can map to
    absolute key position instead of value.) The white keys are on the second
    row, TAB to BACKSLASH, starting with note F3. The black keys map to the top
    row, '1' to BACKSPACE, starting with F#3. 'r' is middle C. Close the
    window or press ESCAPE to quit the program. Key velocity (note
    amplitude) varies vertically on the keyboard image, with minimum velocity
    at the top of a key and maximum velocity at bottom.

    Default Midi output, no device_id given, is to the default output device
    for the computer.

       5      Nzusing output_id :r   r   )Fmake_key_mappingr   ZK_TABZK_1ZK_qZK_2ZK_wZK_3ZK_eZK_rZK_5ZK_tZK_6ZK_yZK_uZK_8ZK_iZK_9ZK_oZK_0ZK_pZK_LEFTBRACKETZK_EQUALSZK_RIGHTBRACKETZK_BACKSPACEZK_BACKSLASHr   r   r   r   Zget_default_output_idr   OutputZset_instrumentKeyboardr    r!   rectsizefillBACKGROUNDCOLORflipSurfaceget_sizedrawupdatemap_regionsr"   Zset_blockedZMOUSEMOTIONsetwaitr$   ZMOUSEBUTTONDOWNZget_atposkey_downZnote_onaddZMOUSEBUTTONUPZnote_offkey_upremover%   r&   keyZK_ESCAPEKeyErrorZKEYUPr   )r)   ZCHURCH_ORGANZ
instrument
start_noten_notesZkey_mappingportZmidi_outkeyboardscreen
backgrounddirty_rectsregionsZ
mouse_noteZon_notesr,   velocity__noter   r   r   output_mainX   s   +
















rR   c                 C   s*   i }t | D ]\}}|| df||< q|S )zEReturn a dictionary of (note, velocity) by computer keyboard key code   )	enumerate)keysrG   mappingr   rE   r   r   r   r1      s   r1   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )NullKeyzA dummy key that ignores events passed to it by other keys

    A NullKey instance is the left key instance used by default
    for the left most keyboard key.

    c                 C      d S r   r   selfr   r   r   _right_white_down
     zNullKey._right_white_downc                 C   rX   r   r   rY   r   r   r   _right_white_up  r\   zNullKey._right_white_upc                 C   rX   r   r   rY   r   r   r   _right_black_down  r\   zNullKey._right_black_downc                 C   rX   r   r   rY   r   r   r   _right_black_up  r\   zNullKey._right_black_upN)__name__
__module____qualname____doc__r[   r]   r^   r_   r   r   r   r   rW     s    rW   c                   @   s  e Zd ZU dZeed< eed< eed< eed< ejed< e	ed< e	ed< e
e ed	< eeeeejf f ed
< eeeeejf f ed< ejed< eeeeeejdf f f ed< eeeeeejdf f f ed< eeeeeejdf f f ed< eeeeeejdf f f ed< dS )KeyDataz8Used for passing in data to subclasses of the Key class.is_white_keyc_widthc_heightc_down_state_initialc_down_state_rect_initialc_notify_down_methodc_notify_up_method	c_updatesc_event_down
c_event_upc_image_stripNc_event_right_white_downc_event_right_white_upc_event_right_black_downc_event_right_black_up)r`   ra   rb   rc   bool__annotations__intr   Rectstrr   r   r   r	   r9   r
   r   r   r   r   rd     s"   
 

"""&rd   c                   @   st   e Zd ZU dZeed< dddZdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )Keya  A key widget, maintains key state and draws the key's image

    Constructor arguments:
    ident - A unique key identifier. Any immutable type suitable as a key.
    posn - The location of the key on the display surface.
    key_left - Optional, the adjacent white key to the left. Changes in
        up and down state are propagated to that key.

    A key has an associated position and state. Related to state is the
    image drawn. State changes are managed with method calls, one method
    per event type. The up and down event methods are public. Other
    internal methods are for passing on state changes to the key_left
    key instance.

    key_dataNc                 C   s   |du rt }t|d |d | jj| jj}|| _| jj| _| jj	| _
|| _t|| _t|| jj| _t|| jj| _|| _t|j|jd | jjd| _| jj|  | jj| _dS )zzReturn a new Key instance

        The initial state is up, with all adjacent keys to the right also
        up.

        Nr   r   r   )null_keyr   rw   rz   rf   rg   r4   rh   _stateri   _source_rect_identhash_hashgetattrrj   _notify_downrk   
_notify_upZ	_key_leftleftbottom_background_rectrl   rB   re   is_white)rZ   identZposnZkey_leftr4   r   r   r   __init__B  s     


zKey.__init__c                 C   @   | j j| j \| _}|dur|| _| j j|  |   dS dS )z1Signal that this key has been depressed (is down)N)rz   rm   r|   r}   rl   rB   r   rZ   Zsource_rectr   r   r   downZ     zKey.downc                 C   r   )z.Signal that this key has been released (is up)N)rz   rn   r|   r}   rl   rB   r   r   r   r   r   upc  r   zKey.upc                 C   8   | j j| j \| _}|dur|| _| j j|  dS dS )zSignal that the adjacent white key has been depressed

        This method is for internal propagation of events between
        key instances.

        N)rz   rp   r|   r}   rl   rB   r   r   r   r   r[   l  
   zKey._right_white_downc                 C   r   )zSignal that the adjacent white key has been released

        This method is for internal propagation of events between
        key instances.

        N)rz   rq   r|   r}   rl   rB   r   r   r   r   r]   y  r   zKey._right_white_upc                 C   r   )zSignal that the adjacent black key has been depressed

        This method is for internal propagation of events between
        key instances.

        N)rz   rr   r|   r}   rl   rB   r   r   r   r   r^     r   zKey._right_black_downc                 C   r   )zSignal that the adjacent black key has been released

        This method is for internal propagation of events between
        key instances.

        N)rz   rs   r|   r}   rl   rB   r   r   r   r   r_     r   zKey._right_black_upc                 C   s   | j |j kS )zTrue if same identifiers)r~   )rZ   otherr   r   r   __eq__  s   z
Key.__eq__c                 C   s   | j S )zReturn the immutable hash value)r   rY   r   r   r   __hash__  s   zKey.__hash__c                 C   s   d| j | jj| jjf S )z4Return the key's identifier and position as a stringz<Key %s at (%d, %d)>)r~   r4   topr   rY   r   r   r   __str__  s   zKey.__str__c                 C   s8   | || j| j | | jj| j| j || j dS )zRedraw the key on the surface surf

        The background is redrawn. The altered region is added to the
        dirty_rects list.

        N)Zblitr   rz   ro   r4   r}   append)rZ   surfrL   rM   r   r   r   r;     s   zKey.drawr   )r`   ra   rb   rc   rd   ru   r   r   r   r[   r]   r^   r_   r   r   r   r;   r   r   r   r   ry   /  s   
 
		ry   Timage_rectsc                    s  d}d}|d> }||B }|d> }||B }	||B }
||
B }| |d | |	|d j \r2d}nd}d| d
d| d|||d fi|||d fi||df||dfi   t|d	kr||d	 f|< ||d f|< |df|< ||d	 f|< |df|< ||d f|< |df|< |df|< |df|< |df|< t|d
kr3|	|d f|< ||d f|
< ||d
 f|	< |
|d
 f|< |
df|< ||d f|	< |df|
< |	|d f|< ||d
 f|< |	|d f|< |
|d
 f|< ||d f|< ||d f|< ||d f|	< ||d f|
< ||d	 f|< G  	
fdddt}|S )a  Return a keyboard key widget class

    Arguments:
    updates - a set into which a key instance adds itself if it needs
        redrawing.
    image_strip - The surface containing the images of all key states.
    image_rects - A list of Rects giving the regions within image_strip that
        are relevant to this key class.
    is_white_key (default True) - Set false if this is a black key.

    This function automates the creation of a key widget class for the
    three basic key types. A key has two basic states, up or down (
    depressed). Corresponding up and down images are drawn for each
    of these two states. But to give the illusion of depth, a key
    may have shadows cast upon it by the adjacent keys to its right.
    These shadows change depending on the up/down state of the key and
    its neighbors. So a key may support multiple images and states
    depending on the shadows. A key type is determined by the length
    of image_rects and the value of is_white.

    r   r   whiteblackZ_right_Z_downZ_upN            c                       s0   e Zd Ze 
	ZdS )zkey_class.<locals>.OurKeyN)r`   ra   rb   rd   rz   r   rh   ri   rm   rr   rs   rp   rq   rn   rg   ro   rj   rk   rl   rf   re   r   r   OurKeyS  s$    r   )r5   copylenry   )ZupdatesZimage_stripr   re   Zdown_state_noneZdown_state_selfZdown_state_whiteZdown_state_self_whiteZdown_state_blackZdown_state_self_blackZdown_state_white_blackZdown_state_allZ	key_colorr   r   r   r   	key_class  s   (0r   returnc            
      C   s   t jt jtd } t j| dd}d}d}d}d}tj|}g d}i }t	d	D ]}	t
|	| d|||||	 < q,t	d	t|D ]}	t
|	| d|||||	 < qD||fS )
a  Return a keyboard keys image strip and a mapping of image locations

    The return tuple is a pygame.Surface and a dictionary keyed by key name and valued by a pygame.Rect.

    This function encapsulates the constants relevant to the keyboard image
    file. There are five key types. One is the black key. The other four
    white keys are determined by the proximity of the black keys. The plain
    white key has no black key adjacent to it. A white-left and white-right
    key has a black key to the left or right of it respectively. A white-center
    key has a black key on both sides. A key may have up to six related
    images depending on the state of adjacent keys to its right.

    r   datazmidikeys.png*         ^   )
black none
black self
white none
white selfwhite self-whitewhite-left nonewhite-left selfwhite-left blackwhite-left self-blackwhite-left self-whitewhite-left allwhite-center nonewhite-center selfwhite-center blackwhite-center self-blackwhite-center self-whitewhite-center allwhite-right nonewhite-right selfwhite-right self-whiter   )ospathsplitabspath__file__joinr   imageloadr   rw   r   )
Zmy_dirZ
strip_filewhite_key_widthwhite_key_heightblack_key_widthblack_key_heightstripnamesZrectsr   r   r   r   
key_imagesi  s$   r   c                
   @   s<  e Zd ZU dZe \ZZed j\ZZ	ed j\Z
Ze Zee ed< eeeed ed gdZeeeed ed ed gZeeeed	 ed
 ed ed ed ed gZeeeed ed ed ed ed ed gZeeeed ed ed gZdedefddZd(ddZd d! Zd"d# Zd$d% Zd&d' ZdS ))r3   ag  Musical keyboard widget

    Constructor arguments:
    start_note: midi note value of the starting note on the keyboard.
    n_notes: number of notes (keys) on the keyboard.

    A Keyboard instance draws the musical keyboard and maintains the state of
    all the keyboard keys. Individual keys can be in a down (depressed) or
    up (released) state.

    r   r   _updatesr   Fr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rG   rH   c                 C   s    || _ || d | _|   dS )z/Return a new Keyboard instance with n_note keysr   N)_start_note	_end_note	_add_keys)rZ   rG   rH   r   r   r   r     s   zKeyboard.__init__r   Nc                 C   sX  dgd }| j }| j}| jd }d}d }}t|rd}n||7 }d}t||d D ]`}	|	}
t|	ry|rR|	|ks>t|	d rH| |
||f|}n'| |
||f|}n|	|ks\t|	d rf| |
||f|}n	| |
||f|}d}|| j	7 }|}n| 
|
|| |f|}d}|||	< q*|| _|| j }|du rd}n|jj}| j}tdd||| _dS )z^Populate the keyboard with key instances

        Set the _keys and rect attributes.

        N   r   r   TFr   )r   r   r   re   r   WhiteKeyWhiteKeyLeftWhiteKeyRightWhiteKeyCenterr   BlackKey_keysr4   rightr   r   rw   )rZ   Zkey_maprG   Zend_noteZblack_offsetZprev_white_keyxyZis_prev_whiterQ   r   rE   Zthe_keyZkb_widthZ	kb_heightr   r   r   r     sB   




zKeyboard._add_keysc                 C   s   | j }g }t| j| jd D ]}| j| }|dur%|jr%t|||j| q|||f q|D ]\}}|dur?t|||j| q/dS )a  Draw the key regions onto surface regions.

        Regions must have at least 3 byte pixels. Each pixel of the keyboard
        rectangle is set to the color (note, velocity, 0). The regions surface
        must be at least as large as (0, 0, self.rect.left, self.rect.bottom)

        r   N)	r   r   r   r   r   r   fill_regionr4   r   )rZ   rN   cutoffZ
black_keysrQ   rE   r   r   r   r=   !  s   
zKeyboard.map_regionsc                 C   s(   | j }|r| ||| |sdS dS )z Redraw all altered keyboard keysN)r   popr;   )rZ   r   rL   rM   Zchanged_keysr   r   r   r;   9  s   zKeyboard.drawc                 C   "   | j | }|dur|  dS dS )z Signal a key down event for noteN)r   r   rZ   rQ   rE   r   r   r   rA   @     
zKeyboard.key_downc                 C   r   )zSignal a key up event for noteN)r   r   r   r   r   r   rC   F  r   zKeyboard.key_up)r   N)r`   ra   rb   rc   r   Z_image_stripZ_rectsr5   r   r   r   r   r>   r   r   r   ru   r   r   r   r   r   r   rv   r   r   r=   r;   rA   rC   r   r   r   r   r3     sd   
 


6r3   c           	   	   C   s   |\}}}}|du r|}|d }|  |ddf||||f |  |ddf||| ||f |  |ddf||d|  ||d|  f dS )a2  Fill the region defined by rect with a (note, velocity, 0) color

    The velocity varies from a small value at the top of the region to
    127 at the bottom. The vertical region 0 to cutoff is split into
    three parts, with velocities 42, 84 and 127. Everything below cutoff
    has velocity 127.

    Nr   r   r   T   rS   r   )r6   )	rN   rQ   r4   r   r   r   widthheightZdelta_heightr   r   r   r   M  s   
"r   c                 C   s   g d}|| d t |  S )z*True if note is represented by a white key)TFTTFTFTTFTF   )r   )rQ   Zkey_patternr   r   r   re   b  s   re   c                   C   s   t d t d t d d S )Nz)--input [device_id] : Midi message loggerz*--output [device_id] : Midi piano keyboardz$--list : list available midi devices)r   r   r   r   r   usagev  s   r   r   c                 C   sJ   | dkr
t | dS | dkrt| dS | dkrt  dS td|  d)ai  Run a Midi example

    Arguments:
    mode - if 'output' run a midi keyboard output example
              'input' run a midi event logger input example
              'list' list available midi devices
           (default 'output')
    device_id - midi device number; if None then use the default midi input or
                output device for the system

    r   r   listzUnknown mode option ''N)r-   rR   r   
ValueError)moder)   r   r   r   main|  s   
r   __main__r)   z--inputz-iz--outputz-oz--listz-lr   )T)r   N),rc   dataclassesr   sysr   typingr   r   r   r   r   r   r	   r
   r   r   Zpygame.midir7   r   r   r-   rR   r1   rW   r{   rd   ry   rw   r   r9   rx   r   r3   r   re   r   r   r`   r)   rv   ru   argvr   r   r   r   r   r   <module>   sZ   (

( #  ".8 -


