History

Move FIR/IIR/Polynomial stuff to its own branch.

Erik de Castro Lopo committed 22 years ago

Commit 72257ee1 parent d981d3111 files · +1 −1344Browse files

Showing the changes to src (5 of 11 files). Show all

Unified · Split

5 files
  1. src/Makefile.am +1 −2
  2. src/common.h +0 −6
  3. src/fip_best.h +0 −43
  4. src/samplerate.c +0 −9
  5. src/src_fir_iir_poly.c +0 −356
src/Makefile.am+1−2
@@ -11,8 +11,7 @@ COEFF_HDRS = high_qual_coeffs.h mid_qual_coeffs.h fastest_coeffs.h · 10 unmodified lines
11 11
12noinst_HEADERS = common.h float_cast.h $(COEFF_HDRS)12noinst_HEADERS = common.h float_cast.h $(COEFF_HDRS)
13 13
14SRC_SOURCES = samplerate.c src_sinc.c $(COEFF_HDRS) src_zoh.c src_linear.c \14SRC_SOURCES = samplerate.c src_sinc.c $(COEFF_HDRS) src_zoh.c src_linear.c
15 src_fir_iir_poly.c
16 15
17# MinGW requires -no-undefined if a DLL is to be built.16# MinGW requires -no-undefined if a DLL is to be built.
18libsamplerate_la_LDFLAGS = -no-undefined version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@17libsamplerate_la_LDFLAGS = -no-undefined version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@
src/common.h+0−6
@@ -116,12 +116,6 @@ const char* zoh_get_description (int src_enum) ; · 115 unmodified lines
116 116
117int zoh_set_converter (SRC_PRIVATE *psrc, int src_enum) ;117int zoh_set_converter (SRC_PRIVATE *psrc, int src_enum) ;
118 118
119/* In src_fir_iir_poly.c */
120const char* fip_get_name (int src_enum) ;
121const char* fip_get_description (int src_enum) ;
122
123int fip_set_converter (SRC_PRIVATE *psrc, int src_enum) ;
124
125#endif /* COMMON_H_INCLUDED */119#endif /* COMMON_H_INCLUDED */
126 120
127/*121/*
src/fip_best.h+0−43
@@ -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
20static 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. */
25static 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*/
src/samplerate.c+0−9
@@ -313,9 +313,6 @@ src_get_name (int converter_type) · 312 unmodified lines
313 if ((desc = linear_get_name (converter_type)) != NULL)313 if ((desc = linear_get_name (converter_type)) != NULL)
314 return desc ;314 return desc ;
315 315
316 if ((desc = fip_get_name (converter_type)) != NULL)
317 return desc ;
318
319 return NULL ;316 return NULL ;
320} /* src_get_name */317} /* src_get_name */
321 318
@@ -332,9 +329,6 @@ src_get_description (int converter_type) · 10 unmodified lines
332 if ((desc = linear_get_description (converter_type)) != NULL)329 if ((desc = linear_get_description (converter_type)) != NULL)
333 return desc ;330 return desc ;
334 331
335 if ((desc = fip_get_description (converter_type)) != NULL)
336 return desc ;
337
338 return NULL ;332 return NULL ;
339} /* src_get_description */333} /* src_get_description */
340 334
@@ -488,9 +482,6 @@ psrc_set_converter (SRC_PRIVATE *psrc, int converter_type) · 147 unmodified lines
488 if (linear_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR)482 if (linear_set_converter (psrc, converter_type) == SRC_ERR_NO_ERROR)
489 return SRC_ERR_NO_ERROR ;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 return SRC_ERR_BAD_CONVERTER ;485 return SRC_ERR_BAD_CONVERTER ;
495} /* psrc_set_converter */486} /* psrc_set_converter */
496 487
src/src_fir_iir_poly.c+0−356
@@ -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
31typedef struct
32{ int count ;
33 int increment ;
34 const float *c ;
35} FIP_COEFF_SET ;
36
37#include "fip_best.h"
38
39typedef 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
68static void fip_reset (SRC_PRIVATE *psrc) ;
69static int fip_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
70
71static int fip_process_var_down (FIR_IIR_POLY * fip, SRC_DATA * data) ;
72static int fip_process_const_down (FIR_IIR_POLY * fip, SRC_DATA * data) ;
73static int fip_process_var_up (FIR_IIR_POLY * fip, SRC_DATA * data) ;
74static int fip_process_const_up (FIR_IIR_POLY * fip, SRC_DATA * data) ;
75
76
77const char*
78fip_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
95const char*
96fip_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
113int
114fip_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
190static void
191fip_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
216static int
217fip_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
259static void
260fip_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
285static int
286fip_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
293static int
294fip_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
304static int
305fip_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
315static int
316fip_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*/

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t