'''
    #################################################################################################################################################################################################
    # This code library is an adaptation of the original Transformers and was designed, developed and programmed by Sapiens Technology®.                                                            #
    # Any alteration and/or disclosure of this code without prior authorization is strictly prohibited and is subject to legal action that will be forwarded by the Sapiens Technology® legal team. #
    # This set of algorithms aims to download, train, fine-tune and/or infer large language models from various sources and slopes.                                                                 #
    #################################################################################################################################################################################################
'''
import numpy as np
from ....configuration_utils import ConfigMixin, register_to_config
from ....schedulers.scheduling_utils import SchedulerMixin
try:
    import librosa
    _librosa_can_be_imported = True
    _import_error = ''
except Exception as e:
    _librosa_can_be_imported = False
    _import_error = f'Cannot import librosa because {e}. Make sure to correctly install librosa to be able to install it.'
from PIL import Image
class Mel(ConfigMixin, SchedulerMixin):
    config_name = 'mel_config.json'
    @register_to_config
    def __init__(self, x_res: int=256, y_res: int=256, sample_rate: int=22050, n_fft: int=2048, hop_length: int=512, top_db: int=80, n_iter: int=32):
        self.hop_length = hop_length
        self.sr = sample_rate
        self.n_fft = n_fft
        self.top_db = top_db
        self.n_iter = n_iter
        self.set_resolution(x_res, y_res)
        self.audio = None
        if not _librosa_can_be_imported: raise ValueError(_import_error)
    def set_resolution(self, x_res: int, y_res: int):
        """Args:"""
        self.x_res = x_res
        self.y_res = y_res
        self.n_mels = self.y_res
        self.slice_size = self.x_res * self.hop_length - 1
    def load_audio(self, audio_file: str=None, raw_audio: np.ndarray=None):
        """Args:"""
        if audio_file is not None: self.audio, _ = librosa.load(audio_file, mono=True, sr=self.sr)
        else: self.audio = raw_audio
        if len(self.audio) < self.x_res * self.hop_length: self.audio = np.concatenate([self.audio, np.zeros((self.x_res * self.hop_length - len(self.audio),))])
    def get_number_of_slices(self) -> int:
        """Returns:"""
        return len(self.audio) // self.slice_size
    def get_audio_slice(self, slice: int=0) -> np.ndarray:
        """Returns:"""
        return self.audio[self.slice_size * slice:self.slice_size * (slice + 1)]
    def get_sample_rate(self) -> int:
        """Returns:"""
        return self.sr
    def audio_slice_to_image(self, slice: int) -> Image.Image:
        """Returns:"""
        S = librosa.feature.melspectrogram(y=self.get_audio_slice(slice), sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels)
        log_S = librosa.power_to_db(S, ref=np.max, top_db=self.top_db)
        bytedata = (((log_S + self.top_db) * 255 / self.top_db).clip(0, 255) + 0.5).astype(np.uint8)
        image = Image.fromarray(bytedata)
        return image
    def image_to_audio(self, image: Image.Image) -> np.ndarray:
        """Returns:"""
        bytedata = np.frombuffer(image.tobytes(), dtype='uint8').reshape((image.height, image.width))
        log_S = bytedata.astype('float') * self.top_db / 255 - self.top_db
        S = librosa.db_to_power(log_S)
        audio = librosa.feature.inverse.mel_to_audio(S, sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_iter=self.n_iter)
        return audio
'''
    #################################################################################################################################################################################################
    # This code library is an adaptation of the original Transformers and was designed, developed and programmed by Sapiens Technology®.                                                            #
    # Any alteration and/or disclosure of this code without prior authorization is strictly prohibited and is subject to legal action that will be forwarded by the Sapiens Technology® legal team. #
    # This set of algorithms aims to download, train, fine-tune and/or infer large language models from various sources and slopes.                                                                 #
    #################################################################################################################################################################################################
'''
