Unified · Split
| @@ -1,40 +0,0 @@ | ||
| 1 | −TARGETS = fir_interp | |
| 2 | − | |
| 3 | −CXX = g++ | |
| 4 | −CXXFLAGS = -g -O3 -Wall -W -Werror -Wstrict-prototypes -Wmissing-prototypes | |
| 5 | − | |
| 6 | −GMATH_INC = $(shell pkg-config --cflags GMath) | |
| 7 | −GMATH_LIB = $(shell pkg-config --libs GMath) | |
| 8 | − | |
| 9 | −FFTW_INC = $(shell pkg-config --cflags fftw3) | |
| 10 | −FFTW_LIB = $(shell pkg-config --libs fftw3) | |
| 11 | − | |
| 12 | − | |
| 13 | − | |
| 14 | −all: $(TARGETS) | |
| 15 | − | |
| 16 | −clean: | |
| 17 | − rm -f $(TARGETS) *.o | |
| 18 | − | |
| 19 | −check: $(TARGETS) | |
| 20 | − ./fir_interp | |
| 21 | − | |
| 22 | −fir_interp: fir_interp.o mag_spectrum.o demin.o | |
| 23 | − $(CXX) $(CXXFLAGS) $+ $(GMATH_LIB) $(FFTW_LIB) -o $@ | |
| 24 | − | |
| 25 | −#--------------------------------------------------------------------- | |
| 26 | − | |
| 27 | −fir_interp.o : fir_interp.cc mag_spectrum.hh | |
| 28 | − $(CXX) $(CXXFLAGS) $(GMATH_INC) -c fir_interp.cc -o $@ | |
| 29 | − | |
| 30 | −mag_spectrum.o : mag_spectrum.cc mag_spectrum.hh | |
| 31 | − $(CXX) $(CXXFLAGS) $(FFTW_INC) -c mag_spectrum.cc -o $@ | |
| 32 | − | |
| 33 | −demin.o : demin.cc | |
| 34 | − $(CXX) $(CXXFLAGS) $(GMATH_INC) -c $+ -o $@ | |
| 35 | − | |
| 36 | −# Do not edit or modify anything in this comment block. | |
| 37 | −# The arch-tag line is a file identity tag for the GNU Arch | |
| 38 | −# revision control system. | |
| 39 | −# | |
| 40 | −# arch-tag: 34b6b183-dca1-4085-9089-c8b7d5b09099 | |
| @@ -1,270 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** Copyright (C) 1998-2004 Erik de Castro Lopo <erikd@mega-nerd.com> | |
| 3 | −** | |
| 4 | −** The copyright above and this notice must be preserved in all | |
| 5 | −** copies of this source code. The copyright above does not | |
| 6 | −** evidence any actual or intended publication of this source code. | |
| 7 | −** | |
| 8 | −** This is unpublished proprietary trade secret of Erik de Castro | |
| 9 | −** Lopo. This source code may not be copied, disclosed, | |
| 10 | −** distributed, demonstrated or licensed except as authorized by | |
| 11 | −** Erik de Castro Lopo. | |
| 12 | −** | |
| 13 | −** No part of this program or publication may be reproduced, | |
| 14 | −** transmitted, transcribed, stored in a retrieval system, | |
| 15 | −** or translated into any language or computer language in any | |
| 16 | −** form or by any means, electronic, mechanical, magnetic, | |
| 17 | −** optical, chemical, manual, or otherwise, without the prior | |
| 18 | −** written permission of Erik de Castro Lopo. | |
| 19 | −*/ | |
| 20 | − | |
| 21 | −#include <stdio.h> | |
| 22 | −#include <unistd.h> | |
| 23 | − | |
| 24 | −#include <Minimize.hh> | |
| 25 | −#include <PsuedoRand.hh> | |
| 26 | − | |
| 27 | −class DEmin | |
| 28 | −{ private : | |
| 29 | − u_int PopSize, FuncCalcs, Generations ; | |
| 30 | − | |
| 31 | − PsuedoRand Rand ; | |
| 32 | − | |
| 33 | − GMatrix *MainVector, *Vector2 ; | |
| 34 | − double *MainCost, *Cost2 ; | |
| 35 | − double *ScaleFactor, *ScaleFactor2 ; | |
| 36 | − double *Crossover, *Crossover2 ; | |
| 37 | − | |
| 38 | − MinFunc Function ; | |
| 39 | − | |
| 40 | − public : | |
| 41 | − DEmin (void) ; | |
| 42 | − ~DEmin (void) ; | |
| 43 | − | |
| 44 | − void Setup (MinFunc func, const GMatrix& start, u_int popsize, double range, u_long seed) ; | |
| 45 | − | |
| 46 | − GMatrix Minimize (double tol, u_int maxgen) ; | |
| 47 | − | |
| 48 | − void PrintStats (void) ; | |
| 49 | − | |
| 50 | −} ; // class DEmin | |
| 51 | − | |
| 52 | −//====================================================================================== | |
| 53 | − | |
| 54 | −inline | |
| 55 | −void Swap (GMatrix **a, GMatrix **b) | |
| 56 | −{ GMatrix *temp ; | |
| 57 | − temp = *a ; *a = *b ; *b = temp ; | |
| 58 | −} ; // | |
| 59 | − | |
| 60 | −inline void | |
| 61 | −Swap (double **a, double **b) | |
| 62 | −{ double *temp ; | |
| 63 | − temp = *a ; *a = *b ; *b = temp ; | |
| 64 | −} ; // Swap | |
| 65 | − | |
| 66 | −inline double | |
| 67 | −Max (double a, double b) | |
| 68 | −{ return (a > b) ? a : b ; | |
| 69 | −} ; // Max | |
| 70 | − | |
| 71 | −inline double | |
| 72 | −Min (double a, double b) | |
| 73 | −{ return (a < b) ? a : b ; | |
| 74 | −} ; // Max | |
| 75 | − | |
| 76 | −//====================================================================================== | |
| 77 | − | |
| 78 | −double | |
| 79 | −MinDiffEvol (MinFunc Function, GMatrix& start, double Ftol, double range, u_long seedval) | |
| 80 | −{ DEmin *pfmin ; | |
| 81 | − u_int dimensions ; | |
| 82 | − | |
| 83 | − dimensions = start.GetElements () ; | |
| 84 | − if (dimensions < 20) | |
| 85 | − dimensions = 20 ; | |
| 86 | − | |
| 87 | − pfmin = new DEmin ; | |
| 88 | − | |
| 89 | − pfmin -> Setup (Function, start, dimensions * 5, range, seedval) ; | |
| 90 | − | |
| 91 | − Ftol = (Ftol < 1e-8) ? 1e-8 : Ftol ; | |
| 92 | − | |
| 93 | − start = pfmin -> Minimize (Ftol, dimensions * 5000) ; | |
| 94 | − | |
| 95 | − delete pfmin ; | |
| 96 | − | |
| 97 | − return Function (start) ; | |
| 98 | −} ; // MinDiffEvol | |
| 99 | − | |
| 100 | − | |
| 101 | −//====================================================================================== | |
| 102 | − | |
| 103 | −DEmin::DEmin (void) | |
| 104 | −{ PopSize = 0 ; | |
| 105 | − FuncCalcs = 0 ; | |
| 106 | − Generations = 0 ; | |
| 107 | − MainVector = NULL ; | |
| 108 | − MainCost = NULL ; | |
| 109 | − ScaleFactor = NULL ; | |
| 110 | − Crossover = NULL ; | |
| 111 | − Vector2 = NULL ; | |
| 112 | − Cost2 = NULL ; | |
| 113 | − ScaleFactor2 = NULL ; | |
| 114 | − Crossover2 = NULL ; | |
| 115 | −} ; // DEmin constructor | |
| 116 | − | |
| 117 | −DEmin::~DEmin (void) | |
| 118 | −{ if (PopSize) | |
| 119 | − { delete [] MainVector ; | |
| 120 | − delete MainCost ; | |
| 121 | − delete ScaleFactor ; | |
| 122 | − delete Crossover ; | |
| 123 | − delete [] Vector2 ; | |
| 124 | − delete Cost2 ; | |
| 125 | − delete ScaleFactor2 ; | |
| 126 | − delete Crossover2 ; | |
| 127 | − } ; | |
| 128 | − PopSize = 0 ; | |
| 129 | −} ; // DEmin destructor | |
| 130 | − | |
| 131 | −void | |
| 132 | −DEmin::Setup (MinFunc func, const GMatrix& start, u_int popsize, double range, u_long seed) | |
| 133 | −{ u_int k ; | |
| 134 | − u_short rows, cols ; | |
| 135 | − | |
| 136 | − Generations = 0 ; | |
| 137 | − Function = func ; | |
| 138 | − | |
| 139 | − PopSize = (popsize < 2) ? popsize + 2 : popsize ; | |
| 140 | − | |
| 141 | − MainVector = new GMatrix [PopSize] ; | |
| 142 | − MainCost = new double [PopSize] ; | |
| 143 | − ScaleFactor = new double [PopSize] ; | |
| 144 | − Crossover = new double [PopSize] ; | |
| 145 | − Vector2 = new GMatrix [PopSize] ; | |
| 146 | − Cost2 = new double [PopSize] ; | |
| 147 | − ScaleFactor2 = new double [PopSize] ; | |
| 148 | − Crossover2 = new double [PopSize] ; | |
| 149 | − | |
| 150 | − Rand.Seed (seed + 1234567) ; | |
| 151 | − | |
| 152 | − rows = start.GetRows () ; | |
| 153 | − cols = start.GetCols () ; | |
| 154 | − | |
| 155 | − GMatrix::PsuedoRandSeed (123123) ; | |
| 156 | − | |
| 157 | − if (IsComplex (start)) | |
| 158 | − for (k = 0 ; k < PopSize ; k++) | |
| 159 | − { MainVector [k].SetSizeComplex (rows, cols) ; | |
| 160 | − MainVector [k].PsuedoRandomize () ; | |
| 161 | − MainVector [k] = (2.0 * range) * (MainVector [k] - Complex (0.5, 0.5)) ; | |
| 162 | − } | |
| 163 | − else | |
| 164 | − for (k = 0 ; k < PopSize ; k++) | |
| 165 | − { MainVector [k].SetSizeDouble (rows, cols) ; | |
| 166 | − MainVector [k].PsuedoRandomize () ; | |
| 167 | − MainVector [k] = (2.0 * range) * (MainVector [k] - 0.5) ; | |
| 168 | − } ; | |
| 169 | − | |
| 170 | − MainVector [0] = start ; // Must include given vector. | |
| 171 | − | |
| 172 | − for (k = 0 ; k < PopSize ; k++) | |
| 173 | − { MainCost [k] = Function (MainVector [k]) ; | |
| 174 | − FuncCalcs ++ ; | |
| 175 | − ScaleFactor [k] = 1.2 * Rand.UDDouble () ; | |
| 176 | − Crossover [k] = Rand.UDDouble () ; | |
| 177 | − } ; | |
| 178 | − | |
| 179 | − return ; | |
| 180 | −} ; // DEmin::Setup | |
| 181 | − | |
| 182 | −GMatrix | |
| 183 | −DEmin::Minimize (double Ftol, u_int maxgen) | |
| 184 | −{ u_int k, a, b, c ; | |
| 185 | − GMatrix temp ; | |
| 186 | − double scalefactor, crossover, cost, improvement, best ; | |
| 187 | − | |
| 188 | − improvement = 100 * Ftol ; | |
| 189 | − best = 10e10 ; | |
| 190 | − | |
| 191 | − while (Generations < maxgen && best > Ftol) | |
| 192 | − { Swap (&MainVector, &Vector2) ; | |
| 193 | − Swap (&MainCost, &Cost2) ; | |
| 194 | − Swap (&ScaleFactor, &ScaleFactor2) ; | |
| 195 | − Swap (&Crossover, &Crossover2) ; | |
| 196 | − | |
| 197 | − improvement = 0.0 ; | |
| 198 | − | |
| 199 | − for (k = 0 ; k < PopSize ; k++) | |
| 200 | − { do | |
| 201 | − a = u_int (double (PopSize) * Rand.UDDouble ()) ; | |
| 202 | − while (a == k || a >= PopSize) ; | |
| 203 | − do | |
| 204 | − b = u_int (double (PopSize) * Rand.UDDouble ()) ; | |
| 205 | − while (b == k || b == a || b >= PopSize) ; | |
| 206 | − do | |
| 207 | − c = u_int (double (PopSize) * Rand.UDDouble ()) ; | |
| 208 | − while (c == k || c == a || c == b || c >= PopSize) ; | |
| 209 | − | |
| 210 | −if (a >= PopSize) { printf ("a - very bad (%u, %u).\n", a, PopSize) ; exit (0) ; } ; | |
| 211 | −if (b >= PopSize) { printf ("b - very bad (%u, %u).\n", b, PopSize) ; exit (0) ; } ; | |
| 212 | −if (c >= PopSize) { printf ("c - very bad (%u, %u).\n", c, PopSize) ; exit (0) ; } ; | |
| 213 | − | |
| 214 | − scalefactor = 0.5 * (ScaleFactor2 [b] + ScaleFactor2 [c]) ; | |
| 215 | − | |
| 216 | − temp = Vector2 [a] + scalefactor * (Vector2 [b] - Vector2 [c]) ; | |
| 217 | − | |
| 218 | − crossover = 0.5 * (Crossover2 [k] + Crossover2 [a]) ; | |
| 219 | − | |
| 220 | − temp.CrossOver (Vector2 [k], crossover) ; | |
| 221 | − | |
| 222 | − cost = Function (temp) ; | |
| 223 | − FuncCalcs ++ ; | |
| 224 | − | |
| 225 | − if (cost < Cost2 [k]) | |
| 226 | − { MainVector [k] = temp ; | |
| 227 | − MainCost [k] = cost ; | |
| 228 | − ScaleFactor [k] = scalefactor ; | |
| 229 | − Crossover [k] = crossover ; | |
| 230 | − improvement = 0.5 * (improvement + Max (improvement, Cost2 [k] - cost)) ; | |
| 231 | − best = Min (best, cost) ; | |
| 232 | − } | |
| 233 | − else | |
| 234 | − { MainVector [k] = Vector2 [k] ; | |
| 235 | − MainCost [k] = Cost2 [k] ; | |
| 236 | − ScaleFactor [k] = ScaleFactor2 [k] ; | |
| 237 | − Crossover [k] = Crossover2 [k] ; | |
| 238 | − } ; // if | |
| 239 | − } ; // for k | |
| 240 | − | |
| 241 | − Generations ++ ; | |
| 242 | − } ; // while | |
| 243 | − | |
| 244 | − // Now find best vector. | |
| 245 | − | |
| 246 | − for (a = 0, k = 1 ; k < PopSize ; k++) | |
| 247 | − if (MainCost [k] < MainCost [a]) | |
| 248 | − a = k ; | |
| 249 | − temp = MainVector [a] ; | |
| 250 | − | |
| 251 | − return temp ; | |
| 252 | −} ; // DEmin::Minimize | |
| 253 | − | |
| 254 | −void | |
| 255 | −DEmin::PrintStats (void) | |
| 256 | −{ printf ("Generations : %8d\n", Generations) ; | |
| 257 | − printf ("Function evaluations : %8d\n", FuncCalcs) ; | |
| 258 | − putchar ('\n') ; | |
| 259 | −} ; // DEmin::PrintStats | |
| 260 | − | |
| 261 | −//====================================================================================== | |
| 262 | − | |
| 263 | − | |
| 264 | − | |
| 265 | −// Do not edit or modify anything in this comment block. | |
| 266 | −// The arch-tag line is a file identity tag for the GNU Arch | |
| 267 | −// revision control system. | |
| 268 | −// | |
| 269 | −// arch-tag: e874ad11-7294-4757-9370-fd1e6e1261d0 | |
| 270 | − | |
| @@ -1,457 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** Copyright (C) 2004 Erik de Castro Lopo <erikd@mega-nerd.com> | |
| 3 | −** | |
| 4 | −** The copyright above and this notice must be preserved in all | |
| 5 | −** copies of this source code. The copyright above does not | |
| 6 | −** evidence any actual or intended publication of this source code. | |
| 7 | −** | |
| 8 | −** This is unpublished proprietary trade secret of Erik de Castro | |
| 9 | −** Lopo. This source code may not be copied, disclosed, | |
| 10 | −** distributed, demonstrated or licensed except as authorized by | |
| 11 | −** Erik de Castro Lopo. | |
| 12 | −** | |
| 13 | −** No part of this program or publication may be reproduced, | |
| 14 | −** transmitted, transcribed, stored in a retrieval system, | |
| 15 | −** or translated into any language or computer language in any | |
| 16 | −** form or by any means, electronic, mechanical, magnetic, | |
| 17 | −** optical, chemical, manual, or otherwise, without the prior | |
| 18 | −** written permission of Erik de Castro Lopo. | |
| 19 | −*/ | |
| 20 | − | |
| 21 | − | |
| 22 | −#include <cstdio> | |
| 23 | −#include <cstdlib> | |
| 24 | −#include <unistd.h> | |
| 25 | −#include <ctime> | |
| 26 | −#include <cstring> | |
| 27 | −#include <complex> | |
| 28 | − | |
| 29 | −#include <GMatrix.hh> | |
| 30 | −#include <Minimize.hh> | |
| 31 | − | |
| 32 | −#include "mag_spectrum.hh" | |
| 33 | − | |
| 34 | −#define UPSAMPLE_RATIO 2 | |
| 35 | −#define ARRAY_LEN(x) (sizeof (x) / sizeof ((x) [0])) | |
| 36 | − | |
| 37 | −#define INTERP_LEN 1600 | |
| 38 | −/* | |
| 39 | −** Number of half cycles of impulse response to the left and right | |
| 40 | −** of the center. | |
| 41 | −** left_half_offset <= right_len | |
| 42 | −*/ | |
| 43 | − | |
| 44 | −static int left_len = 150 ; | |
| 45 | −static int right_len = 750 ; | |
| 46 | − | |
| 47 | − | |
| 48 | −typedef struct | |
| 49 | −{ | |
| 50 | − /* Window coefficients (all in range [0, 1]). */ | |
| 51 | − double y_left [10], y_right [10] ; | |
| 52 | − | |
| 53 | − double sinc_time_fudge ; | |
| 54 | − | |
| 55 | −} FIR_PARAMS ; | |
| 56 | − | |
| 57 | −typedef struct | |
| 58 | −{ | |
| 59 | − union | |
| 60 | − { FIR_PARAMS fir_params ; | |
| 61 | − double data [30] ; | |
| 62 | − } ; | |
| 63 | − | |
| 64 | − unsigned middle, total_len ; | |
| 65 | − | |
| 66 | − double left_window_poly [20] ; | |
| 67 | − double right_window_poly [20] ; | |
| 68 | − | |
| 69 | − double sinc [INTERP_LEN] ; | |
| 70 | − double window [INTERP_LEN] ; | |
| 71 | − double filter [INTERP_LEN] ; | |
| 72 | − double mag [INTERP_LEN / 2] ; | |
| 73 | − double logmag [INTERP_LEN / 2] ; | |
| 74 | − double phase [INTERP_LEN / 2] ; | |
| 75 | −} FIR_INTERP ; | |
| 76 | − | |
| 77 | −static double fir_error (const GMatrix& gm) ; | |
| 78 | −static int calc_window (FIR_INTERP *interp, double * error) ; | |
| 79 | −static void calc_sinc (FIR_INTERP *interp) ; | |
| 80 | −static void calc_filter (FIR_INTERP *interp) ; | |
| 81 | − | |
| 82 | −static void oct_save (const FIR_INTERP *interp) ; | |
| 83 | −static void randomize_data (FIR_INTERP *interp) ; | |
| 84 | − | |
| 85 | −static double evaluate_filter (FIR_INTERP *interp) ; | |
| 86 | − | |
| 87 | −int | |
| 88 | −main (void) | |
| 89 | −{ FIR_INTERP interp ; | |
| 90 | − GMatrix gm_start ; | |
| 91 | − double error ; | |
| 92 | − int param_count ; | |
| 93 | − | |
| 94 | − puts ("Running ........") ; | |
| 95 | − param_count = sizeof (FIR_PARAMS) / sizeof (double) ; | |
| 96 | − | |
| 97 | − randomize_data (&interp) ; | |
| 98 | − | |
| 99 | − gm_start = GMatrix (param_count, 1, interp.data) ; | |
| 100 | − | |
| 101 | − fir_error (gm_start) ; | |
| 102 | − | |
| 103 | − do | |
| 104 | − error = MinDiffEvol (fir_error, gm_start, 1e-15, 2.0, random ()) ; | |
| 105 | − while (error > 10.0) ; | |
| 106 | − | |
| 107 | − printf ("error : %f\n", error) ; | |
| 108 | − | |
| 109 | − return 0 ; | |
| 110 | −} /* main */ | |
| 111 | − | |
| 112 | −/*============================================================================== | |
| 113 | −*/ | |
| 114 | − | |
| 115 | −static inline double | |
| 116 | −poly_evaluate (int order, const double *coeff, double x) | |
| 117 | −{ double result ; | |
| 118 | − int k ; | |
| 119 | − | |
| 120 | − /* | |
| 121 | − ** Use Horner's Rule for evaluating the value of | |
| 122 | − ** the polynomial at x. | |
| 123 | − */ | |
| 124 | − result = coeff [order] ; | |
| 125 | − for (k = order - 1 ; k >= 0 ; k--) | |
| 126 | − result = result * x + coeff [k] ; | |
| 127 | − | |
| 128 | − return result ; | |
| 129 | −} /* poly_evaluate */ | |
| 130 | − | |
| 131 | −static double | |
| 132 | −evaluate_filter (FIR_INTERP *interp) | |
| 133 | −{ double error = 0.0, temp, stop_max = 0.0, stop_sum = 0.0 ; | |
| 134 | − unsigned k ; | |
| 135 | − | |
| 136 | − mag_spectrum (interp->filter, ARRAY_LEN (interp->filter), interp->mag, interp->logmag, interp->phase) ; | |
| 137 | − | |
| 138 | − for (k = ARRAY_LEN (interp->logmag) / UPSAMPLE_RATIO ; k < ARRAY_LEN (interp->logmag) ; k++) | |
| 139 | − { temp = interp->logmag [k] + 150.0 ; | |
| 140 | − if (temp > stop_max) | |
| 141 | − stop_max = temp ; | |
| 142 | − if (temp > 0.0) | |
| 143 | − stop_sum += temp ; | |
| 144 | − } ; | |
| 145 | − | |
| 146 | − error = stop_max * stop_sum ; | |
| 147 | − return error ; | |
| 148 | −} /* evaluate_filter */ | |
| 149 | − | |
| 150 | −static double | |
| 151 | −fir_error (const GMatrix& gm) | |
| 152 | −{ static FIR_INTERP interp ; | |
| 153 | − static int test_count = 0 ; | |
| 154 | − static double best_error = 1e200 ; | |
| 155 | − double error = 0.0 ; | |
| 156 | − unsigned param_count ; | |
| 157 | − | |
| 158 | − memset (&interp, 0, sizeof (interp)) ; | |
| 159 | − | |
| 160 | − param_count = sizeof (FIR_PARAMS) / sizeof (double) ; | |
| 161 | − | |
| 162 | − if (ARRAY_LEN (interp.data) < param_count) | |
| 163 | − { printf ("\n\nError : ARRAY_LEN (interp.data) < param_count.\n\n") ; | |
| 164 | − exit (1) ; | |
| 165 | − } ; | |
| 166 | − | |
| 167 | − if (gm.GetData (param_count, interp.data) != param_count) | |
| 168 | − { printf ("\n\nError : GetData should return %d.\n\n", param_count) ; | |
| 169 | − exit (1) ; | |
| 170 | − } ; | |
| 171 | − | |
| 172 | − /* Eval error in sinc_time_fudge. */ | |
| 173 | − if (fabs (interp.fir_params.sinc_time_fudge - 1.0) > 0.5) | |
| 174 | − return 1e30 * (fabs (interp.fir_params.sinc_time_fudge - 1.0)) ; | |
| 175 | − | |
| 176 | − | |
| 177 | − interp.middle = left_len ; | |
| 178 | − interp.total_len = left_len + right_len ; | |
| 179 | − | |
| 180 | − if (interp.total_len > ARRAY_LEN (interp.sinc)) | |
| 181 | − { printf ("\n\nError : interp.total_len > ARRAY_LEN (interp.sinc).\n") ; | |
| 182 | − exit (1) ; | |
| 183 | − } ; | |
| 184 | − | |
| 185 | − if (calc_window (&interp, &error)) | |
| 186 | − return error ; | |
| 187 | − | |
| 188 | − calc_sinc (&interp) ; | |
| 189 | − calc_filter (&interp) ; | |
| 190 | − | |
| 191 | − error = evaluate_filter (&interp) ; | |
| 192 | − | |
| 193 | − test_count ++ ; | |
| 194 | −// printf ("%s %d : exit\n", __func__, __LINE__) ; | |
| 195 | −// exit (1) ; | |
| 196 | − | |
| 197 | − if (error < best_error) | |
| 198 | − { oct_save (&interp) ; | |
| 199 | − best_error = error ; | |
| 200 | − printf ("%12d best : %f\n", test_count, best_error) ; | |
| 201 | − } ; | |
| 202 | − | |
| 203 | − return error ; | |
| 204 | −} /* fir_error */ | |
| 205 | − | |
| 206 | −static int | |
| 207 | −calc_window (FIR_INTERP *interp, double * returned_error) | |
| 208 | −{ unsigned k ; | |
| 209 | − double error, temp, x ; | |
| 210 | − | |
| 211 | − /* Make sure left poly params are in range [0, 1]. */ | |
| 212 | − error = 0.0 ; | |
| 213 | − for (k = 0 ; k < ARRAY_LEN (interp->fir_params.y_left) ; k++) | |
| 214 | − { temp = fabs (interp->fir_params.y_left [k] - 0.5) ; | |
| 215 | − if (temp > 0.5 && temp > error) | |
| 216 | − error = temp ; | |
| 217 | − } ; | |
| 218 | − | |
| 219 | − if (error > 0.0) | |
| 220 | − { *returned_error = 1e20 * error ; | |
| 221 | − return 1 ; | |
| 222 | − } ; | |
| 223 | − | |
| 224 | − /* Make sure right poly params are in range [0, 1]. */ | |
| 225 | − error = 0.0 ; | |
| 226 | − for (k = 0 ; k < ARRAY_LEN (interp->fir_params.y_right) ; k++) | |
| 227 | − { temp = fabs (interp->fir_params.y_right [k] - 0.5) ; | |
| 228 | − if (temp > 0.5 && temp > error) | |
| 229 | − error = temp ; | |
| 230 | − } ; | |
| 231 | − | |
| 232 | − if (error > 0.0) | |
| 233 | − { *returned_error = 1e18 * error ; | |
| 234 | − return 1 ; | |
| 235 | − } ; | |
| 236 | − | |
| 237 | − /* Generate polynomial for left side of window. */ | |
| 238 | − interp->left_window_poly [0] = interp->fir_params.y_left [0] ; | |
| 239 | − interp->left_window_poly [1] = 12.4166666667 - 12.4166666667 * interp->fir_params.y_left [0] + 31.25 * interp->fir_params.y_left [1] - 41.6666666667 * interp->fir_params.y_left [2] + 41.6666666667 * interp->fir_params.y_left [3] - 31.25 * interp->fir_params.y_left [4] ; | |
| 240 | − interp->left_window_poly [2] = -140.756944444 + 58.2916666667 * interp->fir_params.y_left [0] - 231.770833333 * interp->fir_params.y_left [1] + 413.194444444 * interp->fir_params.y_left [2] - 447.916666667 * interp->fir_params.y_left [3] + 348.958333333 * interp->fir_params.y_left [4] ; | |
| 241 | − interp->left_window_poly [3] = 571.614583333 - 135.416666667 * interp->fir_params.y_left [0] + 662.760416667 * interp->fir_params.y_left [1] - 1395.83333333 * interp->fir_params.y_left [2] + 1682.29166667 * interp->fir_params.y_left [3] - 1385.41666667 * interp->fir_params.y_left [4] ; | |
| 242 | − interp->left_window_poly [4] = -1062.93402778 + 166.666666667 * interp->fir_params.y_left [0] - 917.96875 * interp->fir_params.y_left [1] + 2152.77777778 * interp->fir_params.y_left [2] - 2838.54166667 * interp->fir_params.y_left [3] + 2500. * interp->fir_params.y_left [4] ; | |
| 243 | − interp->left_window_poly [5] = 917.96875 - 104.166666667 * interp->fir_params.y_left [0] + 618.489583333 * interp->fir_params.y_left [1] - 1562.5 * interp->fir_params.y_left [2] + 2213.54166667 * interp->fir_params.y_left [3] - 2083.33333333 * interp->fir_params.y_left [4] ; | |
| 244 | − interp->left_window_poly [6] = -297.309027778 + 26.0416666667 * interp->fir_params.y_left [0] - 162.760416667 * interp->fir_params.y_left [1] + 434.027777778 * interp->fir_params.y_left [2] - 651.041666667 * interp->fir_params.y_left [3] + 651.041666667 * interp->fir_params.y_left [4] ; | |
| 245 | − | |
| 246 | − /* Generate left side of window. */ | |
| 247 | − error = 0.0 ; | |
| 248 | − for (k = 0 ; k < interp->middle ; k++) | |
| 249 | − { x = k / (interp->middle * 1.0) ; | |
| 250 | − interp->window [k] = poly_evaluate (ARRAY_LEN (interp->left_window_poly) - 1, interp->left_window_poly, x) ; | |
| 251 | − } ; | |
| 252 | − | |
| 253 | − /* Ensure start value in range [0, 0,2]. */ | |
| 254 | − if (fabs (interp->window [0] - 0.1) > 0.1) | |
| 255 | − { *returned_error = 1e16 * fabs (interp->window [0] - 0.1) ; | |
| 256 | − return 1 ; | |
| 257 | − } ; | |
| 258 | − | |
| 259 | − /* Generate polynomial for right side of window. */ | |
| 260 | − interp->right_window_poly [0] = 1 ; | |
| 261 | − interp->right_window_poly [1] = 0 ; | |
| 262 | − interp->right_window_poly [2] = -83.4652777778 + 125. * interp->fir_params.y_right [0] - 62.5 * interp->fir_params.y_right [1] + 27.7777777778 * interp->fir_params.y_right [2] - 7.8125 * interp->fir_params.y_right [3] + interp->fir_params.y_right [4] ; | |
| 263 | − interp->right_window_poly [3] = 446.614583333 - 802.083333333 * interp->fir_params.y_right [0] + 557.291666667 * interp->fir_params.y_right [1] - 270.833333333 * interp->fir_params.y_right [2] + 79.4270833333 * interp->fir_params.y_right [3] - 10.4166666667 * interp->fir_params.y_right [4] ; | |
| 264 | − interp->right_window_poly [4] = -932.725694444 + 1848.95833333 * interp->fir_params.y_right [0] - 1536.45833333 * interp->fir_params.y_right [1] + 850.694444444 * interp->fir_params.y_right [2] - 266.927083333 * interp->fir_params.y_right [3] + 36.4583333333 * interp->fir_params.y_right [4] ; | |
| 265 | − interp->right_window_poly [5] = 865.885416667 - 1822.91666667 * interp->fir_params.y_right [0] + 1692.70833333 * interp->fir_params.y_right [1] - 1041.66666667 * interp->fir_params.y_right [2] + 358.072916667 * interp->fir_params.y_right [3] - 52.0833333333 * interp->fir_params.y_right [4] ; | |
| 266 | − interp->right_window_poly [6] = -297.309027778 + 651.041666667 * interp->fir_params.y_right [0] - 651.041666667 * interp->fir_params.y_right [1] + 434.027777778 * interp->fir_params.y_right [2] - 162.760416667 * interp->fir_params.y_right [3] + 26.0416666667 * interp->fir_params.y_right [4] ; | |
| 267 | − | |
| 268 | − /* Generate right side of window. */ | |
| 269 | − error = 0.0 ; | |
| 270 | − for (k = interp->middle ; k < interp->total_len ; k++) | |
| 271 | − { x = (k - interp->middle) / (1.0 * (interp->total_len - interp->middle)) ; | |
| 272 | − interp->window [k] = poly_evaluate (ARRAY_LEN (interp->right_window_poly) - 1, interp->right_window_poly, x) ; | |
| 273 | − } ; | |
| 274 | − | |
| 275 | − /* Ensure end value in range [0, 0,4]. */ | |
| 276 | − k = interp->total_len - 1 ; | |
| 277 | − if (fabs (interp->window [k] - 0.1) > 0.1) | |
| 278 | − { *returned_error = 1e16 * fabs (interp->window [k] - 0.1) ; | |
| 279 | − return 1 ; | |
| 280 | − } ; | |
| 281 | − | |
| 282 | − /* Ensure whole window is in [0, 1] range. */ | |
| 283 | − error = 0.0 ; | |
| 284 | − for (k = 0 ; k < interp->total_len ; k++) | |
| 285 | − { temp = fabs (interp->window [k] - 0.5) ; | |
| 286 | − if (temp > 0.5 && temp > error) | |
| 287 | − error = temp ; | |
| 288 | − } ; | |
| 289 | − | |
| 290 | − if (error > 0.0) | |
| 291 | − { *returned_error = 1e16 * error ; | |
| 292 | − return 1 ; | |
| 293 | − } ; | |
| 294 | − | |
| 295 | − /* Monotonicity of left side of window. */ | |
| 296 | − error = 0.0 ; | |
| 297 | − for (k = 1 ; k < interp->middle ; k++) | |
| 298 | − { temp = (interp->window [k - 1] - interp->window [k]) ; | |
| 299 | − if (temp > 0.0) | |
| 300 | − error += temp ; | |
| 301 | − } ; | |
| 302 | − | |
| 303 | − if (error > 0.0) | |
| 304 | − { *returned_error = 1e14 * error ; | |
| 305 | − return 1 ; | |
| 306 | − } ; | |
| 307 | − | |
| 308 | − /* Monotonicity of right side of window. */ | |
| 309 | − error = 0.0 ; | |
| 310 | − for (k = interp->middle + 1 ; k < interp->total_len ; k++) | |
| 311 | − { temp = (interp->window [k] - interp->window [k - 1]) ; | |
| 312 | − if (temp > 0.0) | |
| 313 | − error += temp ; | |
| 314 | − } ; | |
| 315 | − | |
| 316 | − if (error > 0.0) | |
| 317 | − { *returned_error = 1e14 * error ; | |
| 318 | − return 1 ; | |
| 319 | − } ; | |
| 320 | − | |
| 321 | − return 0 ; | |
| 322 | −} /* calc_window */ | |
| 323 | − | |
| 324 | −static void | |
| 325 | −calc_sinc (FIR_INTERP *interp) | |
| 326 | −{ unsigned k ; | |
| 327 | − double x ; | |
| 328 | − | |
| 329 | − for (k = 0 ; k < interp->middle ; k++) | |
| 330 | − { x = M_PI * (interp->middle - k) * interp->fir_params.sinc_time_fudge / UPSAMPLE_RATIO ; | |
| 331 | − interp->sinc [k] = sin (x) / x ; | |
| 332 | − } ; | |
| 333 | − interp->sinc [interp->middle] = 1.0 ; | |
| 334 | − | |
| 335 | − for (k = interp->middle + 1 ; k < interp->total_len ; k++) | |
| 336 | − { x = M_PI * (k - interp->middle) * interp->fir_params.sinc_time_fudge / UPSAMPLE_RATIO ; | |
| 337 | − interp->sinc [k] = sin (x) / x ; | |
| 338 | − } ; | |
| 339 | − | |
| 340 | −} /* calc_sinc */ | |
| 341 | − | |
| 342 | −static void | |
| 343 | −calc_filter (FIR_INTERP *interp) | |
| 344 | −{ unsigned k ; | |
| 345 | − double sum = 0.0 ; | |
| 346 | − | |
| 347 | − for (k = 0 ; k < interp->total_len ; k++) | |
| 348 | − { interp->filter [k] = interp->sinc [k] * interp->window [k] ; | |
| 349 | − sum += interp->filter [k] ; | |
| 350 | − } ; | |
| 351 | − | |
| 352 | − /* Now normalize. */ | |
| 353 | − for (k = 0 ; k < interp->total_len ; k++) | |
| 354 | − interp->filter [k] /= sum ; | |
| 355 | − | |
| 356 | −} /* calc_filter */ | |
| 357 | − | |
| 358 | −static void | |
| 359 | −oct_save (const FIR_INTERP *interp) | |
| 360 | −{ const char * filename = "a.mat" ; | |
| 361 | − FILE * file ; | |
| 362 | − unsigned k ; | |
| 363 | − | |
| 364 | − unlink (filename) ; | |
| 365 | − | |
| 366 | − if ((file = fopen (filename, "w")) == NULL) | |
| 367 | − { printf ("\nError : fopen failed.\n") ; | |
| 368 | − exit (1) ; | |
| 369 | − } ; | |
| 370 | − | |
| 371 | − fprintf (file, "# Not created by Octave\n") ; | |
| 372 | − | |
| 373 | − fprintf (file, "# name: sinc_time_fudge\n") ; | |
| 374 | − fprintf (file, "# type: scalar\n%16.14f\n", interp->fir_params.sinc_time_fudge) ; | |
| 375 | − | |
| 376 | − fprintf (file, "# name: middle\n") ; | |
| 377 | − fprintf (file, "# type: scalar\n%d\n", interp->middle) ; | |
| 378 | − | |
| 379 | − fprintf (file, "# name: total_len\n") ; | |
| 380 | − fprintf (file, "# type: scalar\n%d\n", interp->total_len) ; | |
| 381 | − | |
| 382 | − fprintf (file, "# name: sinc\n") ; | |
| 383 | − fprintf (file, "# type: matrix\n") ; | |
| 384 | − fprintf (file, "# rows: %d\n", interp->total_len) ; | |
| 385 | − fprintf (file, "# columns: 1\n") ; | |
| 386 | − | |
| 387 | − for (k = 0 ; k < interp->total_len ; k++) | |
| 388 | − fprintf (file, "% f\n", interp->sinc [k]) ; | |
| 389 | − | |
| 390 | − fprintf (file, "# name: win\n") ; | |
| 391 | − fprintf (file, "# type: matrix\n") ; | |
| 392 | − fprintf (file, "# rows: %d\n", interp->total_len) ; | |
| 393 | − fprintf (file, "# columns: 1\n") ; | |
| 394 | − | |
| 395 | − for (k = 0 ; k < interp->total_len ; k++) | |
| 396 | − fprintf (file, "% f\n", interp->window [k]) ; | |
| 397 | − | |
| 398 | − fprintf (file, "# name: filt\n") ; | |
| 399 | − fprintf (file, "# type: matrix\n") ; | |
| 400 | − fprintf (file, "# rows: %d\n", interp->total_len) ; | |
| 401 | − fprintf (file, "# columns: 1\n") ; | |
| 402 | − | |
| 403 | − for (k = 0 ; k < interp->total_len ; k++) | |
| 404 | − fprintf (file, "% f\n", interp->filter [k] * UPSAMPLE_RATIO) ; | |
| 405 | − | |
| 406 | − fprintf (file, "# name: mag\n") ; | |
| 407 | − fprintf (file, "# type: matrix\n") ; | |
| 408 | − fprintf (file, "# rows: %d\n", ARRAY_LEN (interp->mag)) ; | |
| 409 | − fprintf (file, "# columns: 1\n") ; | |
| 410 | − | |
| 411 | − for (k = 0 ; k < ARRAY_LEN (interp->mag) ; k++) | |
| 412 | − fprintf (file, "% f\n", interp->mag [k]) ; | |
| 413 | − | |
| 414 | − fprintf (file, "# name: logmag\n") ; | |
| 415 | − fprintf (file, "# type: matrix\n") ; | |
| 416 | − fprintf (file, "# rows: %d\n", ARRAY_LEN (interp->logmag)) ; | |
| 417 | − fprintf (file, "# columns: 1\n") ; | |
| 418 | − | |
| 419 | − for (k = 0 ; k < ARRAY_LEN (interp->logmag) ; k++) | |
| 420 | − fprintf (file, "% f\n", interp->logmag [k]) ; | |
| 421 | − | |
| 422 | − fprintf (file, "# name: phase\n") ; | |
| 423 | − fprintf (file, "# type: matrix\n") ; | |
| 424 | − fprintf (file, "# rows: %d\n", ARRAY_LEN (interp->phase)) ; | |
| 425 | − fprintf (file, "# columns: 1\n") ; | |
| 426 | − | |
| 427 | − for (k = 0 ; k < ARRAY_LEN (interp->phase) ; k++) | |
| 428 | − fprintf (file, "% f\n", interp->phase [k]) ; | |
| 429 | − | |
| 430 | − fclose (file) ; | |
| 431 | −} /* oct_save */ | |
| 432 | − | |
| 433 | −static void | |
| 434 | −randomize_data (FIR_INTERP *interp) | |
| 435 | −{ FILE * file ; | |
| 436 | − unsigned k, param_count, seed ; | |
| 437 | − | |
| 438 | − file = fopen ("/dev/urandom", "r") ; | |
| 439 | − fread (&seed, 1, sizeof (seed), file) ; | |
| 440 | − fclose (file) ; | |
| 441 | − | |
| 442 | − srandom (seed) ; | |
| 443 | − | |
| 444 | − param_count = sizeof (FIR_PARAMS) / sizeof (double) ; | |
| 445 | − | |
| 446 | − for (k = 0 ; k < param_count ; k++) | |
| 447 | − interp->data [k] = 3.0 * ((1.0 * random ()) / INT_MAX - 0.5) ; | |
| 448 | − | |
| 449 | −} /* randomize_data */ | |
| 450 | − | |
| 451 | −/* | |
| 452 | −** Do not edit or modify anything in this comment block. | |
| 453 | −** The following line is a file identity tag for the GNU Arch | |
| 454 | −** revision control system. | |
| 455 | −** | |
| 456 | −** arch-tag: 3ce7ca6f-394e-432c-aeaa-f228afc05afd | |
| 457 | −*/ | |
| @@ -1,84 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** Copyright (C) 2004 Erik de Castro Lopo <erikd@mega-nerd.com> | |
| 3 | −** | |
| 4 | −** The copyright above and this notice must be preserved in all | |
| 5 | −** copies of this source code. The copyright above does not | |
| 6 | −** evidence any actual or intended publication of this source code. | |
| 7 | −** | |
| 8 | −** This is unpublished proprietary trade secret of Erik de Castro | |
| 9 | −** Lopo. This source code may not be copied, disclosed, | |
| 10 | −** distributed, demonstrated or licensed except as authorized by | |
| 11 | −** Erik de Castro Lopo. | |
| 12 | −** | |
| 13 | −** No part of this program or publication may be reproduced, | |
| 14 | −** transmitted, transcribed, stored in a retrieval system, | |
| 15 | −** or translated into any language or computer language in any | |
| 16 | −** form or by any means, electronic, mechanical, magnetic, | |
| 17 | −** optical, chemical, manual, or otherwise, without the prior | |
| 18 | −** written permission of Erik de Castro Lopo. | |
| 19 | −*/ | |
| 20 | − | |
| 21 | −#include <cstdio> | |
| 22 | −#include <cstdlib> | |
| 23 | −#include <cstring> | |
| 24 | −#include <cmath> | |
| 25 | − | |
| 26 | −#include <fftw3.h> | |
| 27 | − | |
| 28 | −void | |
| 29 | −mag_spectrum (double *input, int len, double *magnitude, double *logmag, double *phase) | |
| 30 | −{ static fftw_plan plan = NULL ; | |
| 31 | − static int saved_len = -1 ; | |
| 32 | − static double *fft_data = NULL ; | |
| 33 | − | |
| 34 | − double maxval ; | |
| 35 | − int k, pi_factor ; | |
| 36 | − | |
| 37 | − if (input == NULL || magnitude == NULL || phase == NULL) | |
| 38 | − { printf ("%s %d : input == NULL || magnitude == NULL || phase == NULL\n", __func__, __LINE__) ; | |
| 39 | − exit (1) ; | |
| 40 | − } ; | |
| 41 | − | |
| 42 | − if (saved_len > 0 && saved_len != len) | |
| 43 | − { printf ("%s %d : saved_len != len.\n", __func__, __LINE__) ; | |
| 44 | − exit (1) ; | |
| 45 | − } ; | |
| 46 | − | |
| 47 | − if (fft_data == NULL) | |
| 48 | − fft_data = (double *) calloc (sizeof (double), len) ; | |
| 49 | − | |
| 50 | − if (plan == NULL) | |
| 51 | − { plan = fftw_plan_r2r_1d (len, input, fft_data, FFTW_R2HC, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT) ; | |
| 52 | − if (plan == NULL) | |
| 53 | − { printf ("%s %d : create plan failed.\n", __func__, __LINE__) ; | |
| 54 | − exit (1) ; | |
| 55 | − } ; | |
| 56 | − } ; | |
| 57 | − | |
| 58 | − fftw_execute (plan) ; | |
| 59 | − | |
| 60 | − /* (k < N/2 rounded up) */ | |
| 61 | − maxval = 0.0 ; | |
| 62 | − for (k = 0 ; k < len / 2 ; k++) | |
| 63 | − { magnitude [k] = sqrt (fft_data [k] * fft_data [k] + fft_data [len - k - 1] * fft_data [len - k - 1]) ; | |
| 64 | − logmag [k] = (magnitude [k] < 1e-10) ? -200.0 : 20 * log10 (magnitude [k]) ; | |
| 65 | − phase [k] = atan2 (fft_data [len - k - 1], fft_data [k]) ; | |
| 66 | − } ; | |
| 67 | − | |
| 68 | − pi_factor = 0 ; | |
| 69 | − for (k = 1 ; k < len / 2 ; k++) | |
| 70 | − { phase [k] -= pi_factor * M_PI ; | |
| 71 | − if (fabs (phase [k] - phase [k - 1]) > 3.0) | |
| 72 | − { phase [k] -= 2 * M_PI ; | |
| 73 | − pi_factor += 2 ; | |
| 74 | − } | |
| 75 | − } ; | |
| 76 | − | |
| 77 | − return ; | |
| 78 | −} /* mag_spectrum */ | |
| 79 | − | |
| 80 | −// Do not edit or modify anything in this comment block. | |
| 81 | −// The following line is a file identity tag for the GNU Arch | |
| 82 | −// revision control system. | |
| 83 | −// | |
| 84 | −// arch-tag: 58aa43ee-b8e1-4178-8861-7621399fa049 | |
| @@ -1,27 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** Copyright (C) 2004 Erik de Castro Lopo <erikd@mega-nerd.com> | |
| 3 | −** | |
| 4 | −** The copyright above and this notice must be preserved in all | |
| 5 | −** copies of this source code. The copyright above does not | |
| 6 | −** evidence any actual or intended publication of this source code. | |
| 7 | −** | |
| 8 | −** This is unpublished proprietary trade secret of Erik de Castro | |
| 9 | −** Lopo. This source code may not be copied, disclosed, | |
| 10 | −** distributed, demonstrated or licensed except as authorized by | |
| 11 | −** Erik de Castro Lopo. | |
| 12 | −** | |
| 13 | −** No part of this program or publication may be reproduced, | |
| 14 | −** transmitted, transcribed, stored in a retrieval system, | |
| 15 | −** or translated into any language or computer language in any | |
| 16 | −** form or by any means, electronic, mechanical, magnetic, | |
| 17 | −** optical, chemical, manual, or otherwise, without the prior | |
| 18 | −** written permission of Erik de Castro Lopo. | |
| 19 | −*/ | |
| 20 | − | |
| 21 | −void mag_spectrum (double *input, int len, double *magnitude, double *logmag, double *phase) ; | |
| 22 | − | |
| 23 | −// Do not edit or modify anything in this comment block. | |
| 24 | −// The following line is a file identity tag for the GNU Arch | |
| 25 | −// revision control system. | |
| 26 | −// | |
| 27 | −// arch-tag: cc5db1c8-4c67-49f7-9c2f-6c5021a69970 | |
| @@ -1,50 +0,0 @@ | ||
| 1 | −function [t, mt, w] = timeline (len, stretch) | |
| 2 | − | |
| 3 | − | |
| 4 | −if (stretch < 0 || stretch > 1) | |
| 5 | − error ("stretch out of range [0, 1].\n"); | |
| 6 | − endif | |
| 7 | − | |
| 8 | −# Mofified time | |
| 9 | − | |
| 10 | −x_w = 0.2 ; | |
| 11 | −x = [-0.5 -0.2 0.2 0.5]; | |
| 12 | −y = [-0.5 -0.4 -0.1 0.5]; | |
| 13 | − | |
| 14 | −p = polyfit (x, y, 4); | |
| 15 | − | |
| 16 | −t = linspace (-0.5, 0.5, 100); | |
| 17 | −y = polyval (p,t); | |
| 18 | −plot (t, y) | |
| 19 | −return | |
| 20 | − | |
| 21 | −mt = ((1 - stretch) * t + stretch * t.^2) - 0.5 ; | |
| 22 | − | |
| 23 | − | |
| 24 | −# Basically a Nuttall window | |
| 25 | −ak = [0.42323 0.49755 0.07922] ; | |
| 26 | − | |
| 27 | −w = zeros (1, len) ; | |
| 28 | − | |
| 29 | −k = 0 ; | |
| 30 | −for a = ak, | |
| 31 | − w = w + a * cos (2 * pi * k * mt) ; | |
| 32 | − k += 1 ; | |
| 33 | − endfor | |
| 34 | − | |
| 35 | −w = fliplr (w / len) ; | |
| 36 | − | |
| 37 | −# Linear t | |
| 38 | − | |
| 39 | −t = linspace (-(len-2)/2, (len-2)/2, len) / len ; | |
| 40 | − | |
| 41 | − | |
| 42 | −end | |
| 43 | − | |
| 44 | −# Do not edit or modify anything in this comment block. | |
| 45 | −# The following line is a file identity tag for the GNU Arch | |
| 46 | −# revision control system. | |
| 47 | −# | |
| 48 | −# arch-tag: 830f701e-5e9c-478a-a929-609513d4b1a6 | |
| 49 | − | |
| 50 | − | |
| @@ -11,8 +11,7 @@ COEFF_HDRS = high_qual_coeffs.h mid_qual_coeffs.h fastest_coeffs.h · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | noinst_HEADERS = common.h float_cast.h $(COEFF_HDRS) |
| 13 | 13 | |
| 14 | −SRC_SOURCES = samplerate.c src_sinc.c $(COEFF_HDRS) src_zoh.c src_linear.c \ | |
| 15 | − src_fir_iir_poly.c | |
| 14 | +SRC_SOURCES = samplerate.c src_sinc.c $(COEFF_HDRS) src_zoh.c src_linear.c | |
| 16 | 15 | |
| 17 | 16 | # MinGW requires -no-undefined if a DLL is to be built. |
| 18 | 17 | libsamplerate_la_LDFLAGS = -no-undefined version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@ |
| @@ -116,12 +116,6 @@ const char* zoh_get_description (int src_enum) ; · 115 unmodified lines | ||
| 116 | 116 | |
| 117 | 117 | int zoh_set_converter (SRC_PRIVATE *psrc, int src_enum) ; |
| 118 | 118 | |
| 119 | −/* In src_fir_iir_poly.c */ | |
| 120 | −const char* fip_get_name (int src_enum) ; | |
| 121 | −const char* fip_get_description (int src_enum) ; | |
| 122 | − | |
| 123 | −int fip_set_converter (SRC_PRIVATE *psrc, int src_enum) ; | |
| 124 | − | |
| 125 | 119 | #endif /* COMMON_H_INCLUDED */ |
| 126 | 120 | |
| 127 | 121 | /* |
| @@ -1,43 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** Copyright (C) 2004 Erik de Castro Lopo <erikd@mega-nerd.com> | |
| 3 | −** | |
| 4 | −** This program is free software; you can redistribute it and/or modify | |
| 5 | −** it under the terms of the GNU General Public License as published by | |
| 6 | −** the Free Software Foundation; either version 2 of the License, or | |
| 7 | −** (at your option) any later version. | |
| 8 | −** | |
| 9 | −** This program is distributed in the hope that it will be useful, | |
| 10 | −** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | −** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | −** GNU General Public License for more details. | |
| 13 | −** | |
| 14 | −** You should have received a copy of the GNU General Public License | |
| 15 | −** along with this program; if not, write to the Free Software | |
| 16 | −** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | |
| 17 | −*/ | |
| 18 | − | |
| 19 | − | |
| 20 | −static const float fip_best_coeffs [250] = | |
| 21 | −{ 0.0, 1.2, 2.3 | |
| 22 | −} ; | |
| 23 | − | |
| 24 | −/* FIP_COEFF_SET needs to be defined before this header is included. */ | |
| 25 | −static const FIP_COEFF_SET fip_best = | |
| 26 | −{ | |
| 27 | − /* count */ | |
| 28 | − ARRAY_LEN (fip_best_coeffs), | |
| 29 | − | |
| 30 | − /* increment */ | |
| 31 | − 1, | |
| 32 | − | |
| 33 | − /* c */ | |
| 34 | − fip_best_coeffs | |
| 35 | −} ; | |
| 36 | − | |
| 37 | −/* | |
| 38 | −** Do not edit or modify anything in this comment block. | |
| 39 | −** The following line is a file identity tag for the GNU Arch | |
| 40 | −** revision control system. | |
| 41 | −** | |
| 42 | −** arch-tag: 86739f0c-c446-45f9-8ad0-35b6903c6135 | |
| 43 | −*/ | |
| @@ -313,9 +313,6 @@ src_get_name (int converter_type) · 312 unmodified lines | ||
| 313 | 313 | if ((desc = linear_get_name (converter_type)) != NULL) |
| 314 | 314 | return desc ; |
| 315 | 315 | |
| 316 | − if ((desc = fip_get_name (converter_type)) != NULL) | |
| 317 | − return desc ; | |
| 318 | − | |
| 319 | 316 | return NULL ; |
| 320 | 317 | } /* src_get_name */ |
| 321 | 318 | |
| @@ -332,9 +329,6 @@ src_get_description (int converter_type) · 10 unmodified lines | ||
| 332 | 329 | if ((desc = linear_get_description (converter_type)) != NULL) |
| 333 | 330 | return desc ; |
| 334 | 331 | |
| 335 | − if ((desc = fip_get_description (converter_type)) != NULL) | |
| 336 | − return desc ; | |
| 337 | − | |
| 338 | 332 | return NULL ; |
| 339 | 333 | } /* src_get_description */ |
| 340 | 334 | |
| @@ -488,9 +482,6 @@ psrc_set_converter (SRC_PRIVATE *psrc, int converter_type) · 147 unmodified lines | ||
| 488 | 482 | if (linear_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR) |
| 489 | 483 | return SRC_ERR_NO_ERROR ; |
| 490 | 484 | |
| 491 | − if (fip_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR) | |
| 492 | − return SRC_ERR_NO_ERROR ; | |
| 493 | − | |
| 494 | 485 | return SRC_ERR_BAD_CONVERTER ; |
| 495 | 486 | } /* psrc_set_converter */ |
| 496 | 487 | |
| @@ -1,356 +0,0 @@ | ||
| 1 | −/* | |
| 2 | −** Copyright (C) 2004 Erik de Castro Lopo <erikd@mega-nerd.com> | |
| 3 | −** | |
| 4 | −** This program is free software; you can redistribute it and/or modify | |
| 5 | −** it under the terms of the GNU General Public License as published by | |
| 6 | −** the Free Software Foundation; either version 2 of the License, or | |
| 7 | −** (at your option) any later version. | |
| 8 | −** | |
| 9 | −** This program is distributed in the hope that it will be useful, | |
| 10 | −** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | −** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | −** GNU General Public License for more details. | |
| 13 | −** | |
| 14 | −** You should have received a copy of the GNU General Public License | |
| 15 | −** along with this program; if not, write to the Free Software | |
| 16 | −** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | |
| 17 | −*/ | |
| 18 | − | |
| 19 | −#include <stdio.h> | |
| 20 | −#include <stdlib.h> | |
| 21 | −#include <string.h> | |
| 22 | − | |
| 23 | −#include "config.h" | |
| 24 | −#include "float_cast.h" | |
| 25 | −#include "common.h" | |
| 26 | − | |
| 27 | −#define FIP_MAGIC_MARKER MAKE_MAGIC ('F', '/', 'I', '/', 'P', ' ') | |
| 28 | − | |
| 29 | −#define BUFFER_LEN 1024 | |
| 30 | − | |
| 31 | −typedef struct | |
| 32 | −{ int count ; | |
| 33 | − int increment ; | |
| 34 | − const float *c ; | |
| 35 | −} FIP_COEFF_SET ; | |
| 36 | − | |
| 37 | −#include "fip_best.h" | |
| 38 | − | |
| 39 | −typedef struct | |
| 40 | −{ int fip_magic_marker ; | |
| 41 | − | |
| 42 | − int channels ; | |
| 43 | − long in_count, in_used ; | |
| 44 | − long out_count, out_gen ; | |
| 45 | − | |
| 46 | − double src_ratio, input_index ; | |
| 47 | − | |
| 48 | − /* The raw coeff set for this converter. */ | |
| 49 | − const FIP_COEFF_SET *coeff_set ; | |
| 50 | − | |
| 51 | − /* The current FIR coefficents for the times 2 upsampler. */ | |
| 52 | − float *coeffs0, * coeffs1 ; | |
| 53 | − int max_half_coeff_len, half_coeff_len ; | |
| 54 | − | |
| 55 | − /* Buffer definitions. */ | |
| 56 | − float *input_buffer ; | |
| 57 | − int in_buf_len, in_current ; | |
| 58 | − | |
| 59 | − float *fir_out ; | |
| 60 | − int fir_out_len, fir_start, fir_end ; | |
| 61 | − | |
| 62 | − float *iir_out ; | |
| 63 | − int iir_out_len, iir_start, iir_end ; | |
| 64 | − | |
| 65 | − float dummy [1] ; | |
| 66 | −} FIR_IIR_POLY ; | |
| 67 | − | |
| 68 | −static void fip_reset (SRC_PRIVATE *psrc) ; | |
| 69 | −static int fip_process (SRC_PRIVATE *psrc, SRC_DATA *data) ; | |
| 70 | − | |
| 71 | −static int fip_process_var_down (FIR_IIR_POLY * fip, SRC_DATA * data) ; | |
| 72 | −static int fip_process_const_down (FIR_IIR_POLY * fip, SRC_DATA * data) ; | |
| 73 | −static int fip_process_var_up (FIR_IIR_POLY * fip, SRC_DATA * data) ; | |
| 74 | −static int fip_process_const_up (FIR_IIR_POLY * fip, SRC_DATA * data) ; | |
| 75 | − | |
| 76 | − | |
| 77 | −const char* | |
| 78 | −fip_get_name (int src_enum) | |
| 79 | −{ | |
| 80 | − switch (src_enum) | |
| 81 | − { case SRC_FIR_IIR_POLY_BEST : | |
| 82 | − return "Best FIR/IIR/Polynomial Interpolator" ; | |
| 83 | −#if 0 | |
| 84 | − case SRC_FIR_IIR_POLY_MEDIUM : | |
| 85 | − return "Medium FIR/IIR/Polynomial Interpolator" ; | |
| 86 | − | |
| 87 | − case SRC_FIR_IIR_POLY_FASTEST : | |
| 88 | − return "Fastest FIR/IIR/Polynomial Interpolator" ; | |
| 89 | −#endif | |
| 90 | − } ; | |
| 91 | − | |
| 92 | − return NULL ; | |
| 93 | −} /* fip_get_descrition */ | |
| 94 | − | |
| 95 | −const char* | |
| 96 | −fip_get_description (int src_enum) | |
| 97 | −{ | |
| 98 | − switch (src_enum) | |
| 99 | − { case SRC_FIR_IIR_POLY_BEST : | |
| 100 | − return "Three stage FIR/IIR/Polynomial Interpolator, best quality, XXdb SNR, XX% BW." ; | |
| 101 | −#if 0 | |
| 102 | − case SRC_FIR_IIR_POLY_MEDIUM : | |
| 103 | − return "Three stage FIR/IIR/Polynomial Interpolator, medium quality, XXdb SNR, XX% BW." ; | |
| 104 | − | |
| 105 | − case SRC_FIR_IIR_POLY_FASTEST : | |
| 106 | − return "Three stage FIR/IIR/Polynomial Interpolator, fastest, XXdb SNR, XX% BW." ; | |
| 107 | −#endif | |
| 108 | − } ; | |
| 109 | − | |
| 110 | − return NULL ; | |
| 111 | −} /* fip_get_descrition */ | |
| 112 | − | |
| 113 | −int | |
| 114 | −fip_set_converter (SRC_PRIVATE *psrc, int src_enum) | |
| 115 | −{ FIR_IIR_POLY *fip = NULL, temp_fip ; | |
| 116 | − int buffer_total ; | |
| 117 | − | |
| 118 | − if (psrc->private_data != NULL) | |
| 119 | − { fip = (FIR_IIR_POLY *) psrc->private_data ; | |
| 120 | − if (fip->fip_magic_marker != FIP_MAGIC_MARKER) | |
| 121 | − { free (psrc->private_data) ; | |
| 122 | − psrc->private_data = NULL ; | |
| 123 | − } ; | |
| 124 | − } ; | |
| 125 | − | |
| 126 | − memset (&temp_fip, 0, sizeof (temp_fip)) ; | |
| 127 | − | |
| 128 | − if ((OFFSETOF (FIR_IIR_POLY, dummy) & 0xF) != 0) | |
| 129 | − { printf ("(OFFSETOF (FIR_IIR_POLY, dummy) & 0xF) != 0\n") ; | |
| 130 | − exit (1) ; | |
| 131 | − } ; | |
| 132 | − | |
| 133 | − temp_fip.fip_magic_marker = FIP_MAGIC_MARKER ; | |
| 134 | − temp_fip.channels = psrc->channels ; | |
| 135 | − | |
| 136 | − psrc->reset = fip_reset ; | |
| 137 | − psrc->process = fip_process ; | |
| 138 | − | |
| 139 | − switch (src_enum) | |
| 140 | − { case SRC_FIR_IIR_POLY_BEST : | |
| 141 | − temp_fip.coeff_set = &fip_best ; | |
| 142 | − break ; | |
| 143 | −#if 0 | |
| 144 | − case SRC_FIR_IIR_POLY_MEDIUM : | |
| 145 | − temp_fip.coeff_set = &fip_medium ; | |
| 146 | − break ; | |
| 147 | − | |
| 148 | − case SRC_FIR_IIR_POLY_FASTEST : | |
| 149 | − temp_fip.coeff_set = &fip_fastest ; | |
| 150 | − break ; | |
| 151 | −#endif | |
| 152 | − default : | |
| 153 | − return SRC_ERR_BAD_CONVERTER ; | |
| 154 | − } ; | |
| 155 | − | |
| 156 | − temp_fip.max_half_coeff_len = SRC_MAX_RATIO * temp_fip.coeff_set->count / temp_fip.coeff_set->increment ; | |
| 157 | − temp_fip.in_buf_len = temp_fip.channels * 2 * temp_fip.max_half_coeff_len ; | |
| 158 | − | |
| 159 | − temp_fip.fir_out_len = BUFFER_LEN ; | |
| 160 | − temp_fip.iir_out_len = 2 * BUFFER_LEN ; | |
| 161 | − | |
| 162 | − buffer_total = 4 + temp_fip.max_half_coeff_len + psrc->channels * (temp_fip.in_buf_len + temp_fip.fir_out_len + temp_fip.iir_out_len) ; | |
| 163 | − | |
| 164 | − if ((fip = calloc (1, sizeof (FIR_IIR_POLY) + sizeof (fip->dummy [0]) * buffer_total)) == NULL) | |
| 165 | − return SRC_ERR_MALLOC_FAILED ; | |
| 166 | − | |
| 167 | − *fip = temp_fip ; | |
| 168 | − memset (&temp_fip, 0xEE, sizeof (temp_fip)) ; | |
| 169 | − | |
| 170 | − psrc->private_data = fip ; | |
| 171 | − | |
| 172 | − /* Allocate buffers. */ | |
| 173 | − fip->coeffs0 = fip->dummy ; | |
| 174 | − while ((((unsigned long) fip->coeffs0) & 0xF) > 0) | |
| 175 | − fip->coeffs0 ++ ; | |
| 176 | − | |
| 177 | − fip->coeffs1 = fip->coeffs0 + fip->max_half_coeff_len ; | |
| 178 | − fip->input_buffer = fip->coeffs1 + fip->max_half_coeff_len ; | |
| 179 | − | |
| 180 | − fip->fir_out = fip->input_buffer + fip->channels * fip->in_buf_len ; | |
| 181 | − fip->iir_out = fip->fir_out + fip->channels * fip->fir_out_len ; | |
| 182 | − | |
| 183 | − printf ("total : %d / %d\n", (fip->iir_out + fip->iir_out_len) - fip->dummy, buffer_total) ; | |
| 184 | − | |
| 185 | − fip_reset (psrc) ; | |
| 186 | − | |
| 187 | − return SRC_ERR_NO_ERROR ; | |
| 188 | −} /* fip_set_converter */ | |
| 189 | − | |
| 190 | −static void | |
| 191 | −fip_reset (SRC_PRIVATE *psrc) | |
| 192 | −{ FIR_IIR_POLY *fip ; | |
| 193 | − | |
| 194 | − fip = (FIR_IIR_POLY *) psrc->private_data ; | |
| 195 | − if (fip == NULL) | |
| 196 | − return ; | |
| 197 | − | |
| 198 | − memset (fip->input_buffer, 0, fip->channels * fip->in_buf_len * sizeof (fip->dummy [0])) ; | |
| 199 | − memset (fip->fir_out, 0, fip->channels * fip->fir_out_len * sizeof (fip->dummy [0])) ; | |
| 200 | − memset (fip->iir_out, 0, fip->channels * fip->iir_out_len * sizeof (fip->dummy [0])) ; | |
| 201 | − | |
| 202 | − fip->in_current = 0 ; | |
| 203 | − fip->fir_start = 0 ; | |
| 204 | − fip->iir_start = fip->iir_end = 0 ; | |
| 205 | − | |
| 206 | − fip->src_ratio = fip->input_index = 0.0 ; | |
| 207 | − | |
| 208 | − fip->half_coeff_len = 0 ; | |
| 209 | − | |
| 210 | − return ; | |
| 211 | −} /* fip_reset */ | |
| 212 | − | |
| 213 | −/*======================================================================================== | |
| 214 | −*/ | |
| 215 | − | |
| 216 | −static int | |
| 217 | −fip_process (SRC_PRIVATE *psrc, SRC_DATA *data) | |
| 218 | −{ FIR_IIR_POLY *fip ; | |
| 219 | − int error ; | |
| 220 | − | |
| 221 | − if (psrc->private_data == NULL) | |
| 222 | − return SRC_ERR_NO_PRIVATE ; | |
| 223 | − | |
| 224 | − fip = (FIR_IIR_POLY*) psrc->private_data ; | |
| 225 | − | |
| 226 | − /* If there is not a problem, this will be optimised out. */ | |
| 227 | − if (sizeof (fip->dummy [0]) != sizeof (data->data_in [0])) | |
| 228 | − return SRC_ERR_SIZE_INCOMPATIBILITY ; | |
| 229 | − | |
| 230 | − /* Just after an fip_reset(), the src_ratio field is invalid. */ | |
| 231 | − if (fip->src_ratio < 1.0 / SRC_MAX_RATIO) | |
| 232 | − fip->src_ratio = data->src_ratio ; | |
| 233 | − | |
| 234 | − fip->in_count = data->input_frames * fip->channels ; | |
| 235 | − fip->out_count = data->output_frames * fip->channels ; | |
| 236 | − fip->in_used = fip->out_gen = 0 ; | |
| 237 | − | |
| 238 | − /* Choose a more specialised process() function. */ | |
| 239 | − if (fip->src_ratio < 1.0 || data->src_ratio < 1.0) | |
| 240 | − { if (fabs (fip->src_ratio - data->src_ratio) > 1e-20) | |
| 241 | − error = fip_process_var_down (fip, data) ; | |
| 242 | − else | |
| 243 | − error = fip_process_const_down (fip, data) ; | |
| 244 | − } | |
| 245 | − else if (fabs (fip->src_ratio - data->src_ratio) > 1e-20) | |
| 246 | − error = fip_process_var_up (fip, data) ; | |
| 247 | − else | |
| 248 | − error = fip_process_const_up (fip, data) ; | |
| 249 | − | |
| 250 | − data->input_frames_used = fip->in_used / fip->channels ; | |
| 251 | − data->output_frames_gen = fip->out_gen / fip->channels ; | |
| 252 | − | |
| 253 | − return error ; | |
| 254 | −} /* fip_process */ | |
| 255 | − | |
| 256 | −/*---------------------------------------------------------------------------------------- | |
| 257 | −*/ | |
| 258 | − | |
| 259 | −static void | |
| 260 | −fip_generate_fir_current_coeffs (FIR_IIR_POLY * fip) | |
| 261 | −{ int k ; | |
| 262 | − | |
| 263 | − if (fip->src_ratio >= 1.0) | |
| 264 | − { fip->half_coeff_len = fip->coeff_set->count / fip->coeff_set->increment / 2 ; | |
| 265 | − | |
| 266 | − for (k = 0 ; k < fip->half_coeff_len ; k++) | |
| 267 | − { fip->coeffs0 [k] = fip->coeff_set->c [fip->coeff_set->increment * k] ; | |
| 268 | − fip->coeffs1 [k] = fip->coeff_set->c [fip->coeff_set->increment * k + fip->coeff_set->increment / 2] ; | |
| 269 | − } ; | |
| 270 | − | |
| 271 | − /* Round it up to a multiple of 4. */ | |
| 272 | − while (fip->half_coeff_len & 3) | |
| 273 | − { fip->coeffs0 [fip->half_coeff_len] = 0.0 ; | |
| 274 | − fip->coeffs1 [fip->half_coeff_len] = 0.0 ; | |
| 275 | − fip->half_coeff_len ++ ; | |
| 276 | − } ; | |
| 277 | − | |
| 278 | − return ; | |
| 279 | − } ; | |
| 280 | − | |
| 281 | − printf ("%s : not implemented yet.\n", __func__) ; | |
| 282 | − exit (1) ; | |
| 283 | −} /* fip_generate_fir_current_coeffs */ | |
| 284 | − | |
| 285 | −static int | |
| 286 | −fip_process_var_down (FIR_IIR_POLY * fip, SRC_DATA * data) | |
| 287 | −{ fip = NULL ; | |
| 288 | − data = NULL ; | |
| 289 | − printf ("%s : not implemented yet.\n", __func__) ; | |
| 290 | − return SRC_ERR_NO_ERROR ; | |
| 291 | −} /* fip_process_var_down */ | |
| 292 | − | |
| 293 | −static int | |
| 294 | −fip_process_const_down (FIR_IIR_POLY * fip, SRC_DATA * data) | |
| 295 | −{ | |
| 296 | − if (fip->half_coeff_len == 0) | |
| 297 | − fip_generate_fir_current_coeffs (fip) ; | |
| 298 | − | |
| 299 | − data = NULL ; | |
| 300 | − printf ("%s : not implemented yet.\n", __func__) ; | |
| 301 | − return SRC_ERR_NO_ERROR ; | |
| 302 | −} /* fip_process_const_down */ | |
| 303 | − | |
| 304 | −static int | |
| 305 | −fip_process_var_up (FIR_IIR_POLY * fip, SRC_DATA * data) | |
| 306 | −{ | |
| 307 | − if (fip->half_coeff_len == 0) | |
| 308 | − fip_generate_fir_current_coeffs (fip) ; | |
| 309 | − | |
| 310 | − data = NULL ; | |
| 311 | − printf ("%s : not implemented yet.\n", __func__) ; | |
| 312 | − return SRC_ERR_NO_ERROR ; | |
| 313 | −} /* fip_process_var_up */ | |
| 314 | − | |
| 315 | −static int | |
| 316 | −fip_process_const_up (FIR_IIR_POLY * fip, SRC_DATA * data) | |
| 317 | −{ long max_in_used ; | |
| 318 | − int ch, indx ; | |
| 319 | − | |
| 320 | − /* If we don't yet have the coeffs, generate them. */ | |
| 321 | − if (fip->half_coeff_len == 0) | |
| 322 | − fip_generate_fir_current_coeffs (fip) ; | |
| 323 | − | |
| 324 | − max_in_used = lrintf (fip->in_count / fip->src_ratio - 0.5) ; | |
| 325 | − max_in_used -= max_in_used & 1 ; | |
| 326 | − | |
| 327 | − if (fip->channels != 1) | |
| 328 | − { printf ("%s : fip->channels != 1\n", __func__) ; | |
| 329 | − exit (1) ; | |
| 330 | − } | |
| 331 | − | |
| 332 | − /* Main processing loop. */ | |
| 333 | − while (fip->out_gen < fip->out_count && fip->in_used < max_in_used) | |
| 334 | − { | |
| 335 | − for (ch = 0 ; ch < fip->channels ; ch ++) | |
| 336 | − { indx = (fip->in_current + fip->half_coeff_len + ch) % fip->in_buf_len ; | |
| 337 | − fip->input_buffer [indx] = data->data_in [fip->in_used ++] ; | |
| 338 | − } ; | |
| 339 | − | |
| 340 | − | |
| 341 | − | |
| 342 | − | |
| 343 | − fip->in_current = (fip->in_current + 1) % fip->in_buf_len ; | |
| 344 | − } ; | |
| 345 | − | |
| 346 | − return SRC_ERR_NO_ERROR ; | |
| 347 | −} /* fip_process_const_up */ | |
| 348 | − | |
| 349 | − | |
| 350 | −/* | |
| 351 | −** Do not edit or modify anything in this comment block. | |
| 352 | −** The arch-tag line is a file identity tag for the GNU Arch | |
| 353 | −** revision control system. | |
| 354 | −** | |
| 355 | −** arch-tag: a6c8bad4-740c-4e4f-99f1-e274174ab540 | |
| 356 | −*/ | |