00001 /* 00002 $Id: Sndfilterkit.h 3544 2009-05-06 20:04:52Z leighsmith $ 00003 00004 Original License: 00005 Copyright (c) 1984, Julius Smith 00006 All rights reserved. 00007 00008 This is free software from the Digital Audio Resampling Home Page: 00009 http://www-ccrma.stanford.edu/~jos/resample/. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions are met: 00013 00014 Redistributions of source code must retain the above copyright notice, this 00015 list of conditions and the following disclaimer. 00016 Redistributions in binary form must reproduce the above copyright notice, 00017 this list of conditions and the following disclaimer in the documentation 00018 and/or other materials provided with the distribution. 00019 Neither the name of CCRMA, Stanford University, nor the names of its 00020 contributors may be used to endorse or promote products derived from this 00021 software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00029 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00030 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00031 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00033 POSSIBILITY OF SUCH DAMAGE. 00034 00035 Subsequent changes: 00036 Copyright (c) 1999, The MusicKit Project. All rights reserved. 00037 00038 */ 00039 00040 #if HAVE_CONFIG_H 00041 # include "SndKitConfig.h" 00042 #endif 00043 00044 /* 00045 * LpFilter() - Calculates the filter coeffs for a Kaiser-windowed low-pass 00046 * filter with a given roll-off frequency. These coeffs 00047 * are stored into a array of doubles. 00048 * writeFilter() - Writes a filter to a file. 00049 * makeFilter() - Calls LpFilter() to create a filter, then scales the double 00050 * coeffs into an array of half words. 00051 * readFilter() - Reads a filter from a file. 00052 * FilterUp() - Applies a filter to a given sample when up-converting. 00053 * FilterUD() - Applies a filter to a given sample when up- or down- 00054 * converting. 00055 * initZerox() - Initialization routine for the zerox() function. Must 00056 * be called before zerox() is called. This routine loads 00057 * the correct filter so zerox() can use it. 00058 * zerox() - Given a pointer into a sample, finds a zero-crossing on the 00059 * interval [pointer-1:pointer+2] by iteration. 00060 */ 00061 00062 void LpFilter(double c[], int N, double frq, double Beta, int Num); 00063 /* 00064 * reference: "Digital Filters, 2nd edition" 00065 * R.W. Hamming, pp. 178-179 00066 * 00067 * LpFilter() computes the coeffs of a Kaiser-windowed low pass filter with 00068 * the following characteristics: 00069 * 00070 * c[] = array in which to store computed coeffs 00071 * frq = roll-off frequency of filter 00072 * N = Half the window length in number of coeffs 00073 * Beta = parameter of Kaiser window 00074 * Num = number of coeffs before 1/frq 00075 * 00076 * Beta trades the rejection of the lowpass filter against the transition 00077 * width from passband to stopband. Larger Beta means a slower 00078 * transition and greater stopband rejection. See Rabiner and Gold 00079 * (Theory and Application of DSP) under Kaiser windows for more about 00080 * Beta. The following table from Rabiner and Gold gives some feel 00081 * for the effect of Beta: 00082 * 00083 * All ripples in dB, width of transition band = D*N where N = window length 00084 * 00085 * BETA D PB RIP SB RIP 00086 * 2.120 1.50 +-0.27 -30 00087 * 3.384 2.23 0.0864 -40 00088 * 4.538 2.93 0.0274 -50 00089 * 5.658 3.62 0.00868 -60 00090 * 6.764 4.32 0.00275 -70 00091 * 7.865 5.0 0.000868 -80 00092 * 8.960 5.7 0.000275 -90 00093 * 10.056 6.4 0.000087 -100 00094 */ 00095 00096 int writeFilter(SND_HWORD Imp[], SND_HWORD ImpD[], SND_UHWORD LpScl, SND_UHWORD Nmult, SND_UHWORD Nwing); 00097 /* 00098 * Write a filter to a file 00099 * Filter file format: 00100 * file name: "F" Nmult "T" Nhc ".filter" 00101 * 1st line: the string "ScaleFactor" followed by its value. 00102 * 2nd line: the string "Length" followed by Nwing's value. 00103 * 3rd line: the string "Coeffs:" on a separate line. 00104 * following lines: Nwing number of 16-bit impulse response values 00105 * in the right wing of the impulse response (the Imp[] array). 00106 * (Nwing is equal to Npc*(Nmult+1)/2+1, where Npc is defined in the 00107 * file "resample.h".) Each coefficient is on a separate line. 00108 * next line: the string "Differences:" on a separate line. 00109 * following lines: Nwing number of 16-bit impulse-response 00110 * successive differences: ImpD[i] = Imp[i+1] - Imp[i]. 00111 * ERROR codes: 00112 * 0 - no error 00113 * 1 - could not open file 00114 */ 00115 00116 int makeFilter(SND_HWORD Imp[], SND_HWORD ImpD[], SND_UHWORD *LpScl, SND_UHWORD Nwing, 00117 double Froll, double Beta); 00118 /* 00119 * makeFilter 00120 * ERROR return codes: 00121 * 0 - no error 00122 * 1 - Nwing too large (Nwing is > MAXNWING) 00123 * 2 - Froll is not in interval [0:1) 00124 * 3 - Beta is < 1.0 00125 * 4 - LpScl will not fit in 16-bits 00126 */ 00127 00128 int readFilter(char *filterFile, 00129 SND_HWORD **ImpP, SND_HWORD **ImpDP, SND_UHWORD *LpScl, 00130 SND_UHWORD *Nmult, SND_UHWORD *Nwing); 00131 /* 00132 * Read-in a filter 00133 * Filter file format: 00134 * Default file name: "F" Nmult "T" Nhc ".filter" 00135 * 1st line: the string "ScaleFactor" followed by its value. 00136 * 2nd line: the string "Length" followed by Nwing's value. 00137 * 3rd line: the string "Coeffs:" on separate line. 00138 * Nwing number of 16-bit impulse response values in the right 00139 * wing of the impulse response. (Length=Npc*(Nmult+1)/2+1, 00140 * where originally Npc=2^9, and Nmult=13.) Each on separate line. 00141 * The string "Differences:" on separate line. 00142 * Nwing number of 16-bit impulse-response successive differences: 00143 * ImpDiff[i] = Imp[i+1] - Imp[i]. 00144 * 00145 * ERROR return codes: 00146 * 0 - no error 00147 * 1 - file not found 00148 * 2 - invalid ScaleFactor in file 00149 * 3 - invalid Length in file 00150 */ 00151 00152 SND_WORD FilterUp(SND_HWORD Imp[], SND_HWORD ImpD[], SND_UHWORD Nwing, BOOL Interp, 00153 SND_HWORD *Xp, SND_HWORD Inc, SND_HWORD Ph); 00154 00155 SND_WORD FilterUD(SND_HWORD Imp[], SND_HWORD ImpD[], SND_UHWORD Nwing, BOOL Interp, 00156 SND_HWORD *Xp, SND_HWORD Ph, SND_HWORD Inc, SND_UHWORD dhb); 00157 00158 int initZerox(SND_UHWORD tempNmult); 00159 /* 00160 * initZerox 00161 * ERROR return values: 00162 * 0 - no error 00163 * 1 - Nmult is even (should be odd) 00164 * 2 - filter file not found 00165 * 3 - invalid ScaleFactor in input file 00166 * 4 - invalid Length in file 00167 */ 00168 00169 /* 00170 * zerox 00171 * Given a pointer into a sound sample, this function uses a low-pass 00172 * filter to estimate the x coordinate of the zero-crossing which must ocurr 00173 * between Data[0] and Data[1]. This value is returned as the value of the 00174 * function. A return value of -100 indicates there was no zero-crossing in 00175 * the x interval [-1,2]. Factor is the resampling factor: Rate(out) / 00176 * Rate(in). Nmult (which determines which filter is used) is passed the 00177 * zerox's initialization routine: initZerox(Nmult) 00178 */ 00179 double zerox(SND_HWORD *Data, double Factor); 00180 00181 #define GetUHWORD(x,y,z) GetUShort(x,y,z) 00182