Skip to main content
gamedev.net
🔒 Locked

Saturation arithmetic

Started by phraine May 27, 2006 at 7:37 AM 5 replies 800+ views
Original Post
phraine
phraine
I need a fast implementation of saturation arithmetics for Intel processors. I already tried doing it with MMX, but it only works for 8-bit and 16-bit values, and I need signed 32-bit saturation arithmetic. I'm doing an audio sequencer which handles pretty much everything as a 32-bit sample. The code is mostly C++, with some assembler code (I'm an optimization freak). So, if there's a way to do it in assembler... I would be very thankful...
C0D1F1ED
C0D1F1ED
For x86, when an integer overflows the processor sets the carry bit. The adc and sbb instructions add/subtract a number plus the carry bit. Also, the cmovc instruction can move data conditionally using the carry bit. So for an addition of a positive integer you can use:
add eax, ebxmov ecx, 0x7FFFFFFFcmovc eax, ecx

It's more complicated for signed additions but I hope I've set the tone.

By the way, why don't you use floating-point numbers? Then you can easily let the values grow beyond range and then clamp them in the end. It's a more correct approach I believe. And with SSE assembly it might even be faster in whole.
Trap
Trap
Quote:
Original post by C0D1F1ED
By the way, why don't you use floating-point numbers? Then you can easily let the values grow beyond range and then clamp them in the end. It's a more correct approach I believe. And with SSE assembly it might even be faster in whole.

You would have to use doubles to get the desired precision (floats are too small with only 24 bits of mantissa). Which means SSE2 only and 2 calculations per SSE2-op instead of 4 with 32-bit ints.
C0D1F1ED
C0D1F1ED
Quote:
Original post by Trap
You would have to use doubles to get the desired precision (floats are too small with only 24 bits of mantissa). Which means SSE2 only and 2 calculations per SSE2-op instead of 4 with 32-bit ints.

I can't imagine 32-bit floats wouldn't be sufficient for an audio sequencer.
Trap
Trap
Quote:
Original post by C0D1F1ED
Quote:
Original post by Trap
You would have to use doubles to get the desired precision (floats are too small with only 24 bits of mantissa).

I can't imagine 32-bit floats wouldn't be sufficient for an audio sequencer.

There is no use for the 8 bit exponent in audio processing (except for things like clamping). That leaves you with the 24-bits of the mantissa. The audio data you are processing is 24-bit with maybe 20 or 21 bit of real data and 4 or 3 bits of noise.

Implementing things like dynamic compressors, equalizers, IIR-filters and so on with only 3 bits of errormargin till your errors start degrading the signal is a bad idea IMO.
C0D1F1ED
C0D1F1ED
Quote:
Original post by Trap
There is no use for the 8 bit exponent in audio processing (except for things like clamping). That leaves you with the 24-bits of the mantissa. The audio data you are processing is 24-bit with maybe 20 or 21 bit of real data and 4 or 3 bits of noise.

The exponent is used as well! If the dynamic range is halved you don't loose any precision, it just lowers the exponent. This also means you get high precision for faint sound, instead of bigger granularity like with integers. You simply always have 24 bits or precision no matter what the range is.

In other words when your sound is scaled between -1.0 and 1.0 you're using 31 bits of the whole 32-bit floating-point format!
JohnBolton
JohnBolton
In the x86 there is an overflow condition code. If it is true, then set the result to 0x7fffffff or 0x80000000 depending on the sign of one of the operands and the operation.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.