codingutf8 2023 the huggingface inc team licensed under the apache license version 2 0 the license you may not use this file except in compliance with the license you may obtain a copy of the license at http www apache orglicenseslicense2 0 unless required by applicable law or agreed to in writing software distributed under the license is distributed on an as is basis without warranties or conditions of any kind either express or implied see the license for the specific language governing permissions and limitations under the license textaudio processor class for musicgen featureextractorclass encodecfeatureextractor tokenizerclass t5tokenizer t5tokenizerfast def initself featureextractor tokenizer super initfeatureextractor tokenizer self currentprocessor self featureextractor self intargetcontextmanager false def getdecoderpromptidsself tasknone languagenone notimestampstrue return self tokenizer getdecoderpromptidstasktask languagelanguage notimestampsnotimestamps def callself args kwargs for backward compatibility if self intargetcontextmanager return self currentprocessorargs kwargs audio kwargs popaudio none samplingrate kwargs popsamplingrate none text kwargs poptext none if lenargs 0 audio args0 args args1 if audio is none and text is none raise valueerroryou need to specify either an audio or text input to process if text is not none inputs self tokenizertext kwargs if audio is not none audioinputs self featureextractoraudio args samplingratesamplingrate kwargs if audio is none return inputs elif text is none return audioinputs else inputsinputvalues audioinputsinputvalues if paddingmask in audioinputs inputspaddingmask audioinputspaddingmask return inputs def batchdecodeself args kwargs audiovalues kwargs popaudio none paddingmask kwargs poppaddingmask none if lenargs 0 audiovalues args0 args args1 if audiovalues is not none return self decodeaudioaudiovalues paddingmaskpaddingmask else return self tokenizer batchdecodeargs kwargs def decodeself args kwargs return self tokenizer decodeargs kwargs def decodeaudioself audiovalues paddingmask optional none listnp ndarray audiovalues tonumpyaudiovalues bsz channels seqlen audiovalues shape if paddingmask is none return listaudiovalues paddingmask tonumpypaddingmask match the sequence length of the padding mask to the generated audio arrays by padding with the nonpadding token so that the generated audio values are not treated as padded tokens difference seqlen paddingmask shape1 paddingvalue 1 self featureextractor paddingvalue paddingmask np padpaddingmask 0 0 0 difference constant constantvaluespaddingvalue audiovalues audiovalues tolist for i in rangebsz slicedaudio np asarrayaudiovaluesi paddingmaskinone self featureextractor paddingvalue audiovaluesi slicedaudio reshapechannels 1 return audiovalues coding utf 8 2023 the huggingface inc team licensed under the apache license version 2 0 the license you may not use this file except in compliance with the license you may obtain a copy of the license at http www apache org licenses license 2 0 unless required by applicable law or agreed to in writing software distributed under the license is distributed on an as is basis without warranties or conditions of any kind either express or implied see the license for the specific language governing permissions and limitations under the license text audio processor class for musicgen constructs a musicgen processor which wraps an encodec feature extractor and a t5 tokenizer into a single processor class musicgenprocessor offers all the functionalities of encodecfeatureextractor and ttokenizer see musicgenprocessor __call__ and musicgenprocessor decode for more information args feature_extractor encodecfeatureextractor an instance of encodecfeatureextractor the feature extractor is a required input tokenizer t5tokenizer an instance of t5tokenizer the tokenizer is a required input forwards the audio argument to encodecfeatureextractor s encodecfeatureextractor __call__ and the text argument to t5tokenizer __call__ please refer to the doctsring of the above two methods for more information for backward compatibility this method is used to decode either batches of audio outputs from the musicgen model or batches of token ids from the tokenizer in the case of decoding token ids this method forwards all its arguments to t5tokenizer s pretrainedtokenizer batch_decode please refer to the docstring of this method for more information this method forwards all its arguments to t5tokenizer s pretrainedtokenizer decode please refer to the docstring of this method for more information this method strips any padding from the audio values to return a list of numpy audio arrays match the sequence length of the padding mask to the generated audio arrays by padding with the non padding token so that the generated audio values are not treated as padded tokens
from typing import List, Optional

import numpy as np

from ...processing_utils import ProcessorMixin
from ...utils import to_numpy


class MusicgenProcessor(ProcessorMixin):
    r

    feature_extractor_class = "EncodecFeatureExtractor"
    tokenizer_class = ("T5Tokenizer", "T5TokenizerFast")

    def __init__(self, feature_extractor, tokenizer):
        super().__init__(feature_extractor, tokenizer)
        self.current_processor = self.feature_extractor
        self._in_target_context_manager = False

    def get_decoder_prompt_ids(self, task=None, language=None, no_timestamps=True):
        return self.tokenizer.get_decoder_prompt_ids(task=task, language=language, no_timestamps=no_timestamps)

    def __call__(self, *args, **kwargs):
        
        
        if self._in_target_context_manager:
            return self.current_processor(*args, **kwargs)

        audio = kwargs.pop("audio", None)
        sampling_rate = kwargs.pop("sampling_rate", None)
        text = kwargs.pop("text", None)
        if len(args) > 0:
            audio = args[0]
            args = args[1:]

        if audio is None and text is None:
            raise ValueError("You need to specify either an `audio` or `text` input to process.")

        if text is not None:
            inputs = self.tokenizer(text, **kwargs)

        if audio is not None:
            audio_inputs = self.feature_extractor(audio, *args, sampling_rate=sampling_rate, **kwargs)

        if audio is None:
            return inputs

        elif text is None:
            return audio_inputs

        else:
            inputs["input_values"] = audio_inputs["input_values"]
            if "padding_mask" in audio_inputs:
                inputs["padding_mask"] = audio_inputs["padding_mask"]
            return inputs

    def batch_decode(self, *args, **kwargs):
        
        audio_values = kwargs.pop("audio", None)
        padding_mask = kwargs.pop("padding_mask", None)

        if len(args) > 0:
            audio_values = args[0]
            args = args[1:]

        if audio_values is not None:
            return self._decode_audio(audio_values, padding_mask=padding_mask)
        else:
            return self.tokenizer.batch_decode(*args, **kwargs)

    def decode(self, *args, **kwargs):
        
        return self.tokenizer.decode(*args, **kwargs)

    def _decode_audio(self, audio_values, padding_mask: Optional = None) -> List[np.ndarray]:
        
        audio_values = to_numpy(audio_values)
        bsz, channels, seq_len = audio_values.shape

        if padding_mask is None:
            return list(audio_values)

        padding_mask = to_numpy(padding_mask)

        
        
        difference = seq_len - padding_mask.shape[-1]
        padding_value = 1 - self.feature_extractor.padding_value
        padding_mask = np.pad(padding_mask, ((0, 0), (0, difference)), "constant", constant_values=padding_value)

        audio_values = audio_values.tolist()
        for i in range(bsz):
            sliced_audio = np.asarray(audio_values[i])[
                padding_mask[i][None, :] != self.feature_extractor.padding_value
            ]
            audio_values[i] = sliced_audio.reshape(channels, -1)

        return audio_values