
'''simple docstring'''


import os
from dataclasses import dataclass, field
from io import BytesIO
from typing import TYPE_CHECKING, Any, ClassVar, Dict, Optional, Union

import numpy as np
import pyarrow as pa

from .. import config
from ..download.streaming_download_manager import xopen, xsplitext
from ..table import array_cast
from ..utils.py_utils import no_op_if_value_is_null, string_to_dict


if TYPE_CHECKING:
   from .features import FeatureType


snake_case_  , snake_case_  , snake_case_ :  int     =					False, False, False


@dataclass
class 						lowercase__	:






   '''simple docstring'''







   _snake_case		   =							None
   _snake_case		   =							True
   _snake_case		   =							True
   _snake_case		   =							None
   # Automatically constructed
   _snake_case		   =							"dict"
   _snake_case		   =							pa.struct({'''bytes''': pa.binary(), '''path''': pa.string()}   )
   _snake_case		   =							field(default='''Audio''',					init=snake_case_,					repr=snake_case_   )







   def __call__(			self   ):

      '''simple docstring'''







      return self.pa_type







   def       UpperCAmelCase				(			self ,   lowerCamelCase__   ):

      '''simple docstring'''







      try:
         import soundfile as sf  # soundfile is a dependency of librosa, needed to decode audio files.
      except ImportError as err:
         raise ImportError('''To support encoding audio data, please install \'soundfile\'.'''   ) from err
      if isinstance(lowerCamelCase__ ,   lowerCamelCase__   ):
         return {"bytes": None, "path": value}
      elif isinstance(lowerCamelCase__ ,   lowerCamelCase__   ):
         return {"bytes": value, "path": None}
      elif "array" in value:
         # convert the audio array to wav bytes
         UpperCamelCase       =  BytesIO()
         sf.write(lowerCamelCase__ ,   value['''array'''] ,   value['''sampling_rate'''] ,   format='''wav'''   )
         return {"bytes": buffer.getvalue(), "path": None}
      elif value.get('''path'''   ) is not None and os.path.isfile(value['''path''']   ):
         # we set "bytes": None to not duplicate the data if they're already available locally
         if value["path"].endswith('''pcm'''   ):
            # "PCM" only has raw audio bytes
            if value.get('''sampling_rate'''   ) is None:
               # At least, If you want to convert "PCM-byte" to "WAV-byte", you have to know sampling rate
               raise KeyError('''To use PCM files, please specify a \'sampling_rate\' in Audio object'''   )
            if value.get('''bytes'''   ):
               # If we already had PCM-byte, we don`t have to make "read file, make bytes" (just use it!)
               UpperCamelCase       =  np.frombuffer(value['''bytes'''] ,   dtype=np.intaa   ).astype(np.floataa   ) / 3_2_7_6_7
            else:
               UpperCamelCase       =  np.memmap(value['''path'''] ,   dtype='''h''' ,   mode='''r'''   ).astype(np.floataa   ) / 3_2_7_6_7

            UpperCamelCase       =  BytesIO(bytes()   )
            sf.write(lowerCamelCase__ ,   lowerCamelCase__ ,   value['''sampling_rate'''] ,   format='''wav'''   )
            return {"bytes": buffer.getvalue(), "path": None}
         else:
            return {"bytes": None, "path": value.get('''path'''   )}
      elif value.get('''bytes'''   ) is not None or value.get('''path'''   ) is not None:
         # store the audio bytes, and path is used to infer the audio format using the file extension
         return {"bytes": value.get('''bytes'''   ), "path": value.get('''path'''   )}
      else:
         raise ValueError(
             f'An audio sample should have one of \'path\' or \'bytes\' but they are missing or None in {value}.'   )







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__ = None   ):

      '''simple docstring'''







      if not self.decode:
         raise RuntimeError('''Decoding is disabled for this feature. Please use Audio(decode=True) instead.'''   )

      UpperCamelCase     , UpperCamelCase       =  (value['''path'''], BytesIO(value['''bytes''']   )) if value['''bytes'''] is not None else (value['''path'''], None)
      if path is None and file is None:
         raise ValueError(f'An audio sample should have one of \'path\' or \'bytes\' but both are None in {value}.'   )

      try:
         import librosa
         import soundfile as sf
      except ImportError as err:
         raise ImportError('''To support decoding audio files, please install \'librosa\' and \'soundfile\'.'''   ) from err

      UpperCamelCase       =  xsplitext(lowerCamelCase__   )[1][1:].lower() if path is not None else None
      if not config.IS_OPUS_SUPPORTED and audio_format == "opus":
         raise RuntimeError(
             '''Decoding \'opus\' files requires system library \'libsndfile\'>=1.0.31, '''
             '''You can try to update `soundfile` python library: `pip install "soundfile>=0.12.1"`. '''   )
      elif not config.IS_MP3_SUPPORTED and audio_format == "mp3":
         raise RuntimeError(
             '''Decoding \'mp3\' files requires system library \'libsndfile\'>=1.1.0, '''
             '''You can try to update `soundfile` python library: `pip install "soundfile>=0.12.1"`. '''   )

      if file is None:
         UpperCamelCase       =  token_per_repo_id or {}
         UpperCamelCase       =  path.split('''::'''   )[-1]
         try:
            UpperCamelCase       =  string_to_dict(lowerCamelCase__ ,   config.HUB_DATASETS_URL   )['''repo_id''']
            UpperCamelCase       =  token_per_repo_id[repo_id]
         except (ValueError, KeyError):
            UpperCamelCase       =  None

         with xopen(lowerCamelCase__ ,   '''rb''' ,   use_auth_token=lowerCamelCase__   ) as f:
            UpperCamelCase     , UpperCamelCase       =  sf.read(lowerCamelCase__   )

      else:
         UpperCamelCase     , UpperCamelCase       =  sf.read(lowerCamelCase__   )

      UpperCamelCase       =  array.T
      if self.mono:
         UpperCamelCase       =  librosa.to_mono(lowerCamelCase__   )
      if self.sampling_rate and self.sampling_rate != sampling_rate:
         UpperCamelCase       =  librosa.resample(lowerCamelCase__ ,   orig_sr=lowerCamelCase__ ,   target_sr=self.sampling_rate   )
         UpperCamelCase       =  self.sampling_rate

      return {"path": path, "array": array, "sampling_rate": sampling_rate}







   def       UpperCAmelCase				(			self   ):

      '''simple docstring'''







      from .features import Value

      if self.decode:
         raise ValueError('''Cannot flatten a decoded Audio feature.'''   )
      return {
          "bytes": Value('''binary'''   ),
          "path": Value('''string'''   ),
      }







   def       UpperCAmelCase				(			self ,   lowerCamelCase__   ):

      '''simple docstring'''







      if pa.types.is_string(storage.type   ):
         UpperCamelCase       =  pa.array([None] * len(lowerCamelCase__   ) ,   type=pa.binary()   )
         UpperCamelCase       =  pa.StructArray.from_arrays([bytes_array, storage] ,   ['''bytes''', '''path'''] ,   mask=storage.is_null()   )
      elif pa.types.is_binary(storage.type   ):
         UpperCamelCase       =  pa.array([None] * len(lowerCamelCase__   ) ,   type=pa.string()   )
         UpperCamelCase       =  pa.StructArray.from_arrays([storage, path_array] ,   ['''bytes''', '''path'''] ,   mask=storage.is_null()   )
      elif pa.types.is_struct(storage.type   ) and storage.type.get_all_field_indices('''array'''   ):
         UpperCamelCase       =  pa.array([Audio().encode_example(lowerCamelCase__   ) if x is not None else None for x in storage.to_pylist()]   )
      elif pa.types.is_struct(storage.type   ):
         if storage.type.get_field_index('''bytes'''   ) >= 0:
            UpperCamelCase       =  storage.field('''bytes'''   )
         else:
            UpperCamelCase       =  pa.array([None] * len(lowerCamelCase__   ) ,   type=pa.binary()   )
         if storage.type.get_field_index('''path'''   ) >= 0:
            UpperCamelCase       =  storage.field('''path'''   )
         else:
            UpperCamelCase       =  pa.array([None] * len(lowerCamelCase__   ) ,   type=pa.string()   )
         UpperCamelCase       =  pa.StructArray.from_arrays([bytes_array, path_array] ,   ['''bytes''', '''path'''] ,   mask=storage.is_null()   )
      return array_cast(lowerCamelCase__ ,   self.pa_type   )







   def       UpperCAmelCase				(			self ,   lowerCamelCase__   ):

      '''simple docstring'''







      @no_op_if_value_is_null
      def path_to_bytes(lowerCamelCase__   ):
         with xopen(lowerCamelCase__ ,   '''rb'''   ) as f:
            UpperCamelCase       =  f.read()
         return bytes_

      UpperCamelCase       =  pa.array(
          [
              (path_to_bytes(x['''path''']   ) if x['''bytes'''] is None else x['''bytes''']) if x is not None else None
              for x in storage.to_pylist()
          ] ,   type=pa.binary() ,   )
      UpperCamelCase       =  pa.array(
          [os.path.basename(lowerCamelCase__   ) if path is not None else None for path in storage.field('''path'''   ).to_pylist()] ,   type=pa.string() ,   )
      UpperCamelCase       =  pa.StructArray.from_arrays([bytes_array, path_array] ,   ['''bytes''', '''path'''] ,   mask=bytes_array.is_null()   )
      return array_cast(lowerCamelCase__ ,   self.pa_type   )







'''simple docstring'''


from typing import TYPE_CHECKING

from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_tf_available, is_torch_available


snake_case_ :  List[Any]     =					{
    'configuration_data2vec_audio': ['DATA2VEC_AUDIO_PRETRAINED_CONFIG_ARCHIVE_MAP', 'Data2VecAudioConfig'],
    'configuration_data2vec_text': [
        'DATA2VEC_TEXT_PRETRAINED_CONFIG_ARCHIVE_MAP',
        'Data2VecTextConfig',
        'Data2VecTextOnnxConfig',
    ],
    'configuration_data2vec_vision': [
        'DATA2VEC_VISION_PRETRAINED_CONFIG_ARCHIVE_MAP',
        'Data2VecVisionConfig',
        'Data2VecVisionOnnxConfig',
    ],
}

try:
   if not is_torch_available():
      raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
   pass
else:
   snake_case_ :  Union[str, Any]     =					[
       'DATA2VEC_AUDIO_PRETRAINED_MODEL_ARCHIVE_LIST',
       'Data2VecAudioForAudioFrameClassification',
       'Data2VecAudioForCTC',
       'Data2VecAudioForSequenceClassification',
       'Data2VecAudioForXVector',
       'Data2VecAudioModel',
       'Data2VecAudioPreTrainedModel',
   ]
   snake_case_ :  str     =					[
       'DATA2VEC_TEXT_PRETRAINED_MODEL_ARCHIVE_LIST',
       'Data2VecTextForCausalLM',
       'Data2VecTextForMaskedLM',
       'Data2VecTextForMultipleChoice',
       'Data2VecTextForQuestionAnswering',
       'Data2VecTextForSequenceClassification',
       'Data2VecTextForTokenClassification',
       'Data2VecTextModel',
       'Data2VecTextPreTrainedModel',
   ]
   snake_case_ :  Optional[int]     =					[
       'DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST',
       'Data2VecVisionForImageClassification',
       'Data2VecVisionForMaskedImageModeling',
       'Data2VecVisionForSemanticSegmentation',
       'Data2VecVisionModel',
       'Data2VecVisionPreTrainedModel',
   ]

if is_tf_available():
   snake_case_ :  List[str]     =					[
       'TFData2VecVisionForImageClassification',
       'TFData2VecVisionForSemanticSegmentation',
       'TFData2VecVisionModel',
       'TFData2VecVisionPreTrainedModel',
   ]

if TYPE_CHECKING:
   from .configuration_dataavec_audio import DATA2VEC_AUDIO_PRETRAINED_CONFIG_ARCHIVE_MAP, DataaVecAudioConfig
   from .configuration_dataavec_text import (
       DATA2VEC_TEXT_PRETRAINED_CONFIG_ARCHIVE_MAP,
       DataaVecTextConfig,
       DataaVecTextOnnxConfig,
   )
   from .configuration_dataavec_vision import (
       DATA2VEC_VISION_PRETRAINED_CONFIG_ARCHIVE_MAP,
       DataaVecVisionConfig,
       DataaVecVisionOnnxConfig,
   )

   try:
      if not is_torch_available():
         raise OptionalDependencyNotAvailable()
   except OptionalDependencyNotAvailable:
      pass
   else:
      from .modeling_dataavec_audio import (
          DATA2VEC_AUDIO_PRETRAINED_MODEL_ARCHIVE_LIST,
          DataaVecAudioForAudioFrameClassification,
          DataaVecAudioForCTC,
          DataaVecAudioForSequenceClassification,
          DataaVecAudioForXVector,
          DataaVecAudioModel,
          DataaVecAudioPreTrainedModel,
      )
      from .modeling_dataavec_text import (
          DATA2VEC_TEXT_PRETRAINED_MODEL_ARCHIVE_LIST,
          DataaVecTextForCausalLM,
          DataaVecTextForMaskedLM,
          DataaVecTextForMultipleChoice,
          DataaVecTextForQuestionAnswering,
          DataaVecTextForSequenceClassification,
          DataaVecTextForTokenClassification,
          DataaVecTextModel,
          DataaVecTextPreTrainedModel,
      )
      from .modeling_dataavec_vision import (
          DATA2VEC_VISION_PRETRAINED_MODEL_ARCHIVE_LIST,
          DataaVecVisionForImageClassification,
          DataaVecVisionForMaskedImageModeling,
          DataaVecVisionForSemanticSegmentation,
          DataaVecVisionModel,
          DataaVecVisionPreTrainedModel,
      )
   if is_tf_available():
      from .modeling_tf_dataavec_vision import (
          TFDataaVecVisionForImageClassification,
          TFDataaVecVisionForSemanticSegmentation,
          TFDataaVecVisionModel,
          TFDataaVecVisionPreTrainedModel,
      )

else:
   import sys

   snake_case_ :  int     =					_LazyModule(__name__, globals()['__file__'], _import_structure, module_spec=__spec__)





