/**
 * 浏览器音频工具 — 麦克风 Float32 → 16kHz PCM16 → base64。
 * 浏览器无 Buffer,base64 用 btoa 分块(避免大数组 String.fromCharCode 栈溢出)。
 */

/** 线性降采样到 16kHz(麦克风通常 44.1k/48k) */
export function downsampleTo16k(input: Float32Array, fromRate: number): Float32Array {
  const toRate = 16000;
  if (fromRate === toRate) return input;
  const ratio = fromRate / toRate;
  const outLen = Math.floor(input.length / ratio);
  const out = new Float32Array(outLen);
  for (let i = 0; i < outLen; i++) {
    const idx = i * ratio;
    const lo = Math.floor(idx);
    const hi = Math.min(lo + 1, input.length - 1);
    const frac = idx - lo;
    out[i] = input[lo]! * (1 - frac) + input[hi]! * frac;
  }
  return out;
}

/** Float32 [-1,1] → Int16 LE bytes */
export function floatToPcm16(input: Float32Array): Uint8Array {
  const out = new DataView(new ArrayBuffer(input.length * 2));
  for (let i = 0; i < input.length; i++) {
    const s = Math.max(-1, Math.min(1, input[i]!));
    out.setInt16(i * 2, s < 0 ? s * 0x8000 : s * 0x7fff, true);
  }
  return new Uint8Array(out.buffer);
}

/** Uint8 → base64(分块,避免栈溢出) */
export function bytesToBase64(bytes: Uint8Array): string {
  let binary = '';
  const chunk = 0x8000;
  for (let i = 0; i < bytes.length; i += chunk) {
    binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
  }
  return btoa(binary);
}
