o
    0 i`                     @   s  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ddddZzejdkrSddlmZ de  d ZnSejdkrddlmZ ddlmZ e d dkrpdZn6e d dkr{dZn+e d!e e ejdkrddlmZ e dv rdZn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y3   zedZ-e-du re de)e-Z*W nS e y0   ejdkrdZ.nejdkrdZ.n
ejdkr dZ.n ddlmZ ejdkr)e dkr)ej#/drdndZ0e)ej#'e0e.Z*ne)e.Z*Y nw Y nw e1e*2 3ddZ4e45drMe4e6dd Z4			dddZ7		dddZ8				dddZ9G dd de:Z;dddZ<dd Z=dddZ>dddZ?dd Z@G dd de:ZAdddZBdd ZCdd ZDdd ZEddÄ ZFddń ZGe*jHfddǄZIddɄ ZJdd˄ ZKdd̈́ ZLG ddτ deMZNG ddф deNeOZPG ddӄ dePZQd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.13.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)ZCONSTANTZAVERAGEVARIABLEdarwin)machineZlibsndfile_z.dylibwin32)architecture64bitzlibsndfile_x64.dll32bitzlibsndfile_x86.dllz%no packaged library for Windows {} {}linux)aarch64Z
aarch64_beZarmv8bZ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@   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outrR   channelsformatsubtypeendianclosefdfdata rb   U/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/soundfile.pyrQ      s   
V
rQ   c	                 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shaperO   write)rS   ra   rR   r]   r^   r\   r_   compression_levelbitrate_modenpr[   r`   rb   rb   rc   rh   8  s   -



"rh   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'

    rN   N)rO   rP   blocks)rS   	blocksizeoverlaprT   rU   rV   rW   rX   rY   rZ   rR   r[   r\   r]   r^   r_   r`   blockrb   rb   rc   rl   q  s   
3
"rl   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)verboserO   namerR   r[   rT   r>   durationr\   r]   r^   format_infosubtype_infosections
extra_info)selfrS   rr   r`   rb   rb   rc   __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)divmodrt   r\   rT   )ry   hoursrestminutessecondsrt   rb   rb   rc   _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
    )joinrr   rx   splitr\   )ry   infoZindented_extra_inforb   rb   rc   __repr__  s   z_SoundFileInfo.__repr__N)__name__
__module____qualname____doc__rz   propertyr   r   rb   rb   rb   rc   rp     s    
rp   c                 C   s
   t | |S )zReturns an object with information about a `SoundFile`.

    Parameters
    ----------
    verbose : bool
        Whether to print additional information.
    )rp   )rS   rr   rb   rb   rc   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_MAJORrb   rb   rb   rc   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 rq   )check_format).0r]   rs   r\   rb   rc   	<genexpr>  s   
 z%available_subtypes.<locals>.<genexpr>)r   r   ZSFC_GET_FORMAT_SUBTYPE_COUNTZSFC_GET_FORMAT_SUBTYPEr   )r\   subtypesrb   r   rc   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)r\   r]   r^   rb   rb   rc   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   rb   rb   rc   default_subtype)  s   r   c                   @   s6  e Zd ZdZ			ded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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/d0 Z#	3	dfd4d5Z$dgd6d7Z%d8d9 Z&d:d; Z'd<d= Z(	2	dhd?d@Z)didAdBZ*dCdD Z+dEdF Z,dGdH Z-dIdJ Z.dKdL Z/dMdN Z0dOdP Z1dQdR Z2dSdT Z3dUdV Z4dWdX Z5dYdZ Z6d[d\ Z7d]d^ Z8d_d` Z9dadb Z:dcdd Z;dS )jrO   zA sound file.

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

    rN   NTc                 C   s   t |dr	| n|}|| _|du rt|dd}t|}|| _|	| _|
| _t|||||||| _	| 
|||| _t|drH|  rH| d t| jtjtjtj | jdurl| | j | jdurn| | 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

        
__fspath__Nmodezr+r   )hasattrr   _namegetattr_check_mode_mode_compression_level_bitrate_mode_create_info_struct_info_open_fileset
issupersetseekableseekr   
sf_commandZSFC_SET_CLIPPING_ffiNULLSF_TRUE_set_compression_level_set_bitrate_mode)ry   rS   r   rR   r[   r]   r^   r\   r_   ri   rj   mode_intrb   rb   rc   rz   A  s.   g



zSoundFile.__init__c                 C      | j S rq   )r   ry   rb   rb   rc   <lambda>      zSoundFile.<lambda>c                 C   r   rq   )r   r   rb   rb   rc   r     r   c                 C      | j jS rq   )r   rR   r   rb   rb   rc   r         c                 C   r   rq   r   rT   r   rb   rb   rc   r     r   c                 C   r   rq   )r   r[   r   rb   rb   rc   r     r   c                 C      t | jjtj@ S rq   )_format_strr   r\   r   SF_FORMAT_TYPEMASKr   rb   rb   rc   r         c                 C   r   rq   )r   r   r\   r   SF_FORMAT_SUBMASKr   rb   rb   rc   r     r   c                 C   r   rq   )r   r   r\   r   ZSF_FORMAT_ENDMASKr   rb   rb   rc   r     r   c                 C      t | jjtj@ d S Nr   )_format_infor   r\   r   r   r   rb   rb   rc   r     
    c                 C   r   r   )r   r   r\   r   r   r   rb   rb   rc   r     r   c                 C   r   rq   )r   rw   r   rb   rb   rc   r     r   c                 C   s
   | j d u S rq   )r   r   rb   rb   rc   r     s   
 c                 C   s   t | jS rq   )r   sf_errorr   r   rb   rb   rc   r     s    c                 C   r   rq   )r   r   rb   rb   rc   r     r   c                 C   r   rq   )r   r   rb   rb   rc   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 @  rK   rL   )	r   newr   r   r   ZSFC_GET_LOG_INFOsizeofstringdecode)ry   r   rb   rb   rc   rx     s
   
zSoundFile.extra_infoc                 C   sD   | j d urd| j nd}|| jd urd| jnd7 }d| |S )Nz, compression_level={0} z, bitrate_mode='{0}'zSoundFile({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}{1}))ri   r\   rj   )ry   Zcompression_settingrb   rb   rc   r     s   

zSoundFile.__repr__c                 C      |    d S rq   closer   rb   rb   rc   __del__     zSoundFile.__del__c                 C   s   | S rq   rb   r   rb   rb   rc   	__enter__  s   zSoundFile.__enter__c                 G   r   rq   r   )ry   argsrb   rb   rc   __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__)ry   rs   valueerrrb   rb   rc   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.rK   rL   r   z)'SoundFile' object has no attribute {0!r})
r   r   r   sf_get_stringr   r   r   r   AttributeErrorr\   )ry   rs   ra   rb   rb   rc   __getattr__  s   zSoundFile.__getattr__c                 C   r   rq   r   r   rb   rb   rc   __len__     zSoundFile.__len__c                 C   s   dS )NTrb   r   rb   rb   rc   __bool__  s   zSoundFile.__bool__c                 C   s   |   S rq   )r   r   rb   rb   rc   __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   rb   rb   rc   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)ry   rT   whencepositionrb   rb   rc   r   +  s   $
zSoundFile.seekc                 C   s   |  dtS )z'Return the current read/write position.r   )r   r   r   rb   rb   rc   tellT  s   zSoundFile.tellrM   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   rQ   )_check_frames_create_empty_arraylen	_array_io)ry   rT   rW   rX   rY   rZ   rb   rb   rc   rQ   X  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)rY   z[]rQ   )r   _check_dtyper   r   r[   	_cdata_iobuffer)ry   rT   rW   ctypecdataZread_framesrb   rb   rc   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

        rQ   )r   _check_bufferr   )ry   r   rW   r   r   rT   rb   rb   rc   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   Nrh   )re   Zascontiguousarrayr   r   _update_frames)ry   ra   rk   writtenrb   rb   rc   rh     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

        rh   N)r   r   r   r   )ry   ra   rW   r   r   rT   r   rb   rb   rc   buffer_write0  s
   
zSoundFile.buffer_writer   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   NrN   +z*blocks() is not allowed in write-only modez)One of {blocksize, out} must be specifiedTz-Only one of {blocksize, out} may be specifiedF)
re   r   SoundFileRuntimeErrorr   r   minr   r   rQ   copy)ry   rm   rn   rT   rW   rX   rY   rZ   rk   Zout_sizeZcopy_outZoverlap_memoryZoutput_offsetZtoreadro   rb   rb   rc   rl   K  sF   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   rT   )ry   rT   r   rb   rb   rc   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   rb   rb   rc   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   )ry   r   rb   rb   rc   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+rD   zInvalid file: {0!r}zError opening {0!r}: prefixr   )$
isinstance_unicodebytes_ospathisfiler   OSErrorr\   rs   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_WRITErT   )ry   rS   r   r_   ZopenfunctionZfile_ptrr   rb   rb   rc   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rS   rb   rc   vio_get_filelen  s
   z3SoundFile._init_virtual_io.<locals>.vio_get_filelenZsf_vio_seekc                    s     | |   S rq   )r   r   )offsetr   r  r  rb   rc   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   rQ   r   )ptrcountr  bufZ	data_readra   r  rb   rc   vio_read
  s   
z,SoundFile._init_virtual_io.<locals>.vio_readZsf_vio_writec                    s2   t | |}|d d  } |}|d u r|}|S rq   )r   r   rh   )r  r  r  r  ra   r   r  rb   rc   	vio_write  s   
z-SoundFile._init_virtual_io.<locals>.vio_writeZsf_vio_tellc                    s      S rq   )r   )r  r  rb   rc   vio_tell!  s   z,SoundFile._init_virtual_io.<locals>.vio_tell)Zget_filelenr   rQ   rh   r   zSF_VIRTUAL_IO*)r   callbackZ_virtual_ior   )ry   rS   r  r  r  r  r   rb   r  rc   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   rb   rb   rc   _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   rb   rb   rc   r   6  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   rT   r   r   )ry   rT   rY   Zremaining_framesrb   rb   rc   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_bufferr|   r   r[   r   r   )ry   ra   r   rT   	remainderrb   rb   rc   r   J  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)re   r[   empty)ry   rT   rX   rW   rk   rg   rb   rb   rc   r   U  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   r\   sortedkeys)ry   rW   rb   rb   rc   r   ^  s   
zSoundFile._check_dtypec                 C   s   |j dvrtd|j|j dk rdd|j dkrdn|jd }|| jkr3td|j| j||jjs;td| |jj	}|jj
t|ksMJ t|d |jd	 d
 }| ||||S )z+Check array and call low-level IO function.)r   r   zInvalid shape: {0!r} ({1})r   z0 dimensions not supportedztoo many dimensionsz5Invalid shape: {0!r} (Expected {1} channels, got {2})zData must be C-contiguous*ra   r   )rf   r   r\   rg   r[   flagsc_contiguousr   rW   rs   itemsizer   r   castZ__array_interface__r   )ry   actionarrayrT   Zarray_channelsr   r   rb   rb   rc   r   f  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   )ry   r1  ra   r   rT   r  funcrb   rb   rc   r   t  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   rT   r   )ry   r   r  rb   rb   rc   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indicesrT   r   r   )ry   rU   rV   rT   _rb   rb   rc   rP     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'.
        rK   rL   )r   itemsr   r   r   r   r   r   )ry   strsZstrtypeZstridra   rb   rb   rc   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)_bitrate_modesr   r   r   r   r   ZSFC_SET_BITRATE_MODEr   r   r   r   )ry   rj   Zpointer_bitrate_moder   rb   rb   rc   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   )ry   ri   Zpointer_compression_levelr   rb   rb   rc   r     s   

z SoundFile._set_compression_level)	rN   NNNNNTNN)rM   r@   FNN)rM   N)Nr   rM   r@   FNNrq   )<r   r   r   r   rz   r   rs   r   rR   rT   r[   r\   r]   r^   ru   rv   rw   r   r   ri   rj   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rQ   r   r   rh   r   rl   r   r   r   r   r  r"  r   r   r   r   r   r   r   r   rP   r9  r   r   rb   rb   rb   rc   rO   9  s    




)

^#!6

]	$3			rO   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  rb   rb   rc   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   r\   r  r  str	_subtypesr   r)  r   _endiansr   r   r[   r   Zsf_format_checkZSF_FALSE)r\   r]   r^   resultr   rb   rb   rc   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   rN   )r  r  r<  r   r\   r   
differencer   r   intersectionr   ZSFM_RDWRSFM_READr  )r   Zmode_setr   rb   rb   rc   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.Nr;  rN   r   zsamplerate must be specifiedzchannels must be specifiedc                 s   s    | ]}|d uV  qd S rq   rb   )r   argrb   rb   rc   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  r<  r   r   r   r   r   rR   r[   r   r\   any)	rS   r   rR   r[   r\   r]   r^   Zoriginal_formatr   rb   rb   rc   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   rs   rM   r   NrK   rL   rN   zGNo format specified and unable to get format from file extension: {0!r})
r   r  r  splitextr   	Exceptionr   _formatsr   r\   )rS   r   r\   rb   rb   rc   rD    s   	rD  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)rH  r=  r>  r7  )
format_int
dictionarykvrb   rb   rc   r   1  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_INFOrK   rL   r   )r   r   r\   r   r   r   r   rs   r   r   r   )rI  format_flagru   rs   rb   rb   rc   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_flagrM  r  rI  rb   rb   rc   r   F  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  r<  r   r\   rH  r   r)  r   )
format_strrI  rb   rb   rc   r   N  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   rh   rQ   r  )r   rB  r  allr   )rS   r   readonlyZ	writeonlyrb   rb   rc   r  Y  s   

r  c                   @      e Zd ZdZdS )SoundFileErrorz-Base class for all soundfile-specific errors.Nr   r   r   r   rb   rb   rb   rc   rS  e  s    rS  c                   @   rR  )r   zKsoundfile module runtime error.

    Errors that used to be `RuntimeError`.NrT  rb   rb   rb   rc   r   i  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 rq   )r   rz   coder  )ry   rU  r  rb   rb   rc   rz   x  s   
zLibsndfileError.__init__c                 C   s(   | j rt| j }t|ddS dS )zRaw libsndfile error message.rK   rL   z'(Garbled error message from libsndfile))rU  r   Zsf_error_numberr   r   r   )ry   Zerr_strrb   rb   rc   error_string}  s   zLibsndfileError.error_stringc                 C   s   | j | j S rq   )r  rV  r   rb   rb   rc   __str__  r   zLibsndfileError.__str__Nr   )r   r   r   r   rz   r   rV  rW  rb   rb   rb   rc   r   o  s    

r   )rM   r   Nr@   FNNNNNNNT)NNNTNN)Nr   rM   r   Nr@   FNNNNNNNT)Frq   )NNrX  )Rr   __version__osr  sysr  r   r   r   Zctypes.utilr   Z_find_libraryZ
_soundfiler   r   unicoder  	NameErrorr<  r   rH  r=  r>  r   r#  r:  r  rC   Z_machineZ_packaged_libnamerE   Z_architecturer  r\   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   rQ   rh   rl   r   rp   r   r   r   r   r   rO   r   r   r   r   rD  r   ZSFC_GET_FORMAT_INFOr   r   r   r  rG  rS  RuntimeErrorr   r   rb   rb   rb   rc   <module>   s<   
	
	
 !"&	



]
9
;
4

       
 
