
'''simple docstring'''


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


snake_case_ :  Union[str, Any]     =					logging.get_logger(__name__)


class 						lowercase__	(  snake_case_   ):






   '''simple docstring'''







   _snake_case		   =							['''input_values''', '''attention_mask''']







   def __init__(			self ,   lowerCamelCase__ = 1 ,   lowerCamelCase__ = 1_6_0_0_0 ,   lowerCamelCase__ = 0.0 ,   lowerCamelCase__ = False ,   lowerCamelCase__ = 8_0 ,   lowerCamelCase__ = 1_6 ,   lowerCamelCase__ = 6_4 ,   lowerCamelCase__ = "hann_window" ,   lowerCamelCase__ = 1.0 ,   lowerCamelCase__ = 8_0 ,   lowerCamelCase__ = 7_6_0_0 ,   lowerCamelCase__ = 1e-1_0 ,   lowerCamelCase__ = 2 ,   lowerCamelCase__ = True ,   **lowerCamelCase__ ,   ):

      '''simple docstring'''







      super().__init__(feature_size=lowerCamelCase__ ,   sampling_rate=lowerCamelCase__ ,   padding_value=lowerCamelCase__ ,   **lowerCamelCase__   )
      UpperCamelCase       =  do_normalize
      UpperCamelCase       =  return_attention_mask

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

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

      UpperCamelCase       =  window_function(window_length=self.sample_size ,   name=self.win_function ,   periodic=lowerCamelCase__   )

      UpperCamelCase       =  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''' ,   lowerCamelCase__ ,   )
      if reduction_factor != 2.0:
         warnings.warn(
             '''The argument `reduction_factor` is deprecated and will be removed in version 4.30.0 of Transformers''' ,   lowerCamelCase__ ,   )







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

      '''simple docstring'''







      if attention_mask is not None:
         UpperCamelCase       =  np.array(lowerCamelCase__ ,   np.intaa   )
         UpperCamelCase       =  []

         for vector, length in zip(lowerCamelCase__ ,   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(lowerCamelCase__   )
      else:
         UpperCamelCase       =  [(x - x.mean()) / np.sqrt(x.var() + 1e-7   ) for x in input_values]

      return normed_input_values







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   ):

      '''simple docstring'''







      UpperCamelCase       =  spectrogram(
          lowerCamelCase__ ,   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 ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = False ,   lowerCamelCase__ = None ,   lowerCamelCase__ = False ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   lowerCamelCase__ = None ,   **lowerCamelCase__ ,   ):

      '''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:
         UpperCamelCase       =  self._process_audio(
             lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   **lowerCamelCase__ ,   )
      else:
         UpperCamelCase       =  None

      if audio_target is not None:
         UpperCamelCase       =  self._process_audio(
             lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   **lowerCamelCase__ ,   )

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

      return inputs







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

      '''simple docstring'''







      UpperCamelCase       =  isinstance(lowerCamelCase__ ,   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}'   )
      UpperCamelCase       =  is_batched_numpy or (
          isinstance(lowerCamelCase__ ,   (list, tuple)   ) and (isinstance(speech[0] ,   (np.ndarray, tuple, list)   ))
      )

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

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

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

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

      UpperCamelCase       =  self.pad(
          lowerCamelCase__ ,   padding=lowerCamelCase__ ,   max_length=lowerCamelCase__ ,   truncation=lowerCamelCase__ ,   pad_to_multiple_of=lowerCamelCase__ ,   return_attention_mask=lowerCamelCase__ ,   **lowerCamelCase__ ,   )

      UpperCamelCase       =  feature_size_hack

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

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

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

      if return_tensors is not None:
         UpperCamelCase       =  padded_inputs.convert_to_tensors(lowerCamelCase__   )

      return padded_inputs







   def       UpperCAmelCase				(			self   ):

      '''simple docstring'''







      UpperCamelCase       =  super().to_dict()

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

      return output







'''simple docstring'''


import tensorflow as tf

from ...tf_utils import shape_list


class 						lowercase__	(  tf.keras.layers.Layer   ):






   '''simple docstring'''







   def __init__(			self ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__=1 ,   lowerCamelCase__=False ,   **lowerCamelCase__   ):

      '''simple docstring'''







      super().__init__(**lowerCamelCase__   )

      UpperCamelCase       =  vocab_size
      UpperCamelCase       =  d_embed
      UpperCamelCase       =  d_proj

      UpperCamelCase       =  cutoffs + [vocab_size]
      UpperCamelCase       =  [0] + self.cutoffs
      UpperCamelCase       =  div_val

      UpperCamelCase       =  self.cutoffs[0]
      UpperCamelCase       =  len(self.cutoffs   ) - 1
      UpperCamelCase       =  self.shortlist_size + self.n_clusters
      UpperCamelCase       =  keep_order

      UpperCamelCase       =  []
      UpperCamelCase       =  []







   def       UpperCAmelCase				(			self ,   lowerCamelCase__   ):

      '''simple docstring'''







      if self.n_clusters > 0:
         UpperCamelCase       =  self.add_weight(
             shape=(self.n_clusters, self.d_embed) ,   initializer='''zeros''' ,   trainable=lowerCamelCase__ ,   name='''cluster_weight'''   )
         UpperCamelCase       =  self.add_weight(
             shape=(self.n_clusters,) ,   initializer='''zeros''' ,   trainable=lowerCamelCase__ ,   name='''cluster_bias'''   )

      if self.div_val == 1:
         for i in range(len(self.cutoffs   )   ):
            if self.d_proj != self.d_embed:
               UpperCamelCase       =  self.add_weight(
                   shape=(self.d_embed, self.d_proj) ,   initializer='''zeros''' ,   trainable=lowerCamelCase__ ,   name=f'out_projs_._{i}' ,   )
               self.out_projs.append(lowerCamelCase__   )
            else:
               self.out_projs.append(lowerCamelCase__   )
            UpperCamelCase       =  self.add_weight(
                shape=(self.vocab_size, self.d_embed) ,   initializer='''zeros''' ,   trainable=lowerCamelCase__ ,   name=f'out_layers_._{i}_._weight' ,   )
            UpperCamelCase       =  self.add_weight(
                shape=(self.vocab_size,) ,   initializer='''zeros''' ,   trainable=lowerCamelCase__ ,   name=f'out_layers_._{i}_._bias' ,   )
            self.out_layers.append((weight, bias)   )
      else:
         for i in range(len(self.cutoffs   )   ):
            UpperCamelCase     , UpperCamelCase       =  self.cutoff_ends[i], self.cutoff_ends[i + 1]
            UpperCamelCase       =  self.d_embed // (self.div_val**i)

            UpperCamelCase       =  self.add_weight(
                shape=(d_emb_i, self.d_proj) ,   initializer='''zeros''' ,   trainable=lowerCamelCase__ ,   name=f'out_projs_._{i}'   )
            self.out_projs.append(lowerCamelCase__   )
            UpperCamelCase       =  self.add_weight(
                shape=(r_idx - l_idx, d_emb_i) ,   initializer='''zeros''' ,   trainable=lowerCamelCase__ ,   name=f'out_layers_._{i}_._weight' ,   )
            UpperCamelCase       =  self.add_weight(
                shape=(r_idx - l_idx,) ,   initializer='''zeros''' ,   trainable=lowerCamelCase__ ,   name=f'out_layers_._{i}_._bias' ,   )
            self.out_layers.append((weight, bias)   )
      super().build(lowerCamelCase__   )







   @staticmethod
   def       UpperCAmelCase				(			lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__=None   ):

      '''simple docstring'''







      UpperCamelCase       =  x
      if proj is not None:
         UpperCamelCase       =  tf.einsum('''ibd,ed->ibe''' ,   lowerCamelCase__ ,   lowerCamelCase__   )
      return tf.einsum('''ibd,nd->ibn''' ,   lowerCamelCase__ ,   lowerCamelCase__   ) + b







   @staticmethod
   def       UpperCAmelCase				(			lowerCamelCase__ ,   lowerCamelCase__   ):

      '''simple docstring'''







      UpperCamelCase       =  shape_list(lowerCamelCase__   )
      UpperCamelCase       =  tf.range(lp_size[0] ,   dtype=target.dtype   )
      UpperCamelCase       =  tf.stack([r, target] ,   1   )
      return tf.gather_nd(lowerCamelCase__ ,   lowerCamelCase__   )







   def       UpperCAmelCase				(			self ,   lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__=True ,   lowerCamelCase__=False   ):

      '''simple docstring'''







      UpperCamelCase       =  0
      if self.n_clusters == 0:
         UpperCamelCase       =  self._logit(lowerCamelCase__ ,   self.out_layers[0][0] ,   self.out_layers[0][1] ,   self.out_projs[0]   )
         if target is not None:
            UpperCamelCase       =  tf.nn.sparse_softmax_cross_entropy_with_logits(labels=lowerCamelCase__ ,   logits=lowerCamelCase__   )
         UpperCamelCase       =  tf.nn.log_softmax(lowerCamelCase__ ,   axis=-1   )
      else:
         UpperCamelCase       =  shape_list(lowerCamelCase__   )
         UpperCamelCase       =  []
         UpperCamelCase       =  tf.zeros(hidden_sizes[:2]   )
         for i in range(len(self.cutoffs   )   ):
            UpperCamelCase     , UpperCamelCase       =  self.cutoff_ends[i], self.cutoff_ends[i + 1]
            if target is not None:
               UpperCamelCase       =  (target >= l_idx) & (target < r_idx)
               UpperCamelCase       =  tf.where(lowerCamelCase__   )
               UpperCamelCase       =  tf.boolean_mask(lowerCamelCase__ ,   lowerCamelCase__   ) - l_idx

            if self.div_val == 1:
               UpperCamelCase       =  self.out_layers[0][0][l_idx:r_idx]
               UpperCamelCase       =  self.out_layers[0][1][l_idx:r_idx]
            else:
               UpperCamelCase       =  self.out_layers[i][0]
               UpperCamelCase       =  self.out_layers[i][1]

            if i == 0:
               UpperCamelCase       =  tf.concat([cur_W, self.cluster_weight] ,   0   )
               UpperCamelCase       =  tf.concat([cur_b, self.cluster_bias] ,   0   )

               UpperCamelCase       =  self._logit(lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   self.out_projs[0]   )
               UpperCamelCase       =  tf.nn.log_softmax(lowerCamelCase__   )
               out.append(head_logprob[..., : self.cutoffs[0]]   )
               if target is not None:
                  UpperCamelCase       =  tf.boolean_mask(lowerCamelCase__ ,   lowerCamelCase__   )
                  UpperCamelCase       =  self._gather_logprob(lowerCamelCase__ ,   lowerCamelCase__   )
            else:
               UpperCamelCase       =  self._logit(lowerCamelCase__ ,   lowerCamelCase__ ,   lowerCamelCase__ ,   self.out_projs[i]   )
               UpperCamelCase       =  tf.nn.log_softmax(lowerCamelCase__   )
               UpperCamelCase       =  self.cutoffs[0] + i - 1  # No probability for the head cluster
               UpperCamelCase       =  head_logprob[..., cluster_prob_idx, None] + tail_logprob
               out.append(lowerCamelCase__   )
               if target is not None:
                  UpperCamelCase       =  tf.boolean_mask(lowerCamelCase__ ,   lowerCamelCase__   )
                  UpperCamelCase       =  tf.boolean_mask(lowerCamelCase__ ,   lowerCamelCase__   )
                  UpperCamelCase       =  self._gather_logprob(lowerCamelCase__ ,   lowerCamelCase__   )
                  cur_logprob += cur_head_logprob[:, self.cutoff_ends[1] + i - 1]
            if target is not None:
               loss += tf.scatter_nd(lowerCamelCase__ ,   -cur_logprob ,   shape_list(lowerCamelCase__   )   )
         UpperCamelCase       =  tf.concat(lowerCamelCase__ ,   axis=-1   )

      if target is not None:
         if return_mean:
            UpperCamelCase       =  tf.reduce_mean(lowerCamelCase__   )
         # Add the training-time loss value to the layer using `self.add_loss()`.
         self.add_loss(lowerCamelCase__   )

         # Log the loss as a metric (we could log arbitrary metrics,
         # including different metrics for training and inference.
         self.add_metric(lowerCamelCase__ ,   name=self.name ,   aggregation='''mean''' if return_mean else ''''''   )

      return out





