1

There are many Q&A's about converting blobs or Uint8Array to base64. But I have been unable to find how to convert from 32-bit arrays to base64. Here is an attempt.

function p(msg) { console.log(msg) }

let wav1 = [0.1,0.2,0.3]
let wav = new Float32Array(wav1)
p(`Len array to encrypt=${wav.length}`)
let omsg = JSON.stringify({onset: { id: 'abc', cntr: 1234}, wav: atob(wav) })
p(omsg)

The atob gives:

 Uncaught InvalidCharacterError: Failed to execute 'atob' on 'Window': 
 The string to be decoded is not correctly encoded."

What intermediate step is needed to allow proper encoding of the floats to base64 ? Note that I have also tried TweetNacl-util instead of atob this way:

 nacl.util.encodeBase64(wav)

This results in the same error.

Update Using JSON.stringify directly converts each float element into its ascii equivalent - which bloats the datasize . For the above that is:

"0.10000000149011612,"1":0.20000000298023224,"2":0.30000001192092896

We are transferring large arrays so this is a suboptimal solution.

Update The crucial element of the solution in the accepted answer is using Float32Array(floats).buffer . I was unaware of the buffer attribute.

6
  • 1
    It should be btoa if you're encoding to base64... But btoa works on strings, not Float32Arrays. Why not just let JSON.stringify do the serialization? Commented Sep 2, 2020 at 21:44
  • Does JSON.stringify retain the float arrays as 4 bytes per element? I see it coming out as the ascii version of each element - which is like 16 bytes per element (see update to question) Commented Sep 2, 2020 at 21:53
  • 1
    Use whatever you saw for Uint8Array on an Uint8Array view of your Float32Array's buffer. The Typed Array is just a view, you can create many of these on the same buffer without any new data assigned. But how come you can't transfer the binary data directly? (Send the buffer directly) Commented Sep 2, 2020 at 23:24
  • @Kaiido The data will be encrypted next: can not do that on floats afaik. In any case the Tweet-Nacl library does not support it. Commented Sep 4, 2020 at 3:06
  • The data is binary data, that you have a Float32Array view over that data doesn't change that. Once again TypedArrays are only views. If some code needs to read the data as Uint8Array, then give them a Uint8Array view of your underlying buffer. There is no float or whatever only data. Commented Sep 4, 2020 at 3:11

1 Answer 1

4

The problem with your current code is that nacl.util.encodeBase64() takes in either a string, Array, or Uint8Array. Since your input isn't an Array or Uint8Array, it assumes you want to pass it in as a string.

The solution, of course, is to encode it into a Uint8Array first, then encode the Uint8Array into base64. When you decode, first decode the base64 into a Uint8Array, then convert the Uint8Array back into your Float32Array. This can be done using JavaScript ArrayBuffer.

const floatSize = 4;

function floatArrayToBytes(floats) {
    var output = floats.buffer; // Get the ArrayBuffer from the float array
    return new Uint8Array(output); // Convert the ArrayBuffer to Uint8s.
}

function bytesToFloatArray(bytes) {
    var output = bytes.buffer; // Get the ArrayBuffer from the Uint8Array.
    return new Float32Array(output); // Convert the ArrayBuffer to floats.
}

var encoded = nacl.util.encodeBase64(floatArrayToBytes(wav)) // Encode
var decoded = bytesToFloatArray(nacl.util.decodeBase64(encoded)) // Decode

If you don't like functions, here's some one-liners!

var encoded = nacl.util.encodeBase64(new Uint8Array(wav.buffer)) // Encode
var decoded = new Float32Array(nacl.util.decodeBase64(encoded).buffer) // Decode
Sign up to request clarification or add additional context in comments.

1 Comment

The key to what you wrote - and which is what I needed is floats.buffer I am awarding for that piece. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.