+unsigned combine_samples(float *src, float *dst, unsigned num_src_samples, unsigned max_samples_saved)
+{
+ unsigned num_samples_saved = 0;
+ for (unsigned i = 0, j = 0; i < num_src_samples; ++i, ++j) {
+ // Copy the sample directly; it will be overwritten later if we can combine.
+ if (dst != NULL) {
+ dst[j * 2 + 0] = src[i * 2 + 0];
+ dst[j * 2 + 1] = src[i * 2 + 1];
+ }
+
+ if (i == num_src_samples - 1) {
+ // Last sample; cannot combine.
+ continue;
+ }
+ assert(num_samples_saved <= max_samples_saved);
+ if (num_samples_saved == max_samples_saved) {
+ // We could maybe save more here, but other rows can't, so don't bother.
+ continue;
+ }
+
+ float w1 = src[i * 2 + 0];
+ float w2 = src[(i + 1) * 2 + 0];
+ if (w1 * w2 < 0.0f) {
+ // Differing signs; cannot combine.
+ continue;
+ }
+
+ float pos1 = src[i * 2 + 1];
+ float pos2 = src[(i + 1) * 2 + 1];
+ assert(pos2 > pos1);
+
+ float offset, total_weight, sum_sq_error;
+ combine_two_samples(w1, w2, &offset, &total_weight, &sum_sq_error);
+
+ // If the interpolation error is larger than that of about sqrt(2) of
+ // a level at 8-bit precision, don't combine. (You'd think 1.0 was enough,
+ // but since the artifacts are not really random, they can get quite
+ // visible. On the other hand, going to 0.25f, I can see no change at
+ // all with 8-bit output, so it would not seem to be worth it.)
+ if (sum_sq_error > 0.5f / (256.0f * 256.0f)) {
+ continue;
+ }
+
+ // OK, we can combine this and the next sample.
+ if (dst != NULL) {
+ dst[j * 2 + 0] = total_weight;
+ dst[j * 2 + 1] = pos1 + offset * (pos2 - pos1);
+ }
+
+ ++i; // Skip the next sample.
+ ++num_samples_saved;
+ }
+ return num_samples_saved;
+}
+