As one block of 64 number is scanned, the min and max values are computed. The min value is subtracted from all the sample, as well as from max.
This implies that
- at least one sample will have the value min
- at least one sample will have the value max
Wouldn't it be cool if we could use these informations to save more space ?
Let's take the example of max, which in our case can be anywhere from 0 to 765 (up to 10 bits for luma). We have 64 values, so the index fits in 6 bits. The gain can be negative or positive:
- in the best case, where max uses 9 bits (due to phase-out, instead of 10 with phase-in), we gain 9-6=3 bits, for a block of 64 values (that's really insignificant)
- in the worst case (max<6) up to 6 bits are lost (though max==0 is a condition to not decode the block, which would be empty)
The same goes with min, though min usually encodes in less bits than max.
In our case, the special values can not be represented in an efficient way. We have to count on using 3R for increased compaction and there is some inherent redundancy that can't be removed. And the above case only addresses the assumption that there is only one value equal to min and one that is equal to max. How do you manage the case where more than one value is used ?
Note for later:
With fewer values of higher amplitude (like, chunks of 16× 16-bits numbers for example), the "min/max index" uses 8 bits and can save up to 24 bits so this is a valuable trick for sound compression.
Part of the answer is the use of recursive σα transforms because the very high values are reduced to few bits, like the very low values.
Another approach is to encode the max value with a different code, such as 1 (0 is reserved for min). The other values are incremented: 1 becomes 2 etc. However this might not be as beneficial because
- There is no direct gain with simple use of phase-in/out only
- It could interfere with the behaviour of 3R and σα.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.