64 bit sound
I am *loving* the sound improvement in msp!!
Since I hear that several the orig. max objects (such as the float number box) are still 32 bit …is there a list of objects with no 64bit mode, so that we can think about things like normalization before going thru a 32 conversion, for quality’s sake?
I guess all the signal paths are 64 bits now…it sure sounds good to me…even simple sounds have a better image, sound more ‘stable’ in my monitors… I guess that’s the 64bit processing…it’s a sound I have previously associated with an improvement in the clock driving my converters…and in a DAW I use adopting 64bit sound processing, :)
Any other sound reactions? Try comparing msp object’s sound against the other release A/B…I can hear improvement…am I just imagining it?
I think I need some helpful explanations re 64-bit sound. My understanding is the bit depth of each sample is 64-bits–is this correct, or does it mean 64-bit addressing? The sneak preview video for max 6
shows a sine wave in a 10-minute long buffer with better sound quality than the equivalent in max v5. This implies 64-bit addressing, does it not? But even if it does i don’t understand where the artifacts shown in the v5 example come from… but then if it’s to do with bit depth, how can the difference between a 64 and 32 be so dramatic when it’s just a sine wave at full word length…(and presumably the DA hardware converter one uses is not necessarily relevant here)?
what’s the DSP theory involved?
Max 6 uses 64-bit (AKA double-precision) floating point numbers to represent MSP signals. Yes, this means bit depth. 64 bit addressing is a different thing altogether – it concerns the inner workings of the software. Max 6 is still a 32-bit application ATM, but if and when it switches to 64 bit, it will be behind the scenes, and won’t affect the way audio signals are represented. Addressing modes just dictate how a program locates memory internally, and what machine instructions the code compiles down to.
64-bit signals means two things:
1. Smaller fractional values can be represented (less quantisation at low volumes == smoother reverb tails, nicer-sounding interpolation, higher-quality mixing (less precision loss with every multiplication)… that sort of thing).
2. Larger values can be represented than were previously possible with 32 bits. With floating point representation, once you reach a certain point, you can no longer represent every possible integer. With 32-bit signals, once you get over 1< <31 - 1, it's no longer possible to represent each whole number: the gap between numbers you can represent becomes greater than 1. This is what causes [play~] to lose accuracy and develop unpleasant noise with long sound files - it becomes impossible to count through every sample to play back a sound accurately. 64-bit floats don't lose accuracy in this way for a *lot* longer, so [play~] can still be fed an accurate position pointer.
yep, I understand the advantages of 64-bit audio re reverb and particularly freq-domain processing, filter coeffs etc…
so it’s actually the msp audio signals being used as _control_ signals that cause inaccuracy illustrated in the video example I mentioned. In this case the line~ object can’t reference the proper point in the buffer. So in that sense the example illustrates an addressing issue, but internal to max, not within the computer hardware or operating system.
OK I think I get it now.
I second the notion that Max 6 Sounds instantly better – just a normal sine wave sounds like it has a "fatter", warmer sound,
the difference is especially noticable on my bad laptop speakers
>the difference is especially noticable on my bad laptop speakers
Which, as is widely known, take advantage of the ear’s propensity to "complete" the low end of a harmonic series to make up for their inherent lack of low frequency production: so the alias artifacts (or lack thereof) in the spectrum are even more pronounced with a (relatively) low frequency wave when the fundamental is "rolled-off"…another way of saying this is the noise is "masked" by the genuine wave in the case of the hifi speakers: but the tiny speakers do not produce that much energy at the genuine fundamental freq, so noise is ‘uncovered’.
Minor correction to chris…
32 bit floating point only gives you 24 bit precision. 32bit fp has 1 sign bit, 8 bits for the exponent and (effectively) 24 bits for the mantissa. It’s the mantissa that gives you precision. When working with integral values, once you get past 2^24 (16,777,216) it is no longer possible to represent every integer.
64 bit fp has a 53 bit mantissa.
Floating point is different from integers. Sometimes it can be important to remember that.
Thanks Peter, my brain was on holiday.
Minor minor correction: When working with integral values, once you get past 2^24 – 1 (16,777,215) it is no longer possible to represent every integer.
I don’t think flonum is still 32 bits. The object displays 6 digits after the dot as default but you can change the setting in the inspector ("Number of Decimal Places") and it goes far beyond 6. By the way, have you noticed there is now a "Parameter Mode" including an initial value ? Very handy.
Max messages are still 32bit floats. Audio signals are 64 bit. I hope that at some point in the future this will change and max float datatypes will be 64bit, but it isn’t the case right now….
AH, thanks for verification…So Maxers, take care passing sample values into and outta max objects: no problem *generally*, if one makes sure to ‘normalize’, so data maintains accuracy, not loses accuracy in the conversion. but if you don’t take care, it’ll sound great in the 64bit objects, but passing it thru 32 bit object will lose resolution, and you’ll hear it…and not only data range issue, but actually how the conversion is done can make a difference: writing to 32 bit files in my audio editor from it’s 64 bit internal format offers several different ‘dithering’ options to reduce auditory issues with the word size change…I bet we don’t dither when passing a 64bit value into the 32 max world.
But we can add very small amounts of [noise~] in 64-bit MSP land :)
Which will make such conversions sound better!!Absolutely!! *if* the 64 bit signal is in the ‘upper’ part of it’s range, so changing bit size doesn’t lose important resolution, as was said, :) …
generally, We would not *want* to add any noise to the old 32bit Max/Msp signal, but such small noise added to the *low order bits* of a 64bit signal, where the important signal is in the upper bits *will* positively affect the quality of the bit reduction conversion.
in other words, yeah, *we* can dither the signal…
But we mostly will have to be careful of the absolute range of the 64 bit signal, which can sound great only using a fraction of it’s "bit-width"…but convert a 64 bit signal to 32 bits when most of the signal lies in the 16 or less low order bits will lose resolution badly.
You *will* hear it… "just sayin’", as ChrisD sez..
cfb aka j2k
If you want to move audio data into Max land for processing, one option is to stuff it into a float64 jitter matrix (or use [jit.buffer~]) and do pretty much anything with it.
OK, that’s no use to people without Jitter. Jus’ sayin’.[/edit]
Jitter is not an add-on with Max 6, so everyone who owns 6 will have jitter.
hmmm…one dim jitter matrix or jit.buffer prob. a *bit* more expensive than a float object for holding a single value: one can still hope for a full 64bit path throughout. esp with all the legacy code out there that might need to be adjusted… But as it is, there are so many mo’ betta mo’ options in Max6, I’m pinching my pennies to save up the upgrade fee…
one can still hope for a full 64bit path throughout
What don’t I understand about this conversation? AFAICT, [buffer~] seems perfectly happy reading and writing 64-bit WAVE files.
specifically, the ‘Flonum’ object in max was in question, and passing floting point numbers around in any but the explicitly audio objects: once the signal is moved to the old max *non-signal* world (max messages, max flonum, max expr etc.), it is suddenly singles…32bit float…not a big problem, since one can generally avoid it in Max6, but it might have some nasty consequences in apps that assume that a msp signal can be moved into and out of max objects as floating point with no alteration, as it could in max 4.X, max5.X…as i recall (still @ work) see the right output of the sig~ object in max5…
A couple of things:
1 – buffer~s are still 32 bit – if you want to store audio temporarily and it needs to be 64bit you can either use a jitter solution, or use gen~s internal storage facilities (I forget the name) which is always 64 bit. This is currently preferable as 64bit buffers would mean a lot of us running out of memory a lot faster. Also, if you are loading from 24 / 16 bit formats the extra bits are pointless (hence why I wrote objects to load in integer format to conserve memory).
2 – You shouldn’t dither the signal when going from 64bit to 32 bit, as you are adding error. Floating point is not like integer representations – adding a constant level of noise to a 64bit float is likely to result in a situation where some numbers when converted to 32bit float are almost totally noise (error). You shouldn’t do anything to the signal – the double/float conversion should do something sensible, although I’m not sure if it truncates or rounds (the latter might be preferable).
3 – I think a little too much may be being made of 64 bit in terms of audible quality. A single 32 bit float format has 24 bits for representing significant digits. However, for smaller signals this exceeds the range of a 24 bit integer system. Problems can result from repeated processing (cumulative roundoff error), but there are certain scenarios in which this is much more apparent (IIR filtering, the drive example for play~ above). Part of the reason the cycle~ is improved is the increased table size, rather than the increased bit depth. Whilst it is great that we no longer have to worry so much about cumulative error, or specific scenarios where 32 bit results in noticeable artefacts, I defy anyone to hear the difference between a 64bit file and a truncated 32 bit version – the range of 32bit is well beyond 144dB, and if I remember correctly no current sound interface can get an SNR that high, so if you hear error beneath 144dB I’d be pretty impressed…
if you are listening to a 64 bit sound,it may sound good at the level it is at: even at a low level it has enough resolution to not have audible quantization error: but if the absolute max amp is well below say an 1/16 the total range, it may sound ok in 64 bit, but when it is simply translated to 32 bit, (with the float max amp in 32bit = float maxamp in 32 bit), I know the resulting sound can and does contain more quantization error. i have done this too many times to not recognize the ‘grittiness’ of the introduced quantization error. That’s my only concern. Given a signal that uses most of the available range, 64->32 bit is not an issue at all: but often i have seen a signal in my DAW that sounds *delightful* and *quiet* in 64 bit internal , when converted to 32 bits for max work can sound ‘hard’ and ‘gritty’, worse when gain is added back, and when flattened to 16 bit integer sounds…well, horribly damaged, not just a little noisy. This is not true if the orig. 64 bit signal uses most of the resolution: is ‘normalized’.
ok, i’m a distracted idiot: I realize now that all my transfer scripts I use convert not to 32 float, but to 24bit integer: and range issues are critical with integer conversion. ..most of the time, 64->32 float will not even be audible..
Charles Baker and Alex Harker thanks for your replies. I wasn’t thinking about MSP to Max connection, and I must have missed the bit in the beta docs that stated the [buffer~] object was still 32-bit.
dithering from 64 float to 32 float seems like a joke, if any, avoiding 32 bit processes in the signal chain is the advice.