





'''simple docstring'''






from typing import List, Optional, Union

import numpy as np
import torch
import torchaudio.compliance.kaldi as ta_kaldi

from ...feature_extraction_sequence_utils import SequenceFeatureExtractor
from ...feature_extraction_utils import BatchFeature
from ...utils import PaddingStrategy, TensorType, logging


A_		:  int		 =						logging.get_logger(__name__)
class 					__snake_case  (					lowerCamelCase__							):






   '''simple docstring'''





   lowerCamelCase__    							=      ['''input_features''', '''attention_mask''']

   def __init__(							self	,		__SCREAMING_SNAKE_CASE=8_0	,		__SCREAMING_SNAKE_CASE=1_6_0_0_0	,		__SCREAMING_SNAKE_CASE=8_0	,		__SCREAMING_SNAKE_CASE=0.0	,		__SCREAMING_SNAKE_CASE=True	,		__SCREAMING_SNAKE_CASE=True	,		__SCREAMING_SNAKE_CASE=True	,		**__SCREAMING_SNAKE_CASE	,		):
    super().__init__(feature_size=__SCREAMING_SNAKE_CASE	,		sampling_rate=__SCREAMING_SNAKE_CASE	,		padding_value=__SCREAMING_SNAKE_CASE	,		**__SCREAMING_SNAKE_CASE       )
    snake_case__     :					List[Any]    =  num_mel_bins
    snake_case__     :					Tuple    =  do_ceptral_normalize
    snake_case__     :					int    =  normalize_means
    snake_case__     :					Tuple    =  normalize_vars
    snake_case__     :					List[Any]    =  True

   def 		__UpperCamelCase						(							self	,		__SCREAMING_SNAKE_CASE	,		):
    snake_case__     :					Union[str, Any]    =  waveform * (2**1_5)  # Kaldi compliance: 16-bit signed integers
    snake_case__     :					Optional[int]    =  torch.from_numpy(__SCREAMING_SNAKE_CASE       ).unsqueeze(0       )
    snake_case__     :					Optional[Any]    =  ta_kaldi.fbank(__SCREAMING_SNAKE_CASE	,		num_mel_bins=self.num_mel_bins	,		sample_frequency=self.sampling_rate       )
    return features.numpy()

   @staticmethod
   def 		__UpperCamelCase						(							__SCREAMING_SNAKE_CASE	,		__SCREAMING_SNAKE_CASE	,		__SCREAMING_SNAKE_CASE = True	,		__SCREAMING_SNAKE_CASE = True	,		__SCREAMING_SNAKE_CASE = 0.0	,		):




    if normalize_means:
     snake_case__     :					List[str]    =  x[:input_length].mean(axis=0       )
     snake_case__     :					int    =  np.subtract(__SCREAMING_SNAKE_CASE	,		__SCREAMING_SNAKE_CASE       )
    if normalize_vars:
     snake_case__     :					Dict    =  x[:input_length].std(axis=0       )
     snake_case__     :					Optional[Any]    =  np.divide(__SCREAMING_SNAKE_CASE	,		__SCREAMING_SNAKE_CASE       )

    if input_length < x.shape[0]:
     snake_case__     :					Dict    =  padding_value

    # make sure array is in float32
    snake_case__     :					Any    =  x.astype(np.floataa       )

    return x

   def 		__UpperCamelCase						(							self	,		__SCREAMING_SNAKE_CASE	,		__SCREAMING_SNAKE_CASE = None       ):
    snake_case__     :					List[Any]    =  attention_mask.sum(-1       ) if attention_mask is not None else [x.shape[0] for x in input_features]
    return [
        self.utterance_cmvn(__SCREAMING_SNAKE_CASE	,		__SCREAMING_SNAKE_CASE	,		self.normalize_means	,		self.normalize_vars	,		self.padding_value       )
        for x, n in zip(__SCREAMING_SNAKE_CASE	,		__SCREAMING_SNAKE_CASE       )
    ]


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




    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 `raw_speech` 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."""       )

    snake_case__     :					List[Any]    =  isinstance(__SCREAMING_SNAKE_CASE	,		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}"       )
    snake_case__     :					str    =  is_batched_numpy or (
        isinstance(__SCREAMING_SNAKE_CASE	,		(list, tuple)       ) and (isinstance(raw_speech[0]	,		(np.ndarray, tuple, list)       ))
    )

    if is_batched:
     snake_case__     :					Any    =  [np.asarray(__SCREAMING_SNAKE_CASE	,		dtype=np.floataa       ) for speech in raw_speech]
    elif not is_batched and not isinstance(__SCREAMING_SNAKE_CASE	,		np.ndarray       ):
     snake_case__     :					Union[str, Any]    =  np.asarray(__SCREAMING_SNAKE_CASE	,		dtype=np.floataa       )
    elif isinstance(__SCREAMING_SNAKE_CASE	,		np.ndarray       ) and raw_speech.dtype is np.dtype(np.floataa       ):
     snake_case__     :					str    =  raw_speech.astype(np.floataa       )

    # always return batch
    if not is_batched:
     snake_case__     :					Any    =  [raw_speech]

    # extract fbank features
    snake_case__     :					List[str]    =  [self._extract_fbank_features(__SCREAMING_SNAKE_CASE       ) for waveform in raw_speech]

    # convert into correct format for padding
    snake_case__     :					Dict    =  BatchFeature({"""input_features""": features}       )

    snake_case__     :					Dict    =  self.pad(
        __SCREAMING_SNAKE_CASE	,		padding=__SCREAMING_SNAKE_CASE	,		max_length=__SCREAMING_SNAKE_CASE	,		truncation=__SCREAMING_SNAKE_CASE	,		pad_to_multiple_of=__SCREAMING_SNAKE_CASE	,		return_attention_mask=__SCREAMING_SNAKE_CASE	,		**__SCREAMING_SNAKE_CASE	,		)

    # make sure list is in array format
    snake_case__     :					Tuple    =  padded_inputs.get("""input_features"""       )
    if isinstance(input_features[0]	,		__SCREAMING_SNAKE_CASE       ):
     snake_case__     :					List[str]    =  [np.asarray(__SCREAMING_SNAKE_CASE	,		dtype=np.floataa       ) for feature in input_features]

    snake_case__     :					List[str]    =  padded_inputs.get("""attention_mask"""       )
    if attention_mask is not None:
     snake_case__     :					List[str]    =  [np.asarray(__SCREAMING_SNAKE_CASE	,		dtype=np.intaa       ) for array in attention_mask]

    # Utterance-level cepstral mean and variance normalization
    if self.do_ceptral_normalize:
     snake_case__     :					List[Any]    =  (
         np.array(__SCREAMING_SNAKE_CASE	,		dtype=np.intaa       )
         if self._get_padding_strategies(__SCREAMING_SNAKE_CASE	,		max_length=__SCREAMING_SNAKE_CASE       ) is not PaddingStrategy.DO_NOT_PAD
         else None
     )
     snake_case__     :					str    =  self.normalize(
         padded_inputs["""input_features"""]	,		attention_mask=__SCREAMING_SNAKE_CASE       )

    if return_tensors is not None:
     snake_case__     :					int    =  padded_inputs.convert_to_tensors(__SCREAMING_SNAKE_CASE       )

    return padded_inputs











from timeit import timeit

_lowerCAmelCase				:   Tuple						       =						{
    '''MALAYALAM''': True,
    '''String''': False,
    '''rotor''': True,
    '''level''': True,
    '''A''': True,
    '''BB''': True,
    '''ABC''': False,
    '''amanaplanacanalpanama''': True,  # "a man a plan a canal panama"
}
# Ensure our test data is valid
assert all((key == key[::-1]) is value for key, value in test_data.items())

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   A_       :					List[str]        =      0
   A_       :					str        =      len(_lowerCAmelCase						) - 1
   while start_i < end_i:
      if s[start_i] == s[end_i]:
         start_i += 1
         end_i -= 1
      else:
         return False
   return True

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   A_       :					int        =      len(_lowerCAmelCase						) // 2
   A_       :					Union[str, Any]        =      len(_lowerCAmelCase						)

   # We need to traverse till half of the length of string
   # as we can get access of the i'th last element from
   # i'th index.
   # eg: [0,1,2,3,4,5] => 4th index can be accessed
   # with the help of 1st index (i==n-i-1)
   # where n is length of string
   return all(s[i] == s[n - i - 1] for i in range(_lowerCAmelCase						)						)

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   if len(_lowerCAmelCase						) <= 2:
      return True
   if s[0] == s[len(_lowerCAmelCase						) - 1]:
      return is_palindrome_recursive(s[1:-1]						)
   else:
      return False

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   return s == s[::-1]

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    None:
   A_       :					int        =      f"all({name}(key) is value for key, value in test_data.items())"
   A_       :					List[str]        =      f"from __main__ import test_data, {name}"
   A_       :					str        =      500000
   A_       :					List[str]        =      timeit(stmt=_lowerCAmelCase					,					setup=_lowerCAmelCase					,					number=_lowerCAmelCase						)
   print(f"{name:<35} finished {number:,} runs in {result:.5f} seconds"						)


if __name__ == "__main__":
 for key, value in test_data.items():
  assert is_palindrome(key) is is_palindrome_recursive(key)
  assert is_palindrome(key) is is_palindrome_slice(key)
  print(F'''{key:21} {value}''')
 print('''a man a plan a canal panama''')

 # finished 500,000 runs in 0.46793 seconds
 benchmark_function('''is_palindrome_slice''')
 # finished 500,000 runs in 0.85234 seconds
 benchmark_function('''is_palindrome''')
 # finished 500,000 runs in 1.32028 seconds
 benchmark_function('''is_palindrome_recursive''')
 # finished 500,000 runs in 2.08679 seconds
 benchmark_function('''is_palindrome_traversal''')
