[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