


"""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


lowercase_			,	lowercase_			,	lowercase_							=							False, False, False







@dataclass
class    __a						:
				lowerCamelCase     :       Optional[int]			       =None
				lowerCamelCase     :       bool			       =True
				lowerCamelCase     :       bool			       =True
				lowerCamelCase     :       Optional[str]			       =None
				# Automatically constructed
				lowerCamelCase     :       ClassVar[str]			       ="dict"
				lowerCamelCase     :       ClassVar[Any]			       =pa.struct({'bytes': pa.binary(), 'path': pa.string()}							)
				lowerCamelCase     :       str			       =field(default='Audio'					,			init=__snake_case					,			repr=__snake_case							)







				def __call__( self   ):

					'''simple docstring'''






					return self.pa_type







				def      lowerCamelCase_     ( self      ,	UpperCAmelCase   ):

					'''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(UpperCAmelCase      ,	UpperCAmelCase   ):
						return {"bytes": None, "path": value}
					elif isinstance(UpperCAmelCase      ,	UpperCAmelCase   ):
						return {"bytes": value, "path": None}
					elif "array" in value:
						# convert the audio array to wav bytes
						lowerCAmelCase_      							=			BytesIO()
						sf.write(UpperCAmelCase      ,	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!)
								lowerCAmelCase_      							=			np.frombuffer(value['''bytes''']      ,	dtype=np.intaa   ).astype(np.floataa   ) / 3_2767
							else:
								lowerCAmelCase_      							=			np.memmap(value['''path''']      ,	dtype='''h'''      ,	mode='''r'''   ).astype(np.floataa   ) / 3_2767

							lowerCAmelCase_      							=			BytesIO(bytes()   )
							sf.write(UpperCAmelCase      ,	UpperCAmelCase      ,	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      lowerCamelCase_     ( self      ,	UpperCAmelCase      ,	UpperCAmelCase = None   ):

					'''simple docstring'''






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

					lowerCAmelCase_							,	lowerCAmelCase_      							=			(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

					lowerCAmelCase_      							=			xsplitext(UpperCAmelCase   )[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:
						lowerCAmelCase_      							=			token_per_repo_id or {}
						lowerCAmelCase_      							=			path.split('''::'''   )[-1]
						try:
							lowerCAmelCase_      							=			string_to_dict(UpperCAmelCase      ,	config.HUB_DATASETS_URL   )['''repo_id''']
							lowerCAmelCase_      							=			token_per_repo_id[repo_id]
						except (ValueError, KeyError):
							lowerCAmelCase_      							=			None

						with xopen(UpperCAmelCase      ,	'''rb'''      ,	use_auth_token=UpperCAmelCase   ) as f:
							lowerCAmelCase_							,	lowerCAmelCase_      							=			sf.read(UpperCAmelCase   )

					else:
						lowerCAmelCase_							,	lowerCAmelCase_      							=			sf.read(UpperCAmelCase   )

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

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







				def      lowerCamelCase_     ( 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      lowerCamelCase_     ( self      ,	UpperCAmelCase   ):

					'''simple docstring'''






					if pa.types.is_string(storage.type   ):
						lowerCAmelCase_      							=			pa.array([None] * len(UpperCAmelCase   )      ,	type=pa.binary()   )
						lowerCAmelCase_      							=			pa.StructArray.from_arrays([bytes_array, storage]      ,	['''bytes''', '''path''']      ,	mask=storage.is_null()   )
					elif pa.types.is_binary(storage.type   ):
						lowerCAmelCase_      							=			pa.array([None] * len(UpperCAmelCase   )      ,	type=pa.string()   )
						lowerCAmelCase_      							=			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'''   ):
						lowerCAmelCase_      							=			pa.array([Audio().encode_example(UpperCAmelCase   ) 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:
							lowerCAmelCase_      							=			storage.field('''bytes'''   )
						else:
							lowerCAmelCase_      							=			pa.array([None] * len(UpperCAmelCase   )      ,	type=pa.binary()   )
						if storage.type.get_field_index('''path'''   ) >= 0:
							lowerCAmelCase_      							=			storage.field('''path'''   )
						else:
							lowerCAmelCase_      							=			pa.array([None] * len(UpperCAmelCase   )      ,	type=pa.string()   )
						lowerCAmelCase_      							=			pa.StructArray.from_arrays([bytes_array, path_array]      ,	['''bytes''', '''path''']      ,	mask=storage.is_null()   )
					return array_cast(UpperCAmelCase      ,	self.pa_type   )







				def      lowerCamelCase_     ( self      ,	UpperCAmelCase   ):

					'''simple docstring'''






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

					lowerCAmelCase_      							=			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()      ,	)
					lowerCAmelCase_      							=			pa.array(
					    [os.path.basename(UpperCAmelCase   ) if path is not None else None for path in storage.field('''path'''   ).to_pylist()]      ,	type=pa.string()      ,	)
					lowerCAmelCase_      							=			pa.StructArray.from_arrays([bytes_array, path_array]      ,	['''bytes''', '''path''']      ,	mask=bytes_array.is_null()   )
					return array_cast(UpperCAmelCase      ,	self.pa_type   )



"""simple docstring"""



from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_tf_available,
    is_tokenizers_available,
    is_torch_available,
)


lowercase_							=							{
    'configuration_mobilebert': [
        'MOBILEBERT_PRETRAINED_CONFIG_ARCHIVE_MAP',
        'MobileBertConfig',
        'MobileBertOnnxConfig',
    ],
    'tokenization_mobilebert': ['MobileBertTokenizer'],
}

try:
		if not is_tokenizers_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		lowercase_							=							['MobileBertTokenizerFast']

try:
		if not is_torch_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		lowercase_							=							[
		    'MOBILEBERT_PRETRAINED_MODEL_ARCHIVE_LIST',
		    'MobileBertForMaskedLM',
		    'MobileBertForMultipleChoice',
		    'MobileBertForNextSentencePrediction',
		    'MobileBertForPreTraining',
		    'MobileBertForQuestionAnswering',
		    'MobileBertForSequenceClassification',
		    'MobileBertForTokenClassification',
		    'MobileBertLayer',
		    'MobileBertModel',
		    'MobileBertPreTrainedModel',
		    'load_tf_weights_in_mobilebert',
		]

try:
		if not is_tf_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		lowercase_							=							[
		    'TF_MOBILEBERT_PRETRAINED_MODEL_ARCHIVE_LIST',
		    'TFMobileBertForMaskedLM',
		    'TFMobileBertForMultipleChoice',
		    'TFMobileBertForNextSentencePrediction',
		    'TFMobileBertForPreTraining',
		    'TFMobileBertForQuestionAnswering',
		    'TFMobileBertForSequenceClassification',
		    'TFMobileBertForTokenClassification',
		    'TFMobileBertMainLayer',
		    'TFMobileBertModel',
		    'TFMobileBertPreTrainedModel',
		]


if TYPE_CHECKING:
		from .configuration_mobilebert import (
		    MOBILEBERT_PRETRAINED_CONFIG_ARCHIVE_MAP,
		    MobileBertConfig,
		    MobileBertOnnxConfig,
		)
		from .tokenization_mobilebert import MobileBertTokenizer

		try:
				if not is_tokenizers_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .tokenization_mobilebert_fast import MobileBertTokenizerFast

		try:
				if not is_torch_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .modeling_mobilebert import (
				    MOBILEBERT_PRETRAINED_MODEL_ARCHIVE_LIST,
				    MobileBertForMaskedLM,
				    MobileBertForMultipleChoice,
				    MobileBertForNextSentencePrediction,
				    MobileBertForPreTraining,
				    MobileBertForQuestionAnswering,
				    MobileBertForSequenceClassification,
				    MobileBertForTokenClassification,
				    MobileBertLayer,
				    MobileBertModel,
				    MobileBertPreTrainedModel,
				    load_tf_weights_in_mobilebert,
				)

		try:
				if not is_tf_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .modeling_tf_mobilebert import (
				    TF_MOBILEBERT_PRETRAINED_MODEL_ARCHIVE_LIST,
				    TFMobileBertForMaskedLM,
				    TFMobileBertForMultipleChoice,
				    TFMobileBertForNextSentencePrediction,
				    TFMobileBertForPreTraining,
				    TFMobileBertForQuestionAnswering,
				    TFMobileBertForSequenceClassification,
				    TFMobileBertForTokenClassification,
				    TFMobileBertMainLayer,
				    TFMobileBertModel,
				    TFMobileBertPreTrainedModel,
				)

else:
		import sys

		lowercase_							=							_LazyModule(__name__, globals()['__file__'], _import_structure, module_spec=__spec__)