
    biG6                         d dl Z d dlmZmZ d dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZ d dlZd dlZddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZmZ e	rd dlmZ ddl m!Z! e G d d             Z"ddde#fdZ$y)    N)	dataclassfield)BytesIO)Path)TYPE_CHECKINGAnyClassVarOptionalUnion   )config)DownloadConfig)
array_cast)is_local_pathxopen)no_op_if_value_is_nullstring_to_dictAudioDecoder   )FeatureTypec                       e Zd ZU dZdZee   ed<   dZe	ed<   dZ
ee   ed<    edd      Zee   ed	<   d
Zee   ed<    ej"                   ej$                          ej&                         d      Zee   ed<    ed dd      Zeed<   d Zdeeeeedf   defdZ	 ddedeeeeee	df   f      ddfdZdedeedf   f   fdZdeej>                  ej@                  f   dej@                  fdZ!ddej@                  dej@                  fdZ"y)Audioa  Audio [`Feature`] to extract audio data from an audio file.

    Input: The Audio feature accepts as input:
    - A `str`: Absolute path to the audio file (i.e. random access is allowed).
    - A `pathlib.Path`: path to the audio file (i.e. random access is allowed).
    - A `dict` with the keys:

        - `path`: String with relative path of the audio file to the archive file.
        - `bytes`: Bytes content of the audio file.

      This is useful for parquet or webdataset files which embed audio files.

    - A `dict` with the keys:

        - `array`: Array containing the audio sample
        - `sampling_rate`: Integer corresponding to the sampling rate of the audio sample.

    - A `torchcodec.decoders.AudioDecoder`: torchcodec audio decoder object.

    Output: The Audio features output data as `torchcodec.decoders.AudioDecoder` objects, with additional keys:

    - `array`: Array containing the audio sample
    - `sampling_rate`: Integer corresponding to the sampling rate of the audio sample.

    Args:
        sampling_rate (`int`, *optional*):
            Target sampling rate. If `None`, the native sampling rate is used.
        mono (`bool`, defaults to `True`):
            Whether to convert the audio signal to mono by averaging samples across
            channels.
        decode (`bool`, defaults to `True`):
            Whether to decode the audio data. If `False`,
            returns the underlying dictionary in the format `{"path": audio_path, "bytes": audio_bytes}`.
        stream_index (`int`, *optional*):
            The streaming index to use from the file. If `None` defaults to the "best" index.

    Example:

    ```py
    >>> from datasets import load_dataset, Audio
    >>> ds = load_dataset("PolyAI/minds14", name="en-US", split="train")
    >>> ds = ds.cast_column("audio", Audio(sampling_rate=44100))
    >>> ds[0]["audio"]
    <datasets.features._torchcodec.AudioDecoder object at 0x11642b6a0>
    >>> audio = ds[0]["audio"]
    >>> audio.get_samples_played_in_range(0, 10)
    AudioSamples:
        data (shape): torch.Size([2, 110592])
        pts_seconds: 0.0
        duration_seconds: 2.507755102040816
        sample_rate: 44100
    ```
    Nsampling_rateTdecodestream_indexF)defaultrepriddictdtypebytespathpa_type)r   initr   _typec                     | j                   S N)r%   )selfs    R/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/datasets/features/audio.py__call__zAudio.__call__X   s    ||    valuer   returnc                    	 ddl }ddlm} |t	        d      t
        j                  rddlm} nd}t        |t              rd|dS t        |t              rdt        |j                               dS t        |t        t        f      r|ddS |t        ||      rt        |      S d|v rjt!               } ||j#                  |d   j%                  t&        j(                              |d	   
      j+                  |d       |j-                         ddS |j/                  d      Ft0        j2                  j5                  |d         r#|d   j7                  d      r|j/                  d	      t9        d      |j/                  d      rIt'        j:                  |d   t&        j<                        j%                  t&        j(                        dz  }n;t'        j>                  |d   dd      j%                  t&        j(                        dz  }t!               } ||j#                  |      |d	   
      j+                  |d       |j-                         ddS d|j/                  d      dS |j/                  d      |j/                  d      #|j/                  d      |j/                  d      dS t	        d| d      # t        $ r}t        d      |d}~ww xY w)zEncode example into a format for Arrow.

        Args:
            value (`str`, `bytes`,`bytearray`,`dict`, `AudioDecoder`):
                Data passed as input to Audio feature.

        Returns:
            `dict`
        r   NAudioEncoder<To support encoding audio data, please install 'torchcodec'.zvalue must be providedr   r"   arrayr   sample_ratewavformatr$   pcmzBTo use PCM files, please specify a 'sampling_rate' in Audio objectr#   )r!   i  hr)r!   modezUAn audio sample should have one of 'path' or 'bytes' but they are missing or None in .) torchtorchcodec.encodersr2   ImportError
ValueErrorr   TORCHCODEC_AVAILABLEtorchcodec.decodersr   
isinstancestrr   absoluter#   	bytearrayencode_torchcodec_audior   
from_numpyastypenpfloat32to_file_likegetvaluegetosr$   isfileendswithKeyError
frombufferint16memmap)r*   r.   r?   r2   errr   bufferbytes_values           r+   encode_examplezAudio.encode_example[   s   	g8 =566&&8  LeS!!511t$!3u~~/?+@AAy12"D11%*UL*I*511YF  w!6!6rzz!BCQVWfQgl6%l0#__.==YYv*rww~~eFm/LV}%%e,99_-5"#ghh99W%"$--gbhh"O"V"VWYWaWa"bej"jK"$))E&M3"O"V"VWYWaWa"bej"jK U--k:oH^_ll5 m  "(!2DAA!%uyy/@AAYYw+uyy/@/L"YYw/69JKKghmgnnop g  	g\]cff	gs   
K 	K
KKtoken_per_repo_idc                    t         j                  rddlm} nt	        d      | j
                  st        d      |d   
|d   |d   fn|d   df\  }}||t        d| d	      |+t        |      r  ||| j                  | j                  
      }n||xs i }|j                  d      d   }|j                  t         j                        rt         j                  nt         j                  }t!        ||      }	|	|j#                  |	d         nd}
t%        |
      }t'        |d|      } ||| j                  | j                  
      }n ||| j                  | j                  
      }||d|_        ||j*                  _        |S )a,  Decode example audio file into audio data.

        Args:
            value (`dict`):
                A dictionary with keys:

                - `path`: String with relative audio file path.
                - `bytes`: Bytes of the audio file.
            token_per_repo_id (`dict`, *optional*):
                To access and decode
                audio files from private repositories on the Hub, you can pass
                a dictionary repo_id (`str`) -> token (`bool` or `str`)

        Returns:
            `torchcodec.decoders.AudioDecoder`
        r   r   z<To support decoding audio data, please install 'torchcodec'.zMDecoding is disabled for this feature. Please use Audio(decode=True) instead.r#   Nr$   zJAn audio sample should have one of 'path' or 'bytes' but both are None in r>   )r   r6   ::repo_idtokenrbdownload_config)r$   r#   )r   rC   _torchcodecr   rA   r   RuntimeErrorrB   r   r   r   split
startswithHF_ENDPOINTHUB_DATASETS_URLHUB_DATASETS_HFFS_URLr   rP   r   r   _hf_encodedmetadatar$   )r*   r.   r\   r   r$   r#   audio
source_urlpatternsource_url_fieldsrb   re   fs                r+   decode_examplezAudio.decode_example   s   & &&1\]]{{noo9>w9SuV}eGn5Z_`fZgimYne<EMijoippqrss=]40 D4E4ESWSeSefE] 1 7RD)"-J+5+@+@ASAS+T''Z`ZvZv  !/z7 CK\Kh%))*;I*FGnrE,59OdD/BA 1B1BPTPbPbcE !T5F5FTXTfTfgE%)E:"r-   r   c                 ^    ddl m} | j                  rt        d       |d       |d      dS )z[If in the decodable state, raise an error, otherwise flatten the feature into a dictionary.r   )Valuez'Cannot flatten a decoded Audio feature.binarystringr"   )featuresrv   r   rB   )r*   rv   s     r+   flattenzAudio.flatten   s0    #;;FGG8_(O
 	
r-   storagec                    t         j                  j                  |j                        rlt        j                  dgt        |      z  t        j                               }t         j                  j                  ||gddg|j                               }nSt         j                  j                  |j                        rlt        j                  dgt        |      z  t        j                               }t         j                  j                  ||gddg|j                               }nt         j                  j                  |j                        rk|j                  j                  d      rPt        j                  |j                  d      D cg c]  }|t               j!                  |      nd! c}      }n*t         j                  j                  |j                        r |j                  j#                  d      d	k\  r|j%                  d      }n6t        j                  dgt        |      z  t        j                               }|j                  j#                  d      d	k\  r|j%                  d      }n6t        j                  dgt        |      z  t        j                               }t         j                  j                  ||gddg|j                               }t'        || j(                        S c c}w )
a  Cast an Arrow array to the Audio arrow storage type.
        The Arrow types that can be converted to the Audio pyarrow storage type are:

        - `pa.string()` - it must contain the "path" data
        - `pa.binary()` - it must contain the audio bytes
        - `pa.struct({"bytes": pa.binary()})`
        - `pa.struct({"path": pa.string()})`
        - `pa.struct({"bytes": pa.binary(), "path": pa.string()})`  - order doesn't matter

        Args:
            storage (`Union[pa.StringArray, pa.StructArray]`):
                PyArrow array to cast.

        Returns:
            `pa.StructArray`: Array in the Audio arrow storage type, that is
                `pa.struct({"bytes": pa.binary(), "path": pa.string()})`
        Ntyper#   r$   maskr4   F)zero_copy_onlyr   )patypes	is_stringr~   r4   lenrw   StructArrayfrom_arraysis_null	is_binaryrx   	is_structget_all_field_indicesto_numpyr   r[   get_field_indexr   r   r%   )r*   r{   bytes_array
path_arrayxs        r+   cast_storagezAudio.cast_storage   s&   $ 88gll+((D6CL#8ryy{KKnn00+w1G'SYIZahapapar0sGXX-4&3w<"7biikJJnn00':1FRXHY`g`o`o`q0rGXX-',,2T2TU\2]hhOVO_O_otO_Ouv!am''*EvG XX-||++G49%mmG4 hhvG'<299;O||++F3q8$]]62
XXtfs7|&;"))+N
nn00+z1JWV\L]dkdsdsdu0vG'4<<00 ws   $K?c           	      r   i t         fd       }t        j                  |j                         D cg c]  }||d    ||d         n|d   nd c}t        j                               }t        j                  |j                  d      j                         D cg c]%  }|t        j                  j                  |      nd' c}t        j                               }t        j                  j                  ||gddg|j                               }t        || j                        S c c}w c c}w )a8  Embed audio files into the Arrow array.

        Args:
            storage (`pa.StructArray`):
                PyArrow array to embed.

        Returns:
            `pa.StructArray`: Array in the Audio arrow storage type, that is
                `pa.struct({"bytes": pa.binary(), "path": pa.string()})`.
        Nc                 r   | j                  d      d   }|j                  t        j                        rt        j                  nt        j
                  }t        ||      }|j                  |d         nd }t        |      }t        | d|      5 }|j                         cd d d        S # 1 sw Y   y xY w)Nr^   r_   r`   ra   rc   rd   )rh   ri   r   rj   rk   rl   r   rP   r   r   read)r$   rp   rq   rr   rb   re   rs   r\   s          r+   path_to_bytesz*Audio.embed_storage.<locals>.path_to_bytes  s    D)"-J+5+@+@ASAS+T''Z`ZvZv  !/z7 CK\Kh%))*;I*FGnrE,59OtT?C  qvvx     s   B--B6r#   r$   r}   r   )r   r   r4   	to_pylistrw   r   rQ   r$   basenamerx   r   r   r   r   r%   )r*   r{   r\   r   r   r   r$   r   s     `     r+   embed_storagezAudio.embed_storage  s%    $ "			  
 		  hh !**, UVTaQwZ-?qy)QwZgkk 
 XXNUmm\bNcNmNmNopdt'7RWWd#TAp

 ..,,k:-FRXHY`k`s`s`u,v'4<<00 qs    D/ *D4r)   )#__name__
__module____qualname____doc__r   r
   int__annotations__r   boolr   r   r   rF   r!   r	   r   structrw   rx   r%   r   r'   r,   r   r#   rH   r    r[   rt   rz   StringArrayr   r   r    r-   r+   r   r      si   4l $(M8C='FD"&L(3-&d7B7!E8C=!&RYYibiik'RSGXc]SwU?E3?BE#ui~*U$V B[_ BJ ]a33.6tCsDRVAW<W7X.Y3	3j	
}d33E.FFG 	
&1E".."..*H$I &1bnn &1P&1R^^ &1PRP^P^ &1r-   r   ro   r   r/   c                 N   t        | d      r| j                  S 	 ddlm} | j                         }t               } ||j                  j                         |j                        j                  |d       |j                         d dS # t        $ r}t	        d      |d }~ww xY w)	Nrm   r   r1   r3   r5   r7   r8   r"   )hasattrrm   r@   r2   rA   get_all_samplesr   datacpur6   rN   rO   )ro   r2   rX   samplesrY   s        r+   rI   rI   0  s    um$   	g8 '')W\\%%'W5H5HIVVW]fkVl*D99  	g\]cff	gs   B
 
	B$BB$)%rQ   dataclassesr   r   ior   pathlibr   typingr   r   r	   r
   r   numpyrL   pyarrowr    r   download.download_configr   tabler   utils.file_utilsr   r   utils.py_utilsr   r   rD   r   ry   r   r   r    rI   r   r-   r+   <module>r      sg    	 (   @ @    5  3 C 0% U1 U1 U1p:> :d :r-   