U
    ¬9%e39  ã                
   @   s¤  d Z ddlZe dd¡ ddlmZmZ ddlZddlZddlZddl	Z	ddl
mZ ddlmZ dd	lmZ d
Zd
ZdZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdae ¡ Ze d¡ dd„ ZG dd„ dejƒZG dd„ deƒZ e!dkr ej"dd… D ]nZ#ej# $ej# %e#¡¡Z#e e#ƒFZ&e'e&j(ƒ e'e&j)ƒ e'e&j*ƒ e&D ]Z+e'e,e+ƒe-e+d ƒƒ qtW 5 Q R X q0dS )aY  Use Gstreamer to decode audio files.

To read an audio file, pass it to the constructor for GstAudioFile()
and then iterate over the contents:

    >>> f = GstAudioFile('something.mp3')
    >>> try:
    >>>     for block in f:
    >>>         ...
    >>> finally:
    >>>     f.close()

Note that there are a few complications caused by Gstreamer's
asynchronous architecture. This module spawns its own Gobject main-
loop thread; I'm not sure how that will interact with other main
loops if your program has them. Also, in order to stop the thread
and terminate your program normally, you need to call the close()
method on every GstAudioFile you create. Conveniently, the file can be
used as a context manager to make this simpler:

    >>> with GstAudioFile('something.mp3') as f:
    >>>     for block in f:
    >>>         ...

Iterating a GstAudioFile yields strings containing short integer PCM
data. You can also read the sample rate and channel count from the
file:

    >>> with GstAudioFile('something.mp3') as f:
    >>>     print f.samplerate
    >>>     print f.channels
    >>>     print f.duration
é    NÚGstz1.0)ÚGLibr   )Úquoteé   )ÚDecodeError)Ú	AudioFileé
   Z__GSTDEC_SENTINEL__c                   @   s   e Zd ZdS )ÚGStreamerErrorN)Ú__name__Ú
__module__Ú__qualname__© r   r   úO/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/audioread/gstdec.pyr	   E   s   r	   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚUnknownTypeErrorz7Raised when Gstreamer can't decode the given file type.c                    s   t ƒ  d| ¡ || _d S )Nzcan't decode stream: )ÚsuperÚ__init__Ú
streaminfo)Úselfr   ©Ú	__class__r   r   r   K   s    ÿzUnknownTypeError.__init__©r
   r   r   Ú__doc__r   Ú__classcell__r   r   r   r   r   I   s   r   c                   @   s   e Zd ZdZdS )ÚFileReadErrorz*Raised when the file can't be read at all.N©r
   r   r   r   r   r   r   r   r   R   s   r   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚNoStreamErrorzTRaised when the file was read successfully but no audio streams
    were found.
    c                    s   t ƒ  d¡ d S )Nzno audio streams found©r   r   ©r   r   r   r   r   [   s    zNoStreamError.__init__r   r   r   r   r   r   W   s   r   c                   @   s   e Zd ZdZdS )ÚMetadataMissingErrorzdRaised when GStreamer fails to report stream metadata (duration,
    channels, or sample rate).
    Nr   r   r   r   r   r   _   s   r   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚIncompleteGStreamerErrorzkRaised when necessary components of GStreamer (namely, the
    principal plugin packages) are missing.
    c                    s   t ƒ  d¡ d S )Nzmissing GStreamer base pluginsr   r   r   r   r   r   j   s    ÿz!IncompleteGStreamerError.__init__r   r   r   r   r   r   f   s   r   c                
   C   s2   t $ tstƒ at ¡  tW  5 Q R £ S Q R X dS )z%Get the shared main-loop thread.
    N)Ú_loop_thread_lockÚ_shared_loop_threadÚMainLoopThreadÚstartr   r   r   r   Úget_loop_threadw   s
    r$   c                       s(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )r"   z7A daemon thread encapsulating a Gobject main loop.
    c                    s$   t ƒ  ¡  tj d d¡| _d| _d S )NFT)r   r   r   ZMainLoopÚnewÚloopÚdaemonr   r   r   r   r   †   s    
zMainLoopThread.__init__c                 C   s   | j  ¡  d S ©N)r&   Úrunr   r   r   r   r)   ‹   s    zMainLoopThread.run)r
   r   r   r   r   r)   r   r   r   r   r   r"   ƒ   s   r"   c                   @   s~   e Zd ZdZdd„ Zd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d„ Zdd„ Zdd„ ZdS )ÚGstAudioFileaä  Reads raw audio data from any audio file that Gstreamer
    knows how to decode.

        >>> with GstAudioFile('something.mp3') as f:
        >>>     print f.samplerate
        >>>     print f.channels
        >>>     print f.duration
        >>>     for block in f:
        >>>         do_something(block)

    Iterating the object yields blocks of 16-bit PCM data. Three
    pieces of stream information are also available: samplerate (in Hz),
    number of channels, and duration (in seconds).

    It's very important that the client call close() when it's done
    with the object. Otherwise, the program is likely to hang on exit.
    Alternatively, of course, one can just use the file as a context
    manager, as shown above.
    c                 C   s   d| _ d| _t ¡ | _tj dd ¡| _tj dd ¡| _tj dd ¡| _	| jd ksd| jd ksd| j	d krjt
ƒ ‚| j ¡ }| ¡  | d| j¡ | d| j¡ dttj |¡ƒ }| j d|¡ | j d	| j¡ | j d
| j¡ | j d| j¡ | j	 dtj d¡¡ | j	 dd¡ | j	 dt¡ | j	 dd¡ | j	 dd¡ | j	 d| j¡ t d¡| _| j	 d¡ d| j¡| _ | j !| j¡ | j !| j¡ | j !| j	¡ | j "| j	¡ t# $t%¡| _#t&ƒ | _'d | _(d| _ d| _)| j *tj+j,¡ | j -¡  | j(rü|  .d¡ | j(‚d S )NFÚuridecodebinZaudioconvertZappsinkzmessage::eoszmessage::errorzfile://Úuriz	pad-addedzno-more-padszunknown-typeÚcapsz!audio/x-raw, format=(string)S16LEZdropzmax-buffersÚsynczemit-signalsTz
new-sampler   Úsinkznotify::caps)/ÚrunningÚfinishedr   ZPipelineÚpipelineZElementFactoryÚmakeÚdecÚconvr/   r   Úget_busZadd_signal_watchÚconnectÚ_messager   ÚosÚpathÚabspathÚset_propertyÚ
_pad_addedÚ_no_more_padsÚ_unkown_typeZCapsZfrom_stringÚBUFFER_SIZEÚ_new_sampleÚ	threadingÚ	SemaphoreÚ	ready_semÚget_static_padÚ_notify_capsÚcaps_handlerÚaddÚlinkÚqueueÚQueueÚ
QUEUE_SIZEr$   ÚthreadÚread_excÚgot_capsÚ	set_stateÚStateZPLAYINGÚacquireÚclose)r   r:   Úbusr,   r   r   r   r   ¥   sZ    


þ ÿ

zGstAudioFile.__init__c                 C   sr   d| _ | ¡  d¡}| d¡d | _| d¡d | _| ¡  tj	j
¡\}}|rZ|d | _n
tdƒ| _| j ¡  dS )	z>The callback for the sinkpad's "notify::caps" signal.
        Tr   Úchannelsr   Zratei Êš;zduration not availableN)rO   Zget_current_capsZget_structureZget_intrU   Ú
samplerateZget_peerZquery_durationr   ZFormatZTIMEÚdurationr   rN   rD   Úrelease)r   ÚpadÚargsÚinfoÚsuccessÚlengthr   r   r   rF   ü   s    
zGstAudioFile._notify_capsFc                 C   s@   |  d¡ ¡ }| d¡r<| j d¡}| ¡ s<d| _| |¡ dS )z:The callback for GstElement's "pad-added" signal.
        Nzaudio/x-rawr/   T)Z
query_capsÚ	to_stringÚ
startswithr5   rE   Z	is_linkedÚ
_got_a_padrI   )r   ÚelementrY   ÚnameZnextpadr   r   r   r=     s    
zGstAudioFile._pad_addedc                 C   s   | j stƒ | _| j ¡  dS )z=The callback for GstElement's "no-more-pads" signal.
        N)r`   r   rN   rD   rX   )r   ra   r   r   r   r>      s    zGstAudioFile._no_more_padsc                 C   sx   | j rp| d¡ ¡ }| ¡ }| tjj¡\}}|rht|j	t
ƒrJt|j	ƒ}n|j	}| |¡ | j |¡ ntdƒ‚tjjS )z8The callback for appsink's "new-sample" signal.
        zpull-samplez3Unable to map buffer memory while reading the file.)r0   ÚemitÚ
get_bufferZget_all_memoryÚmapr   ZMapFlagsÚREADÚ
isinstanceÚdataÚ
memoryviewÚbytesZunmaprJ   Úputr	   Z
FlowReturnÚOK)r   r/   ÚbufZmemr\   r[   rh   r   r   r   rA   *  s    
zGstAudioFile._new_samplec                 C   s.   |  ¡ }| d¡sdS t|ƒ| _| j ¡  dS )z<The callback for decodebin's "unknown-type" signal.
        zaudio/N)r^   r_   r   rN   rD   rX   )r   r+   Z	decodebinr-   r   r   r   r   r?   H  s
    

zGstAudioFile._unkown_typec                 C   s’   | j sŽ|jtjjkr:| j t¡ | jsŽt	ƒ | _
| j ¡  nT|jtjjkrŽ| ¡ \}}d|krft	ƒ | _
nd|krztdƒ| _
n
t|ƒ| _
| j ¡  dS )zXThe callback for GstBus's "message" signal (for two kinds of
        messages).
        z
not-linkedzNo such filezresource not foundN)r1   Útyper   ZMessageTypeZEOSrJ   rk   ÚSENTINELrO   r   rN   rD   rX   ÚERRORZparse_errorÚIOErrorr   )r   rT   ÚmessageZgerrorÚdebugr   r   r   r8   T  s    

zGstAudioFile._messagec                 C   s   | j  ¡ }|tkrt‚|S r(   )rJ   Úgetro   ÚStopIteration)r   Úvalr   r   r   Ú__next__n  s    
zGstAudioFile.__next__c                 C   s   | S r(   r   r   r   r   r   Ú__iter__v  s    zGstAudioFile.__iter__c                 C   s€   | j s
|r|d| _ d| _| j ¡  ¡  | j dd¡ | j d¡ 	| j
¡ z| j ¡  W n tjk
rj   Y nX | j tjj¡ dS )zrClose the file and clean up associated resources.

        Calling `close()` a second time has no effect.
        FTr,   Nr/   )r0   r1   r2   r6   Zremove_signal_watchr4   r<   r/   rE   Z
disconnectrG   rJ   Ú
get_nowaitÚEmptyrP   r   rQ   ZNULL)r   Úforcer   r   r   rS   z  s    
zGstAudioFile.closec                 C   s   |   ¡  d S r(   ©rS   r   r   r   r   Ú__del__˜  s    zGstAudioFile.__del__c                 C   s   | S r(   r   r   r   r   r   Ú	__enter__œ  s    zGstAudioFile.__enter__c                 C   s   |   ¡  dS )NFr|   )r   Úexc_typeÚexc_valÚexc_tbr   r   r   Ú__exit__Ÿ  s    zGstAudioFile.__exit__N)F)r
   r   r   r   r   rF   r`   r=   r>   rA   r?   r8   rw   rx   rS   r}   r~   r‚   r   r   r   r   r*   ‘   s   W

r*   Ú__main__).r   ÚgiZrequire_versionZgi.repositoryr   r   ÚsysrB   r9   rJ   Úurllib.parser   Ú
exceptionsr   Úbaser   rL   r@   ro   r	   r   r   r   r   r   r!   ÚRLockr    Úinitr$   ÚThreadr"   r*   r
   Úargvr:   r;   Ú
expanduserÚfÚprintrU   rV   rW   ÚsÚlenÚordr   r   r   r   Ú<module>   sH   "	
  




