From 4b8a3d8a89814dc3fb365f18d01733e26eb495a1 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Thu, 23 Aug 2007 03:16:02 -0700 Subject: This is a tool to compute the the reconstruction filter coefficients for a sinc audio resampler. Change-Id: I99be2505139b8e0e7647200e1647509d4f7e6067 Signed-off-by: Glenn Kasten --- tools/resampler_tools/Makefile | 17 +++++++ tools/resampler_tools/fir.cpp | 109 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 tools/resampler_tools/Makefile create mode 100644 tools/resampler_tools/fir.cpp (limited to 'tools') diff --git a/tools/resampler_tools/Makefile b/tools/resampler_tools/Makefile new file mode 100644 index 0000000..28bd993 --- /dev/null +++ b/tools/resampler_tools/Makefile @@ -0,0 +1,17 @@ +# Copyright 2005 Google Inc. All Rights Reserved. +# +# Makefile for resampler_tools +# + + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + fir.cpp + +LOCAL_TARGET := fir + +include $(BUILD_HOST_EXECUTABLE) + + diff --git a/tools/resampler_tools/fir.cpp b/tools/resampler_tools/fir.cpp new file mode 100644 index 0000000..919a97b --- /dev/null +++ b/tools/resampler_tools/fir.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2007 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +static double sinc(double x) { + if (fabs(x) == 0.0f) return 1.0f; + return sin(x) / x; +} + +static double sqr(double x) { + return x*x; +} + +static double I0(double x) { + // from the Numerical Recipes in C p. 237 + double ax,ans,y; + ax=fabs(x); + if (ax < 3.75) { + y=x/3.75; + y*=y; + ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492 + +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2))))); + } else { + y=3.75/ax; + ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1 + +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2 + +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1 + +y*0.392377e-2)))))))); + } + return ans; +} + +static double kaiser(int k, int N, double alpha) { + if (k < 0 || k > N) + return 0; + return I0(M_PI*alpha * sqrt(1.0 - sqr((2.0*k)/N - 1.0))) / I0(M_PI*alpha); +} + +int main(int argc, char** argv) +{ + // nc is the number of bits to store the coefficients + int nc = 16; + + // ni is the minimum number of bits needed for interpolation + // (not used for generating the coefficients) + const int ni = nc / 2; + + // nzc is the number of zero-crossing on one half of the filter + int nzc = 12; + + // alpha parameter of the kaiser window + // Larger numbers reduce ripples in the rejection band but increase + // the width of the transition band. In reality there doesn't seem to be + // a good reason to choose a big number because of the limited range + // of our coefficients (16 bits). + double alpha = 3.0; + + // cut off frequency ratio Fc/Fs + double Fcr = 20000.0 / 44100.0; + + // 2^nz is the number coefficients per zero-crossing + // (int theory this should be 1<<(nc/2)) + const int nz = 4; + + // total number of coefficients + const int N = (1 << 4) * nzc; + + // generate the right half of the filter + + printf("const int32_t RESAMPLE_FIR_SIZE = %d;\n", N); + printf("const int32_t RESAMPLE_FIR_NUM_COEF = %d;\n", nzc); + printf("const int32_t RESAMPLE_FIR_COEF_BITS = %d;\n", nc); + printf("const int32_t RESAMPLE_FIR_LERP_FRAC_BITS = %d;\n", ni); + printf("const int32_t RESAMPLE_FIR_LERP_INT_BITS = %d;\n", nz); + printf("\n"); + printf("static int16_t resampleFIR[%d] = {", N); + for (int i=0 ; i= (1<<(nc-1))) yi = (1<<(nc-1))-1; + + //printf("%6d\n", yi); + + if ((i % (1 << 4)) == 0) printf("\n "); + printf("0x%04x, ", yi & 0xFFFF); + } + printf("\n};\n"); + + return 0; + } + \ No newline at end of file -- cgit v1.1