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