Search code examples
javascriptstreamaudio-streaming

Sending and casting a Float32Array after JSON.stringify


Very similar to this question - I'm trying to send a Float32Array from one client to another, but I need to use JSON.stringify before sending the message.

On the sending side I use:

audioBuffer = e.inputBuffer.getChannelData(0)
var aud = { "sessionId": sessionId, "streamData": audioBuffer, "client": "student", "type": "audio" }
ws.send(JSON.stringify(aud));

On the receiving sise I use:

var msg = JSON.parse(message.data);
var streamData = msg.streamData;
var kbuff = new Float32Array(streamData);
context.decodeAudioData(kbuff, onBuffer, onDecodeBufferError);

But this results in the receiving side getting an Object that I cannot seem to cast to a Float32Array:

When the sending side sends the data:

enter image description here

When the receiving side gets the data:

enter image description here

enter image description here

Any idea how to make this work?


Solution

  • JSON doesn't understand Float32Array. If you stringify a Float32Array (for instance, JSON.stringify(Float32Array.of(20, 250, 444))), you get something that looks like this:

    {"0":20,"1":250,"2":444}
    

    You have two options:

    1. Convert the array to a standard array of numbers before stringify and then convert it back after JSON.parse, or

    2. Send it as-is and convert the resulting object back to a Float32Array after JSON.parse.

    Since converting a Float32Array to an array of numbers won't be lossy, and maintains the semantics well, that's what I'd do:

    const original = Float32Array.of(20, 250, 444);
    const json = JSON.stringify(Array.from(original));
    console.log(json);
    const received = new Float32Array(JSON.parse(json));
    console.log(received);

    If this array is part of a greater structure, you may need a replacer function with JSON.stringify and reviver function for JSON.parse.