summaryrefslogtreecommitdiff
path: root/libswresample/dither_template.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-01-09 18:03:49 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-01-09 18:25:06 +0100
commit82742294b7a866b89d6fd228b0692867d9e08fcd (patch)
tree054242b79f9f2ad1dfa6b85d5bbfe3e24d83d3ed /libswresample/dither_template.c
parent5b69c07d12b1e505fd7468828ed85d6d8d634621 (diff)
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.c53
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