ref: 00913a41096f6590dd796df2300df7616c4acbe0
parent: 7963f09aeefb9b584f7a415b11e8e08310ed04c3
author: David Bryant <david@wavpack.com>
date: Sat Oct 1 17:03:06 EDT 2022
- use unsigned ints to fix edge-case overflow possibility in find_period_fast() - increase usable sample count range of merge_blocks() with unsigned calculation
--- a/stretch.c
+++ b/stretch.c
@@ -399,12 +399,12 @@
}
if (best_period * cnxt->num_chans * 2 != cnxt->shortest && best_period * cnxt->num_chans * 2 != cnxt->longest) {
- int high_side_diff = cnxt->results [best_period] - cnxt->results [best_period+1];
- int low_side_diff = cnxt->results [best_period] - cnxt->results [best_period-1];
+ unsigned int high_side_diff = cnxt->results [best_period] - cnxt->results [best_period+1];
+ unsigned int low_side_diff = cnxt->results [best_period] - cnxt->results [best_period-1];
- if (low_side_diff > high_side_diff * 2)
+ if (low_side_diff / 2 > high_side_diff)
best_period = best_period * 2 + 1;
- else if (high_side_diff > low_side_diff * 2)
+ else if (high_side_diff / 2 > low_side_diff)
best_period = best_period * 2 - 1;
else
best_period *= 2;
@@ -425,6 +425,11 @@
* back to signed. This is done to avoid the compression around zero that occurs
* with calculations of this type on C implementations that round division toward
* zero.
+ *
+ * The maximum period handled here without overflow possibility is 65535 samples.
+ * This corresponds to a maximum calculated period of 16383 samples (2x for stereo
+ * and 2x for the "2.0" version of the stretch algorithm). Since the maximum
+ * calculated period is currently set for 2400 samples, we have plenty of margin.
*/
static void merge_blocks (short *output, short *input1, short *input2, int samples)
@@ -432,7 +437,6 @@
int i;
for (i = 0; i < samples; ++i)
- output [i] = (((input1 [i] + 32768) * (samples - i) +
- (input2 [i] + 32768) * i) / samples) - 32768;
+ output [i] = (int)(((unsigned int)(input1 [i] + 32768) * (samples - i) +
+ (unsigned int)(input2 [i] + 32768) * i) / samples) - 32768;
}
-