o
    ?n0j                 '   @   s  U d Z d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mZmZ ddlmZmZmZmZmZ ddlZddlmZ dd	lmZ eeB eB eje B Zee d
< ej!e"edf ej#ej$ej%B ej&B ej'B  f Z(ee d< ej!e"eef ej#ej$ej%B ej&B ej'B  f Z)ee d< ed Z*ee d< ee d< ee d< ddddddddddd
Z+ee,eef  e d< i ddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdI	Z-ee,eef  e dJ< i dKddLddMddNddOddPddQddRddSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcddi dedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd{d|d}d~ddddddddZ.ee,eef  e d< dddddZ/ee,eef  e d< i ddLd dLd"dLd&dLd(dLd*dLd,dLd.dLd0dLd2dQd4dQd6dLd8dsd:dLd<dLd>dLddLdLdLdLdSdudLdLddZ0ee,eef  e d< dddddZ1ee,eef  e d< ddddZ2ee,eef  e d< z{ej3dkrddl3m4Z5 de5  d Z6nNej3dkr0ddl7Z8e89 Z:e:dkrdZ6n8e:dkr!dZ6n0e:dkr)dZ6n(e;de: ej3dkrMddl3m4Z5 e5 dv rEdZ6nde5  d Z6ne;dddl<Z<ej=>e<j?Z@ej=Ae@e6ZBeCeBZDW nu e;eEeFfy   zedZGeGdu re;deCeGZDW nS e;y   ej3dkrdZHnej3dkrdZHn
ej3dkrdZHn ddl3m4Z5 ej3dkre5 dkrej=IdrdndZJeCej=AeJeHZDneCeHZDY nw Y nw eKeDL MddZNeNOdreNePdd ZN				ddededededB de*deQdeRdB de(e)B dB dedB dedB dedB dedB dedB deQde"e(e)B ef fddƄZS				ddede(dededB dedB dedB deQdeRdB dedB ddfdd˄ZT								ddededB dededededB de*deQdeRdB de(e)B dB dedB dedB dedB dedB dedB deQde	e(ddf e	e)ddf B f"ddτZUG ddф dуZVddedeQdeVfddԄZWde,eef fddքZXddedB de,eef fdd؄ZY		ddededB dedB deQfddڄZZdededB fdd܄Z[G ddބ dރZ\d ddZ]dd Z^dd Z_dd Z`dd Zadd ZbeDjcfddZddd Zedd Zfdd ZgG dd dehZiG dd deiejZkG dd dekZld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.14.0    N)	Generator)find_library)SEEK_CURSEEK_ENDSEEK_SET)AnyBinaryIOFinalLiteral	TypeAlias)Self)ffiFileDescriptorOrPath.	AudioDataAudioData_2d)float64float32int32int16	dtype_str_snd_ffi                        	      )
title	copyrightZsoftwareZartistcommentdateZalbumlicenseZtracknumberZgenre
_str_typesZ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MP3_formatsZ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   	_subtypesi   i    i   0)FILEZLITTLEZBIGZCPU_endiansr)   )r*   r+   r,   r-   r.   r/   r0   r1   _default_subtypesdoublefloatintZshort
_ffi_types)ZCONSTANTZAVERAGEVARIABLE_bitrate_modesdarwin)machineZlibsndfile_z.dylibwin32z	win-arm64zlibsndfile_arm64.dllz	win-amd64zlibsndfile_x64.dllzlibsndfile_x86.dllz no packaged library for Windows linux)aarch64Z
aarch64_beZarmv8barmv8lzlibsndfile_arm64.soz.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   FTfileframesstartstopdtype	always_2d
fill_valueout
sampleratechannelsformatsubtypeendianclosefdreturnc              	   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readrk   )rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   fdata rx   P/home/wildlama/miniconda3/envs/lam_a2e/lib/python3.10/site-packages/soundfile.pyru      s   
X
ru   rw   compression_levelbitrate_modec	                 C   sv   ddl }	|	|}|jdkrd}
n|jd }
t| d||
||||||
}|| W d   dS 1 s4w   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, compression_level, bitrate_mode
        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shapers   write)rc   rw   rk   rn   ro   rm   rp   rz   r{   nprl   rv   rx   rx   ry   r   A  s   0



"r   	blocksizeoverlapc              
   c   sh    t | d|
|||||}||||}||||||||	E dH  W d   dS 1 s-w   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'

    rr   N)rs   rt   blocks)rc   r   r   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rv   rx   rx   ry   r   |  s   
7"r   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)verbosers   namerk   rl   rd   rT   durationrm   rn   ro   format_infosubtype_infosections
extra_info)selfrc   r   rv   rx   rx   ry   __init__  s   

"z_SoundFileInfo.__init__c                 C   s   t | jd\}}t |d\}}|dkr#|dd|dd|dd}|S |dkr3|dd|dd	}|S |dkr@| jd
d}|S |dd}|S )Ni  <   r   z.0g:z02.0gz05.3fz hz mindz samplesz.3fz s)divmodr   rd   )r   hoursrestminutessecondsr   rx   rx   ry   _duration_str  s   z_SoundFileInfo._duration_strc                 C   s   d | j d| j dd| j d| j d| j d| j dd	| j d| j dg}| j	rTd
 | j
d}|d d| j d| j d| j dd| dg7 }|S )N
zsamplerate: z Hzz
channels: z
duration: zformat: z []z	subtype: z
    z	
endian: z
sections: zframes: zextra_info: """z    z""")joinr   rk   rl   r   r   rm   r   rn   r   r   splitro   r   rd   )r   infoZindented_extra_inforx   rx   ry   __repr__  s(   





z_SoundFileInfo.__repr__N)__name__
__module____qualname____doc__r   propertyr   r   rx   rx   rx   ry   r     s    
r   r   c                 C   s
   t | |S )zReturns an object with information about a `SoundFile`.

    Parameters
    ----------
    verbose : bool
        Whether to print additional information.
    )r   )rc   r   rx   rx   ry   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_helperr   ZSFC_GET_FORMAT_MAJOR_COUNTZSFC_GET_FORMAT_MAJORrx   rx   rx   ry   available_formats  s   r   c                    s    t tjtj} 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                    s(   i | ]\}} d u st  |r||qS r   )check_format).0rn   r   rm   rx   ry   
<dictcomp>   s    z&available_subtypes.<locals>.<dictcomp>)r   r   ZSFC_GET_FORMAT_SUBTYPE_COUNTZSFC_GET_FORMAT_SUBTYPE)rm   subtypesrx   r   ry   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)rm   rn   ro   rx   rx   ry   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_formatrR   getupperr   rx   rx   ry   default_subtype7  s   r   c                   @   s  e Zd ZdZ						d}dededB dedB dedB d	edB d
edB dedB dededB dedB ddf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	 e
d!d Z	 e
d"d# ZdZdefd$d%Zd~d&d'Zdefd(d)Zd*e ddfd+d,Z!d-ed.e ddfd/d0Z"d-ede fd1d2Z#defd3d4Z$defd5d6Z%defd7d8Z&defd9d:Z'e(fd;ed<edefd=d>Z)defd?d@Z*	B		dd;edDe+dEedFedB dGe,e-B dB de,e-B fdHdIZ.dd;edDe+dB de/fdJdKZ0dLe1e/B e B dDe+defdMdNZ2dOe,ddfdPdQZ3dOe4dDe+ddfdRdSZ5	T	B		ddUedB dVed;edDe+dEedFedB dGe,e-B dB de6e,ddf e6e-ddf B fdWdXZ7dd;edB ddfdYdZZ8d~d[d\Z9d~d]d^Z:e;< Z=d_d` Z>dadb Z?dcdd Z@dedf ZAdgdh ZBdidj ZCdkdl ZDdmdn ZEdodp ZFdqdr ZGdsdt ZHdudv ZIdeJeef fdwdxZKdydz ZLd{d| ZMdS )rs   zA sound file.

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

    rr   NTrc   moderk   rl   rn   ro   rm   rp   rz   r{   rq   c                 C   s   t |tjrt|}|| _|du r t|dd}|du r tdt|}|| _|	| _	|
| _
t|||||||| _| |||| _t|drP|  rP| d t| jtjtjtj | j	durt| | j	 | j
durv| | j
 dS dS 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.
        compression_level : float, optional
            The compression level on 'write()'. The compression level
            should be between 0.0 (minimum compression level) and 1.0
            (highest compression level).
            See `libsndfile document <https://github.com/libsndfile/libsndfile/blob/c81375f070f3c6764969a738eacded64f53a076e/docs/command.md>`__.
        bitrate_mode : {'CONSTANT', 'AVERAGE', 'VARIABLE'}, optional
            The bitrate mode on 'write()'.
            See `libsndfile document <https://github.com/libsndfile/libsndfile/blob/c81375f070f3c6764969a738eacded64f53a076e/docs/command.md>`__.

        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

        Nr   z6Can not get `mode` from file. provided `mode` is None.zr+r   )
isinstance_osPathLikefspath_namegetattrr   _check_mode_mode_compression_level_bitrate_mode_create_info_struct_info_open_fileset
issupersetseekableseekr   
sf_commandZSFC_SET_CLIPPINGr   NULLSF_TRUE_set_compression_level_set_bitrate_mode)r   rc   r   rk   rl   rn   ro   rm   rp   rz   r{   mode_intrx   rx   ry   r   O  s4   h




zSoundFile.__init__c                 C      | j S r   )r   r   rx   rx   ry   <lambda>      zSoundFile.<lambda>c                 C   r   r   )r   r   rx   rx   ry   r     r   c                 C      | j jS r   )r   rk   r   rx   rx   ry   r         c                 C   r   r   r   rd   r   rx   rx   ry   r     r   c                 C   r   r   )r   rl   r   rx   rx   ry   r     r   c                 C      t | jjtj@ S r   )_format_strr   rm   r   SF_FORMAT_TYPEMASKr   rx   rx   ry   r         c                 C   r   r   )r   r   rm   r   SF_FORMAT_SUBMASKr   rx   rx   ry   r     r   c                 C   r   r   )r   r   rm   r   ZSF_FORMAT_ENDMASKr   rx   rx   ry   r     r   c                 C      t | jjtj@ d S Nr   )_format_infor   rm   r   r   r   rx   rx   ry   r     
    c                 C   r   r   )r   r   rm   r   r   r   rx   rx   ry   r     r   c                 C   r   r   )r   r   r   rx   rx   ry   r     r   c                 C   s
   | j d u S r   )r   r   rx   rx   ry   r     s   
 c                 C   s   t | jS r   )r   sf_errorr   r   rx   rx   ry   r     s    c                 C   r   r   )r   r   rx   rx   ry   r     r   c                 C   r   r   )r   r   rx   rx   ry   r     r   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 @  r`   ra   )	r   newr   r   r   ZSFC_GET_LOG_INFOsizeofstringdecode)r   r   rx   rx   ry   r     s
   
zSoundFile.extra_infoc                 C   s|   | j d urd| j  nd}|| jd urd| j dnd7 }d| jd| jd| j d| j d	| jd
| jd| j| dS )Nz, compression_level= z, bitrate_mode=''z
SoundFile(z, mode=z, samplerate=z, channels=z	, format=z
, subtype=z	, endian=))	rz   r{   r   r   rk   rl   rm   rn   ro   )r   Zcompression_settingrx   rx   ry   r     s,   

zSoundFile.__repr__c                 C      |    d S r   closer   rx   rx   ry   __del__     zSoundFile.__del__c                 C   s   | S r   rx   r   rx   rx   ry   	__enter__  s   zSoundFile.__enter__argsc                 G   r   r   r   )r   r   rx   rx   ry   __exit__  r   zSoundFile.__exit__r   valuec                 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)	r'   _check_if_closedr   Zsf_set_stringr   encode_error_checkobject__setattr__)r   r   r   errrx   rx   ry   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.r`   ra   r   z$'SoundFile' object has no attribute )	r'   r   r   sf_get_stringr   r   r   r   AttributeError)r   r   rw   rx   rx   ry   __getattr__   s   zSoundFile.__getattr__c                 C   r   r   r   r   rx   rx   ry   __len__*     zSoundFile.__len__c                 C   s   dS )NTrx   r   rx   rx   ry   __bool__/  s   zSoundFile.__bool__c                 C   s   |   S r   )r   r   rx   rx   ry   __nonzero__4  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   rx   rx   ry   r   9  s   zSoundFile.seekablerd   whencec                 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)r   rd   r   positionrx   rx   ry   r   =  s   $
zSoundFile.seekc                 C   s   |  dtS )z'Return the current read/write position.r   )r   r   r   rx   rx   ry   tellf  s   zSoundFile.tellrb   r   Frg   rh   ri   rj   c                 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   ru   )_check_frames_create_empty_arraylen	_array_io)r   rd   rg   rh   ri   rj   rx   rx   ry   ru   k  s   Q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)ri   z[]ru   )r   _check_dtyper   r   rl   	_cdata_iobuffer)r   rd   rg   ctypecdataZread_framesrx   rx   ry   buffer_read  s   

zSoundFile.buffer_readr  c                 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

        ru   )r  _check_bufferr  )r   r  rg   r  r  rd   rx   rx   ry   buffer_read_into  s   
zSoundFile.buffer_read_intorw   c                 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   Nr   )r}   Zascontiguousarrayr  r  _update_frames)r   rw   r   writtenrx   rx   ry   r     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

        r   N)r  r
  r  r  )r   rw   rg   r  r  rd   r  rx   rx   ry   buffer_writeE  s
   
zSoundFile.buffer_writer   r   r   c              	   c   st   ddl }d| jvrd| jvrtd| ||}|du r:|du r%td|dur+|nt||}	| |	||}d}
n|durBtdt|}d	}
d}|dkr|du rUd}n
t|}||d|< t|| |}| ||||||d  |r|du r|	|| d }n|| d |dd< ||| kr|du r|d||  }n|}|
r|	|n|V  ||8 }|dksNd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   Nrr   +z*blocks() is not allowed in write-only modez)One of {blocksize, out} must be specifiedTz-Only one of {blocksize, out} may be specifiedF)
r}   r   SoundFileRuntimeErrorr   r   minr  r  ru   copy)r   r   r   rd   rg   rh   ri   rj   r   Zout_sizeZcopy_outZoverlap_memoryZoutput_offsetZtoreadblockrx   rx   ry   r   `  sF   4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   rd   )r   rd   r   rx   rx   ry   truncate  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   rx   rx   ry   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   )r   r   rx   rx   ry   r     s   zSoundFile.closec                    sD  t |ttfrHt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 }n t |trT fdd}nt||r`fdd}ntdjj$ |||j}|tjkrt|}t|d	jd
dW d   n1 sw   Y  |tjkrdj_ |S )z9Call the appropriate sf_open*() function from libsndfile.xzFile exists: zw+r[   c                    s   t | || S r   )r   Z
sf_open_fdrc   r   r   )rp   rx   ry   r     s    z!SoundFile._open.<locals>.<lambda>c                    s   t  | ||tjS r   )r   Zsf_open_virtual_init_virtual_ior   r   r  r   rx   ry   r     s    zInvalid file: zError opening z: prefixNr   )!r   strbytesr   pathisfiler   OSErrorr   r   r   r   openO_WRONLYO_TRUNCr   Zsf_open_sysplatformZsf_wchar_openr   getfilesystemencodingrU   _has_virtual_io_attrsr   _sf_error_lockr   r   r   r   r  	SFM_WRITErd   )r   rc   r   rp   ZopenfunctionZfile_ptrr   rx   )rp   r   ry   r     s6   







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rc   rx   ry   vio_get_filelen  s
   z3SoundFile._init_virtual_io.<locals>.vio_get_filelenZsf_vio_seekc                    s     | |   S r   )r   r   )offsetr   r,  r/  rx   ry   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   ru   r  )ptrcountr,  bufZ	data_readrw   r/  rx   ry   vio_read)  s   
z,SoundFile._init_virtual_io.<locals>.vio_readZsf_vio_writec                    s2   t | |}|d d  } |}|d u r|}|S r   )r   r  r   )r4  r5  r,  r6  rw   r  r/  rx   ry   	vio_write6  s   
z-SoundFile._init_virtual_io.<locals>.vio_writeZsf_vio_tellc                    s      S r   )r   )r,  r/  rx   ry   vio_tell@  s   z,SoundFile._init_virtual_io.<locals>.vio_tell)Zget_filelenr   ru   r   r   zSF_VIRTUAL_IO*)r   callbackZ_virtual_ior   )r   rc   r0  r2  r7  r8  r9  rx   r/  ry   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   rx   rx   ry   _getAttributeNamesM  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   rx   rx   ry   r   U  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   rd   r   r   )r   rd   ri   Zremaining_framesrx   rx   ry   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)rV   valuesr   r  r   from_bufferr   r  rl   r   r   )r   rw   r  rd   	remainderrx   rx   ry   r
  i  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)r}   rl   empty)r   rd   rh   rg   r   r   rx   rx   ry   r  t  s
   zSoundFile._create_empty_arrayc                 C   s6   zt | W S  ty   tdtt  d|w )z7Check if dtype string is valid and return ctype string.zdtype must be one of z	 and not )rV   KeyErrorr   sortedkeys)r   rg   rx   rx   ry   r  }  s
   
zSoundFile._check_dtypec                 C   s   |j dvrtd|jd|j dk rdnd d|j dkrdn|jd }|| jkr9td|jd| j d	| d|jjsAtd
| |jj}|jj	t
|ksSJ t
|d |jd d }| ||||S )z+Check array and call low-level IO function.)r   r   zInvalid shape: z (r   z0 dimensions not supportedztoo many dimensionsr   z (Expected z channels, got zData must be C-contiguous*rw   r   )r~   r   r   rl   flagsc_contiguousr  rg   r   itemsizer   r   castZ__array_interface__r  )r   actionarrayrd   Zarray_channelsr  r  rx   rx   ry   r    s   
&
 zSoundFile._array_ioc                 C   sv   |t  v sJ |   d}|  r|  }ttd| d | }|| j||}t| j	 |  r9| 
|| t |S )z.Call one of libsndfile's read/write functions.r   Zsf_Zf_)rV   r<  r   r   r   r   r   r   r   r   r   r   )r   rJ  rw   r  rd   r-  funcrx   rx   ry   r    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   rd   r   )r   r  r-  rx   rx   ry   r    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indicesrd   r   r   )r   re   rf   rd   _rx   rx   ry   rt     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'.
        r`   ra   )r'   itemsr   r   r   r   r   r   )r   strsZstrtypeZstridrw   rx   rx   ry   copy_metadata  s   zSoundFile.copy_metadatac                 C   sf   |t v sJ td}t | |d< t| jtj|t|}|tjkr1t	| j}t
|d| dS )z,Call libsndfile's set bitrate mode function.zint[1]r   zError set bitrate mode N)rX   r   r   r   r   r   ZSFC_SET_BITRATE_MODEr   r   r   r  )r   r{   Zpointer_bitrate_moder   rx   rx   ry   r     s   

zSoundFile._set_bitrate_modec                 C   sz   d|  krdkst d t dtd}||d< t| jtj|t|}|tjkr;t	| j}t
|d| dS )z1Call libsndfile's set compression level function.r   r   z)Compression level must be in range [0..1]z	double[1]zError set compression level N)r   r   r   r   r   r   ZSFC_SET_COMPRESSION_LEVELr   r   r   r  )r   rz   Zpointer_compression_levelr   rx   rx   ry   r     s   

z SoundFile._set_compression_level)	rr   NNNNNTNN)rq   N)rb   r   FNN)rb   N)Nr   rb   r   FNNr   )Nr   r   r   r   r   r  rU   r   rT   r   r   r   r   rk   rd   rl   rm   rn   ro   r   r   r   r  r   rz   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ru   
memoryviewr	  	bytearrayr  r   r  r  r   r   r  r  r   
_threadingLockr)  r   r  r;  r   r   r
  r  r  r  r  r  rt   r   rR  r   r   rx   rx   rx   ry   rs   G  s   
 




)

`#!6

_

%3			rs   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  rx   rx   ry   r     s   r   c                 C   s  t | }|du rt| }|du rtd| nt|ts$td|z
|t|  O }W n ty<   td|w |du rDd}nt|tsPtd|z
|t	|  O }W n tyh   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 zInvalid subtype: zUnknown subtype: rP   zInvalid endian-ness: zUnknown endian-ness: SF_INFO*r   z1Invalid combination of format, subtype and endian)r   r   r   r   r  rO   r   rB  r   rQ   r   r   rm   rl   r   Zsf_format_checkZSF_FALSE)rm   rn   ro   resultr   rx   rx   ry   r     s@   


r   c                 C   s   t | tstd| t| }|dst| t|kr$td| t|ddkr1tdd|v r:tj	}|S d|v rCtj
}|S tj}|S )z=Check if mode is valid and return its integer representation.zInvalid mode: zxrwb+Zxrwr   z&mode must contain exactly one of 'xrw'r  rr   )r   r  r   r   
differencer  r   intersectionr   ZSFM_RDWRSFM_READr*  )r   Zmode_setr   rx   rx   ry   r   
  s   
r   c           	      C   s   |}|du rt | |}t|tsJ nt| td}d|vs&| dkrE|du r.td||_|du r9td||_	t
||||_|S tdd |||||fD rWtd	|S )
z*Check arguments and create SF_INFO struct.NrW  rr   r(   zsamplerate must be specifiedzchannels must be specifiedc                 s   s    | ]}|d uV  qd S r   rx   )r   argrx   rx   ry   	<genexpr>1  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  r   r   r   r   r   rk   rl   r   rm   any)	rc   r   rk   rl   rm   rn   ro   Zoriginal_formatr   rx   rx   ry   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   r   rb   r   Nr`   ra   rr   zBNo format specified and unable to get format from file extension: )	r   r   r  splitextr   	Exceptionr   r2   r   )rc   r   rm   rx   rx   ry   r^  8  s   	r^  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)r2   rO   rQ   rP  )
format_int
dictionarykvrx   rx   ry   r   P  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_INFOr`   ra   r   )r   r   rm   r   r   r   r   r   r   r   r   )rb  format_flagr   r   rx   rx   ry   r   Z  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*rU   r   N)r   r   r   r   r   r   ranger   )Z
count_flagrf  r5  rb  rx   rx   ry   r   e  s   
r   c                 C   sH   t | t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: zUnknown format: )r   r  r   r2   r   rB  r   )
format_strrb  rx   rx   ry   r   m  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   r   ru   r3  )r   r[  r*  allhasattr)rc   r   readonlyZ	writeonlyrx   rx   ry   r(  x  s   

r(  c                   @      e Zd ZdZdS )SoundFileErrorz-Base class for all soundfile-specific errors.Nr   r   r   r   rx   rx   rx   ry   rm    s    rm  c                   @   rl  )r  zKsoundfile module runtime error.

    Errors that used to be `RuntimeError`.Nrn  rx   rx   rx   ry   r    s    r  c                   @   sH   e Zd ZdZddededdfddZedefd	d
ZdefddZ	dS )r  zjlibsndfile errors.


    Attributes
    ----------
    code
        libsndfile internal error number.
    r   coder  rq   Nc                 C   s   t | || || _|| _d S r   )r  r   ro  r  )r   ro  r  rx   rx   ry   r     s   
zLibsndfileError.__init__c                 C   s(   | j rt| j }t|ddS dS )zRaw libsndfile error message.r`   ra   z'(Garbled error message from libsndfile))ro  r   Zsf_error_numberr   r   r   )r   Zerr_strrx   rx   ry   error_string  s   zLibsndfileError.error_stringc                 C   s   | j | j S r   )r  rp  r   rx   rx   ry   __str__  r   zLibsndfileError.__str__r   )
r   r   r   r   rU   r  r   r   rp  rq  rx   rx   rx   ry   r    s    r  )rb   r   Nr   FNNNNNNNT)NNNTNN)Nr   rb   r   Nr   FNNNNNNNT)Fr   )NNrr  )mr   __version__osr   sysr%  	threadingrU  collections.abcr   Zctypes.utilr   Z_find_libraryr   r   r   typingr   r   r	   r
   r   r}   Ztyping_extensionsr   Z
_soundfiler   r   r  rU   r   r   __annotations__Zndarraytuplerg   r   r   r   r   r   r   r   r'   r   r2   rO   rQ   rR   rV   rX   r&  rZ   Z_machineZ_packaged_libname	sysconfig
_sysconfigget_platformZ_win_machiner!  Z_soundfile_datar  dirname__file___pathr   Z
_full_pathdlopenr   ImportErrorr   Z_libnameZ_explicit_libnameisdirZ_hbrew_pathr   Zsf_version_stringr   Z__libsndfile_version__
startswithr  r   rT   ru   r   r   r   r   r   r   r   r   rs   r   r   r   r   r^  r   ZSFC_GET_FORMAT_INFOr   r   r   r(  ra  rm  RuntimeErrorr  r  rx   rx   rx   ry   <module>   s   
88	
	
 !"&	







a
;

=4 
       $ 
