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

问题描述 投票:0回答:1

我有一个来自AudioContext的AudioBuffer,我从AudioBuffer.getChannelData得到Float32Array,它的范围是-1到1,我不知道如何将数据转换成Uint8Array,然后我可以将它编码成base64字符串。

  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)
  recorderScriptNode.onaudioprocess = function (audioProcessingEvent) {
    // Float32Array  -1.0 to 1.0 
    const float32Array = audioProcessingEvent.inputBuffer.getChannelData(0)
    // convert here ...
  }

期待转换代码片段

javascript pcm uint8array audiobuffer
1个回答
0
投票

要将 Float32Array 数据(范围为 -1.0 到 1.0)转换为 Uint8Array,然后将其编码为 Base64 字符串,需要按照以下步骤操作:

  1. 标准化和缩放:Float32Array 值范围从 -1.0 到 1.0。您需要将这些值标准化为 16 位整数的范围(这就是 sampleBit = 16 所建议的)。这是因为 Uint8Array 不直接支持 16 位值。 16 位整数的范围是 -32768 到 32767。
  2. 转换为 Int16Array:缩放后,将这些值转换为 Int16Array。这是转换为 Uint8Array 之前的中间步骤。
  3. 转换为 Uint8Array:由于每个 Int16 值都是 2 个字节,因此需要将每个 16 位整数拆分为两个 8 位整数,将它们存储在 Uint8Array 中。
  4. Base64编码:最后,将Uint8Array转换为base64字符串。

这是演示这些步骤的代码片段:

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);
recorderScriptNode.onaudioprocess = function (audioProcessingEvent) {
  // Get the Float32Array
  const float32Array = audioProcessingEvent.inputBuffer.getChannelData(0);

  // Convert Float32Array to Int16Array
  const int16Array = new Int16Array(float32Array.length);
  for (let i = 0; i < float32Array.length; i++) {
    int16Array[i] = float32Array[i] < 0 ? float32Array[i] * 32768 : float32Array[i] * 32767;
  }

  // Convert Int16Array to Uint8Array
  const uint8Array = new Uint8Array(int16Array.length * 2);
  int16Array.forEach((value, index) => {
    uint8Array[index * 2] = value & 0xff;
    uint8Array[index * 2 + 1] = (value >> 8) & 0xff;
  });

  // Encode to Base64
  const base64String = btoa(String.fromCharCode.apply(null, uint8Array));

  // Convert here ...
  console.log(base64String);
};
© www.soinside.com 2019 - 2024. All rights reserved.