
    |h`                     4   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 	 eZ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	 ej4                  dk(  rddlmZ d e       z   dz   Znej4                  dk(  rNddlmZ ddlmZ  e       d   dk(  rdZni e       d   dk(  rdZnY e djC                   e        e                   ej4                  dk(  r ddlmZ  e       dv rdZnd e       z   dz   Zn e d      ddl"Z"ejF                  jI                  e"jJ                        Z&ejF                  jO                  e&e      Z( ejR                  e(      Z* ejb                  e*je                               jg                  dd      Z4e4jk                  d      re4 e6d      d Z4	 	 	 ddZ7	 	 ddZ8	 	 	 	 ddZ9 G d de:      Z;ddZ<d Z=ddZ>ddZ?d Z@ G d de:      ZAddZBd ZCd ZDd ZEd ZFd ZGe*j                  fdZId ZJd ZKd ZL G d deM      ZN G d deNeO      ZP G d deP      ZQy# e$ r eZY w xY w# e e+e,f$ r 	  ed      Z-e- e d       ejR                  e-      Z*n# e $ r ej4                  dk(  rdZ.n%ej4                  dk(  rdZ.nej4                  dk(  rdZ.n ddlmZ ej4                  dk(  rV e       dk(  rLejF                  j_                  d      rdndZ0 ejR                  ejF                  jO                  e0e.            Z*n ejR                  e.      Z*Y nw xY wY w xY w)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	copyrightsoftwareartistcommentdatealbumlicensetracknumbergenreWAVi   AIFFi   AUi   RAWi   PAFi   SVXi   NISTi   VOCi   IRCAMi  
 W64i   MAT4i   MAT5i   PVFi   XIi   HTKi   SDSi   AVRi   i   i   i   i   i   i    i  ! i  " i  # )	WAVEXSD2FLACCAFWVEOGGMPC2KRF64MP3PCM_S8PCM_16PCM_24PCM_32PCM_U8FLOATDOUBLEULAWALAW   	IMA_ADPCM   MS_ADPCM   GSM610    	VOX_ADPCM!   NMS_ADPCM_16"   NMS_ADPCM_24#   NMS_ADPCM_32$   G721_320   G723_241   G723_402   DWVW_12@   DWVW_16A   DWVW_24B   DWVW_NC   DPCM_8P   DPCM_16Q   VORBIS`   OPUSd   ALAC_16p   ALAC_20q   ALAC_24r   ALAC_32s   MPEG_LAYER_I   MPEG_LAYER_II   MPEG_LAYER_III   i   i    i   0)FILELITTLEBIGCPUr-   )r.   r/   r0   r1   r2   r3   r4   r5   doublefloatintshort)float64float32int32int16)CONSTANTAVERAGEVARIABLEdarwin)machinelibsndfile_z.dylibwin32)architecture64bitzlibsndfile_x64.dll32bitzlibsndfile_x86.dllz%no packaged library for Windows {} {}linux)aarch64
aarch64_bearmv8barmv8lzlibsndfile_arm64.soz.soz%no packaged library for this platform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-c           
          t        | d||	|||
|      5 }|j                  |||      }|j                  |||||      }ddd       j                  fS # 1 sw Y   xY w)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outr   channelsformatsubtypeendianclosefdfdatas                   H/var/www/html/test/engine/venv/lib/python3.12/site-packages/soundfile.pyr   r      ss    l 
4j(FFG
5 A89f5vvfeY
C@A 	A As   )AAc	                     ddl }	|	j                  |      }|j                  dk(  rd}
n|j                  d   }
t	        | d||
||||||
      5 }|j                  |       ddd       y# 1 sw Y   yxY w)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)numpyasarrayndimshaper   write)r   r   r   r   r   r   r   compression_levelbitrate_modenpr   r   s               r   r   r   8  st    Z ::dDyyA~::a=	4j(FFG$l
4 78	  s   A&&A/c           
   #      K   t        | d|
|||||      5 }|j                  |||      }|j                  |||||||	      D ]  }|  	 ddd       y# 1 sw Y   yxY ww)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'

    r   N)r   r   blocks)r   	blocksizeoverlapr   r   r   r   r   r   r   r   r   r   r   r   r   r   blocks                     r   r   r   q  sx     f 
4j(FFG
5 89f5XXi&#Y
CA 	EK	  s   A4A
	AAAc                   ,    e Zd ZdZd Zed        Zd Zy)_SoundFileInfozInformation about a SoundFilec                    || _         t        |      5 }|j                  | _        |j                  | _        |j                  | _        |j
                  | _        t        | j
                        |j                  z  | _        |j                  | _        |j                  | _	        |j                  | _
        |j                  | _        |j                  | _        |j                  | _        |j                  | _        d d d        y # 1 sw Y   y xY wN)verboser   namer   r   r   rw   durationr   r   r   format_infosubtype_infosections
extra_info)selfr   r   r   s       r   __init__z_SoundFileInfo.__init__  s    t_ 	+DIllDOJJDM((DK!$++.q||;DM((DK99DL((DK }}D !DJJDMllDO	+ 	+ 	+s   C#C??Dc                 "   t        | j                  d      \  }}t        |d      \  }}|dk\  rdj                  |||      }|S |dk\  rdj                  ||      }|S |dk  rdj                  | j                        }|S dj                  |      }|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)divmodr   r   r   )r   hoursrestminutessecondsr   s         r   _duration_strz_SoundFileInfo._duration_str  s    T]]D1t!$+A:6==eWgVH  \077IH
 	 \&--dkk:H  #))'2H    c                     dj                  g d      }| j                  r|dj                  g d      z  }dj                  | j                  j                  d            }|j	                  | |      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
    )joinr   r   splitr   )r   infoindented_extra_infos      r   __repr__z_SoundFileInfo.__repr__  sl    yy89 <<DII   D  *//0E0Ed0KL{{4!455r   N)__name__
__module____qualname____doc__r   propertyr   r    r   r   r   r     s#    '+   6r   r   c                     t        | |      S )zReturns an object with information about a `SoundFile`.

    Parameters
    ----------
    verbose : bool
        Whether to print additional information.
    )r   )r   r   s     r   r   r     s     $((r   c                  d    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_sndSFC_GET_FORMAT_MAJOR_COUNTSFC_GET_FORMAT_MAJORr   r   r   available_formatsr     s-    " )$*I*I*.*C*CE F Fr   c                 |     t        t        j                  t        j                        }t	         f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   H   K   | ]  \  }}t        |      r||f  y wr   )check_format).0r   r   r   s      r   	<genexpr>z%available_subtypes.<locals>.<genexpr>  s0      DMGT>\&'%B $ Ds   ")r   r   SFC_GET_FORMAT_SUBTYPE_COUNTSFC_GET_FORMAT_SUBTYPEr   )r   subtypess   ` r   available_subtypesr      s>    " ))J)J)-)D)DFH DX D D Dr   c                 Z    	 t        t        | ||            S # t        t        f$ r Y yw xY 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   s      r   r   r     s2    K899	" s    **c                 ^    t        |        t        j                  | j                               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upper)r   s    r   default_subtyper   )  s#     &  00r   c                   J   e Zd ZdZ	 	 	 d8dZ ed       Z	  ed       Z	  ed       Z	  ed       Z		  ed       Z
	  ed	       Z	  ed
       Z	  ed       Z	  ed       Z	  ed       Z	  ed       Z	  ed       Z	  ed       Z	  ed       Z	  ed       Z	 ed        ZdZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z e!fdZ"d Z#	 	 d9d Z$d:d!Z%d" Z&d# Z'd$ Z(	 	 d;d%Z)d<d&Z*d' Z+d( Z,d) Z-d* Z.d+ Z/d, Z0d- Z1d. Z2d/ Z3d0 Z4d1 Z5d2 Z6d3 Z7d4 Z8d5 Z9d6 Z:d7 Z;y)=r   zA sound file.

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

    Nc           	         t        |d      r|j                         n|}|| _        |t        |dd      }t	        |      }|| _        |	| _        |
| _        t        |||||||      | _	        | j                  |||      | _        t        |      j                  d      r!| j                         r| j                  d       t         j#                  | j                  t         j$                  t&        j(                  t         j*                         | j                  D| j-                  | j                         | j                  | j/                  | j                         yyy)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_commandSFC_SET_CLIPPING_ffiNULLSF_TRUE_set_compression_level_set_bitrate_mode)r   r   r   r   r   r   r   r   r   r   r   mode_ints               r   r   zSoundFile.__init__A  s   N %,D,$?t T
<4.Dt$
"3)(tZ)/&B
ZZh8
t9%$--/IIaL

D$9$9499	& "".''(?(?@!!-&&t'9'9: . /r   c                     | j                   S r   )r   r   s    r   <lambda>zSoundFile.<lambda>  
     r   c                     | j                   S r   )r   r  s    r   r  zSoundFile.<lambda>  r  r   c                 .    | j                   j                  S r   )r  r   r  s    r   r  zSoundFile.<lambda>  s    tzz'<'< r   c                 .    | j                   j                  S r   r  r   r  s    r   r  zSoundFile.<lambda>  s    4::#4#4 r   c                 .    | j                   j                  S r   )r  r   r  s    r   r  zSoundFile.<lambda>      TZZ%8%8 r   c                 b    t        | j                  j                  t        j                  z        S r   )_format_strr  r   r   SF_FORMAT_TYPEMASKr  s    r   r  zSoundFile.<lambda>  s     [!2!2T5L5L!LM r   c                 b    t        | j                  j                  t        j                  z        S r   )r  r  r   r   SF_FORMAT_SUBMASKr  s    r   r  zSoundFile.<lambda>       [!2!2T5K5K!KL r   c                 b    t        | j                  j                  t        j                  z        S r   )r  r  r   r   SF_FORMAT_ENDMASKr  s    r   r  zSoundFile.<lambda>  r  r   c                 h    t        | j                  j                  t        j                  z        d   S Nr   )_format_infor  r   r   r  r  s    r   r  zSoundFile.<lambda>  s-    \$**"3"3"&"9"9#: ;;<> r   c                 h    t        | j                  j                  t        j                  z        d   S r#  )r$  r  r   r   r  r  s    r   r  zSoundFile.<lambda>  s-    \$**"3"3"&"8"8#9 ::;= r   c                 .    | j                   j                  S r   )r  r   r  s    r   r  zSoundFile.<lambda>  r  r   c                     | j                   d u S r   )r  r  s    r   r  zSoundFile.<lambda>  s    4::#5 r   c                 @    t         j                  | j                        S r   )r   sf_errorr  r  s    r   r  zSoundFile.<lambda>  s    t}}TZZ'@ r   c                     | j                   S r   )r   r  s    r   r  zSoundFile.<lambda>  s    d.E.E r   c                     | j                   S r   )r   r  s    r   r  zSoundFile.<lambda>  s    );); r   c                     t        j                  dd      }t        j                  | j                  t        j
                  |t        j                  |             t        j                  |      j                  dd      S )z8Retrieve the log string generated when opening the file.zchar[]i @  r   r   )	r
  newr   r  r  SFC_GET_LOG_INFOsizeofstringdecode)r   r   s     r   r   zSoundFile.extra_info  sX     xx%(

D$9$9dkk$/	1{{4 '';;r   c                     | j                   dj                  | j                         nd}|| j                  dj                  | j                        ndz  }dj                  | |      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}))r   r   r   )r   compression_settings     r   r   zSoundFile.__repr__  sw    "&"8"8"D  9??@V@VWJL 	#'#4#4#@ !7 = =d>O>O PFH	J* +1&7J*K	Mr   c                 $    | j                          y r   closer  s    r   __del__zSoundFile.__del__      

r   c                     | S r   r   r  s    r   	__enter__zSoundFile.__enter__  s    r   c                 $    | j                          y r   r6  )r   argss     r   __exit__zSoundFile.__exit__  r9  r   c                     |t         v rR| j                          t        j                  | j                  t         |   |j                               }t        |       yt        j                  | ||       y)z:Write text meta-data in the sound file through properties.N)	
_str_types_check_if_closedr   sf_set_stringr  encode_error_checkobject__setattr__)r   r   valueerrs       r   rF  zSoundFile.__setattr__  sV    :!!#$$TZZD1A%*\\^5CtT51r   c                    |t         v r`| j                          t        j                  | j                  t         |         }|r%t        j                  |      j                  dd      S dS t        dj                  |            )z9Read text meta-data in the sound file through properties.r   r   r3  z)'SoundFile' object has no attribute {0!r})
r@  rA  r   sf_get_stringr  r
  r0  r1  AttributeErrorr   )r   r   r   s      r   __getattr__zSoundFile.__getattr__  sq    :!!#%%djj*T2BCDCG4;;t$++GY?ORO ;BB4HJ Jr   c                 .    | j                   j                  S r   r  r  s    r   __len__zSoundFile.__len__  s     zz   r   c                      y)NTr   r  s    r   __bool__zSoundFile.__bool__  s     r   c                 "    | j                         S r   )rP  r  s    r   __nonzero__zSoundFile.__nonzero__"  s     }}r   c                 P    | j                   j                  t        j                  k(  S )z)Return True if the file supports seeking.)r  r  r   r  r  s    r   r  zSoundFile.seekable'  s    zz""dll22r   c                     | j                          t        j                  | 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

        )rA  r   sf_seekr  rD  
_errorcode)r   r   whencepositions       r   r  zSoundFile.seek+  s8    H 	<<

FF;T__%r   c                 .    | j                  dt              S )z'Return the current read/write position.r   )r  r   r  s    r   tellzSoundFile.tellT  s    yyH%%r   c                     |&| j                  ||      }| j                  |||      }n|dk  s|t        |      kD  rt        |      }| j                  d||      }t        |      |kD  r||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   r   )_check_frames_create_empty_arraylen	_array_io)r   r   r   r   r   r   s         r   r   zSoundFile.readX  s    ` ;''
;F**69eDCzVc#h.SV4s8f!'6l 
  *FG
r   c                     | j                  |d      }| j                  |      }t        j                  |dz   || j                  z        }| j                  d|||      }||k(  sJ t        j                  |      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)r   z[]r   )r\  _check_dtyper
  r-  r   	_cdata_iobuffer)r   r   r   ctypecdataread_framess         r   buffer_readzSoundFile.buffer_read  sw    8 ##Ft#<!!%(v'=>nnVUE6Bf$$${{5!!r   c                 z    | j                  |      }| j                  ||      \  }}| j                  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

        r   )ra  _check_bufferrb  )r   rc  r   rd  re  r   s         r   buffer_read_intozSoundFile.buffer_read_into  sC    8 !!%(**659vuf=r   c                     ddl }|j                  |      }| j                  d|t        |            }|t        |      k(  sJ | j	                  |       y)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   ascontiguousarrayr_  r^  _update_frames)r   r   r   writtens       r   r   zSoundFile.write  sP    \ 	 ##D)..$D	:#d)###G$r   c                     | j                  |      }| j                  ||      \  }}| j                  d|||      }||k(  sJ | j                  |       y)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)ra  ri  rb  rm  )r   r   r   rd  re  r   rn  s          r   buffer_writezSoundFile.buffer_write0  sZ    * !!%(**47v..%?&   G$r   c           	   #   `  K   ddl }d| j                  vrd| j                  vrt        d      | j                  ||      }|3|t	        d      ||nt        ||      }	| j                  |	||      }d}
n|t	        d      t        |      }d	}
d}|dkD  r|d}nt        |      }||d| t        ||z
  |      }| j                  ||||||d        |r!||j                  || d       }n	|| d |dd |||z   kD  r|	|d||z    }n|}|
r|j                  |      n| ||z  }|dkD  ryyw)
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   Nr   +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^  r   copy)r   r   r   r   r   r   r   r   r   out_sizecopy_outoverlap_memoryoutput_offsettoreadr   s                  r   r   zSoundFile.blocksK  s    d 	diiCtyy$8'(TUU##FJ7;  KLL$.$:yIv@VH**8YFCH$CE ECIHqj% ! #N 3&4N]#]2F;FIIfeY
C<OP!)%'WWS'^%<N(+WHIN1%6G++
0B-Vg-.$,"''%.%7fF+ qjs   D)D.,D.c                 R   || j                         }t        j                  | j                  t        j                  t        j                  d|      t        j                  d            }|r+t        j                  | j                        }t        |d      || j                  _        y)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*
sf_count_tzError truncating the file)rZ  r   r  r  SFC_FILE_TRUNCATEr
  r-  r/  r)  LibsndfileErrorr  r   )r   r   rH  s      r   truncatezSoundFile.truncate  s{     >YY[Foodjj$*@*@"hh}f="kk,79 --

+C!#'BCC"

r   c                 b    | j                          t        j                  | j                         y)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)rA  r   sf_write_syncr  r  s    r   flushzSoundFile.flush  s"     	4::&r   c                     | j                   sB| j                          t        j                  | j                        }d| _        t        |       yy)z.Close the file.  Can be called multiple times.N)closedr  r   sf_closer  rD  )r   rH  s     r   r7  zSoundFile.close  s8    {{JJL--

+CDJ r   c                    t        |t        t        f      r9t        j                  j                  |      rd| j                  v r$t        dj                  | j                              t        | j                        j                  d      rHt        j                  t        j                  |t        j                  t        j                  z               t         j"                  }t        |t              rGt$        j&                  dk(  rt         j(                  }n#|j+                  t%        j,                               } |||| j.                        }nt        |t0              r#t         j3                  ||| j.                  |      }npt5        ||      r@t         j7                  | j9                  |      || j.                  t:        j<                        }n$t?        dj                  | j                              |t:        j<                  k(  r;t         jA                  |      }tC        |dj                  | j                              |t         jD                  k(  rd| j.                  _#        |S )	z9Call the appropriate sf_open*() function from libsndfile.xzFile exists: {0!r}zw+r   zInvalid file: {0!r}zError opening {0!r}: prefixr   )$
isinstance_unicodebytes_ospathisfiler   OSErrorr   r   r  r  r7  openO_WRONLYO_TRUNCr   sf_open_sysplatformsf_wchar_openrC  getfilesystemencodingr  rx   
sf_open_fd_has_virtual_io_attrssf_open_virtual_init_virtual_ior
  r  r   r)  r~  	SFM_WRITEr   )r   r   r  r   openfunctionfile_ptrrH  s          r   r  zSoundFile._open  s   dXu-.xxt$$))#!"6"="=dii"HII^..t4IIchhtS\\CKK-GHI<<L$)==G+#'#5#5L;;t'A'A'CDD#D(DJJ?Hc"tXtzz7KH"42++D,A,A$,G,4djj$))MH 188CDDtyy --)C!#.E.L.LTYY.WXXt~~% !"DJJ r   c                    t        j                  d      fd       }t        j                  d      fd       }t        j                  d      fd       }t        j                  d      fd       }t        j                  d	      fd
       }|||||d| _        t        j                  d| j                        S )z4Initialize callback functions for sf_open_virtual().sf_vio_get_filelenc                     j                         }j                  dt               j                         }j                  |t               |S Nr   )rZ  r  r   r   )	user_datacurrsizer   s      r   vio_get_filelenz3SoundFile._init_virtual_io.<locals>.vio_get_filelen  s:    99;DIIa"99;DIIdH%Kr   sf_vio_seekc                 H    j                  | |       j                         S r   )r  rZ  )offsetrW  r  r   s      r   vio_seekz,SoundFile._init_virtual_io.<locals>.vio_seek  s    IIff%99;r   sf_vio_readc                     	 t        j                  | |      }j                  |      }|S # t        $ r; j	                  |      }t        |      }t        j                  | |      }||d| Y |S w xY wr  )r
  rc  readintorK  r   r^  )ptrcountr  buf	data_readr   r   s         r   vio_readz,SoundFile._init_virtual_io.<locals>.vio_read
  sx    (kk#u- MM#.	  " (yy'I	kk#y1#'Ai (s   ', A A0/A0sf_vio_writec                 h    t        j                  | |      }|d d  }j                  |      }||}|S r   )r
  rc  r   )r  r  r  r  r   rn  r   s         r   	vio_writez-SoundFile._init_virtual_io.<locals>.vio_write  s9    ++c5)Cq6Djj&GNr   sf_vio_tellc                 $    j                         S r   )rZ  )r  r   s    r   vio_tellz,SoundFile._init_virtual_io.<locals>.vio_tell!  s    99;r   )get_filelenr  r   r   rZ  zSF_VIRTUAL_IO*)r
  callback_virtual_ior-  )r   r   r  r  r  r  r  s    `     r   r  zSoundFile._init_virtual_io  s    	+	,	 
-	 
}	%	 
&	 
}	%
	 
&
	 
~	&	 
'	 
}	%	 
&	 ,;$,$,%.$,	. xx($*:*:;;r   c                     t         S )zReturn all attributes used in __setattr__ and __getattr__.

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

        )r@  r  s    r   _getAttributeNameszSoundFile._getAttributeNames.  s
     r   c                 2    | j                   rt        d      y)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  rs  r  s    r   rA  zSoundFile._check_if_closed6  s     ;;'(FGG r   c                     | j                         r-| j                  | j                         z
  }|dk  s||kD  r||}|S |dk  rt        d      |S )z8Reduce frames to no more than are available in the file.r   z/frames must be specified for non-seekable files)r  r   rZ  r   )r   r   r   remaining_framess       r   r\  zSoundFile._check_frames?  s[    ==?#{{TYY[8zf'77(0)  aZNOOr   c                    |t         j                         v sJ t        |t              st	        j
                  |      }t        t        |      | j                  t	        j                  |      z        \  }}|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
  from_bufferr   r^  r   r/  r   )r   r   rd  r   	remainders        r   ri  zSoundFile._check_bufferJ  sw    
))++++$&##D)D"3t9#'==4;;u3E#EG	IJJV|r   c                 x    ddl }|s| j                  dkD  r|| j                  f}n|f}|j                  ||d      S )z-Create an empty array with appropriate shape.r   Nr   C)order)r   r   empty)r   r   r   r   r   r   s         r   r]  zSoundFile._create_empty_arrayU  s=    )DMM)EGExxuCx00r   c           	          	 t         |   S # t        $ r7 t        dj                  t	        t         j                               |            w xY 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)r   r   s     r   ra  zSoundFile._check_dtype^  sM    	3e$$ 	3GNNz()52 3 3	3s
    A Ac                    |j                   dvr>t        dj                  |j                  |j                   dk  r
d            d            |j                   dk(  rdn|j                  d   }|| j                  k7  r0t        dj                  |j                  | j                  |            |j
                  j                  st        d      | j                  |j                  j                        }|j                  j                  t        j                  |      k(  sJ t        j                  |dz   |j                  d	   d
         }| j                  ||||      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*r   r   )r   r   r   r   r   flagsc_contiguousra  r   r   itemsizer
  r/  cast__array_interface__rb  )r   actionarrayr   array_channelsrd  re  s          r   r_  zSoundFile._array_iof  sF   ::U"9@@nsnxnx{|n|Nj  Y  Z  Z  CX  Y  Z  Z#jjAo5;;q>T]]*T[[\a\g\gimiviv  yG  H  I  I{{''899!!%++"2"23{{##t{{5'9999		%#+u'@'@'H'KL~~feUF;;r   c                 l   |t         j                         v sJ | j                          | j                         r| j	                         }t        t        d|z   dz   |z         } || j                  ||      }t        | j                         | j                         r| j                  |z   t               |S )z.Call one of libsndfile's read/write functions.sf_f_)r  r  rA  r  rZ  r   r   r  rD  rV  r  r   )r   r  r   rd  r   r  funcs          r   rb  zSoundFile._cdata_iot  s    
))++++==?99;DtUV^d2U:;djj$/T__%==?IIdVmX.r   c                     | j                         rL| j                         }| j                  dt              | j                  _        | j                  |t               y| j                  xj
                  |z  c_        y)z!Update self.frames after writing.r   N)r  rZ  r  r   r  r   r   )r   rn  r  s      r   rm  zSoundFile._update_frames  sP    ==?99;D $		!X 6DJJIIdH%JJ(r   c                 *   |dk7  r| j                         st        d      |dk\  r|t        d      t        ||      j	                  | j
                        \  }}}||k  r|}|dk  r||z
  }| j                         r| j                  |t               |S )z)Seek to start frame and calculate length.r   z(start is only allowed for seekable filesz&Only one of {frames, stop} may be used)r  r   r   sliceindicesr   r  r   )r   r   r   r   _s        r   r   zSoundFile._prepare_read  s    A:dmmoGHHQ;4+DEEud+33DKK@tQ%<DA:E\F==?IIeX&r   c                     i }t         j                         D ]P  \  }}t        j                  | j                  |      }|s)t        j                  |      j                  dd      ||<   R |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   r   )r@  itemsr   rJ  r  r
  r0  r1  )r   strsstrtypestridr   s        r   copy_metadatazSoundFile.copy_metadata  sf     (..0 	MNGU%%djj%8D $D 1 8 8) LW	M r   c                 b   |t         v sJ t        j                  d      }t         |   |d<   t        j	                  | j
                  t        j                  |t        j                  |            }|t        j                  k7  r.t        j                  | j
                        }t        |d|       y)z,Call libsndfile's set bitrate mode function.zint[1]r   zError set bitrate mode N)_bitrate_modesr
  r-  r   r  r  SFC_SET_BITRATE_MODEr/  r  r)  r~  )r   r   pointer_bitrate_moderH  s       r   r  zSoundFile._set_bitrate_mode  s    ~---#xx1"0">Qoodjj$*C*CEY[_[f[fg{[|}$,,--

+C!#)@'OPP r   c                    d|cxk  rdk  st        d       t        d      t        j                  d      }||d<   t        j	                  | j
                  t        j                  |t        j                  |            }|t        j                  k7  r.t        j                  | j
                        }t        |d|       y)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  SFC_SET_COMPRESSION_LEVELr/  r  r)  r~  )r   r   pointer_compression_levelrH  s       r   r  z SoundFile._set_compression_level  s    &+!+HII ,HII$(HH[$9!'8!!$oodjj$*H*HJceiepep  rK  fL  M$,,--

+C!#)EFWEX'YZZ r   )	r   NNNNNTNN)rz   FNN)r  N)Nr   r  rz   FNNr   )<r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  rV  r   r   r   r  r   r8  r;  r>  rF  rL  rN  rP  rR  r  r   r  rZ  r   rg  rj  r   rp  r   r  r  r7  r  r  r  rA  r\  ri  r]  ra  r_  rb  rm  r   r  r  r  r   r   r   r   r   9  s    BFAE6:};~ +,D*+,D7<=J,45F189H3MOF-LNG4LNF8	>?K ?	=>L :89H356F2@AJ' !EF,;<L'< < EM2J!


3 #+ 'R& :?"&\|!"FB4%l%6 BK59[z#0'"H1<fH		13<) $	Q
[r   r   c                 (    | dk7  rt        | |      y)z+Raise LibsndfileError if there is an error.r   r  N)r~  )rH  r  s     r   rD  rD    s    
axc&11 r   c                    t        |       }|'t        |       }|Jt        dj                  |             t	        |t
        t        f      st        dj                  |            	 |t        |j                            z  }|d}n0t	        |t
        t        f      st        dj                  |            	 |t        |j                            z  }t        j                  d      }||_        d|_        t        j!                  |      t        j"                  k(  rt        d	      |S # t        $ r t        dj                  |            w xY w# t        $ r t        dj                  |            w xY w)
z8Return numeric ID for given format|subtype|endian combo.z)No default subtype for major format {0!r}zInvalid subtype: {0!r}zUnknown subtype: {0!r}rr   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   sf_format_checkSF_FALSE)r   r   r   resultr   s        r   r   r     sh   6"F!&)?;BB6JL L(C1077@AAC)GMMO,, ~304;;FCDDF(6<<>** 88JDDKDMD!T]]2?A 	AM#  C188ABBC  F5<<VDEEFs   &D& 6E &$E
$E1c                    t        | t        t        f      st        dj	                  |             t        |       }|j                  d      st        |       t        |      kD  rt        dj	                  |             t        |j                  d            dk7  rt        d      d|v rt        j                  }|S d|v rt        j                  }|S t        j                  }|S )z=Check if mode is valid and return its integer representation.zInvalid mode: {0!r}zxrwb+xrwr   z&mode must contain exactly one of 'xrw'rr  r   )r  r  r  r   r   r  
differencer^  r   intersectionr   SFM_RDWRSFM_READr  )r   mode_setr  s      r   r   r     s    dXsO,-44T:;;4yH7#s4y3x='@.55d;<<
8  '(A-ABB
h==
 O	 
== O >>Or   c                    |}|$t        | |      }t        |t        t        f      sJ t	        |       t        j                  d      }d|vs|j                         dk(  r<|t        d      ||_	        |t        d      ||_
        t        |||      |_        |S t        d |||||fD              rt        d      |S )z*Check arguments and create SF_INFO struct.r  r   r   zsamplerate must be specifiedzchannels must be specifiedc              3   $   K   | ]  }|d u 
 y wr   r   )r   args     r   r   z&_create_info_struct.<locals>.<genexpr>  s      I3s$ Is   z\Not allowed for existing files (except 'RAW'): samplerate, channels, format, subtype, endian)_get_format_from_filenamer  r  r  r   r
  r-  r   r   r   r   r   r   any)	r   r   r   r   r   r   r   original_formatr   s	            r   r   r     s     O~*46&8S/222f88JD
$&,,.E1:;;$899 !&'6: K	  IHow+H I I L M MKr   c                    d}t        | d|       } 	 t        j                  j                  |       d   dd }|j	                  dd      }|j                         t        vrd|vrt        d	j                  |             |S # t
        $ r Y Aw xY w)
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).

    r3  r   r  r   Nr   r   r   zGNo format specified and unable to get format from file extension: {0!r})
r   r  r  splitextr1  	Exceptionr   _formatsr   r   )r   r   r   s      r   r  r    s     F4&D""4(,QR0w	2 ||~X%#T/ 006t> 	>M  s   7A> >	B
	B
c                 v    t         t        t        fD ]%  }|j                         D ]  \  }}|| k(  s|c c S  ' y)z;Return the string representation of a given numeric format.zn/a)r	  r  r  r  )
format_int
dictionarykvs       r   r  r  1  sE    	83 
$$& 	DAqJ	
 r   c                 B   t        j                  d      }| |_        t        j	                  t         j
                  ||t        j                  d             |j                  }t        |j                        |r&t        j                  |      j                  dd      fS dfS )z6Return the ID and short description of a given format.zSF_FORMAT_INFO*SF_FORMAT_INFOr   r   r3  )r
  r-  r   r   r  r  r/  r   r  r0  r1  )r  format_flagr   r   s       r   r$  r$  ;  s    ((,-K#KOODII{KKK 013D**+<@DKK$$Wi8J JFHJ Jr   c              #      K   t        j                  d      }t        j                  t         j                  | |t        j
                  d             t        |d         D ]  }t        ||        yw)z8Helper for available_formats() and available_subtypes().zint*rx   r   N)r
  r-  r   r  r  r/  ranger$  )
count_flagr  r  r  s       r   r   r   F  sW     HHVEOODIIz5$++e2DEE!Ho 4
:{334s   A1A3c                     t        | t        t        f      st        dj	                  |             	 t
        | j                            }|S # t        $ r t        dj	                  |             w xY 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   r	  r   r  r   )
format_strr  s     r   r   r   N  sr    j8S/2/66zBCCEj..01
   E077
CDDEs   A $A/c           	          |t         j                  k(  }|t         j                  k(  }t        t	        | d      t	        | d      t	        | d      xs |t	        | d      xs t	        | d      xs |g      S )z>Check if file has all the necessary attributes for virtual IO.r  rZ  r   r   r  )r   r  r  allr   )r   r  readonly	writeonlys       r   r  r  Y  sn    4==(HDNN*Iffg*(fGz!:Gi	  r   c                       e Zd ZdZy)SoundFileErrorz-Base class for all soundfile-specific errors.Nr   r   r   r   r   r   r   r  r  e  s    7r   r  c                       e Zd ZdZy)rs  zKsoundfile module runtime error.

    Errors that used to be `RuntimeError`.Nr  r   r   r   rs  rs  i  s    . 	r   rs  c                   .    e Zd ZdZddZed        Zd Zy)r~  zjlibsndfile errors.


    Attributes
    ----------
    code
        libsndfile internal error number.
    c                 N    t         j                  | ||       || _        || _        y r   )rs  r   coder  )r   r!  r  s      r   r   zLibsndfileError.__init__x  s"    &&tT6:	r   c                     | j                   rDt        j                  | j                         }t        j                  |      j                  dd      S y)zRaw libsndfile error message.r   r   z'(Garbled error message from libsndfile))r!  r   sf_error_numberr
  r0  r1  )r   err_strs     r   error_stringzLibsndfileError.error_string}  s@     99**4995G;;w'..w	BB
 =r   c                 4    | j                   | j                  z   S r   )r  r%  r  s    r   __str__zLibsndfileError.__str__  s    {{T....r   Nr3  )r   r   r   r   r   r   r%  r'  r   r   r   r~  r~  o  s%    
 	= 	=/r   r~  )r  r   Nrz   FNNNNNNNT)NNNTNN)Nr   r  r   Nrz   FNNNNNNNT)Fr   )NNr(  )Rr   __version__osr  sysr  r   r   r   ctypes.utilr   _find_library
_soundfiler   r
  unicoder  	NameErrorr  r@  r	  r  r  r   r  r  r  r   _machine_packaged_libnamer   _architecturer  r   _soundfile_datar  dirname__file___pathr   
_full_pathdlopenr   ImportErrorr   _libname_explicit_libnameisdir_hbrew_pathr0  sf_version_stringr1  __libsndfile_version__
startswithr^  r   r   r   rE  r   r   r   r   r   r   r   rD  r   r   r   r  r  SFC_GET_FORMAT_INFOr$  r   r   r  r  r  RuntimeErrorrs  r~  r   r   r   <module>rD     sK  	    + + 5 "H 
	X
X 	X 
X	
 
X 
X X 
X X 
X X X 
X 	X 
X  
X!" 
X#$ 5:#f#f# f# f	#
 f# f# f# f# f# f# f# f# f# f# f#  f!#" f##$ f%#& f'#( f)#* f+#, f-#. f/#0 f1#2 f3#4 f5#6 f7#8 f9#: f;#< f=#> f?#@ fA#B fC#D fE#	L 		X
X 	X
 
X 
X X 
X X 
X X X 
X 	Y 
X  
X!" 
X#$ X%& 5 < 	
 :2}} 0)HJ6A	'	!:0
 ?1( 4_Q7* 4A!6-/8:>@ @	'	!0:FF 5 -
 :U B=>>HH_556Eu&78J4;;z"D< %T%;%;%=>EEgyY $$]33C4F4GH JO>B9=Zz EI=A6r FJBF%);?8v16V 16h)F*D.$1 I[ I[X2@&60 *.)A)A J4		Y 		NL 	/+ /u2  HJ 	i( 22 +TUUt{{8$ 2==H$ 2]]g% 0]]g% / 	1==H$w)>25((..AU2V.& 4;;sxx}}[:KLMD4;;01D'22sI   L 3DL& L#"L#&P/$MPB9PPPPP