o
    iT                     @   sP  d Z dZddlZddlZddlmZmZmZ ddl	m
Z ddlmZ zeZW n ey1   eZY nw ddd	d
ddddddd
Zi ddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=	Zi d>dd?dd@d	dAd
dBddCddDddEddFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWi dXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdyZddzd{d|d}Zi dd?dd?dd?dd?dd?dd?d d?d"d?d$d?d&dDd(dDd*d?d,dfd.d?d0d?d2d?d~d?d?d?d?dFdhd?d?dxdZdddddZz[ejdkrMddlmZ de  d Zn.ejdkrcddlmZ de d  d ZnejdkrwddlmZ de  d Znedddl Z ej!"e j#Z$ej!%e$eZ&e'e&Z(W nu ee)e*fy   zedZ+e+du rede'e+Z(W nS ey   ejdkrdZ,nejdkrdZ,n
ejdkrdZ,n ddlmZ ejdkre dkrej!-drdndZ.e'ej!%e.e,Z(ne'e,Z(Y nw Y nw e/e(0 1ddZ2e23dr"e2e4dd Z2			dddZ5		dddZ6				dddZ7G dd de8Z9dddZ:dd Z;dddZ<dddZ=dd Z>G dd de8Z?dddZ@dd ZAdd ZBdd ZCdd ZDdd ZEe(jFfddZGdd ZHddĄ ZIddƄ ZJG ddȄ deKZLG ddʄ deLeMZNG dd̄ deNZOdS )ak  python-soundfile is an audio library based on libsndfile, CFFI and NumPy.

Sound files can be read or written directly using the functions
`read()` and `write()`.
To read a sound file in a block-wise fashion, use `blocks()`.
Alternatively, sound files can be opened as `SoundFile` objects.

For further information, see https://python-soundfile.readthedocs.io/.

z0.12.1    N)SEEK_SETSEEK_CURSEEK_END)find_library)ffi                        	      )
title	copyrightZsoftwareZartistcommentdateZalbumlicenseZtracknumberZgenreZWAVi   ZAIFFi   ZAUi   RAWi   ZPAFi   ZSVXi   ZNISTi   ZVOCi   ZIRCAMi  
 ZW64i   ZMAT4i   ZMAT5i   ZPVFi   ZXIi   ZHTKi   ZSDSi   ZAVRi   i   i   i   i   i   i    i  ! i  " i  # )	WAVEXSD2FLACCAFWVEOGGMPC2KRF64MP3ZPCM_S8ZPCM_16ZPCM_24ZPCM_32ZPCM_U8FLOATDOUBLEZULAWZALAW   Z	IMA_ADPCM   ZMS_ADPCM   ZGSM610    Z	VOX_ADPCM!   ZNMS_ADPCM_16"   ZNMS_ADPCM_24#   ZNMS_ADPCM_32$   ZG721_320   ZG723_241   ZG723_402   ZDWVW_12@   ZDWVW_16A   ZDWVW_24B   ZDWVW_NC   ZDPCM_8P   ZDPCM_16Q   ZVORBIS`   ZOPUSd   ZALAC_16p   ZALAC_20q   ZALAC_24r   ZALAC_32s   ZMPEG_LAYER_I   ZMPEG_LAYER_II   ZMPEG_LAYER_III   i   i    i   0)FILEZLITTLEZBIGZCPUr   )r   r   r   r   r   r   r   r   doublefloatintZshort)float64Zfloat32Zint32Zint16darwin)machineZlibsndfile_z.dylibwin32)architecturez.dlllinuxz.soz%no packaged library for this platformZsndfilez8sndfile library not found using ctypes.util.find_libraryzlibsndfile.dylibzlibsndfile.dllzlibsndfile.soarm64z/opt/homebrew/lib/z/usr/local/lib/utf-8replacezlibsndfile-r@   FTc              	   C   s`   t | d||	|||
|}||||}||||||}W d   n1 s&w   Y  ||jfS )a  Provide audio data from a sound file as NumPy array.

    By default, the whole file is read from the beginning, but the
    position to start reading can be specified with *start* and the
    number of frames to read can be specified with *frames*.
    Alternatively, a range can be specified with *start* and *stop*.

    If there is less data left in the file than requested, the rest of
    the frames are filled with *fill_value*.
    If no *fill_value* is specified, a smaller array is returned.

    Parameters
    ----------
    file : str or int or file-like object
        The file to read from.  See `SoundFile` for details.
    frames : int, optional
        The number of frames to read. If *frames* is negative, the whole
        rest of the file is read.  Not allowed if *stop* is given.
    start : int, optional
        Where to start reading.  A negative value counts from the end.
    stop : int, optional
        The index after the last frame to be read.  A negative value
        counts from the end.  Not allowed if *frames* is given.
    dtype : {'float64', 'float32', 'int32', 'int16'}, optional
        Data type of the returned array, by default ``'float64'``.
        Floating point audio data is typically in the range from
        ``-1.0`` to ``1.0``.  Integer data is in the range from
        ``-2**15`` to ``2**15-1`` for ``'int16'`` and from ``-2**31`` to
        ``2**31-1`` for ``'int32'``.

        .. note:: Reading int values from a float file will *not*
            scale the data to [-1.0, 1.0). If the file contains
            ``np.array([42.6], dtype='float32')``, you will read
            ``np.array([43], dtype='int32')`` for ``dtype='int32'``.

    Returns
    -------
    audiodata : `numpy.ndarray` or type(out)
        A two-dimensional (frames x channels) NumPy array is returned.
        If the sound file has only one channel, a one-dimensional array
        is returned.  Use ``always_2d=True`` to return a two-dimensional
        array anyway.

        If *out* was specified, it is returned.  If *out* has more
        frames than available in the file (or if *frames* is smaller
        than the length of *out*) and no *fill_value* is given, then
        only a part of *out* is overwritten and a view containing all
        valid frames is returned.
    samplerate : int
        The sample rate of the audio file.

    Other Parameters
    ----------------
    always_2d : bool, optional
        By default, reading a mono sound file will return a
        one-dimensional array.  With ``always_2d=True``, audio data is
        always returned as a two-dimensional array, even if the audio
        file has only one channel.
    fill_value : float, optional
        If more frames are requested than available in the file, the
        rest of the output is be filled with *fill_value*.  If
        *fill_value* is not specified, a smaller array is returned.
    out : `numpy.ndarray` or subclass, optional
        If *out* is specified, the data is written into the given array
        instead of creating a new array.  In this case, the arguments
        *dtype* and *always_2d* are silently ignored!  If *frames* is
        not given, it is obtained from the length of *out*.
    samplerate, channels, format, subtype, endian, closefd
        See `SoundFile`.

    Examples
    --------
    >>> import soundfile as sf
    >>> data, samplerate = sf.read('stereo_file.wav')
    >>> data
    array([[ 0.71329652,  0.06294799],
           [-0.26450912, -0.38874483],
           ...
           [ 0.67398441, -0.11516333]])
    >>> samplerate
    44100

    rN)	SoundFile_prepare_readread
samplerate)fileframesstartstopdtype	always_2d
fill_valueoutrN   channelsformatsubtypeendianclosefdfdata r^   X/var/www/html/eduruby.in/lip-sync/lip-sync-env/lib/python3.10/site-packages/soundfile.pyrM      s   
V
rM   c           
   	   C   sr   ddl }||}|jdkrd}n|jd }t| d||||||}	|	| W d   dS 1 s2w   Y  dS )a  Write data to a sound file.

    .. note:: If *file* exists, it will be truncated and overwritten!

    Parameters
    ----------
    file : str or int or file-like object
        The file to write to.  See `SoundFile` for details.
    data : array_like
        The data to write.  Usually two-dimensional (frames x channels),
        but one-dimensional *data* can be used for mono files.
        Only the data types ``'float64'``, ``'float32'``, ``'int32'``
        and ``'int16'`` are supported.

        .. note:: The data type of *data* does **not** select the data
                  type of the written file. Audio data will be
                  converted to the given *subtype*. Writing int values
                  to a float file will *not* scale the values to
                  [-1.0, 1.0). If you write the value ``np.array([42],
                  dtype='int32')``, to a ``subtype='FLOAT'`` file, the
                  file will then contain ``np.array([42.],
                  dtype='float32')``.

    samplerate : int
        The sample rate of the audio data.
    subtype : str, optional
        See `default_subtype()` for the default value and
        `available_subtypes()` for all possible values.

    Other Parameters
    ----------------
    format, endian, closefd
        See `SoundFile`.

    Examples
    --------
    Write 10 frames of random data to a new file:

    >>> import numpy as np
    >>> import soundfile as sf
    >>> sf.write('stereo_file.wav', np.random.randn(10, 2), 44100, 'PCM_24')

    r   Nr   w)numpyZasarrayndimshaperK   write)
rO   r]   rN   rY   rZ   rX   r[   nprW   r\   r^   r^   r_   rd   $  s   -



"rd   c              
   c   sn    t | d|
|||||!}||||}||||||||	D ]}|V  qW d   dS 1 s0w   Y  dS )a8  Return a generator for block-wise reading.

    By default, iteration starts at the beginning and stops at the end
    of the file.  Use *start* to start at a later position and *frames*
    or *stop* to stop earlier.

    If you stop iterating over the generator before it's exhausted,
    the sound file is not closed. This is normally not a problem
    because the file is opened in read-only mode. To close the file
    properly, the generator's ``close()`` method can be called.

    Parameters
    ----------
    file : str or int or file-like object
        The file to read from.  See `SoundFile` for details.
    blocksize : int
        The number of frames to read per block.
        Either this or *out* must be given.
    overlap : int, optional
        The number of frames to rewind between each block.

    Yields
    ------
    `numpy.ndarray` or type(out)
        Blocks of audio data.
        If *out* was given, and the requested frames are not an integer
        multiple of the length of *out*, and no *fill_value* was given,
        the last block will be a smaller view into *out*.

    Other Parameters
    ----------------
    frames, start, stop
        See `read()`.
    dtype : {'float64', 'float32', 'int32', 'int16'}, optional
        See `read()`.
    always_2d, fill_value, out
        See `read()`.
    samplerate, channels, format, subtype, endian, closefd
        See `SoundFile`.

    Examples
    --------
    >>> import soundfile as sf
    >>> for block in sf.blocks('stereo_file.wav', blocksize=1024):
    >>>     pass  # do something with 'block'

    rJ   N)rK   rL   blocks)rO   	blocksizeoverlaprP   rQ   rR   rS   rT   rU   rV   rN   rW   rX   rY   rZ   r[   r\   blockr^   r^   r_   rf   \  s   
3
"rf   c                   @   s,   e Zd ZdZdd Zedd Zdd ZdS )	_SoundFileInfozInformation about a SoundFilec                 C   s   || _ t|>}|j| _|j| _|j| _|j| _t| j|j | _|j| _|j	| _	|j
| _
|j| _|j| _|j| _|j| _W d    d S 1 sHw   Y  d S N)verboserK   namerN   rW   rP   r>   durationrX   rY   rZ   format_infosubtype_infosections
extra_info)selfrO   rl   r\   r^   r^   r_   __init__  s   

"z_SoundFileInfo.__init__c                 C   sv   t | jd\}}t |d\}}|dkrd|||}|S |dkr(d||}|S |dkr4d| j}|S d|}|S )Ni  <   r   z{0:.0g}:{1:02.0g}:{2:05.3f} hz{0:02.0g}:{1:05.3f} minz{0:d} samplesz	{0:.3f} s)divmodrn   rX   rP   )rs   hoursrestminutessecondsrn   r^   r^   r_   _duration_str  s   
z_SoundFileInfo._duration_strc                 C   sD   d g d}| jr|d g d7 }d | jd}|| |S )N
)z{0.name}zsamplerate: {0.samplerate} Hzzchannels: {0.channels}zduration: {0._duration_str}z$format: {0.format_info} [{0.format}]z'subtype: {0.subtype_info} [{0.subtype}])z
endian: {0.endian}zsections: {0.sections}zframes: {0.frames}zextra_info: """z
    {1}"""z
    )joinrl   rr   splitrX   )rs   infoZindented_extra_infor^   r^   r_   __repr__  s   z_SoundFileInfo.__repr__N)__name__
__module____qualname____doc__rt   propertyr{   r   r^   r^   r^   r_   rj     s    
rj   c                 C   s
   t | |S )zReturns an object with information about a `SoundFile`.

    Parameters
    ----------
    verbose : bool
        Whether to print additional information.
    )rj   )rO   rl   r^   r^   r_   r     s   
r   c                   C   s   t ttjtjS )a  Return a dictionary of available major formats.

    Examples
    --------
    >>> import soundfile as sf
    >>> sf.available_formats()
    {'FLAC': 'FLAC (FLAC Lossless Audio Codec)',
     'OGG': 'OGG (OGG Container format)',
     'WAV': 'WAV (Microsoft)',
     'AIFF': 'AIFF (Apple/SGI)',
     ...
     'WAVEX': 'WAVEX (Microsoft)',
     'RAW': 'RAW (header-less)',
     'MAT5': 'MAT5 (GNU Octave 2.1 / Matlab 5.0)'}

    )dict_available_formats_helper_sndZSFC_GET_FORMAT_MAJOR_COUNTZSFC_GET_FORMAT_MAJORr^   r^   r^   r_   available_formats  s   r   c                    s$   t tjtj}t fdd|D S )ad  Return a dictionary of available subtypes.

    Parameters
    ----------
    format : str
        If given, only compatible subtypes are returned.

    Examples
    --------
    >>> import soundfile as sf
    >>> sf.available_subtypes('FLAC')
    {'PCM_24': 'Signed 24 bit PCM',
     'PCM_16': 'Signed 16 bit PCM',
     'PCM_S8': 'Signed 8 bit PCM'}

    c                 3   s.    | ]\}} d u st  |r||fV  qd S rk   )check_format).0rY   rm   rX   r^   r_   	<genexpr>  s   
 z%available_subtypes.<locals>.<genexpr>)r   r   ZSFC_GET_FORMAT_SUBTYPE_COUNTZSFC_GET_FORMAT_SUBTYPEr   )rX   subtypesr^   r   r_   available_subtypes  s   r   c              	   C   s,   z	t t| ||W S  ttfy   Y dS w )zCheck if the combination of format/subtype/endian is valid.

    Examples
    --------
    >>> import soundfile as sf
    >>> sf.check_format('WAV', 'PCM_24')
    True
    >>> sf.check_format('FLAC', 'VORBIS')
    False

    F)bool_format_int
ValueError	TypeError)rX   rY   rZ   r^   r^   r_   r     s
   r   c                 C   s   t |  t|  S )zReturn the default subtype for a given format.

    Examples
    --------
    >>> import soundfile as sf
    >>> sf.default_subtype('WAV')
    'PCM_16'
    >>> sf.default_subtype('MAT5')
    'DOUBLE'

    )_check_format_default_subtypesgetupperr   r^   r^   r_   default_subtype  s   r   c                   @   s  e Zd ZdZ		d_ddZedd Z	 ed	d Z	 ed
d Z	 edd Z		 edd Z
	 edd Z	 edd Z	 edd Z	 edd Z	 edd Z	 edd Z	 edd Z	 edd Z	 e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& Zd'd( Zd)d* Zefd+d,Z d-d. Z!	1	d`d2d3Z"dad4d5Z#d6d7 Z$d8d9 Z%d:d; Z&	0	dbd=d>Z'dcd?d@Z(dAdB Z)dCdD Z*dEdF Z+dGdH Z,dIdJ Z-dKdL Z.dMdN Z/dOdP Z0dQdR Z1dSdT Z2dUdV Z3dWdX Z4dYdZ Z5d[d\ Z6d]d^ Z7dS )drK   zA sound file.

    For more documentation see the __init__() docstring (which is also
    used for the online documentation (https://python-soundfile.readthedocs.io/).

    rJ   NTc	           
      C   s   t |dr	| n|}|| _|du rt|dd}t|}	|| _t|||||||| _| ||	|| _	t
|drB|  rB| d t| j	tjtjtj dS )a{  Open a sound file.

        If a file is opened with `mode` ``'r'`` (the default) or
        ``'r+'``, no sample rate, channels or file format need to be
        given because the information is obtained from the file. An
        exception is the ``'RAW'`` data format, which always requires
        these data points.

        File formats consist of three case-insensitive strings:

        * a *major format* which is by default obtained from the
          extension of the file name (if known) and which can be
          forced with the format argument (e.g. ``format='WAVEX'``).
        * a *subtype*, e.g. ``'PCM_24'``. Most major formats have a
          default subtype which is used if no subtype is specified.
        * an *endian-ness*, which doesn't have to be specified at all in
          most cases.

        A `SoundFile` object is a *context manager*, which means
        if used in a "with" statement, `close()` is automatically
        called when reaching the end of the code block inside the "with"
        statement.

        Parameters
        ----------
        file : str or int or file-like object
            The file to open.  This can be a file name, a file
            descriptor or a Python file object (or a similar object with
            the methods ``read()``/``readinto()``, ``write()``,
            ``seek()`` and ``tell()``).
        mode : {'r', 'r+', 'w', 'w+', 'x', 'x+'}, optional
            Open mode.  Has to begin with one of these three characters:
            ``'r'`` for reading, ``'w'`` for writing (truncates *file*)
            or ``'x'`` for writing (raises an error if *file* already
            exists).  Additionally, it may contain ``'+'`` to open
            *file* for both reading and writing.
            The character ``'b'`` for *binary mode* is implied because
            all sound files have to be opened in this mode.
            If *file* is a file descriptor or a file-like object,
            ``'w'`` doesn't truncate and ``'x'`` doesn't raise an error.
        samplerate : int
            The sample rate of the file.  If `mode` contains ``'r'``,
            this is obtained from the file (except for ``'RAW'`` files).
        channels : int
            The number of channels of the file.
            If `mode` contains ``'r'``, this is obtained from the file
            (except for ``'RAW'`` files).
        subtype : str, sometimes optional
            The subtype of the sound file.  If `mode` contains ``'r'``,
            this is obtained from the file (except for ``'RAW'``
            files), if not, the default value depends on the selected
            `format` (see `default_subtype()`).
            See `available_subtypes()` for all possible subtypes for
            a given `format`.
        endian : {'FILE', 'LITTLE', 'BIG', 'CPU'}, sometimes optional
            The endian-ness of the sound file.  If `mode` contains
            ``'r'``, this is obtained from the file (except for
            ``'RAW'`` files), if not, the default value is ``'FILE'``,
            which is correct in most cases.
        format : str, sometimes optional
            The major format of the sound file.  If `mode` contains
            ``'r'``, this is obtained from the file (except for
            ``'RAW'`` files), if not, the default value is determined
            from the file extension.  See `available_formats()` for
            all possible values.
        closefd : bool, optional
            Whether to close the file descriptor on `close()`. Only
            applicable if the *file* argument is a file descriptor.

        Examples
        --------
        >>> from soundfile import SoundFile

        Open an existing file for reading:

        >>> myfile = SoundFile('existing_file.wav')
        >>> # do something with myfile
        >>> myfile.close()

        Create a new sound file for reading and writing using a with
        statement:

        >>> with SoundFile('new_file.wav', 'x+', 44100, 2) as myfile:
        >>>     # do something with myfile
        >>>     # ...
        >>>     assert not myfile.closed
        >>>     # myfile.close() is called automatically at the end
        >>> assert myfile.closed

        
__fspath__Nmodezr+r   )hasattrr   _namegetattr_check_mode_mode_create_info_struct_info_open_fileset
issupersetseekableseekr   
sf_commandZSFC_SET_CLIPPING_ffiNULLSF_TRUE)
rs   rO   r   rN   rW   rY   rZ   rX   r[   mode_intr^   r^   r_   rt   ,  s   ^

zSoundFile.__init__c                 C      | j S rk   )r   rs   r^   r^   r_   <lambda>      zSoundFile.<lambda>c                 C   r   rk   )r   r   r^   r^   r_   r     r   c                 C      | j jS rk   )r   rN   r   r^   r^   r_   r         c                 C   r   rk   r   rP   r   r^   r^   r_   r     r   c                 C   r   rk   )r   rW   r   r^   r^   r_   r     r   c                 C      t | jjtj@ S rk   )_format_strr   rX   r   SF_FORMAT_TYPEMASKr   r^   r^   r_   r         c                 C   r   rk   )r   r   rX   r   SF_FORMAT_SUBMASKr   r^   r^   r_   r     r   c                 C   r   rk   )r   r   rX   r   ZSF_FORMAT_ENDMASKr   r^   r^   r_   r     r   c                 C      t | jjtj@ d S Nr   )_format_infor   rX   r   r   r   r^   r^   r_   r     
    c                 C   r   r   )r   r   rX   r   r   r   r^   r^   r_   r     r   c                 C   r   rk   )r   rq   r   r^   r^   r_   r     r   c                 C   s
   | j d u S rk   )r   r   r^   r^   r_   r     s   
 c                 C   s   t | jS rk   )r   sf_errorr   r   r^   r^   r_   r     s    c                 C   s8   t dd}t| jtj|t | t |ddS )z8Retrieve the log string generated when opening the file.zchar[]i @  rG   rH   )	r   newr   r   r   ZSFC_GET_LOG_INFOsizeofstringdecode)rs   r   r^   r^   r_   rr     s
   
zSoundFile.extra_infoc                 C   s
   d | S )NzSoundFile({0.name!r}, mode={0.mode!r}, samplerate={0.samplerate}, channels={0.channels}, format={0.format!r}, subtype={0.subtype!r}, endian={0.endian!r})r   r   r^   r^   r_   r     s   zSoundFile.__repr__c                 C      |    d S rk   closer   r^   r^   r_   __del__     zSoundFile.__del__c                 C   s   | S rk   r^   r   r^   r^   r_   	__enter__  s   zSoundFile.__enter__c                 G   r   rk   r   )rs   argsr^   r^   r_   __exit__  r   zSoundFile.__exit__c                 C   sF   |t v r|   t| jt | | }t| dS t| || dS )z:Write text meta-data in the sound file through properties.N)	
_str_types_check_if_closedr   Zsf_set_stringr   encode_error_checkobject__setattr__)rs   rm   valueerrr^   r^   r_   r     s   zSoundFile.__setattr__c                 C   sJ   |t v r|   t| jt | }|rt|ddS dS td	|)z9Read text meta-data in the sound file through properties.rG   rH    z)'SoundFile' object has no attribute {0!r})
r   r   r   sf_get_stringr   r   r   r   AttributeErrorrX   )rs   rm   r]   r^   r^   r_   __getattr__  s   zSoundFile.__getattr__c                 C   r   rk   r   r   r^   r^   r_   __len__     zSoundFile.__len__c                 C   s   dS )NTr^   r   r^   r^   r_   __bool__  s   zSoundFile.__bool__c                 C   s   |   S rk   )r   r   r^   r^   r_   __nonzero__  r   zSoundFile.__nonzero__c                 C   s   | j jtjkS )z)Return True if the file supports seeking.)r   r   r   r   r   r^   r^   r_   r     s   zSoundFile.seekablec                 C   s&   |    t| j||}t| j |S )a  Set the read/write position.

        Parameters
        ----------
        frames : int
            The frame index or offset to seek.
        whence : {SEEK_SET, SEEK_CUR, SEEK_END}, optional
            By default (``whence=SEEK_SET``), *frames* are counted from
            the beginning of the file.
            ``whence=SEEK_CUR`` seeks from the current position
            (positive and negative values are allowed for *frames*).
            ``whence=SEEK_END`` seeks from the end (use negative value
            for *frames*).

        Returns
        -------
        int
            The new absolute read/write position in frames.

        Examples
        --------
        >>> from soundfile import SoundFile, SEEK_END
        >>> myfile = SoundFile('stereo_file.wav')

        Seek to the beginning of the file:

        >>> myfile.seek(0)
        0

        Seek to the end of the file:

        >>> myfile.seek(0, SEEK_END)
        44100  # this is the file length

        )r   r   Zsf_seekr   r   
_errorcode)rs   rP   whencepositionr^   r^   r_   r     s   $
zSoundFile.seekc                 C   s   |  dtS )z'Return the current read/write position.r   )r   r   r   r^   r^   r_   tell%  s   zSoundFile.tellrI   r@   Fc                 C   s   |du r|  ||}| |||}n|dk s|t|kr t|}| d||}t||kr?|du r9|d| }|S |||d< |S )a  Read from the file and return data as NumPy array.

        Reads the given number of frames in the given data format
        starting at the current read/write position.  This advances the
        read/write position by the same number of frames.
        By default, all frames from the current read/write position to
        the end of the file are returned.
        Use `seek()` to move the current read/write position.

        Parameters
        ----------
        frames : int, optional
            The number of frames to read. If ``frames < 0``, the whole
            rest of the file is read.
        dtype : {'float64', 'float32', 'int32', 'int16'}, optional
            Data type of the returned array, by default ``'float64'``.
            Floating point audio data is typically in the range from
            ``-1.0`` to ``1.0``. Integer data is in the range from
            ``-2**15`` to ``2**15-1`` for ``'int16'`` and from
            ``-2**31`` to ``2**31-1`` for ``'int32'``.

            .. note:: Reading int values from a float file will *not*
                scale the data to [-1.0, 1.0). If the file contains
                ``np.array([42.6], dtype='float32')``, you will read
                ``np.array([43], dtype='int32')`` for
                ``dtype='int32'``.

        Returns
        -------
        audiodata : `numpy.ndarray` or type(out)
            A two-dimensional NumPy (frames x channels) array is
            returned. If the sound file has only one channel, a
            one-dimensional array is returned. Use ``always_2d=True``
            to return a two-dimensional array anyway.

            If *out* was specified, it is returned. If *out* has more
            frames than available in the file (or if *frames* is
            smaller than the length of *out*) and no *fill_value* is
            given, then only a part of *out* is overwritten and a view
            containing all valid frames is returned.

        Other Parameters
        ----------------
        always_2d : bool, optional
            By default, reading a mono sound file will return a
            one-dimensional array. With ``always_2d=True``, audio data
            is always returned as a two-dimensional array, even if the
            audio file has only one channel.
        fill_value : float, optional
            If more frames are requested than available in the file,
            the rest of the output is be filled with *fill_value*. If
            *fill_value* is not specified, a smaller array is
            returned.
        out : `numpy.ndarray` or subclass, optional
            If *out* is specified, the data is written into the given
            array instead of creating a new array. In this case, the
            arguments *dtype* and *always_2d* are silently ignored! If
            *frames* is not given, it is obtained from the length of
            *out*.

        Examples
        --------
        >>> from soundfile import SoundFile
        >>> myfile = SoundFile('stereo_file.wav')

        Reading 3 frames from a stereo file:

        >>> myfile.read(3)
        array([[ 0.71329652,  0.06294799],
               [-0.26450912, -0.38874483],
               [ 0.67398441, -0.11516333]])
        >>> myfile.close()

        See Also
        --------
        buffer_read, .write

        Nr   rM   )_check_frames_create_empty_arraylen	_array_io)rs   rP   rS   rT   rU   rV   r^   r^   r_   rM   )  s   PzSoundFile.readc                 C   sT   | j |dd}| |}t|d || j }| d|||}||ks%J t|S )a  Read from the file and return data as buffer object.

        Reads the given number of *frames* in the given data format
        starting at the current read/write position.  This advances the
        read/write position by the same number of frames.
        By default, all frames from the current read/write position to
        the end of the file are returned.
        Use `seek()` to move the current read/write position.

        Parameters
        ----------
        frames : int, optional
            The number of frames to read. If ``frames < 0``, the whole
            rest of the file is read.
        dtype : {'float64', 'float32', 'int32', 'int16'}
            Audio data will be converted to the given data type.

        Returns
        -------
        buffer
            A buffer containing the read data.

        See Also
        --------
        buffer_read_into, .read, buffer_write

        N)rU   z[]rM   )r   _check_dtyper   r   rW   	_cdata_iobuffer)rs   rP   rS   ctypecdataZread_framesr^   r^   r_   buffer_read  s   

zSoundFile.buffer_readc                 C   s.   |  |}| ||\}}| d|||}|S )a  Read from the file into a given buffer object.

        Fills the given *buffer* with frames in the given data format
        starting at the current read/write position (which can be
        changed with `seek()`) until the buffer is full or the end
        of the file is reached.  This advances the read/write position
        by the number of frames that were read.

        Parameters
        ----------
        buffer : writable buffer
            Audio frames from the file are written to this buffer.
        dtype : {'float64', 'float32', 'int32', 'int16'}
            The data type of *buffer*.

        Returns
        -------
        int
            The number of frames that were read from the file.
            This can be less than the size of *buffer*.
            The rest of the buffer is not filled with meaningful data.

        See Also
        --------
        buffer_read, .read

        rM   )r   _check_bufferr   )rs   r   rS   r   r   rP   r^   r^   r_   buffer_read_into  s   
zSoundFile.buffer_read_intoc                 C   sB   ddl }||}| d|t|}|t|ksJ | | dS )a  Write audio data from a NumPy array to the file.

        Writes a number of frames at the read/write position to the
        file. This also advances the read/write position by the same
        number of frames and enlarges the file if necessary.

        Note that writing int values to a float file will *not* scale
        the values to [-1.0, 1.0). If you write the value
        ``np.array([42], dtype='int32')``, to a ``subtype='FLOAT'``
        file, the file will then contain ``np.array([42.],
        dtype='float32')``.

        Parameters
        ----------
        data : array_like
            The data to write. Usually two-dimensional (frames x
            channels), but one-dimensional *data* can be used for mono
            files. Only the data types ``'float64'``, ``'float32'``,
            ``'int32'`` and ``'int16'`` are supported.

            .. note:: The data type of *data* does **not** select the
                  data type of the written file. Audio data will be
                  converted to the given *subtype*. Writing int values
                  to a float file will *not* scale the values to
                  [-1.0, 1.0). If you write the value ``np.array([42],
                  dtype='int32')``, to a ``subtype='FLOAT'`` file, the
                  file will then contain ``np.array([42.],
                  dtype='float32')``.

        Examples
        --------
        >>> import numpy as np
        >>> from soundfile import SoundFile
        >>> myfile = SoundFile('stereo_file.wav')

        Write 10 frames of random data to a new file:

        >>> with SoundFile('stereo_file.wav', 'w', 44100, 2, 'PCM_24') as f:
        >>>     f.write(np.random.randn(10, 2))

        See Also
        --------
        buffer_write, .read

        r   Nrd   )ra   Zascontiguousarrayr   r   _update_frames)rs   r]   re   writtenr^   r^   r_   rd     s
   .
zSoundFile.writec                 C   sD   |  |}| ||\}}| d|||}||ksJ | | dS )a  Write audio data from a buffer/bytes object to the file.

        Writes the contents of *data* to the file at the current
        read/write position.
        This also advances the read/write position by the number of
        frames that were written and enlarges the file if necessary.

        Parameters
        ----------
        data : buffer or bytes
            A buffer or bytes object containing the audio data to be
            written.
        dtype : {'float64', 'float32', 'int32', 'int16'}
            The data type of the audio data stored in *data*.

        See Also
        --------
        .write, buffer_read

        rd   N)r   r   r   r   )rs   r]   rS   r   r   rP   r   r^   r^   r_   buffer_write   s
   
zSoundFile.buffer_writer   c              	   c   s^   ddl }d| jvrd| jvrtd|du r)|du rtd| |||}d}	n|dur1tdt|}d	}	d}
| ||}|dkr|
du rJd}n
t|
}|
|d|< t|| |}| ||||||d  |r|
du ry|	|| d }
n|| d |
dd< ||| kr|du r|d||  }n|}|	r|	|n|V  ||8 }|dksCdS dS )
a  Return a generator for block-wise reading.

        By default, the generator yields blocks of the given
        *blocksize* (using a given *overlap*) until the end of the file
        is reached; *frames* can be used to stop earlier.

        Parameters
        ----------
        blocksize : int
            The number of frames to read per block. Either this or *out*
            must be given.
        overlap : int, optional
            The number of frames to rewind between each block.
        frames : int, optional
            The number of frames to read.
            If ``frames < 0``, the file is read until the end.
        dtype : {'float64', 'float32', 'int32', 'int16'}, optional
            See `read()`.

        Yields
        ------
        `numpy.ndarray` or type(out)
            Blocks of audio data.
            If *out* was given, and the requested frames are not an
            integer multiple of the length of *out*, and no
            *fill_value* was given, the last block will be a smaller
            view into *out*.


        Other Parameters
        ----------------
        always_2d, fill_value, out
            See `read()`.
        fill_value : float, optional
            See `read()`.
        out : `numpy.ndarray` or subclass, optional
            If *out* is specified, the data is written into the given
            array instead of creating a new array. In this case, the
            arguments *dtype* and *always_2d* are silently ignored!

        Examples
        --------
        >>> from soundfile import SoundFile
        >>> with SoundFile('stereo_file.wav') as f:
        >>>     for block in f.blocks(blocksize=1024):
        >>>         pass  # do something with 'block'

        r   NrJ   +z*blocks() is not allowed in write-only modez)One of {blocksize, out} must be specifiedTz-Only one of {blocksize, out} may be specifiedF)
ra   r   SoundFileRuntimeErrorr   r   r   r   minrM   copy)rs   rg   rh   rP   rS   rT   rU   rV   re   Zcopy_outZoverlap_memoryZoutput_offsetZtoreadri   r^   r^   r_   rf     sD   2zSoundFile.blocksc                 C   sX   |du r|   }t| jtjtd|td}|r&t| j}t	|d|| j
_dS )an  Truncate the file to a given number of frames.

        After this command, the read/write position will be at the new
        end of the file.

        Parameters
        ----------
        frames : int, optional
            Only the data before *frames* is kept, the rest is deleted.
            If not specified, the current read/write position is used.

        Nzsf_count_t*Z
sf_count_tzError truncating the file)r   r   r   r   ZSFC_FILE_TRUNCATEr   r   r   r   LibsndfileErrorr   rP   )rs   rP   r   r^   r^   r_   truncatew  s   

zSoundFile.truncatec                 C   s   |    t| j dS )aj  Write unwritten data to the file system.

        Data written with `write()` is not immediately written to
        the file system but buffered in memory to be written at a later
        time.  Calling `flush()` makes sure that all changes are
        actually written to the file system.

        This has no effect on files opened in read-only mode.

        N)r   r   Zsf_write_syncr   r   r^   r^   r_   flush  s   zSoundFile.flushc                 C   s0   | j s|   t| j}d| _t| dS dS )z.Close the file.  Can be called multiple times.N)closedr   r   Zsf_closer   r   )rs   r   r^   r^   r_   r     s   zSoundFile.closec                 C   s0  t |ttfrOtj|r/d| jv rtd| j	t
| jdr/tt|tjtjB  tj}t |trGtjdkr@tj}n|t }|||| j}n*t |tr^t||| j|}nt||rqt| ||| jtj}ntd| j	|tjkrt |}t!|d| j	d|tj"krd| j_#|S )	z9Call the appropriate sf_open*() function from libsndfile.xzFile exists: {0!r}zw+rC   zInvalid file: {0!r}zError opening {0!r}: prefixr   )$
isinstance_unicodebytes_ospathisfiler   OSErrorrX   rm   r   r   r   openO_WRONLYO_TRUNCr   Zsf_open_sysplatformZsf_wchar_openr   getfilesystemencodingr   r?   Z
sf_open_fd_has_virtual_io_attrsZsf_open_virtual_init_virtual_ior   r   r   r   r   	SFM_WRITErP   )rs   rO   r   r[   ZopenfunctionZfile_ptrr   r^   r^   r_   r     s2   








zSoundFile._openc                    s   t d fdd}t d fdd}t d fdd	}t d
 fdd}t d fdd}|||||d| _t d| jS )z4Initialize callback functions for sf_open_virtual().Zsf_vio_get_filelenc                    s,      } dt    } |t |S Nr   )r   r   r   r   )	user_datacurrsizerO   r^   r_   vio_get_filelen  s
   z3SoundFile._init_virtual_io.<locals>.vio_get_filelenZsf_vio_seekc                    s     | |   S rk   )r   r   )offsetr   r	  r  r^   r_   vio_seek  s   z,SoundFile._init_virtual_io.<locals>.vio_seekZsf_vio_readc                    s\   zt | |} |}W |S  ty-    |}t|}t | |}||d|< Y |S w r  )r   r   readintor   rM   r   )ptrcountr	  bufZ	data_readr]   r  r^   r_   vio_read  s   
z,SoundFile._init_virtual_io.<locals>.vio_readZsf_vio_writec                    s2   t | |}|d d  } |}|d u r|}|S rk   )r   r   rd   )r  r  r	  r  r]   r   r  r^   r_   	vio_write  s   
z-SoundFile._init_virtual_io.<locals>.vio_writeZsf_vio_tellc                    s      S rk   )r   )r	  r  r^   r_   vio_tell  s   z,SoundFile._init_virtual_io.<locals>.vio_tell)Zget_filelenr   rM   rd   r   zSF_VIRTUAL_IO*)r   callbackZ_virtual_ior   )rs   rO   r  r  r  r  r  r^   r  r_   r    s"   	zSoundFile._init_virtual_ioc                 C   s   t S )zReturn all attributes used in __setattr__ and __getattr__.

        This is useful for auto-completion (e.g. IPython).

        )r   r   r^   r^   r_   _getAttributeNames  s   zSoundFile._getAttributeNamesc                 C   s   | j rtddS )zCheck if the file is closed and raise an error if it is.

        This should be used in every method that uses self._file.

        zI/O operation on closed fileN)r   r   r   r^   r^   r_   r     s   zSoundFile._check_if_closedc                 C   sJ   |   r| j|   }|dk s||kr|du r|}|S |dk r#td|S )z8Reduce frames to no more than are available in the file.r   Nz/frames must be specified for non-seekable files)r   rP   r   r   )rs   rP   rU   Zremaining_framesr^   r^   r_   r     s   zSoundFile._check_framesc                 C   sV   |t  v sJ t|tst|}tt|| jt	| \}}|r't
d||fS )z1Convert buffer to cdata and check for valid size.z*Data size must be a multiple of frame size)
_ffi_typesvaluesr   r   r   Zfrom_bufferrv   r   rW   r   r   )rs   r]   r   rP   	remainderr^   r^   r_   r     s   

zSoundFile._check_bufferc                 C   s8   ddl }|s| jdkr|| jf}n|f}|j||ddS )z-Create an empty array with appropriate shape.r   Nr   C)order)ra   rW   empty)rs   rP   rT   rS   re   rc   r^   r^   r_   r   $  s
   zSoundFile._create_empty_arrayc              	   C   s2   zt | W S  ty   tdtt  |w )z7Check if dtype string is valid and return ctype string.z(dtype must be one of {0!r} and not {1!r})r  KeyErrorr   rX   sortedkeys)rs   rS   r^   r^   r_   r   -  s   
zSoundFile._check_dtypec                 C   s   |j dvs|j dkr| jdks|j dkr$|jd | jkr$td|j|jjs,td| |jj	}|jj
t|ks>J t|d |jd d }| ||||S )	z+Check array and call low-level IO function.)r   r   r   r   zInvalid shape: {0!r}zData must be C-contiguous*r]   r   )rb   rW   rc   r   rX   flagsc_contiguousr   rS   rm   itemsizer   r   castZ__array_interface__r   )rs   actionarrayrP   r   r   r^   r^   r_   r   5  s   
zSoundFile._array_ioc                 C   sr   |t  v sJ |   |  r|  }ttd| d | }|| j||}t| j	 |  r7| 
|| t |S )z.Call one of libsndfile's read/write functions.Zsf_Zf_)r  r  r   r   r   r   r   r   r   r   r   r   )rs   r'  r]   r   rP   r
  funcr^   r^   r_   r   B  s   
zSoundFile._cdata_ioc                 C   sD   |   r|  }| dt| j_| |t dS | j j|7  _dS )z!Update self.frames after writing.r   N)r   r   r   r   r   rP   r   )rs   r   r
  r^   r^   r_   r   O  s
   zSoundFile._update_framesc                 C   s|   |dkr|   std|dkr|durtdt||| j\}}}||k r*|}|dk r2|| }|   r<| |t |S )z)Seek to start frame and calculate length.r   z(start is only allowed for seekable filesNz&Only one of {frames, stop} may be used)r   r   r   sliceindicesrP   r   r   )rs   rQ   rR   rP   _r^   r^   r_   rL   X  s   zSoundFile._prepare_readc                 C   sB   i }t  D ]\}}t| j|}|rt|dd||< q|S )a5  Get all metadata present in this SoundFile

        Returns
        -------

        metadata: dict[str, str]
            A dict with all metadata. Possible keys are: 'title', 'copyright',
            'software', 'artist', 'comment', 'date', 'album', 'license',
            'tracknumber' and 'genre'.
        rG   rH   )r   itemsr   r   r   r   r   r   )rs   strsZstrtypeZstridr]   r^   r^   r_   copy_metadatah  s   zSoundFile.copy_metadata)rJ   NNNNNT)rI   r@   FNN)rI   N)Nr   rI   r@   FNNrk   )8r   r   r   r   rt   r   rm   r   rN   rP   rW   rX   rY   rZ   ro   rp   rq   r   r   rr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rM   r   r   rd   r   rf   r   r   r   r   r  r  r   r   r   r   r   r   r   r   rL   r/  r^   r^   r^   r_   rK   $  s    
m


)

^#!5

\	$3			rK   r   c                 C   s   | dkr
t | |ddS )z+Raise LibsndfileError if there is an error.r   r   N)r   )r   r   r^   r^   r_   r   |  s   r   c                 C   s  t | }|du rt| }|du rtd| nt|ttfs&td|z
|t|  O }W n t	y>   t
d|w |du rFd}nt|ttfsTtd|z
|t|  O }W n t	yl   t
d|w td}||_d	|_t|tjkrt
d
|S )z8Return numeric ID for given format|subtype|endian combo.Nz)No default subtype for major format {0!r}zInvalid subtype: {0!r}zUnknown subtype: {0!r}r<   zInvalid endian-ness: {0!r}zUnknown endian-ness: {0!r}SF_INFO*r   z1Invalid combination of format, subtype and endian)r   r   r   rX   r   r   str	_subtypesr   r  r   _endiansr   r   rW   r   Zsf_format_checkZSF_FALSE)rX   rY   rZ   resultr   r^   r^   r_   r     s@   
r   c                 C   s   t | ttfstd| t| }|dst| t|kr&td| t|	ddkr3tdd|v r<t
j}|S d|v rEt
j}|S t
j}|S )z=Check if mode is valid and return its integer representation.zInvalid mode: {0!r}zxrwb+Zxrwr   z&mode must contain exactly one of 'xrw'r   rJ   )r   r   r1  r   rX   r   
differencer   r   intersectionr   ZSFM_RDWRSFM_READr  )r   Zmode_setr   r^   r^   r_   r     s   r   c           	      C   s   |}|du rt | |}t|ttfsJ nt| td}d|vs(| dkrG|du r0td||_	|du r;td||_
t||||_|S tdd |||||fD rYtd	|S )
z*Check arguments and create SF_INFO struct.Nr0  rJ   r   zsamplerate must be specifiedzchannels must be specifiedc                 s   s    | ]}|d uV  qd S rk   r^   )r   argr^   r^   r_   r     s    z&_create_info_struct.<locals>.<genexpr>z\Not allowed for existing files (except 'RAW'): samplerate, channels, format, subtype, endian)_get_format_from_filenamer   r   r1  r   r   r   r   r   rN   rW   r   rX   any)	rO   r   rN   rW   rX   rY   rZ   Zoriginal_formatr   r^   r^   r_   r     s(   



r   c                 C   sr   d}t | d| } ztj| d dd }|dd}W n	 ty%   Y nw | tvr7d|vr7td		| |S )
a  Return a format string obtained from file (or file.name).

    If file already exists (= read mode), an empty string is returned on
    error.  If not, an exception is raised.
    The return type will always be str or unicode (even if
    file/file.name is a bytes object).

    r   rm   rI   r   NrG   rH   rJ   zGNo format specified and unable to get format from file extension: {0!r})
r   r   r   splitextr   	Exceptionr   _formatsr   rX   )rO   r   rX   r^   r^   r_   r9    s   	r9  c                 C   s:   t ttfD ]}| D ]\}}|| kr|    S qqdS )z;Return the string representation of a given numeric format.zn/a)r=  r2  r3  r-  )
format_int
dictionarykvr^   r^   r_   r     s   r   c                 C   sT   t d}| |_tt j||t d |j}t|j|r't 	|
ddfS dfS )z6Return the ID and short description of a given format.zSF_FORMAT_INFO*ZSF_FORMAT_INFOrG   rH   r   )r   r   rX   r   r   r   r   rm   r   r   r   )r>  format_flagro   rm   r^   r^   r_   r     s   
r   c                 c   sF    t d}tt j| |t d t|d D ]}t||V  qdS )z8Helper for available_formats() and available_subtypes().zint*r?   r   N)r   r   r   r   r   r   ranger   )Z
count_flagrB  r  r>  r^   r^   r_   r     s   
r   c                 C   sL   t | ttfstd| z	t|   }W |S  ty%   td| w )z4Check if `format_str` is valid and return format ID.zInvalid format: {0!r}zUnknown format: {0!r})	r   r   r1  r   rX   r=  r   r  r   )
format_strr>  r^   r^   r_   r     s   r   c                 C   sN   |t jk}|t jk}tt| dt| dt| dp|t| dp$t| dp$|gS )z>Check if file has all the necessary attributes for virtual IO.r   r   rd   rM   r  )r   r7  r  allr   )rO   r   readonlyZ	writeonlyr^   r^   r_   r    s   

r  c                   @      e Zd ZdZdS )SoundFileErrorz-Base class for all soundfile-specific errors.Nr   r   r   r   r^   r^   r^   r_   rH    s    rH  c                   @   rG  )r   zKsoundfile module runtime error.

    Errors that used to be `RuntimeError`.NrI  r^   r^   r^   r_   r      s    r   c                   @   s.   e Zd ZdZd
ddZedd Zdd Zd	S )r   zjlibsndfile errors.


    Attributes
    ----------
    code
        libsndfile internal error number.
    r   c                 C   s   t | || || _|| _d S rk   )r   rt   coder   )rs   rJ  r   r^   r^   r_   rt   /  s   
zLibsndfileError.__init__c                 C   s(   | j rt| j }t|ddS dS )zRaw libsndfile error message.rG   rH   z'(Garbled error message from libsndfile))rJ  r   Zsf_error_numberr   r   r   )rs   Zerr_strr^   r^   r_   error_string4  s   zLibsndfileError.error_stringc                 C   s   | j | j S rk   )r   rK  r   r^   r^   r_   __str__@  r   zLibsndfileError.__str__Nr   )r   r   r   r   rt   r   rK  rL  r^   r^   r^   r_   r   &  s    

r   )rI   r   Nr@   FNNNNNNNT)NNNT)Nr   rI   r   Nr@   FNNNNNNNT)Frk   )NNrM  )Pr   __version__osr   sysr  r   r   r   Zctypes.utilr   Z_find_libraryZ
_soundfiler   r   unicoder   	NameErrorr1  r   r=  r2  r3  r   r  r  rB   Z_machineZ_packaged_libnamerD   Z_architecturer   Z_soundfile_datar   dirname__file___pathr}   Z
_full_pathZdlopenr   ImportErrorr   Z_libnameZ_explicit_libnameisdirZ_hbrew_pathr   Zsf_version_stringr   Z__libsndfile_version__
startswithr   rM   rd   rf   r   rj   r   r   r   r   r   rK   r   r   r   r   r9  r   ZSFC_GET_FORMAT_INFOr   r   r   r  r<  rH  RuntimeErrorr   r   r^   r^   r^   r_   <module>   s    
	
	
 !"&	



]
8
;
4

      
^ 
