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


SCREAMING_SNAKE_CASE_:     Any  =logging.get_logger(__name__)




class        __A      ( UpperCAmelCase__	):
    a__       :						Optional[int]          =  ["""input_features""", """is_longer"""]



    def __init__(self    :    int   ,			__a    :    Tuple=64   ,			__a    :    str=48000   ,			__a    :    Tuple=480   ,			__a    :    List[Any]=10   ,			__a    :    Optional[int]=1024   ,			__a    :    Union[str, Any]=0.0   ,			__a    :    Tuple=False   ,			__a    :    Tuple = 0   ,			__a    :    Dict = 14000   ,			__a    :    str = None   ,			__a    :    List[str] = "fusion"   ,			__a    :    int = "repeatpad"   ,			**__a    :    Union[str, Any]   ,			):
         super().__init__(
             feature_size=__lowercase   ,			sampling_rate=__lowercase   ,			padding_value=__lowercase   ,			return_attention_mask=__lowercase   ,			**__lowercase   ,			)
         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=__lowercase   ,			min_frequency=__lowercase   ,			max_frequency=__lowercase   ,			sampling_rate=__lowercase   ,			norm=__lowercase   ,			mel_scale="htk"   ,			)
         UpperCAmelCase_           =   mel_filter_bank(
             num_frequency_bins=self.nb_frequency_bins   ,			num_mel_filters=__lowercase   ,			min_frequency=__lowercase   ,			max_frequency=__lowercase   ,			sampling_rate=__lowercase   ,			norm="slaney"   ,			mel_scale="slaney"   ,			)



    def 					_lowercase						(self    :    Tuple ):
         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 					_lowercase						(self    :    Tuple   ,			__a    :    Dict   ,			__a    :    List[str] = None ):
         UpperCAmelCase_           =   spectrogram(
             __lowercase   ,			window_function(self.fft_window_size   ,			"hann" )   ,			frame_length=self.fft_window_size   ,			hop_length=self.hop_length   ,			power=2.0   ,			mel_filters=__lowercase   ,			log_mel="dB"   ,			)
         return log_mel_spectrogram.T



    def 					_lowercase						(self    :    Tuple   ,			__a    :    List[str]   ,			__a    :    Optional[Any]   ,			__a    :    Optional[Any] ):
         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(
             __lowercase   ,			size=[chunk_frames, 64]   ,			mode="bilinear"   ,			align_corners=__lowercase )
         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 					_lowercase						(self    :    int   ,			__a    :    str   ,			__a    :    Union[str, Any]   ,			__a    :    Any   ,			__a    :    Union[str, Any] ):
         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(__lowercase ) - max_length
                   UpperCAmelCase_           =   np.random.randint(0   ,			overflow + 1 )
                   UpperCAmelCase_           =   waveform[idx : idx + max_length]
                   UpperCAmelCase_           =   self._np_extract_fbank_features(__lowercase   ,			self.mel_filters_slaney )[None, :]
              elif truncation == "fusion":
                   UpperCAmelCase_           =   self._np_extract_fbank_features(__lowercase   ,			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(__lowercase   ,			__lowercase   ,			__lowercase )
                        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(__lowercase ) )
                        UpperCAmelCase_           =   np.stack(np.tile(__lowercase   ,			n_repeat + 1 ) )[:max_length]
                   if padding == "repeatpad":
                        UpperCAmelCase_           =   int(max_length / len(__lowercase ) )
                        UpperCAmelCase_           =   np.stack(np.tile(__lowercase   ,			__lowercase ) )
                   UpperCAmelCase_           =   np.pad(__lowercase   ,			(0, max_length - waveform.shape[0])   ,			mode="constant"   ,			constant_values=0 )

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

         return input_mel, longer






    def __call__(self    :    Tuple   ,			__a    :    List[str]   ,			__a    :    int = None   ,			__a    :    Tuple = None   ,			__a    :    Dict = None   ,			__a    :    Optional[Any] = None   ,			__a    :    List[str] = None   ,			**__a    :    Dict   ,			):
         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(__lowercase   ,			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(__lowercase   ,			(list, tuple) ) and (isinstance(raw_speech[0]   ,			(np.ndarray, tuple, list) ))
         )

         if is_batched:
              UpperCAmelCase_           =   [np.asarray(__lowercase   ,			dtype=np.floataa ) for speech in raw_speech]
         elif not is_batched and not isinstance(__lowercase   ,			np.ndarray ):
              UpperCAmelCase_           =   np.asarray(__lowercase   ,			dtype=np.floataa )
         elif isinstance(__lowercase   ,			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(__lowercase )]

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

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

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

         if isinstance(input_mel[0]   ,			__lowercase ):
              UpperCAmelCase_           =   [np.asarray(__lowercase   ,			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(__lowercase )

         if return_tensors is not None:
              UpperCAmelCase_           =   input_features.convert_to_tensors(__lowercase )

         return input_features








import inspect
import unittest







class  snake_case__(							unittest.TestCase							):







						'''simple docstring'''




						def   lowercase_       ( self							)    ->			int:
										try:
														import diffusers  # noqa: F401
										except ImportError:
														assert False




						def   lowercase_       ( self							)    ->			List[str]:
										import diffusers
										from diffusers.dependency_versions_table import deps

										lowerCAmelCase_       :					Any			 = inspect.getmembers(__lowercase      ,  inspect.isclass							)

										for cls_name, cls_module in all_classes:
														if "dummy_" in cls_module.__module__:
																		for backend in cls_module._backends:
																						if backend == "k_diffusion":
																										lowerCAmelCase_       :					Optional[int]			 = '''k-diffusion'''
																						elif backend == "invisible_watermark":
																										lowerCAmelCase_       :					Dict			 = '''invisible-watermark'''
																						assert backend in deps, f"""{backend} is not in the deps table!"""