






'''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


lowerCamelCase_				   =   logging.get_logger(__name__)

class   _UpperCAmelCase     (	__snake_case		):




   """simple docstring"""

   snake_case       							=		["""audio_values""", """audio_mask"""]

   def __init__(						self					:      int , __UpperCAmelCase					:      str=2048 , __UpperCAmelCase					:      Optional[Any]=1 , __UpperCAmelCase					:      Dict=[16, 16] , __UpperCAmelCase					:      Optional[int]=128 , __UpperCAmelCase					:      int=44100 , __UpperCAmelCase					:      Union[str, Any]=86 , __UpperCAmelCase					:      Any=2048 , __UpperCAmelCase					:      List[Any]=0.0 , **__UpperCAmelCase					:      int , ):





         '''simple docstring'''





         super().__init__(
             feature_size=__SCREAMING_SNAKE_CASE , sampling_rate=__SCREAMING_SNAKE_CASE , padding_value=__SCREAMING_SNAKE_CASE , **__SCREAMING_SNAKE_CASE , )

         _A     	=      spectrogram_length
         _A     	=      num_channels
         _A     	=      patch_size
         _A     	=      feature_size // self.patch_size[1]
         _A     	=      n_fft
         _A     	=      sampling_rate // hop_length_to_sampling_rate
         _A     	=      sampling_rate
         _A     	=      padding_value
         _A     	=      mel_filter_bank(
             num_frequency_bins=1 + n_fft // 2 , num_mel_filters=__SCREAMING_SNAKE_CASE , min_frequency=0.0 , max_frequency=22050.0 , sampling_rate=__SCREAMING_SNAKE_CASE , norm="slaney" , mel_scale="slaney" , ).T

   def 		lowerCAmelCase					(						self					:      Dict , __UpperCAmelCase					:      np.array						):





         '''simple docstring'''





         _A     	=      spectrogram(
             __SCREAMING_SNAKE_CASE , 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 , )
         _A     	=      log_spec[:, :-1]
         _A     	=      log_spec - 20.0
         _A     	=      np.clip(log_spec / 40.0 , -2.0 , 0.0						) + 1.0
         return log_spec

   def __call__(						self					:      str , __UpperCAmelCase					:      Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]] , __UpperCAmelCase					:      Optional[Union[str, TensorType]] = None , __UpperCAmelCase					:      Optional[bool] = True , __UpperCAmelCase					:      Optional[int] = None , __UpperCAmelCase					:      bool = False , __UpperCAmelCase					:      bool = False , **__UpperCAmelCase					:      List[str] , ):





         '''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."						)

         _A     	=      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}'''						)
         _A     	=      is_batched_numpy or (
             isinstance(__SCREAMING_SNAKE_CASE , (list, tuple)						) and (isinstance(raw_speech[0] , (np.ndarray, tuple, list)						))
         )
         if is_batched:
               _A     	=      [np.asarray([speech] , dtype=np.floataa						).T for speech in raw_speech]
         elif not is_batched and not isinstance(__SCREAMING_SNAKE_CASE , np.ndarray						):
               _A     	=      np.asarray(__SCREAMING_SNAKE_CASE , dtype=np.floataa						)
         elif isinstance(__SCREAMING_SNAKE_CASE , np.ndarray						) and raw_speech.dtype is np.dtype(np.floataa						):
               _A     	=      raw_speech.astype(np.floataa						)
         # always return batch
         if not is_batched:
               _A     	=      [np.asarray([raw_speech]						).T]

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

         # Create audio attention mask
         _A     	=      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:
               _A     	=      [
                   (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
               ]
               _A     	=      np.array(__SCREAMING_SNAKE_CASE						).astype(np.floataa						)

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

         # return as BatchFeature
         if return_attention_mask:
               _A     	=      {"audio_values": padded_audio_features, "audio_mask": audio_mask}
         else:
               _A     	=      {"audio_values": padded_audio_features}

         _A     	=      BatchFeature(data=__SCREAMING_SNAKE_CASE , tensor_type=__SCREAMING_SNAKE_CASE						)
         return encoded_inputs













"""simple docstring"""





def 	lowerCamelCase__			(				_lowerCamelCase			:						str					) ->							bool:
  lowerCamelCase_       	=		0
  for ch in input_str:
    lowerCamelCase_       	=		ord(_lowerCamelCase					)
    lowerCamelCase_       	=		pow(2						,							_lowerCamelCase					)

    # If we already turned on bit for current character's unicode
    if bitmap >> ch_unicode & 1 == 1:
      return False
    bitmap |= ch_bit_index_on
  return True


if __name__ == "__main__":
  import doctest

  doctest.testmod()




