You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Float32Array格式的PCM数据转换为Uint8Array?

Float32Array 转 Uint8Array 实现方案

转换逻辑

AudioContext 获取的 Float32Array 采样值范围是 [-1.0, 1.0],而 Uint8Array 是无符号8位整数(范围 [0, 255]),通过以下公式完成映射:
uint8值 = Math.round(浮点值 * 127.5 + 127.5)
同时加入边界限制,避免采样值因处理误差超出范围导致转换结果溢出。

完整代码实现

const sampleRate = 16000
const sampleBit = 16
const context = new AudioContext({
  sampleRate: sampleRate
})
const audioSliceMs = 160
let streamEnd = false
const audioSliceByte = sampleRate * sampleBit / 8 / 1000 * audioSliceMs
const recorderScriptNode = context.createScriptProcessor(1024, 1, 1);
let bufferOffset = 0
let bufferFloat32Array = new Float32Array(audioSliceByte)
// 新增:存储转换后的Uint8格式音频数据
let bufferUint8Array = new Uint8Array(audioSliceByte)

// Float32转Uint8的工具函数
function float32ToUint8(floatArray) {
  const uint8Array = new Uint8Array(floatArray.length);
  for (let i = 0; i < floatArray.length; i++) {
    // 限制浮点值在[-1,1]区间,避免溢出
    const clampedValue = Math.max(-1, Math.min(1, floatArray[i]));
    // 映射到Uint8的0-255范围并取整
    uint8Array[i] = Math.round(clampedValue * 127.5 + 127.5);
  }
  return uint8Array;
}

recorderScriptNode.onaudioprocess = function (audioProcessingEvent) {
  // 获取输入的Float32格式音频数据
  const float32Array = audioProcessingEvent.inputBuffer.getChannelData(0)
  
  // 转换为Uint8Array
  const convertedUint8 = float32ToUint8(float32Array);
  
  // 将转换后的数据写入缓冲区,和原切片逻辑对齐
  const copyLength = Math.min(convertedUint8.length, bufferUint8Array.length - bufferOffset);
  bufferUint8Array.set(convertedUint8.subarray(0, copyLength), bufferOffset);
  bufferOffset += copyLength;
  
  // 缓冲区满或流结束时,转换为base64
  if (bufferOffset >= bufferUint8Array.length || streamEnd) {
    // 截取有效数据段
    const validUint8 = bufferUint8Array.subarray(0, bufferOffset);
    // 转换为base64字符串
    const base64Str = btoa(String.fromCharCode(...validUint8));
    
    // 这里可以添加base64数据的处理逻辑(如发送、存储)
    console.log('生成的base64音频片段:', base64Str);
    
    // 重置缓冲区偏移量
    bufferOffset = 0;
  }
}

关键说明

  • 使用 btoa 完成 Uint8Array 到 base64 的转换,需先通过 String.fromCharCode(...validUint8) 将字节数组转为字符序列
  • 边界限制确保转换后的数值始终在 Uint8 的合法范围内,避免音频失真或编码错误
  • 缓冲区逻辑和原代码的切片时长设置保持一致,确保按指定的 audioSliceMs 分段处理

内容的提问来源于stack exchange,提问作者apm29

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 17:40:20