[PATCH 02/13] dsound: Resample filter table generator. (resend)

Krzysztof Nikiel knik00 at gmail.com
Fri Feb 11 05:36:35 CST 2011


---
 dlls/dsound/mkfir.c |  199 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 199 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..8eab81a
--- /dev/null
+++ b/dlls/dsound/mkfir.c
@@ -0,0 +1,199 @@
+/* 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



More information about the wine-patches mailing list