7

I have some audio buffer in usigned 8bit PCM format need to play via web audio which only accept signed 32bit PCM. And now I have ArrayBuffer for pieces of pcm_u8 data(come from Uint8array). How can I convert it to Float32Array?

Wilson Luniz
  • 459
  • 2
  • 7
  • 18

2 Answers2

15

ECMAScript 2015 and onwards has TypedArray.from which converts any typed array (and indeed, any iterable) to the specified typed array format.

So converting a Uint8Array to a Float32Array is now as easy as:

const intArray = new Uint8Array()
const floatArray = Float32Array.from(intArray)
robjtede
  • 736
  • 5
  • 16
13

This function converts an ArrayBuffer to Float32Array

var convertBlock(buffer) { // incoming data is an ArrayBuffer
    var incomingData = new Uint8Array(buffer); // create a uint8 view on the ArrayBuffer
    var i, l = incomingData.length; // length, we need this for the loop
    var outputData = new Float32Array(incomingData.length); // create the Float32Array for output
    for (i = 0; i < l; i++) {
        outputData[i] = (incomingData[i] - 128) / 128.0; // convert audio to float
    }
    return outputData; // return the Float32Array
}

This one converts a Uint8Array to Float32Array

var convertBlock(incomingData) { // incoming data is a UInt8Array
    var i, l = incomingData.length;
    var outputData = new Float32Array(incomingData.length);
    for (i = 0; i < l; i++) {
        outputData[i] = (incomingData[i] - 128) / 128.0;
    }
    return outputData;
}
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • This works great! Thank you! I'm curious, `float32` has a range approx -3.4E+38 to +3.4E+38 but WebAudioAPI only use -1 to +1. Is it limited the precision(only part of 32bit)? Or something I misunderstood? – Wilson Luniz Jan 08 '16 at 07:33
  • I have no idea to be honest - but float32 with a range of +/- 1 is not an uncommon audio range – Jaromanda X Jan 08 '16 at 07:36
  • I tried to change `outputData[i] = (incomingData[i] - 128) / 128.0 * 0xFFFFFFFF;` or even `0xFFFF` and it gives me the exactly same audio(and I can see the value really growing bcoz i wrote my only sine wave generator for testing). I'm really confuse about this. – Wilson Luniz Jan 08 '16 at 08:07
  • you may need to look into the range expected/allowed in the data – Jaromanda X Jan 08 '16 at 08:09
  • Using values outside the range of [-1, 1] is undefined – Esailija Jan 08 '16 at 11:23
  • Within the WebAudio graph, you can use full float range to do whatever you want. But if you eventually want to hear it you have to map it back to the +/- 1 range in some way. In Chrome, if you don't, all of your values will get clamped to +/-1 for you so the signal you hear will be distorted. – Raymond Toy Jan 08 '16 at 16:28
  • 1
    The point of using floating point is that the "range" of -1/+1 is a NOMINAL range - that is, when you output it to the speakers, it should be [-1,+1] or it will clip, but audio signals elsewhere in the pipeline may go well outside that range. – cwilso Jan 08 '16 at 17:14
  • Why not just `new Float32Array(buffer)`? – Osman Mazinov Jul 06 '21 at 07:55
  • @OsmanMazinov - you're right. You should post that as an answer – Bravo Jul 07 '21 at 04:38