





import copy
from typing import Any, Dict, List, Optional, Union

import numpy as np

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


UpperCAmelCase_           =	logging.get_logger(__name__)




class 			__UpperCamelCase    (							A__    ):
     __A	:  str							  =   ["""input_features"""]





     def __init__(     self				,							_UpperCamelCase=80				,							_UpperCamelCase=16000				,							_UpperCamelCase=160				,							_UpperCamelCase=30				,							_UpperCamelCase=400				,							_UpperCamelCase=0.0				,							_UpperCamelCase=False				,							**_UpperCamelCase				,							):
        super().__init__(
            feature_size=_UpperCamelCase				,							sampling_rate=_UpperCamelCase				,							padding_value=_UpperCamelCase				,							return_attention_mask=_UpperCamelCase				,							**_UpperCamelCase				,							)
        _UpperCAmelCase           =   n_fft
        _UpperCAmelCase           =   hop_length
        _UpperCAmelCase           =   chunk_length
        _UpperCAmelCase           =   chunk_length * sampling_rate
        _UpperCAmelCase           =   self.n_samples // hop_length
        _UpperCAmelCase           =   sampling_rate
        _UpperCAmelCase           =   mel_filter_bank(
            num_frequency_bins=1 + n_fft // 2				,							num_mel_filters=_UpperCamelCase				,							min_frequency=0.0				,							max_frequency=8000.0				,							sampling_rate=_UpperCamelCase				,							norm='''slaney'''				,							mel_scale='''slaney'''				,							)





     def 		UpperCamelCase(     self				,							_UpperCamelCase					):
        _UpperCAmelCase           =   spectrogram(
            _UpperCamelCase				,							window_function(self.n_fft				,							'''hann'''					)				,							frame_length=self.n_fft				,							hop_length=self.hop_length				,							power=2.0				,							mel_filters=self.mel_filters				,							log_mel='''log10'''				,							)
        _UpperCAmelCase           =   log_spec[:, :-1]
        _UpperCAmelCase           =   np.maximum(_UpperCamelCase				,							log_spec.max() - 8.0					)
        _UpperCAmelCase           =   (log_spec + 4.0) / 4.0
        return log_spec





     @staticmethod
     # Copied from transformers.models.wav2vec2.feature_extraction_wav2vec2.Wav2Vec2FeatureExtractor.zero_mean_unit_var_norm
     def 		UpperCamelCase(     _UpperCamelCase				,							_UpperCamelCase				,							_UpperCamelCase = 0.0					):
        if attention_mask is not None:
           _UpperCAmelCase           =   np.array(_UpperCamelCase				,							np.intaa					)
           _UpperCAmelCase           =   []

           for vector, length in zip(_UpperCamelCase				,							attention_mask.sum(-1					)					):
              _UpperCAmelCase           =   (vector - vector[:length].mean()) / np.sqrt(vector[:length].var() + 1e-7					)
              if length < normed_slice.shape[0]:
                 _UpperCAmelCase           =   padding_value

              normed_input_values.append(_UpperCamelCase					)
        else:
           _UpperCAmelCase           =   [(x - x.mean()) / np.sqrt(x.var() + 1e-7					) for x in input_values]

        return normed_input_values





     def __call__(     self				,							_UpperCamelCase				,							_UpperCamelCase = True				,							_UpperCamelCase = None				,							_UpperCamelCase = None				,							_UpperCamelCase = None				,							_UpperCamelCase = "max_length"				,							_UpperCamelCase = None				,							_UpperCamelCase = None				,							_UpperCamelCase = None				,							**_UpperCamelCase				,							):

        if sampling_rate is not None:
           if sampling_rate != self.sampling_rate:
              raise ValueError(
                  f'''The model corresponding to this feature extractor: {self.__class__.__name__} was trained using a'''
                  f''' sampling rate of {self.sampling_rate}. Please make sure that the provided `raw_speech` input'''
                  f''' was sampled 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(_UpperCamelCase				,							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(_UpperCamelCase				,							(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(_UpperCamelCase				,							np.ndarray					):
           _UpperCAmelCase           =   np.asarray(_UpperCamelCase				,							dtype=np.floataa					)
        elif isinstance(_UpperCamelCase				,							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]

        _UpperCAmelCase           =   BatchFeature({'''input_features''': raw_speech}					)

        # convert into correct format for padding

        _UpperCAmelCase           =   self.pad(
            _UpperCamelCase				,							padding=_UpperCamelCase				,							max_length=max_length if max_length else self.n_samples				,							truncation=_UpperCamelCase				,							pad_to_multiple_of=_UpperCamelCase				,							return_attention_mask=return_attention_mask or do_normalize				,							)

        # zero-mean and unit-variance normalization
        if do_normalize:
           _UpperCAmelCase           =   self.zero_mean_unit_var_norm(
               padded_inputs['''input_features''']				,							attention_mask=padded_inputs['''attention_mask''']				,							padding_value=self.padding_value				,							)
           _UpperCAmelCase           =   np.stack(padded_inputs['''input_features''']				,							axis=0					)

        # make sure list is in array format
        _UpperCAmelCase           =   padded_inputs.get('''input_features'''					).transpose(2				,							0				,							1					)

        _UpperCAmelCase           =   [self._np_extract_fbank_features(_UpperCamelCase					) for waveform in input_features[0]]

        if isinstance(input_features[0]				,							_UpperCamelCase					):
           _UpperCAmelCase           =   [np.asarray(_UpperCamelCase				,							dtype=np.floataa					) for feature in input_features]
        else:
           _UpperCAmelCase           =   input_features

        if return_attention_mask:
           # rescale from sample (48000) to feature (3000)
           _UpperCAmelCase           =   padded_inputs['''attention_mask'''][:, :: self.hop_length]

        if return_tensors is not None:
           _UpperCAmelCase           =   padded_inputs.convert_to_tensors(_UpperCamelCase					)

        return padded_inputs





     def 		UpperCamelCase(     self					):
        _UpperCAmelCase           =   copy.deepcopy(self.__dict__					)
        _UpperCAmelCase           =   self.__class__.__name__
        if "mel_filters" in output:
           del output["mel_filters"]
        return output






from ..utils import DummyObject, requires_backends




class 			__UpperCamelCase    (							metaclass=A__    ):
     __A	:  str							  =   ["""torch""", """scipy"""]





     def __init__(     self				,							*_UpperCamelCase				,							**_UpperCamelCase					):
        requires_backends(self				,							['''torch''', '''scipy''']					)





     @classmethod
     def 		UpperCamelCase(     cls				,							*_UpperCamelCase				,							**_UpperCamelCase					):
        requires_backends(cls				,							['''torch''', '''scipy''']					)





     @classmethod
     def 		UpperCamelCase(     cls				,							*_UpperCamelCase				,							**_UpperCamelCase					):
        requires_backends(cls				,							['''torch''', '''scipy''']					)