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 feature extractor class for encodec from typing import list optional union import numpy as np from featureextractionsequenceutils import sequencefeatureextractor from featureextractionutils import batchfeature from utils import paddingstrategy tensortype logging logger logging getloggername class encodecfeatureextractorsequencefeatureextractor r constructs an encodec feature extractor this feature extractor inherits from featureextractionsequenceutils sequencefeatureextractor which contains most of the main methods users should refer to this superclass for more information regarding those methods instantiating a feature extractor with the defaults will yield a similar configuration to that of the facebookencodec24khzhttps huggingface cofacebookencodec24khz architecture args featuresize int optional defaults to 1 the feature dimension of the extracted features use 1 for mono 2 for stereo samplingrate int optional defaults to 24000 the sampling rate at which the audio waveform should be digitalized expressed in hertz hz paddingvalue float optional defaults to 0 0 the value that is used to fill the padding values chunklengths float optional if defined the audio is preprocessed into chunks of lengths chunklengths and then encoded overlap float optional defines the overlap between each chunk it is used to compute the chunkstride using the following formulae int1 0 self overlap self chunklength this is a property because you might want to change the chunklengths on the fly this is a property because you might want to change the chunklengths on the fly main method to featurize and prepare for the model one or several sequences args rawaudio np ndarray listfloat listnp ndarray listlistfloat the sequence or batch of sequences to be processed each sequence can be a numpy array a list of float values a list of numpy arrays or a list of list of float values the numpy array must be of shape numsamples for mono audio featuresize 1 or 2 numsamples for stereo audio featuresize 2 padding bool str or utils paddingstrategy optional defaults to true select a strategy to pad the returned sequences according to the model s padding side and padding index among true or longest pad to the longest sequence in the batch or no padding if only a single sequence if provided maxlength pad to a maximum length specified with the argument maxlength or to the maximum acceptable input length for the model if that argument is not provided false or donotpad default no padding i e can output a batch with sequences of different lengths truncation bool optional defaults to false activates truncation to cut input sequences longer than maxlength to maxlength maxlength int optional maximum length of the returned list and optionally padding length see above returntensors str or utils tensortype optional if set will return tensors instead of list of python integers acceptable values are tf return tensorflow tf constant objects pt return pytorch torch tensor objects np return numpy np ndarray objects samplingrate int optional the sampling rate at which the audio input was sampled it is strongly recommended to pass samplingrate at the forward call to prevent silent errors by default let s pad the inputs always return batch verify inputs are valid normal padding on batch 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 feature extractor class for encodec constructs an encodec feature extractor this feature extractor inherits from feature_extraction_sequence_utils sequencefeatureextractor which contains most of the main methods users should refer to this superclass for more information regarding those methods instantiating a feature extractor with the defaults will yield a similar configuration to that of the facebook encodec_24khz https huggingface co facebook encodec_24khz architecture args feature_size int optional defaults to 1 the feature dimension of the extracted features use 1 for mono 2 for stereo sampling_rate int optional defaults to 24000 the sampling rate at which the audio waveform should be digitalized expressed in hertz hz padding_value float optional defaults to 0 0 the value that is used to fill the padding values chunk_length_s float optional if defined the audio is pre processed into chunks of lengths chunk_length_s and then encoded overlap float optional defines the overlap between each chunk it is used to compute the chunk_stride using the following formulae int 1 0 self overlap self chunk_length this is a property because you might want to change the chunk_length_s on the fly this is a property because you might want to change the chunk_length_s on the fly main method to featurize and prepare for the model one or several sequence s args raw_audio np ndarray list float list np ndarray list list float the sequence or batch of sequences to be processed each sequence can be a numpy array a list of float values a list of numpy arrays or a list of list of float values the numpy array must be of shape num_samples for mono audio feature_size 1 or 2 num_samples for stereo audio feature_size 2 padding bool str or utils paddingstrategy optional defaults to true select a strategy to pad the returned sequences according to the model s padding side and padding index among true or longest pad to the longest sequence in the batch or no padding if only a single sequence if provided max_length pad to a maximum length specified with the argument max_length or to the maximum acceptable input length for the model if that argument is not provided false or do_not_pad default no padding i e can output a batch with sequences of different lengths truncation bool optional defaults to false activates truncation to cut input sequences longer than max_length to max_length max_length int optional maximum length of the returned list and optionally padding length see above return_tensors str or utils tensortype optional if set will return tensors instead of list of python integers acceptable values are tf return tensorflow tf constant objects pt return pytorch torch tensor objects np return numpy np ndarray objects sampling_rate int optional the sampling rate at which the audio input was sampled it is strongly recommended to pass sampling_rate at the forward call to prevent silent errors by default let s pad the inputs always return batch verify inputs are valid normal padding on batch
from typing import List, Optional, Union

import numpy as np

from ...feature_extraction_sequence_utils import SequenceFeatureExtractor
from ...feature_extraction_utils import BatchFeature
from ...utils import PaddingStrategy, TensorType, logging


logger = logging.get_logger(__name__)


class EncodecFeatureExtractor(SequenceFeatureExtractor):
    r

    model_input_names = ["input_values", "padding_mask"]

    def __init__(
        self,
        feature_size: int = 1,
        sampling_rate: int = 24000,
        padding_value: float = 0.0,
        chunk_length_s: float = None,
        overlap: float = None,
        **kwargs,
    ):
        super().__init__(feature_size=feature_size, sampling_rate=sampling_rate, padding_value=padding_value, **kwargs)
        self.chunk_length_s = chunk_length_s
        self.overlap = overlap

    
    @property
    def chunk_length(self) -> Optional[int]:
        if self.chunk_length_s is None:
            return None
        else:
            return int(self.chunk_length_s * self.sampling_rate)

    
    @property
    def chunk_stride(self) -> Optional[int]:
        if self.chunk_length_s is None or self.overlap is None:
            return None
        else:
            return max(1, int((1.0 - self.overlap) * self.chunk_length))

    def __call__(
        self,
        raw_audio: Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]],
        padding: Optional[Union[bool, str, PaddingStrategy]] = None,
        truncation: Optional[bool] = False,
        max_length: Optional[int] = None,
        return_tensors: Optional[Union[str, TensorType]] = None,
        sampling_rate: Optional[int] = None,
    ) -> BatchFeature:
        
        if sampling_rate is not None:
            if sampling_rate != self.sampling_rate:
                raise ValueError(
                    f"The model corresponding to this feature extractor: {self} was trained using a sampling rate of"
                    f" {self.sampling_rate}. Please make sure that the provided audio input was sampled with"
                    f" {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."
            )

        if padding and truncation:
            raise ValueError("Both padding and truncation were set. Make sure you only set one.")
        elif padding is None:
            
            padding = True

        is_batched = bool(
            isinstance(raw_audio, (list, tuple)) and (isinstance(raw_audio[0], (np.ndarray, tuple, list)))
        )

        if is_batched:
            raw_audio = [np.asarray(audio, dtype=np.float32).T for audio in raw_audio]
        elif not is_batched and not isinstance(raw_audio, np.ndarray):
            raw_audio = np.asarray(raw_audio, dtype=np.float32)
        elif isinstance(raw_audio, np.ndarray) and raw_audio.dtype is np.dtype(np.float64):
            raw_audio = raw_audio.astype(np.float32)

        
        if not is_batched:
            raw_audio = [np.asarray(raw_audio).T]

        
        for idx, example in enumerate(raw_audio):
            if example.ndim > 2:
                raise ValueError(f"Expected input shape (channels, length) but got shape {example.shape}")
            if self.feature_size == 1 and example.ndim != 1:
                raise ValueError(f"Expected mono audio but example has {example.shape[-1]} channels")
            if self.feature_size == 2 and example.shape[-1] != 2:
                raise ValueError(f"Expected stereo audio but example has {example.shape[-1]} channels")

        padded_inputs = None
        input_values = BatchFeature({"input_values": raw_audio})
        if self.chunk_stride is not None and self.chunk_length is not None and max_length is None:
            if truncation:
                max_length = min(array.shape[0] for array in raw_audio)
                nb_step = int(np.floor(max_length / self.chunk_stride))
                max_length = (nb_step - 1) * self.chunk_stride + self.chunk_length
            elif padding:
                max_length = max(array.shape[0] for array in raw_audio)
                nb_step = int(np.ceil(max_length / self.chunk_stride))
                max_length = (nb_step - 1) * self.chunk_stride + self.chunk_length
                padding = "max_length"
            else:
                padded_inputs = input_values

        
        if padded_inputs is None:
            padded_inputs = self.pad(
                input_values,
                max_length=max_length,
                truncation=truncation,
                padding=padding,
                return_attention_mask=padding,
            )
            if padding:
                padded_inputs["padding_mask"] = padded_inputs.pop("attention_mask")

        input_values = []
        for example in padded_inputs.pop("input_values"):
            if self.feature_size == 1:
                example = example[..., None]
            input_values.append(example.T)

        padded_inputs["input_values"] = input_values
        if return_tensors is not None:
            padded_inputs = padded_inputs.convert_to_tensors(return_tensors)

        return padded_inputs