





'''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        _lowerCAmelCase    (			UpperCAmelCase_							):


  '''simple docstring'''
  a_							:       Dict      					=["""audio_values""", """audio_mask"""]







  def __init__(      self      :					List[str]      ,				UpperCamelCase      :					List[str]=20_48      ,				UpperCamelCase      :					Union[str, Any]=1      ,				UpperCamelCase      :					Optional[Any]=[16, 16]      ,				UpperCamelCase      :					Dict=1_28      ,				UpperCamelCase      :					str=4_41_00      ,				UpperCamelCase      :					List[str]=86      ,				UpperCamelCase      :					int=20_48      ,				UpperCamelCase      :					Tuple=0.0      ,				**UpperCamelCase      :					Optional[Any]      ,				):


    '''simple docstring'''





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

    _snake_case   :				List[str]														=	spectrogram_length
    _snake_case   :				Optional[int]														=	num_channels
    _snake_case   :				List[Any]														=	patch_size
    _snake_case   :				List[Any]														=	feature_size // self.patch_size[1]
    _snake_case   :				Optional[Any]														=	n_fft
    _snake_case   :				Dict														=	sampling_rate // hop_length_to_sampling_rate
    _snake_case   :				Optional[int]														=	sampling_rate
    _snake_case   :				Any														=	padding_value
    _snake_case   :				Union[str, Any]														=	mel_filter_bank(
        num_frequency_bins=1 + n_fft // 2      ,				num_mel_filters=UpperCamelCase      ,				min_frequency=0.0      ,				max_frequency=2_20_50.0      ,				sampling_rate=UpperCamelCase      ,				norm='slaney'      ,				mel_scale='slaney'      ,				).T







  def UpperCamelCase_ (      self      :					int      ,				UpperCamelCase      :					np.array							):


    '''simple docstring'''





    _snake_case   :				Any														=	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.T      ,				log_mel='dB'      ,				db_range=80.0      ,				)
    _snake_case   :				List[str]														=	log_spec[:, :-1]
    _snake_case   :				Optional[Any]														=	log_spec - 20.0
    _snake_case   :				Union[str, Any]														=	np.clip(log_spec / 40.0      ,				-2.0      ,				0.0							) + 1.0
    return log_spec







  def __call__(      self      :					List[Any]      ,				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      :					Dict      ,				):


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

    _snake_case   :				str														=	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}"""							)
    _snake_case   :				Optional[int]														=	is_batched_numpy or (
        isinstance(UpperCamelCase      ,				(list, tuple)							) and (isinstance(raw_speech[0]      ,				(np.ndarray, tuple, list)							))
    )
    if is_batched:
      _snake_case   :				List[str]														=	[np.asarray([speech]      ,				dtype=np.floataa							).T for speech in raw_speech]
    elif not is_batched and not isinstance(UpperCamelCase      ,				np.ndarray							):
      _snake_case   :				int														=	np.asarray(UpperCamelCase      ,				dtype=np.floataa							)
    elif isinstance(UpperCamelCase      ,				np.ndarray							) and raw_speech.dtype is np.dtype(np.floataa							):
      _snake_case   :				List[Any]														=	raw_speech.astype(np.floataa							)
    # always return batch
    if not is_batched:
      _snake_case   :				Dict														=	[np.asarray([raw_speech]							).T]

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

    # Create audio attention mask
    _snake_case   :				Union[str, Any]														=	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:
      _snake_case   :				Dict														=	[
          (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
      ]
      _snake_case   :				Optional[Any]														=	np.array(UpperCamelCase							).astype(np.floataa							)

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

    # return as BatchFeature
    if return_attention_mask:
      _snake_case   :				Union[str, Any]														=	{'audio_values': padded_audio_features, 'audio_mask': audio_mask}
    else:
      _snake_case   :				int														=	{'audio_values': padded_audio_features}

    _snake_case   :				List[str]														=	BatchFeature(data=UpperCamelCase      ,				tensor_type=UpperCamelCase							)
    return encoded_inputs











def     lowerCamelCase_	(      lowerCAmelCase:	int				)->		int:

  if not isinstance(lowerCAmelCase    ,							lowerCAmelCase				):
    _snake_case   :				Union[str, Any]														=	F"""Input value of [number={number}] must be an integer"""
    raise TypeError(lowerCAmelCase				)

  if number < 1:
    _snake_case   :				int														=	F"""Input value of [number={number}] must be > 0"""
    raise ValueError(lowerCAmelCase				)

  _snake_case   :				int														=	1

  for i in range(1    ,							lowerCAmelCase				):
    current_number *= 4 * i - 2
    current_number //= i + 1

  return current_number


if __name__ == "__main__":
      import doctest

      doctest.testmod()




