13
0

Fix shaped dither (#9342)

This commit is contained in:
Robin Gareus 2023-05-22 04:48:53 +02:00
parent e9dc1335f9
commit f1f352a6e9
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -189,7 +189,7 @@ gdither_innner_loop (const GDitherType dt,
uint8_t* o8 = (uint8_t*)y; uint8_t* o8 = (uint8_t*)y;
int16_t* o16 = (int16_t*)y; int16_t* o16 = (int16_t*)y;
int32_t* o32 = (int32_t*)y; int32_t* o32 = (int32_t*)y;
float tmp, r, ideal; float tmp, r, err;
int64_t clamped; int64_t clamped;
i = channel; i = channel;
@ -208,21 +208,24 @@ gdither_innner_loop (const GDitherType dt,
ts[channel] = r; ts[channel] = r;
break; break;
case GDitherShaped: case GDitherShaped:
/* Save raw value for error calculations */
assert (ss); assert (ss);
ideal = tmp;
/* Run FIR and add white noise */ /* Run FIR */
ss->buffer[ss->phase] = gdither_noise () * 0.5f;
tmp += ss->buffer[ss->phase] * shaped_bs[0] tmp += ss->buffer[ss->phase] * shaped_bs[0]
+ ss->buffer[(ss->phase - 1) & GDITHER_SH_BUF_MASK] * shaped_bs[1] + ss->buffer[(ss->phase - 1) & GDITHER_SH_BUF_MASK] * shaped_bs[1]
+ ss->buffer[(ss->phase - 2) & GDITHER_SH_BUF_MASK] * shaped_bs[2] + ss->buffer[(ss->phase - 2) & GDITHER_SH_BUF_MASK] * shaped_bs[2]
+ ss->buffer[(ss->phase - 3) & GDITHER_SH_BUF_MASK] * shaped_bs[3] + ss->buffer[(ss->phase - 3) & GDITHER_SH_BUF_MASK] * shaped_bs[3]
+ ss->buffer[(ss->phase - 4) & GDITHER_SH_BUF_MASK] * shaped_bs[4]; + ss->buffer[(ss->phase - 4) & GDITHER_SH_BUF_MASK] * shaped_bs[4];
/* Capture signal for error calculation before adding white noise */
err = tmp;
/* Add white noise */
tmp += (gdither_noise () + gdither_noise ()) * 0.5f;
/* Roll buffer and store last error */ /* Roll buffer and store last error */
ss->phase = (ss->phase + 1) & GDITHER_SH_BUF_MASK; ss->phase = (ss->phase + 1) & GDITHER_SH_BUF_MASK;
ss->buffer[ss->phase] = (float)lrintf (tmp) - ideal; ss->buffer[ss->phase] = err - (float)lrintf (tmp);
break; break;
} }
@ -259,7 +262,7 @@ gdither_innner_loop_fp (const GDitherType dt,
uint32_t pos, i; uint32_t pos, i;
float* oflt = (float*)y; float* oflt = (float*)y;
double* odbl = (double*)y; double* odbl = (double*)y;
float tmp, r, ideal; float tmp, r, err;
double clamped; double clamped;
i = channel; i = channel;
@ -279,20 +282,23 @@ gdither_innner_loop_fp (const GDitherType dt,
break; break;
case GDitherShaped: case GDitherShaped:
assert (ss); assert (ss);
/* Save raw value for error calculations */
ideal = tmp;
/* Run FIR and add white noise */ /* Run FIR */
ss->buffer[ss->phase] = gdither_noise () * 0.5f;
tmp += ss->buffer[ss->phase] * shaped_bs[0] tmp += ss->buffer[ss->phase] * shaped_bs[0]
+ ss->buffer[(ss->phase - 1) & GDITHER_SH_BUF_MASK] * shaped_bs[1] + ss->buffer[(ss->phase - 1) & GDITHER_SH_BUF_MASK] * shaped_bs[1]
+ ss->buffer[(ss->phase - 2) & GDITHER_SH_BUF_MASK] * shaped_bs[2] + ss->buffer[(ss->phase - 2) & GDITHER_SH_BUF_MASK] * shaped_bs[2]
+ ss->buffer[(ss->phase - 3) & GDITHER_SH_BUF_MASK] * shaped_bs[3] + ss->buffer[(ss->phase - 3) & GDITHER_SH_BUF_MASK] * shaped_bs[3]
+ ss->buffer[(ss->phase - 4) & GDITHER_SH_BUF_MASK] * shaped_bs[4]; + ss->buffer[(ss->phase - 4) & GDITHER_SH_BUF_MASK] * shaped_bs[4];
/* Capture signal for error calculation before adding white noise */
err = tmp;
/* Add white noise */
tmp += (gdither_noise () + gdither_noise ()) * 0.5f;
/* Roll buffer and store last error */ /* Roll buffer and store last error */
ss->phase = (ss->phase + 1) & GDITHER_SH_BUF_MASK; ss->phase = (ss->phase + 1) & GDITHER_SH_BUF_MASK;
ss->buffer[ss->phase] = (float)lrintf (tmp) - ideal; ss->buffer[ss->phase] = err - (float)lrintf (tmp);
break; break;
} }