1 /**
2 * Smarc
3 *
4 * Copyright (c) 2009-2011 Institut Télécom - Télécom Paristech
5 * Télécom ParisTech / dept. TSI
6 *
7 * Authors : Benoit Mathieu, Jacques Prado
8 *
9 * This file is part of Smarc.
10 *
11 * Smarc is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * Smarc is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "smarc.h"
26 #include "stage_impl.h"
27 #include "multi_stage.h"
28 #include "polyfilt.h"
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <math.h>
33
34 #define FIRST_BUFFER_SIZE 512
35
36 struct PFilter
37 {
38 int fsin;
39 int fsout;
40 double fpass;
41 double fstop;
42 double rp;
43 double rs;
44 int nb_stages;
45 struct PSFilter** filter;
46 };
47
smarc_get_fs_in(struct PFilter * pfilt)48 int smarc_get_fs_in(struct PFilter* pfilt)
49 {
50 return pfilt->fsin;
51 }
52
smarc_get_fs_out(struct PFilter * pfilt)53 int smarc_get_fs_out(struct PFilter* pfilt)
54 {
55 return pfilt->fsout;
56 }
57
smarc_get_output_buffer_size(struct PFilter * pfilt,int inSize)58 int smarc_get_output_buffer_size(struct PFilter* pfilt,int inSize)
59 {
60 int outSize = 1 + (int) ceil((double)inSize * (double) pfilt->fsout / (double) pfilt->fsin);
61 double stage_fsout = pfilt->fsin;
62 for (int i=0;i<pfilt->nb_stages;i++)
63 {
64 stage_fsout *= (double)pfilt->filter[i]->L / (double)pfilt->filter[i]->M;
65 outSize += ceil( pfilt->fsout * pfilt->filter[i]->filter_delay / stage_fsout);
66 }
67 return outSize;
68 }
69
70
smarc_init_pfilter(int fsin,const int fsout,double bandwidth,double rp,double rs,double tol,const char * userratios,int searchfastconversion)71 struct PFilter* smarc_init_pfilter(int fsin, const int fsout, double bandwidth, double rp, double rs, double tol, const char* userratios, int searchfastconversion)
72 {
73 if (fsout==fsin)
74 {
75 printf("ERROR: in and out samplerates are equals ! (%i Hz)\n",fsin);
76 return NULL;
77 }
78
79 struct PMultiStageDef* pdef;
80 if (userratios!=NULL && strlen(userratios)>0)
81 {
82 pdef = get_user_ratios(fsin,fsout,userratios);
83 if (!pdef)
84 return NULL;
85 } else if (searchfastconversion) {
86 pdef = build_fast_ratios(fsin,fsout,tol,bandwidth,rp,rs);
87 } else {
88 pdef = get_predef_ratios(fsin,fsout);
89 if (!pdef)
90 {
91 pdef = build_auto_ratios(fsin,fsout, tol);
92 }
93 }
94
95 if (!pdef)
96 {
97 printf("ERROR: cannot design multistage samplerate converter ! try to increase tolerance or define it yourself.\n");
98 return NULL;
99 }
100
101 struct PFilter* pfilt = malloc(sizeof(struct PFilter));
102 pfilt->fsin = fsin;
103 pfilt->fsout = fsout;
104 pfilt->rp = rp;
105 pfilt->rs = rs;
106
107 pfilt->nb_stages = pdef->nb_stages;
108 pfilt->filter = malloc(pfilt->nb_stages*sizeof(struct PSFilter*));
109
110 pfilt->fstop = (fsin>fsout ? fsout/2 : fsin/2);
111 double fpass = bandwidth*pfilt->fstop;
112 pfilt->fpass = fpass;
113 double stage_fsin = fsin;
114 for (int i=0;i<pdef->nb_stages;i++)
115 {
116 double fstop = 0;
117 double fmax = pdef->L[i]*stage_fsin;
118 if (pdef->L[i] > pdef->M[i])
119 {
120 // interpolation
121 fstop = stage_fsin - pfilt->fstop;
122 } else {
123 // decimation
124 fstop = ((stage_fsin * pdef->L[i]) / pdef->M[i]) - (pfilt->fstop);
125 }
126 pfilt->filter[i] = init_psfilter(pdef->L[i],pdef->M[i],
127 fpass / fmax,fstop / fmax,rp,rs,pdef->nb_stages);
128 if (pfilt->filter[i]==NULL)
129 return NULL;
130 stage_fsin = (stage_fsin * pdef->L[i]) / pdef->M[i];
131 }
132 if (fabs(stage_fsin - fsout) > tol*fsin)
133 {
134 printf("ERROR: multistage filter output %f != %i ! (there should be an error in multistage definition)\n", stage_fsin,fsout);
135 return NULL;
136 } else if (stage_fsin!=fsout)
137 {
138 printf("WARNING: output samplerate is %f\n",stage_fsin);
139 }
140
141 destroy_multistagedef(pdef);
142
143 return pfilt;
144 }
145
smarc_destroy_pfilter(struct PFilter * pfilt)146 void smarc_destroy_pfilter(struct PFilter* pfilt)
147 {
148 for (int i=0;i<pfilt->nb_stages;i++)
149 destroy_psfilter(pfilt->filter[i]);
150 free(pfilt->filter);
151 free(pfilt);
152 }
153
smarc_print_pfilter(struct PFilter * pfilt)154 void smarc_print_pfilter(struct PFilter* pfilt)
155 {
156 printf("multi-stage polyphase resample from %iHz to %iHz\n",pfilt->fsin,pfilt->fsout);
157 printf(" passband to %0.2fHz, passband ripple factor %0.2fdB\n",pfilt->fpass,pfilt->rp);
158 printf(" stopband from %0.2fHz, stopband ripple factor %0.2fdB\n", pfilt->fstop,pfilt->rs);
159 printf("successive resample stages are :\n");
160 for (int s=0;s<pfilt->nb_stages;s++)
161 printf(" %i / %i : filter length = %i, delay = %i\n",pfilt->filter[s]->L,pfilt->filter[s]->M,pfilt->filter[s]->flen,pfilt->filter[s]->filter_delay);
162 }
163
164 struct PStageBuffer
165 {
166 double* data;
167 int size;
168 int pos;
169 };
170
171 struct PState
172 {
173 int nb_stages;
174 struct PSState** state;
175 struct PStageBuffer** buffer;
176 // flush vars
177 double* flush_buf;
178 int flush_size;
179 int flush_pos;
180 int flush_stage;
181 };
182
smarc_init_pstate(struct PFilter * pfilt)183 struct PState* smarc_init_pstate(struct PFilter* pfilt)
184 {
185 struct PState* pstate = malloc(sizeof(struct PState));
186 pstate->nb_stages = pfilt->nb_stages;
187 pstate->flush_buf = NULL;
188
189 // init states
190 pstate->state = malloc(pstate->nb_stages*sizeof(struct PSState*));
191 for (int i=0;i<pstate->nb_stages;i++)
192 pstate->state[i] = init_psstate(pfilt->filter[i]);
193
194 // init buffers
195 pstate->buffer = malloc((pstate->nb_stages+1)*sizeof(struct PStageBuffer*));
196 int total_size = 0;
197 int current_buffer_size = 0;
198 for (int i=0;i<pstate->nb_stages+1;i++)
199 {
200 struct PStageBuffer* cbuf = malloc(sizeof(struct PStageBuffer));
201 pstate->buffer[i] = cbuf;
202 if (i==0) {
203 current_buffer_size = FIRST_BUFFER_SIZE;
204 }
205 else {
206 current_buffer_size = current_buffer_size * pfilt->filter[i-1]->L / pfilt->filter[i-1]->M + 1;
207 }
208 int filter_len = 0;
209 if (i<pstate->nb_stages)
210 filter_len = pfilt->filter[i]->K - 1;
211 cbuf->size = current_buffer_size + filter_len;
212 cbuf->pos = 0;
213 // printf("buffer %i has buffer size %i + %i = %i \n",i,current_buffer_size,filter_len,cbuf->size);
214 total_size += cbuf->size;
215 }
216
217 // allocate all buffer contiguously
218 pstate->buffer[0]->data = (double*) malloc(total_size*sizeof(double));
219 for (int i=1;i<pstate->nb_stages+1;i++)
220 pstate->buffer[i]->data = pstate->buffer[i-1]->data + pstate->buffer[i-1]->size;
221
222 // reset pstate before returning it
223 smarc_reset_pstate(pstate,pfilt);
224 return pstate;
225 }
226
smarc_destroy_pstate(struct PState * pstate)227 void smarc_destroy_pstate(struct PState* pstate)
228 {
229 for (int i=0;i<pstate->nb_stages;i++)
230 destroy_psstate(pstate->state[i]);
231 free(pstate->buffer[0]->data);
232 for (int i=0;i<pstate->nb_stages+1;i++)
233 free(pstate->buffer[i]);
234 if (pstate->flush_buf)
235 free(pstate->flush_buf);
236 free(pstate->buffer);
237 free(pstate);
238 }
239
smarc_reset_pstate(struct PState * pstate,struct PFilter * pfilt)240 void smarc_reset_pstate(struct PState* pstate, struct PFilter* pfilt)
241 {
242 for (int i=0;i<pstate->nb_stages;i++)
243 reset_psstate(pstate->state[i],pfilt->filter[i]);
244 for (int i=0;i<pstate->nb_stages;i++) {
245 struct PStageBuffer* buf = pstate->buffer[i];
246 buf->pos = pfilt->filter[i]->K - 1;
247 for (int k=0;k<buf->pos;k++)
248 buf->data[k] = 0;
249 }
250 pstate->buffer[pstate->nb_stages]->pos = 0;
251 if (pstate->flush_buf) {
252 free(pstate->flush_buf);
253 pstate->flush_buf = NULL;
254 }
255 pstate->flush_stage = 0;
256 pstate->flush_pos = 0;
257 pstate->flush_size = 0;
258 }
259
smarc_resample(struct PFilter * pfilt,struct PState * pstate,const double * signal,int signalLength,double * output,int outputLength)260 int smarc_resample(struct PFilter* pfilt, struct PState* pstate,
261 const double* signal,
262 int signalLength,
263 double* output,
264 int outputLength)
265 {
266 int nbRead = 0;
267 int nbWritten = 0;
268 unsigned char inputRemains = 1; // use it as a flag
269 while (inputRemains && nbWritten<outputLength) {
270 inputRemains = 0;
271 // printf("process signal %i/%i, written %i/%i\n",*nbRead,signalLength,*nbWritten,outputLength);
272 // fill first buffer
273 {
274 struct PStageBuffer* fbuf = pstate->buffer[0];
275 int toRead = fbuf->size - fbuf->pos;
276 if (toRead>signalLength-nbRead)
277 toRead = signalLength - nbRead;
278 else
279 inputRemains = 1;
280 // printf("Push %i sample in first buffer %i/%i\n",toRead,fbuf->pos,fbuf->size);
281 if (toRead>0) {
282 memcpy(fbuf->data + fbuf->pos, signal + nbRead, toRead*sizeof(double));
283 fbuf->pos += toRead;
284 nbRead += toRead;
285 }
286 }
287 // process all stages
288 for (int i=0;i<pfilt->nb_stages;i++)
289 {
290 struct PSFilter* filt = pfilt->filter[i];
291 struct PSState* state = pstate->state[i];
292 struct PStageBuffer* inbuf = pstate->buffer[i];
293 struct PStageBuffer* outbuf = pstate->buffer[i+1];
294 int nbStageRead;
295 int nbStageWritten;
296 polyfiltLM(filt,state,inbuf->data,inbuf->pos,&nbStageRead,outbuf->data + outbuf->pos,outbuf->size - outbuf->pos,&nbStageWritten);
297
298 // printf("stage %i: read %i [%i/%i] write %i [%i/%i] K=%i\n",i,nbStageRead,inbuf->pos,inbuf->size,nbStageWritten,outbuf->pos,outbuf->size,filt->K);
299
300 // keep non processed input
301 if (nbStageRead<inbuf->pos) {
302 memmove(inbuf->data, inbuf->data + nbStageRead, (inbuf->pos - nbStageRead)*sizeof(double));
303 }
304 inbuf->pos -= nbStageRead;
305 if (inbuf->pos>filt->K-1)
306 inputRemains = 1;
307
308 // update output pos
309 outbuf->pos += nbStageWritten;
310 }
311 // report last buffer to output
312 {
313 struct PStageBuffer* lbuf = pstate->buffer[pstate->nb_stages];
314 int toWrite = lbuf->pos;
315 if (nbWritten + toWrite >= outputLength) {
316 printf("WARNING: cannot write all output samples, please provide larger output buffer !");
317 toWrite = outputLength - nbWritten;
318 }
319 // printf("write %i samples from last buf %i/%i into output buffer %i/%i\n",toWrite,lbuf->pos,lbuf->size,*nbWritten,outputLength);
320 if (toWrite>0)
321 memcpy(output + nbWritten,lbuf->data,toWrite*sizeof(double));
322 if (toWrite<lbuf->pos)
323 memmove(lbuf->data,lbuf->data+toWrite,(lbuf->pos-toWrite)*sizeof(double));
324 nbWritten += toWrite;
325 lbuf->pos -= toWrite;
326 }
327 }
328 return nbWritten;
329 }
330
smarc_resample_flush(struct PFilter * pfilt,struct PState * pstate,double * output,int outputLength)331 int smarc_resample_flush(struct PFilter* pfilt, struct PState* pstate,
332 double* output,
333 int outputLength)
334 {
335 int nbWritten = 0;
336 // flush all stages
337 while (pstate->flush_stage<pfilt->nb_stages && nbWritten<outputLength)
338 {
339 // printf("flushing stage %i [%i/%i]\n",pstate->flush_stage,pstate->flush_pos,pstate->flush_size);
340 struct PSFilter* filt = pfilt->filter[pstate->flush_stage];
341 struct PStageBuffer* inbuf = pstate->buffer[pstate->flush_stage];
342 if (pstate->flush_buf==NULL) {
343 int toFlush = filt->K - 1 - inbuf->pos + (filt->filter_delay * filt->M) / filt->L;
344 if (toFlush<(inbuf->size-inbuf->pos)) {
345 // printf("flushing straight %i samples\n",toFlush);
346 // just write flush samples into buffer
347 for (int k=0;k<toFlush;k++)
348 inbuf->data[inbuf->pos+k] = inbuf->data[inbuf->pos - 2 - k];
349 inbuf->pos += toFlush;
350 } else {
351 // remember samples to flush
352 pstate->flush_buf = (double*) malloc(toFlush*sizeof(double));
353 pstate->flush_size = toFlush;
354 for (int k=0;k<toFlush;k++)
355 pstate->flush_buf[k] = inbuf->data[inbuf->pos - 2 - k];
356 // fill inbuf
357 for (int k=0;k<inbuf->size-inbuf->pos;k++)
358 inbuf->data[inbuf->pos+k] = pstate->flush_buf[k];
359 // printf("flushing %i/%i samples\n", inbuf->size-inbuf->pos, toFlush);
360 pstate->flush_pos = inbuf->size-inbuf->pos;
361 inbuf->pos = inbuf->size;
362 }
363 } else {
364 // continue flushing
365 int toWrite = inbuf->size - inbuf->pos;
366 if (toWrite> (pstate->flush_size-pstate->flush_pos))
367 toWrite = pstate->flush_size-pstate->flush_pos;
368 for (int k=0;k<toWrite;k++)
369 inbuf->data[inbuf->pos+k] = pstate->flush_buf[pstate->flush_pos+k];
370 // printf("flushing next %i samples starting at %i/%i\n",toWrite,pstate->flush_pos,pstate->flush_size);
371 pstate->flush_pos += toWrite;
372 inbuf->pos += toWrite;
373 }
374
375 // process filtering
376 nbWritten += smarc_resample(pfilt,pstate,NULL,0,output + nbWritten, outputLength - nbWritten);
377
378 // check if all have been read
379 if ((inbuf->pos<filt->K) && (pstate->flush_pos==pstate->flush_size)) {
380 // end flushing this stage
381 if (pstate->flush_buf) {
382 free(pstate->flush_buf);
383 pstate->flush_buf = NULL;
384 pstate->flush_pos = 0;
385 pstate->flush_size = 0;
386 }
387 pstate->flush_stage++;
388 }
389 }
390 return nbWritten;
391 }
392