
    tKg39              
       ,   d Z ddlZ ej                  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e      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Zda ej4                         Z ej8                  d       d Z G d dej<                        Z G d de      Z e!dk(  rejD                  dd D ]  Z#ejF                  jI                  ejF                  jK                  e#            Z# e e#      5 Z& e'e&jP                          e'e&jR                          e'e&jT                         e&D ]  Z+ e' e,e+       e-e+d                 	 ddd        yy# 1 sw Y   xY w)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
   __GSTDEC_SENTINEL__c                       e Zd Zy)GStreamerErrorN)__name__
__module____qualname__     T/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/audioread/gstdec.pyr   r   E   s    r   r   c                   "     e Zd ZdZ fdZ xZS )UnknownTypeErrorz7Raised when Gstreamer can't decode the given file type.c                 8    t         |   d|z          || _        y )Nzcan't decode stream: )super__init__
streaminfo)selfr   	__class__s     r   r   zUnknownTypeError.__init__K   s!    #j0	
 %r   r   r   r   __doc__r   __classcell__r   s   @r   r   r   I   s    A% %r   r   c                       e Zd ZdZy)FileReadErrorz*Raised when the file can't be read at all.Nr   r   r   r   r   r   r   r    r    R   s    4r   r    c                   "     e Zd ZdZ fdZ xZS )NoStreamErrorzTRaised when the file was read successfully but no audio streams
    were found.
    c                 $    t         |   d       y )Nzno audio streams foundr   r   r   r   s    r   r   zNoStreamError.__init__[   s    12r   r   r   s   @r   r#   r#   W   s    3 3r   r#   c                       e Zd ZdZy)MetadataMissingErrorzdRaised when GStreamer fails to report stream metadata (duration,
    channels, or sample rate).
    Nr!   r   r   r   r(   r(   _   s     	r   r(   c                   "     e Zd ZdZ fdZ xZS )IncompleteGStreamerErrorzkRaised when necessary components of GStreamer (namely, the
    principal plugin packages) are missing.
    c                 $    t         |   d       y )Nzmissing GStreamer base pluginsr%   r&   s    r   r   z!IncompleteGStreamerError.__init__j   s    ,	
r   r   r   s   @r   r*   r*   f   s    
 
r   r*   c                      t         5  t        st               at        j                          t        cddd       S # 1 sw Y   yxY w)z%Get the shared main-loop thread.
    N)_loop_thread_lock_shared_loop_threadMainLoopThreadstartr   r   r   get_loop_threadr1   w   s.     
""0"2%%'" 
		s	   *;Ac                   (     e Zd ZdZ fdZd Z xZS )r/   z7A daemon thread encapsulating a Gobject main loop.
    c                 z    t         |           t        j                  j	                  d d      | _        d| _        y )NFT)r   r   r   MainLoopnewloopdaemonr&   s    r   r   zMainLoopThread.__init__   s-    MM%%dE2	r   c                 8    | j                   j                          y N)r6   runr   s    r   r:   zMainLoopThread.run   s    		r   )r   r   r   r   r   r:   r   r   s   @r   r/   r/      s    
r   r/   c                   d    e Zd ZdZd Zd ZdZd Zd Zd Z	d Z
d	 Zd
 Zd ZddZd Zd Zd Zy)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                    d| _         d| _        t        j                         | _        t        j
                  j                  dd       | _        t        j
                  j                  dd       | _        t        j
                  j                  dd       | _	        | j                  | j                  | j                  
t               | j                  j                         }|j                          |j                  d| j                         |j                  d| j                         dt        t         j"                  j%                  |            z   }| j                  j'                  d|       | j                  j                  d	| j(                         | j                  j                  d
| j*                         | j                  j                  d| j,                         | j                  j'                  dt        j.                  j1                  d             | j                  j'                  dd       | j                  j'                  dt2               | j                  j'                  dd       | j                  j'                  dd       | j                  j                  d| j4                         t7        j8                  d      | _        | j                  j=                  d      j                  d| j>                        | _         | j                  jC                  | j                         | j                  jC                  | j                         | j                  jC                  | j                         | j                  jE                  | j                         tG        jH                  tJ              | _#        tM               | _'        d | _(        d| _         d| _)        | j                  jU                  t        jV                  jX                         | j:                  j[                          | jP                  r| j]                  d       | jP                  y )NFuridecodebinaudioconvertappsinkzmessage::eoszmessage::errorzfile://uriz	pad-addedzno-more-padszunknown-typecapsz!audio/x-raw, format=(string)S16LEdropzmax-bufferssynczemit-signalsTz
new-sampler   sinkznotify::caps)/runningfinishedr   PipelinepipelineElementFactorymakedecconvrF   r*   get_busadd_signal_watchconnect_messager   ospathabspathset_property
_pad_added_no_more_pads_unkown_typeCapsfrom_stringBUFFER_SIZE_new_sample	threading	Semaphore	ready_semget_static_pad_notify_capscaps_handleraddlinkqueueQueue
QUEUE_SIZEr1   threadread_excgot_caps	set_stateStatePLAYINGacquireclose)r   rT   busrB   s       r   r   zGstAudioFile.__init__   s	    %%**>4@&&++NDA	&&++It<	88tyy0DII4E +,, mm##%NDMM2$dmm4 % 566eS)doo6););<):):; 			HH  !DE	
 			vu-		}k:		vu-		~t4		,(8(89 #,,Q/ II44V<DDD--
 	$((#$))$$))$		tyy! [[,
%'  		 1 12 ==JJt-- r   c                    d| _         |j                         j                  d      }|j                  d      d   | _        |j                  d      d   | _        |j                         j                  t        j                  j                        \  }}|r|dz  | _        nt        d      | _        | j                  j                          y)	z>The callback for the sinkpad's "notify::caps" signal.
        Tr   channelsr   ratei ʚ;zduration not availableN)rk   get_current_capsget_structureget_intrs   
samplerateget_peerquery_durationr   FormatTIMEdurationr(   rj   r`   release)r   padargsinfosuccesslengths         r   rb   zGstAudioFile._notify_caps   s     ##%33A6 Z03,,v.q1 ,,.77

H"Z/DM01IJDM 	 r   Fc                     |j                  d      j                         }|j                  d      rE| j                  j	                  d      }|j                         sd| _        |j                  |       yyy)z:The callback for GstElement's "pad-added" signal.
        Nzaudio/x-rawrF   T)
query_caps	to_string
startswithrN   ra   	is_linked
_got_a_padre   )r   elementr   namenextpads        r   rW   zGstAudioFile._pad_added  sd     ~~d#--/??=)ii..v6G$$&"&! ' *r   c                 p    | j                   s*t               | _        | j                  j	                          yy)z=The callback for GstElement's "no-more-pads" signal.
        N)r   r#   rj   r`   r~   )r   r   s     r   rX   zGstAudioFile._no_more_pads   s)     )ODMNN""$ r   c                 "   | j                   r|j                  d      j                         }|j                         }|j	                  t
        j                  j                        \  }}|rt        |j                  t              rt        |j                        }n|j                  }|j                  |       | j                  j                  |       t
        j                   j"                  S 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.)rG   emit
get_bufferget_all_memorymapr   MapFlagsREAD
isinstancedata
memoryviewbytesunmaprf   putr   
FlowReturnOK)r   rF   bufmemr   r   r   s          r   r]   zGstAudioFile._new_sample*  s     << ))M*557C $$&CGGCLL$5$56MGTdii4 !+D  99D		$

t$ ~~    %%Z[[~~   r   c                     |j                         }|j                  d      syt        |      | _        | j                  j                          y)z<The callback for decodebin's "unknown-type" signal.
        zaudio/N)r   r   r   rj   r`   r~   )r   r?   	decodebinrC   r   s        r   rY   zGstAudioFile._unkown_typeH  s=    
 ^^%
$$X.(4 r   c                 6   | j                   s|j                  t        j                  j                  k(  rV| j
                  j                  t               | j                  s*t               | _
        | j                  j                          yy|j                  t        j                  j                  k(  rg|j                         \  }}d|v rt               | _
        n%d|v rt        d      | _
        nt!        |      | _
        | j                  j                          yyy)zXThe callback for GstBus's "message" signal (for two kinds of
        messages).
        z
not-linkedzNo such filezresource not foundN)rH   typer   MessageTypeEOSrf   r   SENTINELrk   r#   rj   r`   r~   ERRORparse_errorIOErrorr    )r   rq   messagegerrordebugs        r   rR   zGstAudioFile._messageT  s     }}||s222

x(}} %2ODMNN**,	 % !6!66 ' 3 3 55($1ODM#u,$+,@$ADM$1%$8DM&&( 7 r   c                 X    | j                   j                         }|t        k(  rt        |S r9   )rf   getr   StopIteration)r   vals     r   __next__zGstAudioFile.__next__n  s$    jjnn(?
r   c                     | S r9   r   r;   s    r   __iter__zGstAudioFile.__iter__v      r   c                    | j                   s|rd| _         d| _        | j                  j                         j	                          | j
                  j                  dd       | j                  j                  d      j                  | j                         	 | j                  j                          | j                  j                  t        j                   j"                         yy# t        j                  $ r Y Jw xY w)zrClose the file and clean up associated resources.

        Calling `close()` a second time has no effect.
        FTrB   NrF   )rG   rH   rJ   rO   remove_signal_watchrM   rV   rF   ra   
disconnectrc   rf   
get_nowaitEmptyrl   r   rm   NULL)r   forces     r   rp   zGstAudioFile.closez  s    
 <<5 DL DM
 MM!!#779 HH!!%.II$$V,778I8IJ


%%'
 MM##CIINN3/ !& ;; s   C% %C;:C;c                 $    | j                          y r9   rp   r;   s    r   __del__zGstAudioFile.__del__  s    

r   c                     | S r9   r   r;   s    r   	__enter__zGstAudioFile.__enter__  r   r   c                 $    | j                          y)NFr   )r   exc_typeexc_valexc_tbs       r   __exit__zGstAudioFile.__exit__  s    

r   N)F)r   r   r   r   r   rb   r   rW   rX   r]   rY   rR   r   r   rp   r   r   r   r   r   r   r=   r=      sQ    &S n!. J	"%!<
!)44<r   r=   __main__).r   girequire_versiongi.repositoryr   r   sysr^   rS   rf   urllib.parser   
exceptionsr   baser   rh   r\   r   r   r   r    r#   r(   r*   r.   RLockr-   initr1   Threadr/   r=   r   argvrT   rU   
expanduserfprintrs   rx   r}   slenordr   r   r   <module>r      s~   D 
   5%   # 
  	   # 
 
	[ 	%~ %	N 	
3N 3	> 	
~ 
  #IOO%  	#	Y%% 	P9 Ph zwwrww11$78$1!**!,,!**c!fc!A$i( 	      s   'AF

F	