o
    dZh3;                     @  sx   d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
G dd deZdd Zdd ZdS )	    )annotationsNc                   @  sX   e Zd ZdZdd ZedddZdd
dZdddZdddZ	dddZ
dddZd	S )	AudioDataa  
    Creates a new ``AudioData`` instance, which represents mono audio data.

    The raw audio data is specified by ``frame_data``, which is a sequence of bytes representing audio samples. This is the frame data structure used by the PCM WAV format.

    The width of each sample, in bytes, is specified by ``sample_width``. Each group of ``sample_width`` bytes represents a single audio sample.

    The audio data is assumed to have a sample rate of ``sample_rate`` samples per second (Hertz).

    Usually, instances of this class are obtained from ``recognizer_instance.record`` or ``recognizer_instance.listen``, or in the callback for ``recognizer_instance.listen_in_background``, rather than instantiating them directly.
    c                 C  sZ   |dksJ d|d dkrd|  krdks J d J d|| _ || _t|| _d S )Nr   z&Sample rate must be a positive integer      z.Sample width must be between 1 and 4 inclusive)
frame_datasample_rateintsample_width)selfr   r   r	    r   G/var/www/auris/lib/python3.10/site-packages/speech_recognition/audio.py__init__   s    zAudioData.__init__	file_pathstrreturnc                 C  sH   ddl }| }||}||W  d   S 1 sw   Y  dS )z8Creates a new ``AudioData`` instance from an audio file.r   N)Zspeech_recognitionZ
RecognizerZ	AudioFilerecord)clsr   srrsourcer   r   r   	from_file$   s
   $zAudioData.from_fileNc                 C  s   |du s|dksJ d|du s||du rdn|ksJ d|du r%d}nt || j | j d }|du r;t| j}nt || j | j d }t| j|| | j| jS )ag  
        Returns a new ``AudioData`` instance, trimmed to a given time interval. In other words, an ``AudioData`` instance with the same audio data except starting at ``start_ms`` milliseconds in and ending ``end_ms`` milliseconds in.

        If not specified, ``start_ms`` defaults to the beginning of the audio, and ``end_ms`` defaults to the end.
        Nr   z*``start_ms`` must be a non-negative numberzI``end_ms`` must be a non-negative number greater or equal to ``start_ms``i  )r   r   r	   lenr   r   )r
   Zstart_msZend_msZ
start_byteZend_byter   r   r   get_segment-   s.   
zAudioData.get_segmentc              
     sN  |du s|dksJ d|du s(|d dkr$d|  kr#dks(J d J d| j  | jdkr7t dd |durN| j|krNt | jd| j|d\ }|dur| j|kr|dkrt | jd z	td	dd W n tjy   d	 fd
dt	dt
 dD  Y nw t | j| nt | j| |dkrt dd  S )a)  
        Returns a byte string representing the raw frame data for the audio represented by the ``AudioData`` instance.

        If ``convert_rate`` is specified and the audio sample rate is not ``convert_rate`` Hz, the resulting audio is resampled to match.

        If ``convert_width`` is specified and the audio samples are not ``convert_width`` bytes each, the resulting audio is converted to match.

        Writing these bytes directly to a file results in a valid `RAW/PCM audio file <https://en.wikipedia.org/wiki/Raw_audio_format>`__.
        Nr   z4Sample rate to convert to must be a positive integerr   r   z<Sample width to convert to must be between 1 and 4 inclusivei       c                 3  s$    | ]} |d  |d  V  qdS )r   r   Nr   .0iraw_datar   r   	<genexpr>~   s
    
z)AudioData.get_raw_data.<locals>.<genexpr>   )r   r	   audioopZbiasr   ZratecvZlin2linerrorjoinranger   )r
   convert_rateconvert_width_r   r   r   get_raw_dataK   sd    

zAudioData.get_raw_datac           	   	   C  s   |  ||}|du r| jn|}|du r| jn|}t 3}t|d}z|| || |	d |
| | }W |  n|  w W d   |S 1 sRw   Y  |S )a!  
        Returns a byte string representing the contents of a WAV file containing the audio represented by the ``AudioData`` instance.

        If ``convert_width`` is specified and the audio samples are not ``convert_width`` bytes each, the resulting audio is converted to match.

        If ``convert_rate`` is specified and the audio sample rate is not ``convert_rate`` Hz, the resulting audio is resampled to match.

        Writing these bytes directly to a file results in a valid `WAV file <https://en.wikipedia.org/wiki/WAV>`__.
        Nwbr   )r)   r   r	   ioBytesIOwaveopensetframeratesetsampwidthsetnchannelswriteframesgetvalueclose)	r
   r&   r'   r   r   r	   Zwav_fileZ
wav_writerwav_datar   r   r   get_wav_data   s$   









zAudioData.get_wav_datac              	     s  |  || |du r| jn|}|du r| jn|ttdr$t  n d dd d fddtd t D   t	
 3}t|d}z|| | |d |  | }W |  n|  w W d   |S 1 s|w   Y  |S )	aB  
        Returns a byte string representing the contents of an AIFF-C file containing the audio represented by the ``AudioData`` instance.

        If ``convert_width`` is specified and the audio samples are not ``convert_width`` bytes each, the resulting audio is converted to match.

        If ``convert_rate`` is specified and the audio sample rate is not ``convert_rate`` Hz, the resulting audio is resampled to match.

        Writing these bytes directly to a file results in a valid `AIFF-C file <https://en.wikipedia.org/wiki/Audio_Interchange_File_Format>`__.
        Nbyteswapr   r   c                 3  s"    | ]} | |d  V  qdS )r8   Nr   r   r   r	   r   r   r       s
    
z*AudioData.get_aiff_data.<locals>.<genexpr>r*   )r)   r   r	   hasattrr"   r7   r$   r%   r   r+   r,   aifcr.   r/   r0   r1   r2   r3   r4   )r
   r&   r'   r   Z	aiff_fileZaiff_writerZ	aiff_datar   r9   r   get_aiff_data   s2   
 









zAudioData.get_aiff_datac           	      C  s   |du s|d dkrd|  krdksJ d J d| j dkr'|du r'd}| ||}t }tjdkrFt }| jtjO  _tj	|_
nd}tj|ddd	d
gtjtj|d}||\}}|S )a  
        Returns a byte string representing the contents of a FLAC file containing the audio represented by the ``AudioData`` instance.

        Note that 32-bit FLAC is not supported. If the audio data is 32-bit and ``convert_width`` is not specified, then the resulting FLAC will be a 24-bit FLAC.

        If ``convert_rate`` is specified and the audio sample rate is not ``convert_rate`` Hz, the resulting audio is resampled to match.

        If ``convert_width`` is specified and the audio samples are not ``convert_width`` bytes each, the resulting audio is converted to match.

        Writing these bytes directly to a file results in a valid `FLAC file <https://en.wikipedia.org/wiki/FLAC>`__.
        Nr   r   r   z<Sample width to convert to must be between 1 and 3 inclusiventz--stdoutz--totally-silentz--best-)stdinstdoutstartupinfo)r	   r6   get_flac_converterosname
subprocessZSTARTUPINFOZdwFlagsZSTARTF_USESHOWWINDOWZSW_HIDEZwShowWindowPopenPIPEcommunicate)	r
   r&   r'   r5   flac_converterZstartup_infoprocessZ	flac_datastderrr   r   r   get_flac_data   s>    
zAudioData.get_flac_data)r   r   r   r   )NN)__name__
__module____qualname____doc__r   classmethodr   r   r)   r6   r<   rL   r   r   r   r   r      s    	


H
*r   c                  C  s:  t d} | du r_tjtjt}t t }}|dkr+|dv r+tj	|d} n4|dkr;|dv r;tj	|d} n$|d	krK|d
v rKtj	|d} n|d	kr[|dv r[tj	|d} nt
dz3t| tjst| }t| |jtjB  d	t v rtjdkrt ntd W | S W | S W | S  t
y   Y | S w )zdReturns the absolute path of a FLAC converter executable, or raises an OSError if none can be found.ZflacNWindows>   x86_64x86AMD64i786i686zflac-win32.exeDarwin>   rS   rT   arm64rU   rV   rW   zflac-macLinux>   rW   rT   rV   zflac-linux-x86>   rS   rU   zflac-linux-x86_64zFLAC conversion utility not available - consider installing the FLAC command line application by running `apt-get install flac` or your operating system's equivalent)r   r   sync)shutil_whichrC   pathdirnameabspath__file__platformsystemmachiner$   OSErroraccessX_OKstatchmodst_modeS_IEXECsysversion_infor[   )rI   	base_pathrb   rc   	stat_infor   r   r   rB     sB   

	rB   c                 C  sR   t d}|t jjD ]}t j|| }t j|r&t |t jr&|  S qdS )zDPython 2 compatibility: backport of ``shutil.which()`` from Python 3PATHN)	rC   getenvsplitr]   pathsepr$   existsre   rf   )Zpgmr]   pr   r   r   r\   C  s   
r\   )
__future__r   r;   r"   r+   rC   ra   rg   rE   rk   r-   objectr   rB   r\   r   r   r   r   <module>   s      3