Fix an overflow in the fix16_t usage which can lead to audio distortion.

This commit is contained in:
George Norton 2023-03-31 13:15:43 +01:00
parent cca0639485
commit e6ece89049
2 changed files with 19 additions and 15 deletions

View File

@ -22,7 +22,7 @@
#include <stdio.h>
#include <inttypes.h>
#include <math.h>
#include <limits.h>
#include "fix16.h"
fix16_t fix16_from_int(int16_t a) {
@ -30,9 +30,23 @@ fix16_t fix16_from_int(int16_t a) {
}
int16_t fix16_to_int(fix16_t a) {
if (a >= 0)
return (a + (fix16_one >> 1)) / fix16_one;
return (a - (fix16_one >> 1)) / fix16_one;
// Handle rounding up front, adding one can cause an overflow/underflow
a+=(fix16_one >> 1);
// Saturate the value if an overflow has occurred
uint32_t upper = (a >> 30);
if (a < 0) {
if (~upper)
{
return SHRT_MIN;
}
} else {
if (upper)
{
return SHRT_MAX;
}
}
return (a >> 15);
}
fix16_t fix16_from_dbl(double a) {
@ -49,16 +63,6 @@ double fix16_to_dbl(fix16_t a) {
fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) {
int64_t product = (int64_t)inArg0 * inArg1;
uint32_t upper = (product >> 47);
if (product < 0) {
if (~upper)
return fix16_overflow;
product--;
} else {
if (upper)
return fix16_overflow;
}
fix16_t result = product >> 15;
result += (product & 0x4000) >> 14;

View File

@ -91,7 +91,7 @@ static void _as_audio_packet(struct usb_endpoint *ep) {
int samples = usb_buffer->data_len / 2;
for (int i = 0; i < samples; i++)
out[i] = in[i] / 4; // fixes digital distortion bug
out[i] = in[i];
multicore_fifo_push_blocking(CORE0_READY);
multicore_fifo_push_blocking(samples);