

'''simple docstring'''





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

import numpy as np
import torch

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


lowerCAmelCase__       = logging.get_logger(__name__)






class 						__magic_name__    (       __lowercase    ):
 UpperCAmelCase							    =						['''input_features''', '''is_longer''']


 def __init__(						self		: Optional[Any]			,						lowerCAmelCase__		: str=6_4			,						lowerCAmelCase__		: List[str]=4_8_0_0_0			,						lowerCAmelCase__		: List[Any]=4_8_0			,						lowerCAmelCase__		: Dict=1_0			,						lowerCAmelCase__		: List[Any]=1_0_2_4			,						lowerCAmelCase__		: str=0.0			,						lowerCAmelCase__		: int=False			,						lowerCAmelCase__		: float = 0			,						lowerCAmelCase__		: float = 1_4_0_0_0			,						lowerCAmelCase__		: int = None			,						lowerCAmelCase__		: str = "fusion"			,						lowerCAmelCase__		: str = "repeatpad"			,						**lowerCAmelCase__		: Union[str, Any]			,						)    ->      Dict:
   super().__init__(
       feature_size=__a			,						sampling_rate=__a			,						padding_value=__a			,						return_attention_mask=__a			,						**__a			,						)
   UpperCAmelCase					      =  top_db
   UpperCAmelCase					      =  truncation
   UpperCAmelCase					      =  padding
   UpperCAmelCase					      =  fft_window_size
   UpperCAmelCase					      =  (fft_window_size >> 1) + 1
   UpperCAmelCase					      =  hop_length
   UpperCAmelCase					      =  max_length_s
   UpperCAmelCase					      =  max_length_s * sampling_rate
   UpperCAmelCase					      =  sampling_rate
   UpperCAmelCase					      =  frequency_min
   UpperCAmelCase					      =  frequency_max
   UpperCAmelCase					      =  mel_filter_bank(
       num_frequency_bins=self.nb_frequency_bins			,						num_mel_filters=__a			,						min_frequency=__a			,						max_frequency=__a			,						sampling_rate=__a			,						norm=__a			,						mel_scale="htk"			,						)
   UpperCAmelCase					      =  mel_filter_bank(
       num_frequency_bins=self.nb_frequency_bins			,						num_mel_filters=__a			,						min_frequency=__a			,						max_frequency=__a			,						sampling_rate=__a			,						norm="slaney"			,						mel_scale="slaney"			,						)


 def _UpperCamelCase	(						self		: Any    )    ->      Dict[str, Any]:
   UpperCAmelCase					      =  copy.deepcopy(self.__dict__    )
   UpperCAmelCase					      =  self.__class__.__name__
   if "mel_filters" in output:
     del output["mel_filters"]
   if "mel_filters_slaney" in output:
     del output["mel_filters_slaney"]
   return output


 def _UpperCamelCase	(						self		: Any			,						lowerCAmelCase__		: np.array			,						lowerCAmelCase__		: Optional[np.array] = None    )    ->      np.ndarray:
   UpperCAmelCase					      =  spectrogram(
       __a			,						window_function(self.fft_window_size			,						"hann"    )			,						frame_length=self.fft_window_size			,						hop_length=self.hop_length			,						power=2.0			,						mel_filters=__a			,						log_mel="dB"			,						)
   return log_mel_spectrogram.T


 def _UpperCamelCase	(						self		: Union[str, Any]			,						lowerCAmelCase__		: Union[str, Any]			,						lowerCAmelCase__		: Optional[Any]			,						lowerCAmelCase__		: Any    )    ->      Optional[int]:
   UpperCAmelCase					      =  np.array_split(list(range(0			,						total_frames - chunk_frames + 1    )    )			,						3    )
   if len(ranges[1]    ) == 0:
     # if the audio is too short, we just use the first chunk
     UpperCAmelCase					      =  [0]
   if len(ranges[2]    ) == 0:
     # if the audio is too short, we just use the first chunk
     UpperCAmelCase					      =  [0]
   # randomly choose index for each part
   UpperCAmelCase					      =  np.random.choice(ranges[0]    )
   UpperCAmelCase					      =  np.random.choice(ranges[1]    )
   UpperCAmelCase					      =  np.random.choice(ranges[2]    )

   UpperCAmelCase					      =  mel[idx_front : idx_front + chunk_frames, :]
   UpperCAmelCase					      =  mel[idx_middle : idx_middle + chunk_frames, :]
   UpperCAmelCase					      =  mel[idx_back : idx_back + chunk_frames, :]

   UpperCAmelCase					      =  torch.tensor(mel[None, None, :]    )
   UpperCAmelCase					      =  torch.nn.functional.interpolate(
       __a			,						size=[chunk_frames, 6_4]			,						mode="bilinear"			,						align_corners=__a    )
   UpperCAmelCase					      =  mel_shrink[0][0].numpy()
   UpperCAmelCase					      =  np.stack([mel_shrink, mel_chunk_front, mel_chunk_middle, mel_chunk_back]			,						axis=0    )
   return mel_fusion


 def _UpperCamelCase	(						self		: Union[str, Any]			,						lowerCAmelCase__		: np.array			,						lowerCAmelCase__		: List[Any]			,						lowerCAmelCase__		: str			,						lowerCAmelCase__		: List[Any]    )    ->      np.array:
   if waveform.shape[0] > max_length:
     if truncation == "rand_trunc":
       UpperCAmelCase					      =  True
       # random crop to max_length (for compatibility) -> this should be handled by self.pad
       UpperCAmelCase					      =  len(__a    ) - max_length
       UpperCAmelCase					      =  np.random.randint(0			,						overflow + 1    )
       UpperCAmelCase					      =  waveform[idx : idx + max_length]
       UpperCAmelCase					      =  self._np_extract_fbank_features(__a			,						self.mel_filters_slaney    )[None, :]
     elif truncation == "fusion":
       UpperCAmelCase					      =  self._np_extract_fbank_features(__a			,						self.mel_filters    )
       UpperCAmelCase					      =  max_length // self.hop_length + 1  # the +1 related to how the spectrogram is computed
       UpperCAmelCase					      =  mel.shape[0]
       if chunk_frames == total_frames:
         # there is a corner case where the audio length is larger than max_length but smaller than max_length+hop_length.
         # In this case, we just use the whole audio.
         UpperCAmelCase					      =  np.stack([mel, mel, mel, mel]			,						axis=0    )
         UpperCAmelCase					      =  False
       else:
         UpperCAmelCase					      =  self._random_mel_fusion(__a			,						__a			,						__a    )
         UpperCAmelCase					      =  True
     else:
       raise NotImplementedError(f"data_truncating {truncation} not implemented"    )

   else:
     UpperCAmelCase					      =  False
     # only use repeat as a new possible value for padding. you repeat the audio before applying the usual max_length padding
     if waveform.shape[0] < max_length:
       if padding == "repeat":
         UpperCAmelCase					      =  int(max_length / len(__a    )    )
         UpperCAmelCase					      =  np.stack(np.tile(__a			,						n_repeat + 1    )    )[:max_length]
       if padding == "repeatpad":
         UpperCAmelCase					      =  int(max_length / len(__a    )    )
         UpperCAmelCase					      =  np.stack(np.tile(__a			,						__a    )    )
       UpperCAmelCase					      =  np.pad(__a			,						(0, max_length - waveform.shape[0])			,						mode="constant"			,						constant_values=0    )

     if truncation == "fusion":
       UpperCAmelCase					      =  self._np_extract_fbank_features(__a			,						self.mel_filters    )
       UpperCAmelCase					      =  np.stack([input_mel, input_mel, input_mel, input_mel]			,						axis=0    )
     else:
       UpperCAmelCase					      =  self._np_extract_fbank_features(__a			,						self.mel_filters_slaney    )[None, :]

   return input_mel, longer


 def __call__(						self		: List[Any]			,						lowerCAmelCase__		: Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]]			,						lowerCAmelCase__		: str = None			,						lowerCAmelCase__		: Optional[str] = None			,						lowerCAmelCase__		: Optional[int] = None			,						lowerCAmelCase__		: Optional[int] = None			,						lowerCAmelCase__		: Optional[Union[str, TensorType]] = None			,						**lowerCAmelCase__		: str			,						)    ->      BatchFeature:
   UpperCAmelCase					      =  truncation if truncation is not None else self.truncation
   UpperCAmelCase					      =  padding if padding else self.padding

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

   UpperCAmelCase					      =  isinstance(__a			,						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}"    )
   UpperCAmelCase					      =  is_batched_numpy or (
       isinstance(__a			,						(list, tuple)    ) and (isinstance(raw_speech[0]			,						(np.ndarray, tuple, list)    ))
   )

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

   # always return batch
   if not is_batched:
     UpperCAmelCase					      =  [np.asarray(__a    )]

   # convert to mel spectrogram, truncate and pad if needed.
   UpperCAmelCase					      =  [
       self._get_input_mel(__a			,						max_length if max_length else self.nb_max_samples			,						__a			,						__a    )
       for waveform in raw_speech
   ]

   UpperCAmelCase					      =  []
   UpperCAmelCase					      =  []
   for mel, longer in padded_inputs:
     input_mel.append(__a    )
     is_longer.append(__a    )

   if truncation == "fusion" and sum(__a    ) == 0:
     # if no audio is longer than 10s, then randomly select one audio to be longer
     UpperCAmelCase					      =  np.random.randint(0			,						len(__a    )    )
     UpperCAmelCase					      =  True

   if isinstance(input_mel[0]			,						__a    ):
     UpperCAmelCase					      =  [np.asarray(__a			,						dtype=np.floataa    ) for feature in input_mel]

   # is_longer is a list of bool
   UpperCAmelCase					      =  [[longer] for longer in is_longer]

   UpperCAmelCase					      =  {"""input_features""": input_mel, """is_longer""": is_longer}
   UpperCAmelCase					      =  BatchFeature(__a    )

   if return_tensors is not None:
     UpperCAmelCase					      =  input_features.convert_to_tensors(__a    )

   return input_features






lowerCAmelCase__       = "\n# Transformers 설치 방법\n! pip install transformers datasets\n# 마지막 릴리스 대신 소스에서 설치하려면, 위 명령을 주석으로 바꾸고 아래 명령을 해제하세요.\n# ! pip install git+https://github.com/huggingface/transformers.git\n"

lowerCAmelCase__       = [{"type": "code", "content": INSTALL_CONTENT}]
lowerCAmelCase__       = {
    "{processor_class}": "FakeProcessorClass",
    "{model_class}": "FakeModelClass",
    "{object_class}": "FakeObjectClass",
}



