
"""simple docstring"""





from math import ceil
from typing import List, Optional, Union

import numpy as np

from ...audio_utils import mel_filter_bank, spectrogram, window_function
from ...feature_extraction_sequence_utils import BatchFeature, SequenceFeatureExtractor
from ...utils import TensorType, logging


_a								=						logging.get_logger(__name__)






class        _UpperCAmelCase(       lowerCamelCase      ):
		lowercase__         = ['audio_values', 'audio_mask']



		def __init__(   self							,						__a=20_48							,						__a=1							,						__a=[16, 16]							,						__a=1_28							,						__a=4_41_00							,						__a=86							,						__a=20_48							,						__a=0.0							,						**__a							,						)			->			Optional[int]:






							'''simple docstring'''
							super().__init__(
							    feature_size=__a							,						sampling_rate=__a							,						padding_value=__a							,						**__a							,						)

							_UpperCamelCase									=    spectrogram_length
							_UpperCamelCase									=    num_channels
							_UpperCamelCase									=    patch_size
							_UpperCamelCase									=    feature_size // self.patch_size[1]
							_UpperCamelCase									=    n_fft
							_UpperCamelCase									=    sampling_rate // hop_length_to_sampling_rate
							_UpperCamelCase									=    sampling_rate
							_UpperCamelCase									=    padding_value
							_UpperCamelCase									=    mel_filter_bank(
							    num_frequency_bins=1 + n_fft // 2							,						num_mel_filters=__a							,						min_frequency=0.0							,						max_frequency=2_2050.0							,						sampling_rate=__a							,						norm='''slaney'''							,						mel_scale='''slaney'''							,						).T



		def 		UpperCAmelCase				(   self							,						__a)			->			np.ndarray:






							'''simple docstring'''
							_UpperCamelCase									=    spectrogram(
							    __a							,						window_function(self.n_fft							,						'''hann''')							,						frame_length=self.n_fft							,						hop_length=self.hop_length							,						power=2.0							,						mel_filters=self.mel_filters.T							,						log_mel='''dB'''							,						db_range=80.0							,						)
							_UpperCamelCase									=    log_spec[:, :-1]
							_UpperCamelCase									=    log_spec - 20.0
							_UpperCamelCase									=    np.clip(log_spec / 40.0							,						-2.0							,						0.0) + 1.0
							return log_spec




		def __call__(   self							,						__a							,						__a = None							,						__a = True							,						__a = None							,						__a = False							,						__a = False							,						**__a							,						)			->			BatchFeature:






							'''simple docstring'''

							if sampling_rate is not None:
												if sampling_rate != self.sampling_rate:
																	raise ValueError(
																	    '''This feature extractor is set to support sampling rate'''
																	    F''' of {self.sampling_rate}. Please make sure that the provided `raw_speech` input was sampled'''
																	    F''' with {self.sampling_rate} and not {sampling_rate}.''')
							else:
												logger.warning(
												    '''It is strongly recommended to pass the `sampling_rate` argument to this function. '''
												    '''Failing to do so can result in silent errors that might be hard to debug.''')

							_UpperCamelCase									=    isinstance(__a							,						np.ndarray) and len(raw_speech.shape) > 1
							if is_batched_numpy and len(raw_speech.shape) > 2:
												raise ValueError(F'''Only mono-channel audio is supported for input to {self}''')
							_UpperCamelCase									=    is_batched_numpy or (
							    isinstance(__a							,						(list, tuple)) and (isinstance(raw_speech[0]							,						(np.ndarray, tuple, list)))
							)
							if is_batched:
												_UpperCamelCase									=    [np.asarray([speech]							,						dtype=np.floataa).T for speech in raw_speech]
							elif not is_batched and not isinstance(__a							,						np.ndarray):
												_UpperCamelCase									=    np.asarray(__a							,						dtype=np.floataa)
							elif isinstance(__a							,						np.ndarray) and raw_speech.dtype is np.dtype(np.floataa):
												_UpperCamelCase									=    raw_speech.astype(np.floataa)
							# always return batch
							if not is_batched:
												_UpperCamelCase									=    [np.asarray([raw_speech]).T]

							# Convert audio signals to log mel spectrograms, truncate by time axis
							_UpperCamelCase									=    [
							    self._np_extract_fbank_features(waveform.squeeze()).T[: self.spectrogram_length] for waveform in raw_speech
							]
							if isinstance(audio_features[0]							,						__a):
												_UpperCamelCase									=    [np.asarray(__a							,						dtype=np.floataa) for feature in audio_features]

							# Create audio attention mask
							_UpperCamelCase									=    max(
							    [ceil(feature.shape[0] / self.patch_size[0]) * self.freq_len for feature in audio_features])  # The maximum number of audio patches in a batch
							if return_attention_mask:
												_UpperCamelCase									=    [
												    (ceil(feature.shape[0] / self.patch_size[0]) * self.freq_len) * [1]
												    + (max_patch_len - ceil(feature.shape[0] / self.patch_size[0]) * self.freq_len) * [0]
												    for feature in audio_features
												]
												_UpperCamelCase									=    np.array(__a).astype(np.floataa)

							# convert into correct format for padding
							_UpperCamelCase									=    max_patch_len // self.freq_len * self.patch_size[0]  # The maximum audio size in a batch
							_UpperCamelCase									=    np.ones([len(__a), 1, max_time_len, self.feature_size]).astype(np.floataa)
							_UpperCamelCase									=    padded_audio_features * self.padding_value
							for i in range(len(__a)):
												_UpperCamelCase									=    audio_features[i]
												_UpperCamelCase									=    feature

							# return as BatchFeature
							if return_attention_mask:
												_UpperCamelCase									=    {'''audio_values''': padded_audio_features, '''audio_mask''': audio_mask}
							else:
												_UpperCamelCase									=    {'''audio_values''': padded_audio_features}

							_UpperCamelCase									=    BatchFeature(data=__a							,						tensor_type=__a)
							return encoded_inputs








import warnings
from contextlib import contextmanager

from ....processing_utils import ProcessorMixin




class        _SCREAMING_SNAKE_CASE	( snake_case_		):
	lowerCAmelCase__   =					'MCTCTFeatureExtractor'
	lowerCAmelCase__   =					'AutoTokenizer'



	def __init__(       self		,    lowercase		,    lowercase					)							->			str:
					super().__init__(lowercase		,    lowercase					)
					lowerCamelCase_         =     self.feature_extractor
					lowerCamelCase_         =     False



	def __call__(       self		,    *lowercase		,    **lowercase					)							->			List[str]:
					# For backward compatibility
					if self._in_target_context_manager:
									return self.current_processor(*lowercase		,    **lowercase					)

					if "raw_speech" in kwargs:
									warnings.warn("Using `raw_speech` as a keyword argument is deprecated. Use `audio` instead."					)
									lowerCamelCase_         =     kwargs.pop("raw_speech"					)
					else:
									lowerCamelCase_         =     kwargs.pop("audio"		,    lowercase					)
					lowerCamelCase_         =     kwargs.pop("sampling_rate"		,    lowercase					)
					lowerCamelCase_         =     kwargs.pop("text"		,    lowercase					)
					if len(lowercase					) > 0:
									lowerCamelCase_         =     args[0]
									lowerCamelCase_         =     args[1:]

					if audio is None and text is None:
									raise ValueError("You need to specify either an `audio` or `text` input to process."					)

					if audio is not None:
									lowerCamelCase_         =     self.feature_extractor(lowercase		,    *lowercase		,    sampling_rate=lowercase		,    **lowercase					)
					if text is not None:
									lowerCamelCase_         =     self.tokenizer(lowercase		,    **lowercase					)

					if text is None:
									return inputs
					elif audio is None:
									return encodings
					else:
									lowerCamelCase_         =     encodings["input_ids"]
									return inputs



	def        SCREAMING_SNAKE_CASE_(       self		,    *lowercase		,    **lowercase					)							->			Optional[Any]:
					return self.tokenizer.batch_decode(*lowercase		,    **lowercase					)



	def        SCREAMING_SNAKE_CASE_(       self		,    *lowercase		,    **lowercase					)							->			Optional[Any]:
					# For backward compatibility
					if self._in_target_context_manager:
									return self.current_processor.pad(*lowercase		,    **lowercase					)

					lowerCamelCase_         =     kwargs.pop("input_features"		,    lowercase					)
					lowerCamelCase_         =     kwargs.pop("labels"		,    lowercase					)
					if len(lowercase					) > 0:
									lowerCamelCase_         =     args[0]
									lowerCamelCase_         =     args[1:]

					if input_features is not None:
									lowerCamelCase_         =     self.feature_extractor.pad(lowercase		,    *lowercase		,    **lowercase					)
					if labels is not None:
									lowerCamelCase_         =     self.tokenizer.pad(lowercase		,    **lowercase					)

					if labels is None:
									return input_features
					elif input_features is None:
									return labels
					else:
									lowerCamelCase_         =     labels["input_ids"]
									return input_features



	def        SCREAMING_SNAKE_CASE_(       self		,    *lowercase		,    **lowercase					)							->			List[str]:
					return self.tokenizer.decode(*lowercase		,    **lowercase					)



	@contextmanager
	def        SCREAMING_SNAKE_CASE_(       self					)							->			Optional[int]:
					warnings.warn(
					    "`as_target_processor` is deprecated and will be removed in v5 of Transformers. You can process your "
					    "labels by using the argument `text` of the regular `__call__` method (either in the same call as "
					    "your audio inputs, or in a separate call."					)
					lowerCamelCase_         =     True
					lowerCamelCase_         =     self.tokenizer
					yield
					lowerCamelCase_         =     self.feature_extractor
					lowerCamelCase_         =     False


