UNPKG

@huggingface/transformers

Version:

State-of-the-art Machine Learning for the web. Run 🤗 Transformers directly in your browser, with no need for a server!

72 lines (62 loc) • 2.74 kB
import { FeatureExtractor, validate_audio_inputs } from '../../feature_extraction_utils.js'; import { mel_filter_bank, spectrogram, window_function } from '../../utils/audio.js'; export class VoxtralRealtimeFeatureExtractor extends FeatureExtractor { constructor(config) { super(config); this.config.mel_filters ??= mel_filter_bank( Math.floor(1 + this.config.n_fft / 2), // num_frequency_bins this.config.feature_size, // num_mel_filters 0.0, // min_frequency 8000.0, // max_frequency this.config.sampling_rate, // sampling_rate 'slaney', // norm 'slaney', // mel_scale ); this.window = window_function(this.config.n_fft, 'hann'); } /** * Computes the log-Mel spectrogram of the provided audio waveform. * @param {Float32Array|Float64Array} waveform The audio waveform to process. * @param {Object} [options] * @param {boolean} [options.center=true] Whether to center-pad the waveform for STFT. * @returns {Promise<import('../../utils/tensor.js').Tensor>} The log-Mel spectrogram tensor of shape [num_mel_bins, num_frames]. */ async _extract_fbank_features(waveform, { center = true } = {}) { const { n_fft, hop_length, mel_filters, global_log_mel_max } = this.config; // torch.stft drops the last frame via [:-1] // center=True: floor(signal_len / hop_length) frames // center=False: floor((signal_len - n_fft) / hop_length) frames const max_num_frames = center ? Math.floor(waveform.length / hop_length) : Math.floor((waveform.length - n_fft) / hop_length); return await spectrogram( waveform, this.window, n_fft, // frame_length hop_length, { power: 2.0, mel_filters, log_mel: 'log10_max_norm', max_log_mel: global_log_mel_max, center, max_num_frames, do_pad: false, }, ); } /** * Extract mel spectrogram features from audio. * @param {Float32Array|Float64Array} audio The audio data. * @param {Object} [options] * @param {boolean} [options.center=true] Whether to center-pad the waveform. * @returns {Promise<{ input_features: import('../../utils/tensor.js').Tensor }>} */ async _call(audio, { center = true } = {}) { validate_audio_inputs(audio, 'VoxtralRealtimeFeatureExtractor'); const features = await this._extract_fbank_features(audio, { center }); return { input_features: features.unsqueeze_(0), }; } }