[PATCH 02/13] dsound: Resample filter table generator.
Krzysztof Nikiel
knik00 at gmail.com
Fri Feb 11 03:20:42 CST 2011
---
dlls/dsound/mkfir.c | 202
+++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 202 insertions(+), 0 deletions(-)
create mode 100644 dlls/dsound/mkfir.c
diff --git a/dlls/dsound/mkfir.c b/dlls/dsound/mkfir.c
new file mode 100644
index 0000000..001778b
--- /dev/null
+++ b/dlls/dsound/mkfir.c
@@ -0,0 +1,202 @@
+/* DirectSound
+ *
+ * Resample filter table generator
+ * Copyright 2010 Krzysztof Nikiel
+ *
+ * Initially based on resample:
+ * http://www-ccrma.stanford.edu/~jos/resample/
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdint.h>
+#include <time.h>
+
+#ifndef RESAMPLE_INSANE
+#define RESAMPLE_INSANE 0
+#endif
+
+#define FREE(x) if(x)free(x);x=NULL
+#define ALLOC(x,size) FREE(x);x=malloc(size*sizeof(x[0]));\
+ memset(x,0,size*sizeof(x[0]))
+
+
+typedef struct {
+ double *wing;
+ int size;
+ int step;
+} fir_t;
+
+static fir_t FIR;
+static fir_t *g_fir = &FIR;
+
+static struct {
+ const char *const name;
+ const int step;
+ const double Beta;
+ const double width0;
+ const double passband;
+ const char *const comment;
+} firparams[] = {
+ {"fast",
+ 12, 4, 4, 0.8
+ },
+ {"good",
+ 22, 6, 10, 0.92
+ },
+ {"best",
+ 62, 8, 16, 0.94
+ },
+ {"slow",
+ 502, 12, 28, 0.95
+ },
+#if RESAMPLE_INSANE
+ {"insane",
+ 2381, 16.2, 142.8975, 0.965,
+ "same as libsamplerate high_qual"},
+#endif
+ {NULL}
+};
+
+
+/**
+ * Kaiser windowed filter generator
+ */
+static double Izero(double x)
+{
+ const double IzeroEPSILON = 1e-30; /* Max error acceptable in Izero */
+ double sum, u, halfx, temp;
+ int n;
+
+ sum = u = n = 1;
+ halfx = x / 2.0;
+ do
+ {
+ temp = halfx / (double) n;
+ n += 1;
+ temp *= temp;
+ u *= temp;
+ sum += u;
+ }
+ while (u >= IzeroEPSILON * sum);
+
+ return (sum);
+}
+
+static void makefir(int idx)
+{
+ int cnt;
+ double IBeta;
+ double tmp, tmp2;
+ double cutoff;
+
+ for (cnt = 0; cnt <= idx; cnt++)
+ {
+ if (!firparams[cnt].name)
+ break;
+ }
+ idx = cnt - 1;
+
+ fprintf(stderr, "creating %s filter...", firparams[idx].name);
+ fflush(stderr);
+
+ g_fir->step = firparams[idx].step;
+ g_fir->size = firparams[idx].width0 * g_fir->step;
+ ALLOC(g_fir->wing, g_fir->size);
+
+ IBeta = 1.0 / Izero(firparams[idx].Beta);
+ cutoff = firparams[idx].passband / g_fir->step;
+ g_fir->wing[0] = 1.0;
+
+ for (cnt = 1; cnt < g_fir->size; cnt++)
+ {
+ tmp = (double) (cnt) / g_fir->size;
+ tmp2 = M_PI * cnt * cutoff;
+
+ /* Kaiser windowed sinc */
+ g_fir->wing[cnt] = sin(tmp2) / tmp2
+ * Izero(firparams[idx].Beta * sqrt(1.0 - tmp * tmp)) * IBeta;
+ }
+
+ /* normalize the table */
+ tmp = g_fir->wing[0];
+ for (cnt = 1; cnt < g_fir->size; cnt++)
+ tmp += 2.0 * g_fir->wing[cnt];
+ tmp = 1.0 / tmp;
+ for (cnt = 0; cnt < g_fir->size; cnt++)
+ g_fir->wing[cnt] *= tmp;
+
+ fprintf(stderr, "OK\n");
+}
+
+static void deletefir(void)
+{
+ FREE(g_fir->wing);
+ g_fir->size = 0;
+}
+
+static void printhdr(char *item)
+{
+ time_t t;
+
+ time(&t);
+ printf("/* %s autogenerated on %s */\n", item, ctime(&t));
+}
+
+static void printfir(const char *name)
+{
+ int cnt;
+
+ printf("fir_t fir%s = {\n%d,\n%d,\n{\n", name, g_fir->size, g_fir->step);
+
+ for (cnt = 0; cnt < g_fir->size - 1; cnt++)
+ printf("%.18g,\n", g_fir->wing[cnt]);
+
+ printf("%.18g\n}};\n\n", g_fir->wing[cnt]);
+}
+
+int main(void)
+{
+ int firidx;
+
+ memset(g_fir, 0, sizeof(g_fir));
+
+ printhdr("File");
+
+ printf("\n#define RESAMPLE_INSANE %d\n", RESAMPLE_INSANE);
+
+ printf("\ntypedef struct {\n"
+ "int size;\n"
+ "int step;\n"
+ "double wing[];\n"
+ "} fir_t;\n\n");
+
+ for (firidx = 0; firparams[firidx].name; firidx++)
+ {
+ makefir(firidx);
+ fprintf(stderr, "size:%d\n", g_fir->size);
+ if (firparams[firidx].comment)
+ printf("/* %s */\n", firparams[firidx].comment);
+ printfir(firparams[firidx].name);
+ deletefir();
+ }
+
+ return 0;
+}
--
1.7.2.3
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20110211/25e038fa/attachment.htm>
More information about the wine-patches
mailing list