Converting Float32Array to Uint8Array while Preserving IEEE 754 Representation

ⅰ亾dé卋堺 提交于 2019-12-20 06:29:14

问题


I have a float32Array from decodeAudioData method, which I want to convert it to Uint8Array while preserving the float32 IEEE 754 audio data.

So far I tried,

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;

Edit:

I just need to hold on to the binary representation just as in this answer.


回答1:


It's not very clear what you're asking; or, rather, what it appears you're asking is a thing that makes no sense.

A Float32Array instance is a view onto a buffer of "raw" byte values, like all typed arrays. Each element of the array represents 4 of those raw bytes. Extracting a value via a simple array lookup:

var n = float32array[1];

implicitly interprets those 4 bytes as an IEEE 32-bit floating point value, and then that value is converted to a standard JavaScript number. JavaScript numbers are always 64-bit IEEE floating point values.

Similarly, a Uint8Array is a view onto a buffer, and each element gives the unsigned integer value of one byte. That is,

var n = uint8array[1];

accesses that element, interprets it as an unsigned one-byte integer, and converts that to a JavaScript number.

So: if you want to examine a list of 32-bit floating point values as the raw integer value of each byte, you can create a Uint8Array that "shares" the same buffer as the Float32Array:

var uintShared = new Uint8Array(float32array.buffer);

The number values you'd see from looking at the Uint8Array values will not appear to have anything to do with the number values you get from looking at the Float32Array elements, which is to be expected.

On the other hand, if you want to create a new Uint8Array to hold the apparent values from the Float32Array, you can just create a new array of the same length and copy each value:

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

Now that won't work too well, in general, because the numeric range of values in a Float32Array is vastly greater than that of values in the Uint8Array. For one thing, the 32-bit floating point values can be negative. What's more, even if you know that the floating point values are all integers in the range 0 to 255, you definitely will not get the same bit patterns in the Uint8Array, for the simple reason that a 32-bit floating point number is just not the same as an 8-bit unsigned integer. To "preserve the IEEE-754 representation" makes no sense.

So that's the reality of the situation. If you were to explain why you think you want to somehow cram all 32 bits of a 32-bit IEEE float into an 8-bit unsigned integer, it would be possible to provide a more directly helpful answer.




回答2:


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;

Anyone got doubt in mind can test this easily with Audacity's Import Raw Data feature.

  1. Download the sample raw data which I decoded from a video file using Web Audio Api's decodeAudioData method.
  2. Convert the Float32Array that sample raw data is filled with to Uint8Array by using the method above (or use your own method e.g. new Uint8Array(float32Array.buffer) to hear the corrupted sizzling sound) and download the uint8 pcm file.

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

  3. Encode your downloaded data in Audacity using File-> Import -> Raw Data... Encoding should be set to Unsigned 8-bit PCM and Sample Rate should be 16000 Hz since the original decoded audio file was in 16000 Hz.



来源:https://stackoverflow.com/questions/49348743/converting-float32array-to-uint8array-while-preserving-ieee-754-representation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!