



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

import numpy as np

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


a_								=       logging.get_logger(__name__)



class 			__lowerCAmelCase  (						lowerCAmelCase__ ):
 lowerCAmelCase__							       =	["""input_values""", """attention_mask"""]




 def __init__(    self						,					__UpperCAmelCase = 1						,					__UpperCAmelCase = 16000						,					__UpperCAmelCase = 0.0						,					__UpperCAmelCase = False						,					__UpperCAmelCase = 80						,					__UpperCAmelCase = 16						,					__UpperCAmelCase = 64						,					__UpperCAmelCase = "hann_window"						,					__UpperCAmelCase = 1.0						,					__UpperCAmelCase = 80						,					__UpperCAmelCase = 7600						,					__UpperCAmelCase = 1E-1_0						,					__UpperCAmelCase = 2						,					__UpperCAmelCase = True						,					**__UpperCAmelCase						,					):



    '''simple docstring'''
    super().__init__(feature_size=__UpperCAmelCase						,					sampling_rate=__UpperCAmelCase						,					padding_value=__UpperCAmelCase						,					**__UpperCAmelCase					)
    __lowerCamelCase    				=     do_normalize
    __lowerCamelCase    				=     return_attention_mask

    __lowerCamelCase    				=     num_mel_bins
    __lowerCamelCase    				=     hop_length
    __lowerCamelCase    				=     win_length
    __lowerCamelCase    				=     win_function
    __lowerCamelCase    				=     frame_signal_scale
    __lowerCamelCase    				=     fmin
    __lowerCamelCase    				=     fmax
    __lowerCamelCase    				=     mel_floor
    __lowerCamelCase    				=     reduction_factor

    __lowerCamelCase    				=     win_length * sampling_rate // 1000
    __lowerCamelCase    				=     hop_length * sampling_rate // 1000
    __lowerCamelCase    				=     optimal_fft_length(self.sample_size					)
    __lowerCamelCase    				=     (self.n_fft // 2) + 1

    __lowerCamelCase    				=     window_function(window_length=self.sample_size						,					name=self.win_function						,					periodic=__UpperCAmelCase					)

    __lowerCamelCase    				=     mel_filter_bank(
        num_frequency_bins=self.n_freqs						,					num_mel_filters=self.num_mel_bins						,					min_frequency=self.fmin						,					max_frequency=self.fmax						,					sampling_rate=self.sampling_rate						,					norm='''slaney'''						,					mel_scale='''slaney'''						,					)

    if frame_signal_scale != 1.0:
       warnings.warn(
           '''The argument `frame_signal_scale` is deprecated and will be removed in version 4.30.0 of Transformers'''						,					__UpperCAmelCase						,					)
    if reduction_factor != 2.0:
       warnings.warn(
           '''The argument `reduction_factor` is deprecated and will be removed in version 4.30.0 of Transformers'''						,					__UpperCAmelCase						,					)




 @staticmethod
 # Copied from transformers.models.wav2vec2.feature_extraction_wav2vec2.Wav2Vec2FeatureExtractor.zero_mean_unit_var_norm
 def 							lowerCamelCase   (    __UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase = 0.0					):



    '''simple docstring'''
    if attention_mask is not None:
       __lowerCamelCase    				=     np.array(__UpperCAmelCase						,					np.intaa					)
       __lowerCamelCase    				=     []

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

          normed_input_values.append(__UpperCAmelCase					)
    else:
       __lowerCamelCase    				=     [(x - x.mean()) / np.sqrt(x.var() + 1E-7					) for x in input_values]

    return normed_input_values




 def 							lowerCamelCase   (    self						,					__UpperCAmelCase						,					):



    '''simple docstring'''
    __lowerCamelCase    				=     spectrogram(
        __UpperCAmelCase						,					window=self.window						,					frame_length=self.sample_size						,					hop_length=self.sample_stride						,					fft_length=self.n_fft						,					mel_filters=self.mel_filters						,					mel_floor=self.mel_floor						,					log_mel='''log10'''						,					)
    return log_mel_spec.T




 def __call__(    self						,					__UpperCAmelCase = None						,					__UpperCAmelCase = None						,					__UpperCAmelCase = False						,					__UpperCAmelCase = None						,					__UpperCAmelCase = False						,					__UpperCAmelCase = None						,					__UpperCAmelCase = None						,					__UpperCAmelCase = None						,					__UpperCAmelCase = None						,					**__UpperCAmelCase						,					):



    '''simple docstring'''
    if audio is None and audio_target is None:
       raise ValueError('''You must provide either `audio` or `audio_target` values.'''					)

    if sampling_rate is not None:
       if sampling_rate != self.sampling_rate:
          raise ValueError(
              F"""The model corresponding to this feature extractor: {self} was trained using a sampling rate of"""
              F""" {self.sampling_rate}. Please make sure that the provided audio input was sampled with"""
              F""" {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.'''					)

    if audio is not None:
       __lowerCamelCase    				=     self._process_audio(
           __UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					**__UpperCAmelCase						,					)
    else:
       __lowerCamelCase    				=     None

    if audio_target is not None:
       __lowerCamelCase    				=     self._process_audio(
           __UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					__UpperCAmelCase						,					**__UpperCAmelCase						,					)

       if inputs is None:
          return inputs_target
       else:
          __lowerCamelCase    				=     inputs_target['''input_values''']
          __lowerCamelCase    				=     inputs_target.get('''attention_mask'''					)
          if decoder_attention_mask is not None:
             __lowerCamelCase    				=     decoder_attention_mask

    return inputs




 def 							lowerCamelCase   (    self						,					__UpperCAmelCase						,					__UpperCAmelCase = False						,					__UpperCAmelCase = False						,					__UpperCAmelCase = None						,					__UpperCAmelCase = False						,					__UpperCAmelCase = None						,					__UpperCAmelCase = None						,					__UpperCAmelCase = None						,					**__UpperCAmelCase						,					):



    '''simple docstring'''
    __lowerCamelCase    				=     isinstance(__UpperCAmelCase						,					np.ndarray					) and len(speech.shape					) > 1
    if is_batched_numpy and len(speech.shape					) > 2:
       raise ValueError(F"""Only mono-channel audio is supported for input to {self}"""					)
    __lowerCamelCase    				=     is_batched_numpy or (
        isinstance(__UpperCAmelCase						,					(list, tuple)					) and (isinstance(speech[0]						,					(np.ndarray, tuple, list)					))
    )

    if is_batched:
       __lowerCamelCase    				=     [np.asarray(__UpperCAmelCase						,					dtype=np.floataa					) for speech in speech]
    elif not is_batched and not isinstance(__UpperCAmelCase						,					np.ndarray					):
       __lowerCamelCase    				=     np.asarray(__UpperCAmelCase						,					dtype=np.floataa					)
    elif isinstance(__UpperCAmelCase						,					np.ndarray					) and speech.dtype is np.dtype(np.floataa					):
       __lowerCamelCase    				=     speech.astype(np.floataa					)

    # always return batch
    if not is_batched:
       __lowerCamelCase    				=     [speech]

    # needed to make pad() work on spectrogram inputs
    __lowerCamelCase    				=     self.feature_size

    # convert into correct format for padding
    if is_target:
       __lowerCamelCase    				=     [self._extract_mel_features(__UpperCAmelCase					) for waveform in speech]
       __lowerCamelCase    				=     BatchFeature({'''input_values''': features}					)
       __lowerCamelCase    				=     self.num_mel_bins
    else:
       __lowerCamelCase    				=     BatchFeature({'''input_values''': speech}					)

    __lowerCamelCase    				=     self.pad(
        __UpperCAmelCase						,					padding=__UpperCAmelCase						,					max_length=__UpperCAmelCase						,					truncation=__UpperCAmelCase						,					pad_to_multiple_of=__UpperCAmelCase						,					return_attention_mask=__UpperCAmelCase						,					**__UpperCAmelCase						,					)

    __lowerCamelCase    				=     feature_size_hack

    # convert input values to correct format
    __lowerCamelCase    				=     padded_inputs['''input_values''']
    if not isinstance(input_values[0]						,					np.ndarray					):
       __lowerCamelCase    				=     [np.asarray(__UpperCAmelCase						,					dtype=np.floataa					) for array in input_values]
    elif (
        not isinstance(__UpperCAmelCase						,					np.ndarray					)
        and isinstance(input_values[0]						,					np.ndarray					)
        and input_values[0].dtype is np.dtype(np.floataa					)
    ):
       __lowerCamelCase    				=     [array.astype(np.floataa					) for array in input_values]
    elif isinstance(__UpperCAmelCase						,					np.ndarray					) and input_values.dtype is np.dtype(np.floataa					):
       __lowerCamelCase    				=     input_values.astype(np.floataa					)

    # convert attention_mask to correct format
    __lowerCamelCase    				=     padded_inputs.get('''attention_mask'''					)
    if attention_mask is not None:
       __lowerCamelCase    				=     [np.asarray(__UpperCAmelCase						,					dtype=np.intaa					) for array in attention_mask]

    # zero-mean and unit-variance normalization
    if not is_target and self.do_normalize:
       __lowerCamelCase    				=     (
           attention_mask
           if self._get_padding_strategies(__UpperCAmelCase						,					max_length=__UpperCAmelCase					) is not PaddingStrategy.DO_NOT_PAD
           else None
       )
       __lowerCamelCase    				=     self.zero_mean_unit_var_norm(
           padded_inputs['''input_values''']						,					attention_mask=__UpperCAmelCase						,					padding_value=self.padding_value					)

    if return_tensors is not None:
       __lowerCamelCase    				=     padded_inputs.convert_to_tensors(__UpperCAmelCase					)

    return padded_inputs




 def 							lowerCamelCase   (    self					):



    '''simple docstring'''
    __lowerCamelCase    				=     super().to_dict()

    # Don't serialize these as they are derived from the other properties.
    __lowerCamelCase    				=     ['''window''', '''mel_filters''', '''sample_size''', '''sample_stride''', '''n_fft''', '''n_freqs''']
    for name in names:
       if name in output:
          del output[name]

    return output











import math





def 		a__      (		_UpperCamelCase      :			float			,_UpperCamelCase      :			float				):
   if (
       not isinstance(_UpperCamelCase			,(int, float)				)
       or power_factor < -1
       or power_factor > 1
   ):
      raise ValueError('''power_factor must be a valid float value between -1 and 1.'''				)
   return apparent_power * power_factor





def 		a__      (		_UpperCamelCase      :			float			,_UpperCamelCase      :			float				):
   if (
       not isinstance(_UpperCamelCase			,(int, float)				)
       or power_factor < -1
       or power_factor > 1
   ):
      raise ValueError('''power_factor must be a valid float value between -1 and 1.'''				)
   return apparent_power * math.sqrt(1 - power_factor**2				)


if __name__ == "__main__":
  import doctest

  doctest.testmod()






