
    {KgT                        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	 ej2                  dk(  rddlmZ d e       z   dz   ZnQej2                  dk(  rddlmZ d e       d   z   dz   Zn+ej2                  dk(  rddlmZ d e       z   dz   Zn ed      ddl Z ejB                  jE                  e jF                        Z$ejB                  jK                  e$e      Z& ejN                  e&      Z( ej^                  e(ja                               jc                  dd      Z2e2jg                  d      re2 e4d      d Z2	 	 	 ddZ5	 	 ddZ6	 	 	 	 ddZ7 G d de8      Z9ddZ:d Z;ddZ<ddZ=d Z> G d de8      Z?ddZ@d ZAd ZBd ZCd ZDd ZEe(j                  fdZGd ZHd ZId ZJ G d deK      ZL G d deLeM      ZN G d deN      ZOy# e$ r eZY w xY w# ee)e*f$ r 	  ed      Z+e+ ed       ejN                  e+      Z(n# e$ r ej2                  dk(  rdZ,n%ej2                  dk(  rdZ,nej2                  dk(  rdZ,n ddlmZ ej2                  dk(  rV e       dk(  rLejB                  j[                  d      rdndZ. ejN                  ejB                  jK                  e.e,            Z(n ejN                  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.12.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darwin)machinelibsndfile_z.dylibwin32)architecturez.dlllinuxz.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                   M/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/soundfile.pyr   r      sj    l 
4j(FFG
589f5vvfeY
C@
5 	
5 
5s   )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
        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   npr   r   s
             r   r   r   $  sj    Z ::dDyyA~::a=	4j(FFG
589	
5 
5 
5s   	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   \  so     f 
4j(FFG
589f5XXi&#Y
CAEKA
5 
5 
5s   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>  s.      DXMGT>\&'%B $Xs   ")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                      e Zd ZdZ	 	 d4d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!	 	 d5dZ"d6dZ#d  Z$d! Z%d" Z&	 	 d7d#Z'd8d$Z(d% Z)d& Z*d' Z+d( Z,d) Z-d* Z.d+ Z/d, Z0d- Z1d. Z2d/ Z3d0 Z4d1 Z5d2 Z6d3 Z7y)9r   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&                         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.

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

        Open an existing file for reading:

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

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

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

        
__fspath__Nmodezr+r   )hasattrr   _namegetattr_check_mode_mode_create_info_struct_info_open_fileset
issupersetseekableseekr   
sf_commandSFC_SET_CLIPPING_ffiNULLSF_TRUE)
r   r   r   r   r   r   r   r   r   mode_ints
             r   r   zSoundFile.__init__,  s    | %,D,$?t T
<4.Dt$
(tZ)/&B
ZZh8
t9%$--/IIaL

D$9$9499	&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#4r   c                 .    | j                   j                  S r   )r   r   r  s    r   r  zSoundFile.<lambda>      TZZ%8%8r   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Mr   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Lr   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::#5r   c                 @    t         j                  | j                        S r   )r   sf_errorr   r  s    r   r  zSoundFile.<lambda>  s    t}}TZZ'@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                 $    dj                  |       S )NzSoundFile({0.name!r}, mode={0.mode!r}, samplerate={0.samplerate}, channels={0.channels}, format={0.format!r}, subtype={0.subtype!r}, endian={0.endian!r})r   r  s    r   r   zSoundFile.__repr__  s    ' (.vd|	5r   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   r$  )r   argss     r   __exit__zSoundFile.__exit__  r'  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   r4  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    z)'SoundFile' object has no attribute {0!r})
r.  r/  r   sf_get_stringr   r   r   r!  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   )r?  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

        )r/  r   sf_seekr   r2  
_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.tell%  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.read)  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   )rK  _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   )rP  _check_bufferrQ  )r   rR  r   rS  rT  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   ascontiguousarrayrN  rM  _update_frames)r   r   r   writtens       r   r   zSoundFile.write  sN    \ 	##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)rP  rX  rQ  r\  )r   r   r   rS  rT  r   r]  s          r   buffer_writezSoundFile.buffer_write   sZ    * !!%(**47v..%?&   G$r   c           	   #   @  K   ddl }d| j                  vrd| j                  vrt        d      |#|t        d      | j	                  |||      }d}	n|t        d      t        |      }d	}	d}
| j                  ||      }|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   rL  rM  rK  minr   copy)r   r   r   r   r   r   r   r   r   copy_outoverlap_memoryoutput_offsettoreadr   s                 r   r   zSoundFile.blocks  so    d 	diiCtyy$8'(TUU;  KLL**9iGCH$CE ECIH##FJ7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)rI  r   r   r   SFC_FILE_TRUNCATEr   r  r  r  LibsndfileErrorr   r   )r   r   r6  s      r   truncatezSoundFile.truncatew  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)r/  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)closedrp  r   sf_closer   r2  )r   r6  s     r   r%  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   r%  openO_WRONLYO_TRUNCr   sf_open_sysplatformsf_wchar_openr1  getfilesystemencodingr   rx   
sf_open_fd_has_virtual_io_attrssf_open_virtual_init_virtual_ior   r   r   r  rl  	SFM_WRITEr   )r   r   r  r   openfunctionfile_ptrr6  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   )rI  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   rI  )offsetrF  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   rR  readintor:  r   rM  )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   rR  r   )r  r  r  r  r   r]  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   )rI  )r  r   s    r   vio_tellz,SoundFile._init_virtual_io.<locals>.vio_tell  s    99;r   )get_filelenr   r   r   rI  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)rr  rb  r  s    r   r/  zSoundFile._check_if_closed  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   rI  r   )r   r   r   remaining_framess       r   rK  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valuesrx  rz  r   from_bufferr   rM  r   r  r   )r   r   rS  r   	remainders        r   rX  zSoundFile._check_buffer  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   rL  zSoundFile._create_empty_array$  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   rP  zSoundFile._check_dtype-  sM    	3e$$ 	3GNNz()52 3 3	3s
    A Ac                 Z   |j                   dvsI|j                   dk(  r| j                  dk7  s+|j                   dk(  r@|j                  d   | j                  k7  r$t        d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	   r   r	   zInvalid shape: {0!r}zData must be C-contiguous*r   r   )r   r   r   r   r   flagsc_contiguousrP  r   r   itemsizer   r  cast__array_interface__rQ  )r   actionarrayr   rS  rT  s         r   rN  zSoundFile._array_io5  s    JJf$

aDMMQ$6

aEKKNdmm$C3::5;;GHH{{''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  r/  r   rI  r   r   r   r2  rE  r   r   )r   r  r   rS  r   r  funcs          r   rQ  zSoundFile._cdata_ioB  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   rI  r   r   r   r   r   )r   r]  r  s      r   r\  zSoundFile._update_framesO  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_readX  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   r9  r   r   r   r!  )r   strsstrtypestridr   s        r   copy_metadatazSoundFile.copy_metadatah  s_     (..0NGU%%djj%8D $D 1 8 8) LW 1 r   )r   NNNNNT)rz   FNN)r  N)Nr   r  rz   FNNr   )8r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rr  rE  r   r   r   r&  r)  r,  r4  r;  r=  r?  rA  r   r   r   rI  r   rV  rY  r   r_  r   rm  rp  r%  r   r  r  r/  rK  rX  rL  rP  rN  rQ  r\  r   r  r   r   r   r   r   $  s    BFAEk&Z +,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52J!


3 #+ 'R& :?"&\|!"FB3%j%6 BK59Zx#0'"H1<fH		13<) r   r   c                 (    | dk7  rt        | |      y)z+Raise LibsndfileError if there is an error.r   rv  N)rl  )r6  rw  s     r   r2  r2  |  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   rx  ry  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'ra  r   )rx  ry  r  r   r   r   
differencerM  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 +H3s$ +Hs   z\Not allowed for existing files (except 'RAW'): samplerate, channels, format, subtype, endian)_get_format_from_filenamerx  ry  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).

    r8  r   r  r   Nr   r   r   zGNo format specified and unable to get format from file extension: {0!r})
r   r{  r|  splitextr!  	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    s;    	83
$$&DAqJ ' 4
 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   r8  )r   r  r   r   r   r   r  r   r  r   r!  )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     sR     HHVEOODIIz5$++e2DEE!Ho
:{33 &s   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})	rx  ry  r  r   r   r  r   r  r   )
format_strr  s     r   r   r     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   rI  r   r   r  )r   r  r  allr   )r   r  readonly	writeonlys       r   r  r    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    s    7r   r  c                       e Zd ZdZy)rb  zKsoundfile module runtime error.

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


    Attributes
    ----------
    code
        libsndfile internal error number.
    c                 N    t         j                  | ||       || _        || _        y r   )rb  r   coderw  )r   r  rw  s      r   r   zLibsndfileError.__init__/  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   r   r!  )r   err_strs     r   error_stringzLibsndfileError.error_string4  s@     99**4995G;;w'..w	BB
 =r   c                 4    | j                   | j                  z   S r   )rw  r  r  s    r   __str__zLibsndfileError.__str__@  s    {{T....r   Nr8  )r   r   r   r   r   r   r  r  r   r   r   rl  rl  &  s%    
 	= 	=/r   rl  )r  r   Nrz   FNNNNNNNT)NNNT)Nr   r  r   Nrz   FNNNNNNNT)Fr   )NNr  )Pr   __version__osr{  sysr  r   r   r   ctypes.utilr   _find_library
_soundfiler   r   unicodery  	NameErrorr  r.  r  r  r  r   r  r  r   _machine_packaged_libnamer   _architecturer~  _soundfile_datar|  dirname__file___pathr   
_full_pathdlopenr   ImportErrorr   _libname_explicit_libnameisdir_hbrew_pathr   sf_version_stringr!  __libsndfile_version__
startswithrM  r   r   r   r3  r   r   r   r   r   r   r   r2  r   r   r   r  r  SFC_GET_FORMAT_INFOr  r   r   r  r  r  RuntimeErrorrb  rl  r   r   r   <module>r*     s  	    + + 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	'	!:)MOA,>>G	'	!0)HJ6>=>>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5p FJBF%);?8v16V 16h)F*D.$1 T Tp2@&60 *.)A)A J4		Y 		NL 	/+ /c0  Hb 	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   K -CK KKO&$L
OB9OOOOO