1

I'm trying to convert a PCM stream to a readable float32Array. I'm trying to convert with the following method

function parseHexString(str) { 
    var result = [];
    while (str.length >= 8) { 
        int16 = parseInt(str.substring(0, 8), 16);
        float32 = (int16 / 32767) - 1;
        result.push(float32);

        str = str.substring(8, str.length);
    }

    return result;
}

the input (int16)

\x86%\x03%>$\xb1#\x06#8"\xc0!E!\xc5 \xad \xa4 \x97 \xe4 \x1e!/!\x80!\xb5!\xcb!+"u"\x8e"\xd2"\xdd"\xa4"\x98"l"$"3">"<"\x8a"\xc4"\xd9"$#I#@#h#j#8#2#\t#\xbf"\xc1"\xcb"\xd3")#h#t#\x9c#\x8d#?#\x15#\xbb"("\xbc!*!w \r \xa3\x1f2\x1f\x13\x1f\xf1\x1e\xbe\x1e\xd3\x1e\xd4\x1e\xae\x1e\xb1\x1e\x81\x1e\x16\x1e\xda\x1d\x84\x1d\x19\x1d\xfa\x1c\xd2\x1c\x9c\x1c\xb4\x1c\xd0\x1c\xe5\x1cK\x1d\x9b\x1d\xb0\x1d\xd2\x1d\x9d\x1d\x0b\x1d\x90\x1c\xf3\x1bF\x1b\x02...

which returns something like this

[NaN, NaN, -0.9929502243110446, -0.999603259376812, NaN, -0.99954222235786, NaN, -0.9929502243110446, NaN, -0.9929502243110446, NaN, -0.9929502243110446, NaN, -0.9929502243110446, NaN, -0.9929502243110446, NaN, NaN, -0.9929502243110446, NaN, -0.999664296395764, NaN, -0.999877925962096, NaN, NaN, -0.999908444471572, NaN, NaN, -0.999908444471572, NaN, NaN, -0.999877925962096, NaN, NaN,

I'm not sure why I get the NaN. Anyone? I'm also not sure if the PCM stream is in a correct format

boortmans
  • 1,138
  • 2
  • 24
  • 40

2 Answers2

1

I would love to be mistaken on this - however my usage of web sockets sadly is limited to sending binary data over the wire as unsigned 8 bit ints (not 16 bit ints say nothing about dreaming of directly sending 32 bit floats) - so on your sending side assure your data gets dumbed down appropriately - please tell me if web sockets handle 16 bit ints as your code suggests. Similarly on the receiving side of the socket you need to resuscitate 32 bit floats from shifting and stitching together 4 instances of 8 bit ints. I wrote code in javascript to do these steps on both ends of the pipe. Luckily javascript hides this stitching together. Here is how a web socket receives an array of 8 bit ints in form of an array buffer and converts it into a 32 bit typed array :

socket.binaryType = "arraybuffer";

socket.onmessage = function (e) {

    if (e.data instanceof ArrayBuffer) {

        var retrieved_buffer_obj = {};

        retrieved_buffer_obj.buffer = new Float32Array(e.data);

        // now do something with your new floats

    }
}

You mention stream - in my code it operate at the level of a buffer of data where each buffer is just a gulp of your streaming data transmission.

Scott Stensland
  • 26,870
  • 12
  • 93
  • 104
0

As Scott says, you need to set the websocket to give you arraybuffers. But need to convert the WebSocket output to an Uint16Array, and not Float32Array, and then convert that to floats using the code I gave you.

padenot
  • 1,515
  • 8
  • 11