Team Ai
Apppublic

anmol-unitmole/streaming-speech-recognition-whisper-encoder-decoder

sourceHugging Facemitupdated 2mo agoView on Hugging Face
0likes
audio_preprocessing.js51 linesDownload Raw Back to root
1export const TARGET_SAMPLE_RATE = 16000;2 3export async function decodeAudioBlob(blob) {4  if (!(blob instanceof Blob)) throw new TypeError('Expected an audio Blob.');5  const AudioContextClass = window.AudioContext || window.webkitAudioContext;6  if (!AudioContextClass) throw new Error('Web Audio API is not supported in this browser.');7  const context = new AudioContextClass();8  try {9    const buffer = await context.decodeAudioData(await blob.arrayBuffer());10    const mono = mixToMono(buffer);11    const samples = resampleLinear(mono, buffer.sampleRate, TARGET_SAMPLE_RATE);12    return { samples, samplingRate: TARGET_SAMPLE_RATE, duration: samples.length / TARGET_SAMPLE_RATE, originalSamplingRate: buffer.sampleRate, channels: buffer.numberOfChannels };13  } catch (error) {14    throw new Error(`The browser could not decode this audio file: ${error.message}`);15  } finally {16    await context.close();17  }18}19 20export function mixToMono(audioBuffer) {21  const output = new Float32Array(audioBuffer.length);22  for (let channel = 0; channel < audioBuffer.numberOfChannels; channel += 1) {23    const data = audioBuffer.getChannelData(channel);24    for (let i = 0; i < data.length; i += 1) output[i] += data[i] / audioBuffer.numberOfChannels;25  }26  return output;27}28 29export function resampleLinear(samples, sourceRate, targetRate = TARGET_SAMPLE_RATE) {30  if (sourceRate === targetRate) return new Float32Array(samples);31  if (sourceRate <= 0 || targetRate <= 0) throw new Error('Sampling rates must be positive.');32  const ratio = sourceRate / targetRate;33  const length = Math.max(1, Math.round(samples.length / ratio));34  const output = new Float32Array(length);35  for (let i = 0; i < length; i += 1) {36    const position = i * ratio;37    const left = Math.floor(position);38    const right = Math.min(left + 1, samples.length - 1);39    const weight = position - left;40    output[i] = samples[left] * (1 - weight) + samples[right] * weight;41  }42  return output;43}44 45export function formatDuration(seconds) {46  const safe = Math.max(0, Number(seconds) || 0);47  const minutes = Math.floor(safe / 60);48  const remainder = Math.floor(safe % 60);49  return `${String(minutes).padStart(2, '0')}:${String(remainder).padStart(2, '0')}`;50}51