在保留IEEE 754表示的同时将Float32Array转换为Uint8Array

时间:2018-03-18 14:05:02

标签: javascript ieee-754 typed-arrays

我有来自decodeAudioData方法的float32Array,我希望将其转换为Uint8Array,而保留float32 IEEE 754音频数据

到目前为止,我试过了,

var length = float32Array.length;

var emptyBuffer = new ArrayBuffer(length * 4);
var view = new DataView(emptyBuffer);

for (var i = 0; i < length; i++) {
  view.setFloat32(i * 4, float32Array[i], true);
}

var outputArray = new Uint8Array(length);

for (var j = 0; j < length; j++) {
  outputArray[j] = view.getUint8(j * 4);
}

return outputArray;

修改

我只需要保持二进制表示,就像在这个answer.

中一样

2 个答案:

答案 0 :(得分:1)

你不清楚你在问什么;或者更确切地说,出现你所问的是一件毫无意义的事情。

Float32Array实例是&#34; raw&#34;的缓冲区视图。字节值,与所有类型的数组一样。数组的每个元素代表其中4个原始字节。通过简单的数组查找提取值:

var n = float32array[1];

隐式将这4个字节解释为IEEE 32位浮点值,然后将该值转换为标准JavaScript编号。 JavaScript编号始终是64位IEEE浮点值。

类似地,Uint8Array是缓冲区的视图,每个元素给出一个字节的无符号整数值。也就是说,

var n = uint8array[1];

访问该元素,将其解释为无符号的单字节整数,并将其转换为JavaScript编号。

所以:如果你想检查一个32位浮点值列表作为每个字节的原始整数值,你可以创建一个Uint8Array&#34; share&#34;与Float32Array

相同的缓冲区
var uintShared = new Uint8Array(float32array.buffer);

您在查看Uint8Array值时看到的数字值似乎与查看Float32Array元素所获得的数字值无关可以预料。

另一方面,如果你想创建一个新的Uint8Array来保存Float32Array中明显的,你可以创建一个新的同一个数组长度并复制每个值:

var uintCopy = new Uint8Array(float32array.length);
for (let i = 0; i < float32array.length; ++i)
  uintCopy[i] = float32array[i]; // deeply problematic; see below

现在,一般来说,这不会太好,因为Float32Array中的数值范围远远大于Uint8Array中值的数值范围。首先,32位浮点值可以是负数。更重要的是,即使你知道浮点值都是0到255范围内的整数,你肯定不会在Uint8Array得到相同的位模式,原因很简单,就是32位浮点数与8位无符号整数不同。要保留IEEE-754表示&#34;毫无意义。

这就是现实情况。如果你要解释为什么你认为你想以某种方式将32位IEEE浮点的所有32位塞进一个8位无符号整数,那么就有可能提供一个更直接有用的答案。

答案 1 :(得分:0)

var output = new Uint8Array(float32Array.length);

for (var i = 0; i < float32Array.length; i++) {
  var tmp = Math.max(-1, Math.min(1, float32Array[i]));
  tmp = tmp < 0 ? (tmp * 0x8000) : (tmp * 0x7FFF);
  tmp = tmp / 256;
  output[i] = tmp + 128;
}

return output;

任何有疑问的人都可以使用Audacity导入原始数据功能轻松测试。

  1. 使用Web Audio Api的decodeAudioData方法下载我从视频文件中解码的sample raw data
  2. 使用上面的方法将示例原始数据填充的Float32Array转换为Uint8Array(或使用您自己的方法,例如new Uint8Array(float32Array.buffer)来听到损坏的嘶嘶声)和下载uint8 pcm文件。

    forceDownload(new Blob([output], { type: 'application/octet-binary' }));

  3. 使用文件 - &gt;在Audacity中对下载的数据进行编码导入 - &gt;原始数据...... 编码应设置为无符号8位PCM ,采样率应为16000 Hz,因为原始解码音频文件的频率为16000 Hz。