diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-01-09 18:03:49 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-01-09 18:25:06 +0100 |
commit | 82742294b7a866b89d6fd228b0692867d9e08fcd (patch) | |
tree | 054242b79f9f2ad1dfa6b85d5bbfe3e24d83d3ed /libswresample/dither_template.c | |
parent | 5b69c07d12b1e505fd7468828ed85d6d8d634621 (diff) | |
download | ffmpeg-82742294b7a866b89d6fd228b0692867d9e08fcd.tar.gz |
swr: Implement Noise shaping dither
The following variants are implemented:
lipshitz noise shaping dither
shibata noise shaping dither
low shibata noise shaping dither
high shibata noise shaping dither
f-weighted noise shaping dither
modified-e-weighted noise shaping dither
improved-e-weighted noise shaping dither
Data tables taken from SOX
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libswresample/dither_template.c')
-rw-r--r-- | libswresample/dither_template.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/libswresample/dither_template.c b/libswresample/dither_template.c new file mode 100644 index 0000000000..7e99c50700 --- /dev/null +++ b/libswresample/dither_template.c @@ -0,0 +1,53 @@ + +#if defined(TEMPLATE_DITHER_DBL) +# define RENAME(N) N ## _double +# define DELEM double +# define CLIP(v) + +#elif defined(TEMPLATE_DITHER_FLT) +# define RENAME(N) N ## _float +# define DELEM float +# define CLIP(v) + +#elif defined(TEMPLATE_DITHER_S32) +# define RENAME(N) N ## _int32 +# define DELEM int32_t +# define CLIP(v) v = FFMAX(FFMIN(v, INT32_MAX), INT32_MIN) + +#elif defined(TEMPLATE_DITHER_S16) +# define RENAME(N) N ## _int16 +# define DELEM int16_t +# define CLIP(v) v = FFMAX(FFMIN(v, INT16_MAX), INT16_MIN) + +#else +ERROR +#endif + +void RENAME(swri_noise_shaping)(SwrContext *s, AudioData *srcs, AudioData *noises, int count){ + int i, j, pos, ch; + int taps = s->ns_taps; + float S = s->ns_scale; + float S_1 = s->ns_scale_1; + + for (ch=0; ch<srcs->ch_count; ch++) { + const float *noise = ((const float *)noises->ch[ch]) + s->dither_pos; + DELEM *data = (DELEM*)srcs->ch[ch]; + pos = s->ns_pos; + for (i=0; i<count; i++) { + double d1, d = data[i]; + for(j=0; j<taps; j++) + d -= s->ns_coeffs[j] * s->ns_errors[ch][pos + j]; + pos = pos ? pos - 1 : pos - 1 + taps; + d1 = rint((d + noise[i]) * S_1)*S; + s->ns_errors[ch][pos + taps] = s->ns_errors[ch][pos] = d1 - d; + CLIP(d1); + data[i] = d1; + } + } + + s->ns_pos = pos; +} + +#undef RENAME +#undef DELEM +#undef CLIP |