Search code examples
javascriptbytedataviewlow-levelarraybuffer

How to set a signed 24-bit integer in a DataView?


I found this, but it's for unsigned 24-bit integers:

DataView.prototype.setUint24 = function(pos, val) {
    this.setUint16(pos, val >> 8);
    this.setUint8(pos+2, val & ~4294967040); // this "magic number" masks off the first 16 bits
}

Simply changing setUint16 for setInt16 and setUint8 for setInt8 doesn't seem to work. My knowledge about low level binary stuff is very limited, so I would need some help. I understand most of this function:

  • val >> 8 keeps only the first 16 bits to store as a 16-bit
  • pos + 2 is because a 16-bit integer takes 2 bytes in terms of space
  • As for val & ~4294967040, well there's a comment lol.

I'm not too sure why just changing the calls to methods that set signed value doesn't work/ I'm not too sure why the process differs when setting signed/unsigned values.


Solution

  • As commented by @Ryan and @Thomas, this method works. I thought it wasn't working, because the wav file I was creating was pure white noise. It turns out that while this method works, it might be setting the bytes in the wrong order (which is problematic for wav files, but not for other processings). See Is there anything special I have to do to create a 24-bit WAV file? for more information.