audioconvert: optimize dither

Add sse2 dither optimization
This commit is contained in:
Wim Taymans 2022-06-27 14:15:01 +02:00
parent 9f55708e9d
commit b41d52cfd1
6 changed files with 160 additions and 17 deletions

View file

@ -24,19 +24,45 @@
#include "dither-ops.h"
/* 32 bit xorshift PRNG, see https://en.wikipedia.org/wiki/Xorshift */
static inline uint32_t
xorshift(uint32_t *state)
{
uint32_t x = *state;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return (*state = x);
}
static inline void update_dither_c(struct dither *dt, uint32_t n_samples)
{
uint32_t n;
for (n = 0; n < n_samples; n++)
dt->dither[n] = ((int32_t)xorshift(&dt->random[0])) * dt->scale;
}
void dither_f32_c(struct dither *dt, void * SPA_RESTRICT dst[],
const void * SPA_RESTRICT src[], uint32_t n_samples)
{
uint32_t i, n;
uint32_t i, n, m, chunk;
const float **s = (const float**)src;
float **d = (float**)dst;
const float *t = dt->tab;
int tab_idx = dt->tab_idx;
float *t = dt->dither;
for (i = 0; i < dt->n_channels; i++) {
for (n = 0; n < n_samples; n++)
d[i][n] = s[i][n] + t[tab_idx++ & DITHER_MOD];
tab_idx += 61;
chunk = SPA_MIN(n_samples, dt->dither_size);
update_dither_c(dt, chunk);
for (n = 0; n < n_samples; n += chunk) {
chunk = SPA_MIN(n_samples - n, dt->dither_size);
for (i = 0; i < dt->n_channels; i++) {
float *di = &d[i][n];
const float *si = &s[i][n];
for (m = 0; m < chunk; m++)
di[m] = si[m] + t[m];
}
}
dt->tab_idx = tab_idx & DITHER_MOD;
}