
    ^jQ                       d dl mZ d dlZd dlZd dlmZ d dlmZmZm	Z	m
Z
mZ d dlmZmZ er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e G d d                      Z G d d          Ze G d d                      Z G d d          Z G d de          Z G d de          Z G d de          Z  G d d          Z!dS )    )annotationsN)	dataclass)TYPE_CHECKINGBinaryIOListOptionalUnion)CannotSeekExceptionMediaException)AbstractImage)	Animation)MediaEncoder)
MediaEventPlayerc                  B    e Zd ZdZddZdd
ZddZddZddZddZ	dS )AudioFormata  Audio details.

    An instance of this class is provided by sources with audio tracks.  You
    should not modify the fields, as they are used internally to describe the
    format of data provided by the source.

    Args:
        channels (int): The number of channels: 1 for mono or 2 for stereo
            (pyglet does not yet support surround-sound sources).
        sample_size (int): Bits per sample; only 8 or 16 are supported.
        sample_rate (int): Samples per second (in Hertz).
    channelsintsample_sizesample_ratereturnNonec                    || _         || _        || _        |dz  |z  | _        | j        |z  | _        | j        | _        d S )N   )r   r   r   bytes_per_framebytes_per_secondbytes_per_sample)selfr   r   r   s       S/home/agentuser/manim-venv/lib/python3.11/site-packages/pyglet/media/codecs/base.py__init__zAudioFormat.__init__    sR     && !,q 0H< $ 4{ B $ 4	 	    	num_bytesc                    ||| j         z  z
  S )zgAlign a given amount of bytes to the audio frame size of this
        audio format, downwards.
        r   r   r#   s     r    alignzAudioFormat.align3   s     I(<<==r"   c                    || | j         z  z   S )zeAlign a given amount of bytes to the audio frame size of this
        audio format, upwards.
        r%   r&   s     r    
align_ceilzAudioFormat.align_ceil9   s     YJ)==>>r"   	timestampfloatc                V    |                      t          || j        z                      S )zGiven a timestamp, return the amount of bytes that an emitter with
        this audio format would have to have played to reach it, aligned
        to the audio frame size.
        )r'   r   r   r   r*   s     r    timestamp_to_bytes_alignedz&AudioFormat.timestamp_to_bytes_aligned?   s&    
 zz#i$*??@@AAAr"   otherobjectboolc                    t          |t                    r0| j        |j        k    o| j        |j        k    o| j        |j        k    S t
          S N)
isinstancer   r   r   r   NotImplemented)r   r/   s     r    __eq__zAudioFormat.__eq__F   sS    e[)) 	;MU^3 :$(99:$(99; r"   strc                F    d| j         j        | j        | j        | j        fz  S )Nz/%s(channels=%d, sample_size=%d, sample_rate=%d))	__class____name__r   r   r   r   s    r    __repr__zAudioFormat.__repr__M   s,    @N#T]D4DD  	r"   N)r   r   r   r   r   r   r   r   )r#   r   r   r   )r*   r+   r   r   )r/   r0   r   r1   )r   r7   )
r:   
__module____qualname____doc__r!   r'   r)   r.   r6   r<    r"   r    r   r      s            &> > > >? ? ? ?B B B B        r"   r   c                  D    e Zd ZU dZded<   ded<   dZded<   dZd	ed
<   dS )VideoFormata  Video details.

    An instance of this class is provided by sources with a video stream. You
    should not modify the fields.

    Note that the sample aspect has no relation to the aspect ratio of the
    video image.  For example, a video image of 640x480 with sample aspect 2.0
    should be displayed at 1280x480.  It is the responsibility of the
    application to perform this scaling.

    Args:
        width (int): Width of video image, in pixels.
        height (int): Height of video image, in pixels.
        sample_aspect (float): Aspect ratio (width over height) of a single
            video pixel.
        frame_rate (float): Frame rate (frames per second) of the video.

            .. versionadded:: 1.2
    r   widthheight        r+   sample_aspectNzfloat | None
frame_rate)r:   r=   r>   r?   __annotations__rF   rG   r@   r"   r    rB   rB   R   sR          & JJJKKKM#J######r"   rB   c                  &    e Zd ZdZdZ	 	 	 dddZdS )	AudioDataa  A single packet of audio data.

    This class is used internally by pyglet.

    Args:
        data (bytes, ctypes array, or supporting buffer protocol): Sample data.
        length (int): Size of sample data, in bytes.
        timestamp (float): Time of the first sample, in seconds.
        duration (float): Total data duration, in seconds.
        events (List[:class:`pyglet.media.drivers.base.MediaEvent`]): List of events
            contained within this packet. Events are timestamped relative to
            this audio packet.

    .. deprecated:: 2.0.10
            `timestamp` and `duration` are unused and will be removed eventually.
    )datadurationeventslengthpointerr*   rE   NrK   bytes | ctypes.ArrayrN   r   r*   r+   rL   rM   list[MediaEvent] | Noner   r   c                   t          |t                    r*t          j        |t          j                  j        | _        nt          |t          j                  rt          j        |          | _        nU	 t          j        t          j	        
                    |                    | _        n# t          $ r t          d          w xY w|| _        || _        || _        || _        |g n|| _        d S )NzUnsupported AudioData type.)r4   bytesctypescastc_void_pvaluerO   Array	addressofc_intfrom_buffer	TypeErrorrK   rN   r*   rL   rM   )r   rK   rN   r*   rL   rM   s         r    r!   zAudioData.__init__   s     dE"" 
	? ";tV_==CDLLfl++ 	?!+D11DLL?%/0H0H0N0NOO ? ? ? =>>>? 	 " "Nbbs   56B, ,C)rE   rE   N)rK   rP   rN   r   r*   r+   rL   r+   rM   rQ   r   r   )r:   r=   r>   r?   	__slots__r!   r@   r"   r    rJ   rJ   m   sJ         " OI
 %(#&377 7 7 7 7 7 7r"   rJ   c                      e Zd ZU dZdZded<   dZded<   dZded<   dZded<   dZ	ded<   d	Z
d
ed<   d	Zd
ed<   dZded<   dS )
SourceInfoa  Source metadata information.

    Fields are the empty string or zero if the information is not available.

    Args:
        title (str): Title
        author (str): Author
        copyright (str): Copyright statement
        comment (str): Comment
        album (str): Album name
        year (int): Year
        track (int): Track number
        genre (str): Genre

    .. versionadded:: 1.2
     r7   titleauthor	copyrightcommentalbumr   r   yeartrackgenreN)r:   r=   r>   r?   ra   rH   rb   rc   rd   re   rf   rg   rh   r@   r"   r    r_   r_      s            EOOOOFIGEOOOODMMMMENNNNEOOOOOOr"   r_   c                      e Zd ZU dZdZg Zded<   dZdZdZ	dZ
ed$d            Zd%d
Zd&dZd'dZd(dZ	 	 d)d*dZd+dZd,dZd-dZd.d/d#ZdS )0Sourcea  An audio and/or video source.

    Args:
        audio_format (:class:`.AudioFormat`): Format of the audio in this
            source, or ``None`` if the source is silent.
        video_format (:class:`.VideoFormat`): Format of the video in this
            source, or ``None`` if there is no video.
        info (:class:`.SourceInfo`): Source metadata such as title, artist,
            etc; or ``None`` if the` information is not available.

            .. versionadded:: 1.2

    Attributes:
        is_player_source (bool): Determine if this source is a player
            current source.

            Check on a :py:class:`~pyglet.media.player.Player` if this source
            is the current source.
    NzList['Player']_playersFr   r+   c                    | j         S )zfloat: The length of the source, in seconds.

        Not all source durations can be determined; in this case the value
        is ``None``.

        Read-only.
        )	_durationr;   s    r    rL   zSource.duration   s     ~r"   'Player'c                    ddl m}  |                                |                                             t          j                                       fd}|_        S )zPlay the source.

        This is a convenience method which creates a Player for
        this source and plays it immediately.

        Returns:
            :class:`.Player`
        r   r   c                 |    t           j                                        d  _                                          d S r3   )rj   rk   removeon_player_eosdelete)players   r    _on_player_eosz#Source.play.<locals>._on_player_eos   s2    O""6***#'F MMOOOOOr"   )pyglet.media.playerr   queueplayrj   rk   appendrr   )r   r   ru   rt   s      @r    rx   zSource.play   s     	/.....Tv&&&	 	 	 	 	  .r"   r   c                $   ddl m}m} | j        s |g           S g }d}|                                 }|R|                                 }|&||z
  }|                     |||                     |}|                                 }|R ||          S )a	  Import all video frames into memory.

        An empty animation will be returned if the source has no video.
        Otherwise, the animation will contain all unplayed video frames (the
        entire source, if it has not been queued on a player). After creating
        the animation, the source will be at EOS (end of stream).

        This method is unsuitable for videos running longer than a
        few seconds.

        .. versionadded:: 1.1

        Returns:
            :class:`pyglet.image.Animation`
        r   )r   AnimationFrame)pyglet.imager   r{   video_formatget_next_video_timestampget_next_video_framery   )r   r   r{   frameslast_tsnext_tsimagedelays           r    get_animationzSource.get_animation   s      	;:::::::  	%9R== FG3355G%1133$#g-EMM..">">???%G7799 % 9V$$$r"   Optional[float]c                    dS )zGet the timestamp of the next video frame.

        .. versionadded:: 1.1

        Returns:
            float: The next timestamp, or ``None`` if there are no more video
            frames.
        Nr@   r;   s    r    r~   zSource.get_next_video_timestamp  s	     	r"   Optional['AbstractImage']c                    dS )a  Get the next video frame.

        .. versionadded:: 1.1

        Returns:
            :class:`pyglet.image.AbstractImage`: The next video frame image,
            or ``None`` if the video frame could not be decoded or there are
            no more video frames.
        Nr@   r;   s    r    r   zSource.get_next_video_frame&  s	     	r"   filenamer7   fileOptional[BinaryIO]encoderOptional['MediaEncoder']r   c                    |r|                     | ||          S ddl}|j        j        j                             | ||          S )a  Save this Source to a file.

        :Parameters:
            `filename` : str
                Used to set the file format, and to open the output file
                if `file` is unspecified.
            `file` : file-like object or None
                File to write audio data to.
            `encoder` : MediaEncoder or None
                If unspecified, all encoders matching the filename extension
                are tried.  If all fail, the exception from the first one
                attempted is raised.

        r   N)encodepyglet.media.codecsmediacodecsregistry)r   r   r   r   pyglets        r    savezSource.save2  sO    $  	M>>$$777&&&&<&/66tXtLLLr"   r1   c                    dS )a  bool: Whether this source is considered precise.

        ``x`` bytes on source ``s`` are considered aligned if
        ``x % s.audio_format.bytes_per_frame == 0``, so there'd be no partial
        audio frame in the returned data.

        A source is precise if - for an aligned request of ``x`` bytes - it
        returns:\

          - If ``x`` or more bytes are available, ``x`` bytes.
          - If not enough bytes are available anymore, ``r`` bytes where
            ``r < x`` and ``r`` is aligned.

        A source is **not** precise if it does any of these:

          - Return less than ``x`` bytes for an aligned request of ``x``
            bytes although data still remains so that an additional request
            would return additional :class:`.AudioData` / not ``None``.
          - Return more bytes than requested.
          - Return an unaligned amount of bytes for an aligned request.

        pyglet's internals are guaranteed to never make unaligned
        requests, or requests of less than 1024 bytes.

        If this method returns ``False``, pyglet will wrap the source in an
        alignment-forcing buffer creating additional overhead.

        If this method is overridden to return ``True`` although the source
        does not comply with the requirements above, audio playback may be
        negatively impacted at best and memory access violations occur at
        worst.

        :Returns:
            bool: Whether the source is precise.
        Fr@   r;   s    r    
is_precisezSource.is_preciseL  s
    H ur"   r*   c                    t                      )zSeek to given timestamp.

        Args:
            timestamp (float): Time where to seek in the source. The
                ``timestamp`` will be clamped to the duration of the source.
        )r
   r-   s     r    seekzSource.seekr  s     "###r"   'Source'c                    | S )zReturn the ``Source`` to be used as the queue source for a player.

        Default implementation returns ``self``.

        Returns:
            :class:`Source`
        r@   r;   s    r    get_queue_sourcezSource.get_queue_source{  s	     r"   rE   r#   r   Optional[AudioData]c                    dS )a7  Get next packet of audio data.

        Args:
            num_bytes (int): A size hint for the amount of bytes to return,
                but the returned amount may be lower or higher.
            compensation_time (float): Time in sec to compensate due to a
                difference between the master clock and the audio clock.

        .. deprecated:: 2.0.10
            compensation_time: Will always be given as ``0.0``.

        Returns:
            :class:`.AudioData`: Next packet of audio data, or ``None`` if
            there is no (more) data.
        Nr@   r   r#   compensation_times      r    get_audio_datazSource.get_audio_data  s	      tr"   )r   r+   )r   rn   )r   r   )r   r   )r   r   )NN)r   r7   r   r   r   r   r   r   r   r1   r*   r+   r   r   )r   r   rE   )r#   r   r   r   )r:   r=   r>   r?   rm   rk   rH   audio_formatr}   infois_player_sourcepropertyrL   rx   r   r~   r   r   r   r   r   r   r@   r"   r    rj   rj      s8         ( I!H!!!!LLD   X   0% % % %B	 	 	 	
 
 
 
 )-15M M M M M4$ $ $ $L$ $ $ $         r"   rj   c                  ,     e Zd ZdZd fdZddZ xZS )	StreamingSourcezA source that is decoded as it is being played.

    The source can only be played once at a time on any
    :class:`~pyglet.media.player.Player`.
    r   'StreamingSource'c                ~    | j         rt          d          d| _         t                                                      S )zReturn the ``Source`` to be used as the source for a player.

        Default implementation returns self.

        Returns:
            :class:`.Source`
        z*This source is already queued on a player.T)r   r   superr   )r   r9   s    r    r   z StreamingSource.get_queue_source  s>       	O !MNNN $ww'')))r"   r   c                    dS )z3Release the resources held by this StreamingSource.Nr@   r;   s    r    rs   zStreamingSource.delete  s    r"   )r   r   r   r   )r:   r=   r>   r?   r   rs   __classcell__)r9   s   @r    r   r     s[         * * * * * *       r"   r   c                  ,    e Zd ZdZddZddZdddZdS )StaticSourceaE  A source that has been completely decoded in memory.

    This source can be queued onto multiple players any number of times.

    Construct a :py:class:`~pyglet.media.StaticSource` for the data in
    ``source``.

    Args:
        source (Source):  The source to read and decode audio and video data
            from.
    sourcerj   r   r   c                   |                                 }|j        rt          d          |j        | _        | j        d | _        d| _        d S d}t          j                    }	 |                    |          }|n|	                    |j
                   3|                                | _        t          | j                  | j        j        z  | _        d S )Nz'Static sources not supported for video.rE   i   )r   r}   NotImplementedErrorr   _datarm   ioBytesIOr   writerK   getvaluelenr   )r   r   buffer_sizerK   
audio_datas        r    r!   zStaticSource.__init__  s    ((** 	Q%&OPPP"/$DJ DNF  z||	(..{;;J!JJz'''		(
 ]]__
TZ4+<+MMr"   Optional['StaticMemorySource']c                H    | j         t          | j         | j                  S d S r3   )r   StaticMemorySourcer   r;   s    r    r   zStaticSource.get_queue_source  s$    :!%dj$2CDDDtr"   rE   r#   r+   r   r   c                     t          d          )a+  The StaticSource does not provide audio data.

        When the StaticSource is queued on a
        :class:`~pyglet.media.player.Player`, it creates a
        :class:`.StaticMemorySource` containing its internal audio data and
        audio format.

        Raises:
            RuntimeError
        zStaticSource cannot be queued.)RuntimeErrorr   s      r    r   zStaticSource.get_audio_data  s     ;<<<r"   Nr   rj   r   r   )r   r   r   r#   r+   r   r+   r   r   )r:   r=   r>   r?   r!   r   r   r@   r"   r    r   r     sc        
 
N N N N4   
= = = = = = =r"   r   c                  4    e Zd ZdZddZddZddZdddZdS )r   a   
    Helper class for default implementation of :class:`.StaticSource`.

    Do not use directly. This class is used internally by pyglet.

    Args:
        data (readable buffer): The audio data.
        audio_format (AudioFormat): The audio format.
    r   r   r   r   c                    t          j        |          | _        t          |          | _        || _        t          |          t          |j                  z  | _        dS )z5Construct a memory source over the given data buffer.N)	r   r   _filer   _max_offsetr   r+   r   rm   )r   rK   r   s      r    r!   zStaticMemorySource.__init__  sJ    Z%%
t99(TU<+H%I%IIr"   r1   c                    dS )NTr@   r;   s    r    r   zStaticMemorySource.is_precise  s    tr"   r*   r+   c                    t          || j        j        z            }| j                            | j                            |                     dS )zqSeek to given timestamp.

        Args:
            timestamp (float): Time where to seek in the source.
        N)r   r   r   r   r   r'   )r   r*   offsets      r    r   zStaticMemorySource.seek   sG     Y!2!CCDD
)//7788888r"   rE   r#   r   r   c                   | j                                         }| j                             |          }|sdS t          |          | j        j        z  }t          |          | j        j        z  }t          |t          |          ||          S )a   Get next packet of audio data.

        Args:
            num_bytes (int): Maximum number of bytes of data to return.

        Returns:
            :class:`.AudioData`: Next packet of audio data, or ``None`` if
            there is no (more) data.
        N)r   tellreadr+   r   r   r   rJ   )r   r#   r   offset_beforerK   r*   rL   s          r    r   z!StaticMemorySource.get_audio_data
  s}     
))zy)) 	4-((4+<+MM	t99t0AAs4yy)X>>>r"   N)r   r   r   r   r   r   r   r   )r:   r=   r>   r?   r!   r   r   r   r@   r"   r    r   r     sw         J J J J   9 9 9 9? ? ? ? ? ? ?r"   r   c                  T    e Zd Z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dZdS )SourceGroupzGroup of like sources to allow gapless playback.

    Seamlessly read data from a group of sources to allow for
    gapless playback. All sources must share the same audio format.
    The first source added sets the format.
    r   r   c                v    d | _         d | _        d | _        d| _        d| _        g | _        g | _        d| _        d S )NrE   F)r   r}   r   rL   _timestamp_offset_dequeued_durations_sourcesr   r;   s    r    r!   zSourceGroup.__init__'  sE      	!$#%  %r"   r1   c                    dS )NFr@   r;   s    r    r   zSourceGroup.is_precise1  s    ur"   timer+   c                X    | j         r"| j         d                             |           d S d S Nr   )r   r   )r   r   s     r    r   zSourceGroup.seek4  s7    = 	(M!!!$'''''	( 	(r"   r   rj   c                   | j         p|j         | _         | j        p|j        | _        |                                }|j         | j         k    s
J d            | j                            |           | xj        |j        z  c_        d S )Nz)Sources must share the same audio format.)r   r   r   r   ry   rL   )r   r   s     r    addzSourceGroup.add8  s     -D1DI,	((**#t'8888;f888V$$$(r"   c                2    t          | j                  dk    S )N   )r   r   r;   s    r    has_nextzSourceGroup.has_next@  s    4=!!A%%r"   'SourceGroup'c                    | S r3   r@   r;   s    r    r   zSourceGroup.get_queue_sourceC  s    r"   c                b   | j         r| xj        | j         d         j        z  c_        | j                            d| j         d         j                   | j                             d          }| xj        |j        z  c_        t          |t                    r|                                 d S d S d S r   )	r   r   rL   r   insertpopr4   r   rs   )r   
old_sources     r    _advancezSourceGroup._advanceF  s    = 	$""dmA&6&??""$++At}Q/?/HIII**1--JMMZ00MM*o66 $!!#####	$ 	$$ $r"   rE   r#   r   c                p   | j         sdS d}d}d}t          |          |k     rv| j         ro| j         d                             |          }|r||j        z  }||j        z  }|| j        z  }n|                                  t          |          |k     r| j         ot          |t          |          ||          S )zGet next audio packet.

        :Parameters:
            `num_bytes` : int
                Hint for preferred size of audio packet; may be ignored.

        :rtype: `AudioData`
        :return: Audio data, or None if there is no more data.
        Nr"   rE   r   )r   r   r   rK   rL   r   r   rJ   )r   r#   r   bufferrL   r*   	audiodatas          r    r   zSourceGroup.get_audio_dataP  s     } 	4	&kkI%%$-%a(77	BBI  ).(I..T33		 &kkI%%$-% ViBBBr"   Nr   r   )r   r+   r   r   r   )r   r   r   )r#   r+   r   r   )r:   r=   r>   r?   r!   r   r   r   r   r   r   r   r@   r"   r    r   r     s         & & & &   ( ( ( () ) ) )& & & &   $ $ $ $C C C C C C Cr"   r   )"
__future__r   rT   r   dataclassesr   typingr   r   r   r   r	   pyglet.media.exceptionsr
   r   r|   r   pyglet.image.animationr   r   r   pyglet.media.drivers.baser   rv   r   r   rB   rJ   r_   rj   r   r   r   r   r@   r"   r    <module>r      s   " " " " " "  				 ! ! ! ! ! ! A A A A A A A A A A A A A A G G G G G G G G +******000000000000444444******> > > > > > > >@ $ $ $ $ $ $ $ $4.7 .7 .7 .7 .7 .7 .7 .7b        6[ [ [ [ [ [ [ [|    f   27= 7= 7= 7= 7=6 7= 7= 7=t1? 1? 1? 1? 1? 1? 1? 1?hLC LC LC LC LC LC LC LC LC LCr"   