Skip to content

Commit 1d50297

Browse files
premix: reimplement pcm_write_samples_float_to_32 with full correctness in mind (fixes #3292)
1 parent 3b328b8 commit 1d50297

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/premix.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,14 +452,24 @@ pcm_write_samples_float_to_32 (const ddb_waveformat_t * restrict inputfmt, const
452452
continue;
453453
}
454454
float fsample = (*((float*)(input + channelmap[c] * 4)));
455-
if (fsample > (float)0x7fffffff/0x80000000) {
456-
fsample = (float)0x7fffffff/0x80000000;
455+
456+
// Need to use 64 bit intermediates here, otherwise precision loss is imminent
457+
int64_t sample;
458+
if (fsample > 0) {
459+
sample = (int64_t)((double)fsample * (double)0x7fffffff);
460+
}
461+
else {
462+
sample = (int64_t)((double)fsample * (double)0x80000000);
457463
}
458-
else if (fsample < -1.f) {
459-
fsample = -1.f;
464+
465+
if (sample > 0x7fffffff) {
466+
sample = 0x7fffffff;
460467
}
461-
int32_t sample = ftoi(fsample * (float)0x80000000);
462-
*((int32_t *)(output + 4 * c)) = sample;
468+
else if (sample < -0x80000000) {
469+
sample = -0x80000000;
470+
}
471+
472+
*((int32_t *)(output + 4 * c)) = (int32_t)sample;
463473
}
464474
input += 4 * inputfmt->channels;
465475
output += outputsamplesize;

0 commit comments

Comments
 (0)