Bit-exact representation of 24bit int

Magnus Berendes's icon

Hi there,

I'm currently experimenting with some things and noticed that I cannot get a bitexact copy of my input pcm samples.

When I'm reading in a 24 bit wavfile using sfplay~ and immediately write it back onto the disk using sfrecord~ (with @bitdepth 24 @dither 0 @quantization 0) I get off-by-ones at roughly 50% of the samples (+1 sample delay, which is not the problem).
As far as my understanding goes Max uses 64bit floats to represent audio internally which shouldn't have any problem representing a 24 bit int exactly, should it?

Obviously, this isn't an audible problem but for my application bitexact transport would be necessary.

Any ideas where I lose my precision and any idea how I could get it back?

Thanks!

Roman Thilenius's icon

>> "uses 64bit floats to represent audio internally which shouldn't have any problem representing a 24 bit int exactly, should it?"

hm, unless you changed the amplitude?

or unless one of the objects in question still has that bug where the top half of the values are offset by 1.

(insiders know where we once had that bug... even matlab had that same bug for years)

i suspect that sfplay/sfrecord is the cause, you can try if the same happens with buffer releated objects then you´ll see.

Magnus Berendes's icon

Thanks for your answer!

>> unless you changed the amplitude?

My first experiment was literally sfplay into sfrecord, no gain involved anywhere.

Now I used a buffer~ object (buffer~ inbuf <filename> 1000 6 @dither 0 @filetype wave @format int24 @quantization 0 @samps 48000) and used importreplace to import a file, then using writewave I wrote the buffer to the disk and compared it with my input file - no bueno, same picture. Off by ones all over the place.

To me it seems it is just happening with high amplitude samples, maybe see if I can find a threshold...

Roman Thilenius's icon

if it is what i mentioned above it, should be only the positive values.

Magnus Berendes's icon

Yes, it is exactly what you mentioned: all values in [0.5*MAX, MAX] (for 24bit int) are off by one. Okay, so it is this bug and apparently sfrecord~/sfplay~ AND buffer~ are affected. Do you know if this bug is also "in" the patch cords? I.e. if I implement file reading and writing myself, will I be fine?

Or any way to get bugfree buffer~/sfplay~ implementations?

(Version of Max is 8.5.3, currently updating to 8.5.5)

Roman Thilenius's icon

that is a good question if it is runtime wide, and i would have to speculate, and to be honest i assumed that was long fixed.

for music and for listening to the result it does not matter much, for other applications it can. and if you import and export 100 times, the offset will be 100 values.

how to fix that? no idea. personally i would use file/fileout in max 4.x as a post process to other things. :)

for the read/write scenario adding one bit will fix it. but as soon as you perform some algo in 64 bit before, you could still get some wrong values.

are you abusing signals for something? alternatively you can abuse jitter matrixes for data collections, too.

proposed testing scenario:

create an "original audio file" in text format containing only (signed) min, max, max-1, and 0.

open the text with max, write it into buffer~

play it from the buffer~ using play~ and record with record~ into another buffer

check the values in the buffer (as far as it is possible to get the full 64 value for max-1/24bit?)

save audio file from buffer and see what is in it.