comparison libaf/af_resample.c @ 8867:558f0b1f45ee

New auto config for volume and resample and added support for float flag in configuration
author anders
date Fri, 10 Jan 2003 01:01:38 +0000
parents 906f7a2dc085
children 398e3fb7c103
comparison
equal deleted inserted replaced
8866:f84a5237f914 8867:558f0b1f45ee
32 #endif 32 #endif
33 33
34 #include "af_resample.h" 34 #include "af_resample.h"
35 35
36 // Filtering types 36 // Filtering types
37 #define TYPE_LIN 0 // Linear interpolation 37 #define RSMP_LIN (0<<0) // Linear interpolation
38 #define TYPE_INT 1 // 16 bit integer 38 #define RSMP_INT (1<<0) // 16 bit integer
39 #define TYPE_FLOAT 2 // 32 bit floating point 39 #define RSMP_FLOAT (2<<0) // 32 bit floating point
40 #define RSMP_MASK (3<<0)
41
42 // Defines for sloppy or exact resampling
43 #define FREQ_SLOPPY (0<<2)
44 #define FREQ_EXACT (1<<2)
45 #define FREQ_MASK (1<<2)
40 46
41 // Accuracy for linear interpolation 47 // Accuracy for linear interpolation
42 #define STEPACCURACY 32 48 #define STEPACCURACY 32
43 49
44 // local data 50 // local data
51 uint32_t i; // Number of new samples to put in x queue 57 uint32_t i; // Number of new samples to put in x queue
52 uint32_t dn; // Down sampling factor 58 uint32_t dn; // Down sampling factor
53 uint32_t up; // Up sampling factor 59 uint32_t up; // Up sampling factor
54 uint64_t step; // Step size for linear interpolation 60 uint64_t step; // Step size for linear interpolation
55 uint64_t pt; // Pointer remainder for linear interpolation 61 uint64_t pt; // Pointer remainder for linear interpolation
56 int sloppy; // Enable sloppy resampling to reduce memory usage 62 int setup; // Setup parameters cmdline or through postcreate
57 int type; // Filter type
58 } af_resample_t; 63 } af_resample_t;
59 64
60 // Euclids algorithm for calculating Greatest Common Divisor GCD(a,b) 65 // Euclids algorithm for calculating Greatest Common Divisor GCD(a,b)
61 static inline int gcd(register int a, register int b) 66 static inline int gcd(register int a, register int b)
62 { 67 {
118 s->pt=pt & ((1LL<<STEPACCURACY)-1); 123 s->pt=pt & ((1LL<<STEPACCURACY)-1);
119 } 124 }
120 return len; 125 return len;
121 } 126 }
122 127
128 /* Determine resampling type and format */
129 static int set_types(struct af_instance_s* af, af_data_t* data)
130 {
131 af_resample_t* s = af->setup;
132 int rv = AF_OK;
133 float rd = 0;
134
135 // Make sure this filter isn't redundant
136 if((af->data->rate == data->rate) || (af->data->rate == 0))
137 return AF_DETACH;
138
139 /* If sloppy and small resampling difference (2%) */
140 rd = abs((float)af->data->rate - (float)data->rate)/(float)data->rate;
141 if((((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (rd < 0.02) &&
142 (data->format != (AF_FORMAT_NE | AF_FORMAT_F))) ||
143 ((s->setup & RSMP_MASK) == RSMP_LIN)){
144 s->setup = (s->setup & ~RSMP_MASK) | RSMP_LIN;
145 af->data->format = AF_FORMAT_NE | AF_FORMAT_SI;
146 af->data->bps = 2;
147 af_msg(AF_MSG_VERBOSE,"[resample] Using linear interpolation. \n");
148 }
149 else{
150 /* If the input format is float or if float is explicitly selected
151 use float, otherwise use int */
152 if((data->format == (AF_FORMAT_NE | AF_FORMAT_F)) ||
153 ((s->setup & RSMP_MASK) == RSMP_FLOAT)){
154 s->setup = (s->setup & ~RSMP_MASK) | RSMP_FLOAT;
155 af->data->format = AF_FORMAT_NE | AF_FORMAT_F;
156 af->data->bps = 4;
157 }
158 else{
159 s->setup = (s->setup & ~RSMP_MASK) | RSMP_INT;
160 af->data->format = AF_FORMAT_NE | AF_FORMAT_SI;
161 af->data->bps = 2;
162 }
163 af_msg(AF_MSG_VERBOSE,"[resample] Using %s processing and %s frequecy"
164 " conversion.\n",
165 ((s->setup & RSMP_MASK) == RSMP_FLOAT)?"floating point":"integer",
166 ((s->setup & FREQ_MASK) == FREQ_SLOPPY)?"inexact":"exact");
167 }
168
169 if(af->data->format != data->format || af->data->bps != data->bps)
170 rv = AF_FALSE;
171 data->format = af->data->format;
172 data->bps = af->data->bps;
173 af->data->nch = data->nch;
174 return rv;
175 }
176
123 // Initialization and runtime control 177 // Initialization and runtime control
124 static int control(struct af_instance_s* af, int cmd, void* arg) 178 static int control(struct af_instance_s* af, int cmd, void* arg)
125 { 179 {
126 switch(cmd){ 180 switch(cmd){
127 case AF_CONTROL_REINIT:{ 181 case AF_CONTROL_REINIT:{
128 af_resample_t* s = (af_resample_t*)af->setup; 182 af_resample_t* s = (af_resample_t*)af->setup;
129 af_data_t* n = (af_data_t*)arg; // New configureation 183 af_data_t* n = (af_data_t*)arg; // New configureation
130 int i,d = 0; 184 int i,d = 0;
131 int rv = AF_OK; 185 int rv = AF_OK;
132 size_t tsz = (s->type==TYPE_INT) ? sizeof(int16_t) : sizeof(float); 186
133 187 // Free space for circular bufers
134 // Make sure this filter isn't redundant 188 if(s->xq){
135 if((af->data->rate == n->rate) || (af->data->rate == 0)) 189 for(i=1;i<af->data->nch;i++)
190 if(s->xq[i])
191 free(s->xq[i]);
192 free(s->xq);
193 }
194
195 if(AF_DETACH == (rv = set_types(af,n)))
136 return AF_DETACH; 196 return AF_DETACH;
137 197
138 // If linear interpolation 198 // If linear interpolation
139 if(s->type == TYPE_LIN){ 199 if((s->setup & RSMP_MASK) == RSMP_LIN){
140 s->pt=0LL; 200 s->pt=0LL;
141 s->step=((uint64_t)n->rate<<STEPACCURACY)/(uint64_t)af->data->rate+1LL; 201 s->step=((uint64_t)n->rate<<STEPACCURACY)/(uint64_t)af->data->rate+1LL;
142 af_msg(AF_MSG_VERBOSE,"[resample] Linear interpolation step: 0x%016X.\n", 202 af_msg(AF_MSG_DEBUG0,"[resample] Linear interpolation step: 0x%016X.\n",
143 s->step); 203 s->step);
144 af->mul.n = af->data->rate; 204 af->mul.n = af->data->rate;
145 af->mul.d = n->rate; 205 af->mul.d = n->rate;
146 } 206 return AF_OK;
147 207 }
148 // Create space for circular bufers (if nesessary)
149 if((af->data->nch != n->nch) && (s->type != TYPE_LIN)){
150 // First free the old ones
151 if(s->xq){
152 for(i=1;i<af->data->nch;i++)
153 if(s->xq[i])
154 free(s->xq[i]);
155 free(s->xq);
156 }
157 // ... then create new
158 s->xq = malloc(n->nch*sizeof(void*));
159 for(i=0;i<n->nch;i++)
160 s->xq[i] = malloc(2*L*tsz);
161 s->xi = 0;
162 }
163
164 // Set parameters
165 af->data->nch = n->nch;
166 if(s->type == TYPE_INT || s->type == TYPE_LIN){
167 af->data->format = AF_FORMAT_NE | AF_FORMAT_SI;
168 af->data->bps = 2;
169 }
170 else{
171 af->data->format = AF_FORMAT_NE | AF_FORMAT_F;
172 af->data->bps = 4;
173 }
174 if(af->data->format != n->format || af->data->bps != n->bps)
175 rv = AF_FALSE;
176 n->format = af->data->format;
177 n->bps = af->data->bps;
178
179 // If linear interpolation is used the setup is done.
180 if(s->type == TYPE_LIN)
181 return rv;
182 208
183 // Calculate up and down sampling factors 209 // Calculate up and down sampling factors
184 d=gcd(af->data->rate,n->rate); 210 d=gcd(af->data->rate,n->rate);
185 211
186 // If sloppy resampling is enabled limit the upsampling factor 212 // If sloppy resampling is enabled limit the upsampling factor
187 if(s->sloppy && (af->data->rate/d > 5000)){ 213 if(((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (af->data->rate/d > 5000)){
188 int up=af->data->rate/2; 214 int up=af->data->rate/2;
189 int dn=n->rate/2; 215 int dn=n->rate/2;
190 int m=2; 216 int m=2;
191 while(af->data->rate/(d*m) > 5000){ 217 while(af->data->rate/(d*m) > 5000){
192 d=gcd(up,dn); 218 d=gcd(up,dn);
193 up/=2; dn/=2; m*=2; 219 up/=2; dn/=2; m*=2;
194 } 220 }
195 d*=m; 221 d*=m;
196 } 222 }
223
224 // Create space for circular bufers
225 s->xq = malloc(n->nch*sizeof(void*));
226 for(i=0;i<n->nch;i++)
227 s->xq[i] = malloc(2*L*af->data->bps);
228 s->xi = 0;
197 229
198 // Check if the the design needs to be redone 230 // Check if the the design needs to be redone
199 if(s->up != af->data->rate/d || s->dn != n->rate/d){ 231 if(s->up != af->data->rate/d || s->dn != n->rate/d){
200 float* w; 232 float* w;
201 float* wt; 233 float* wt;
208 fc = 1/(float)(max(s->up,s->dn)); 240 fc = 1/(float)(max(s->up,s->dn));
209 // Allocate space for polyphase filter bank and protptype filter 241 // Allocate space for polyphase filter bank and protptype filter
210 w = malloc(sizeof(float) * s->up *L); 242 w = malloc(sizeof(float) * s->up *L);
211 if(NULL != s->w) 243 if(NULL != s->w)
212 free(s->w); 244 free(s->w);
213 s->w = malloc(L*s->up*tsz); 245 s->w = malloc(L*s->up*af->data->bps);
214 246
215 // Design prototype filter type using Kaiser window with beta = 10 247 // Design prototype filter type using Kaiser window with beta = 10
216 if(NULL == w || NULL == s->w || 248 if(NULL == w || NULL == s->w ||
217 -1 == design_fir(s->up*L, w, &fc, LP|KAISER , 10.0)){ 249 -1 == design_fir(s->up*L, w, &fc, LP|KAISER , 10.0)){
218 af_msg(AF_MSG_ERROR,"[resample] Unable to design prototype filter.\n"); 250 af_msg(AF_MSG_ERROR,"[resample] Unable to design prototype filter.\n");
220 } 252 }
221 // Copy data from prototype to polyphase filter 253 // Copy data from prototype to polyphase filter
222 wt=w; 254 wt=w;
223 for(j=0;j<L;j++){//Columns 255 for(j=0;j<L;j++){//Columns
224 for(i=0;i<s->up;i++){//Rows 256 for(i=0;i<s->up;i++){//Rows
225 if(s->type == TYPE_INT){ 257 if((s->setup & RSMP_MASK) == RSMP_INT){
226 float t=(float)s->up*32767.0*(*wt); 258 float t=(float)s->up*32767.0*(*wt);
227 ((int16_t*)s->w)[i*L+j] = (int16_t)((t>=0.0)?(t+0.5):(t-0.5)); 259 ((int16_t*)s->w)[i*L+j] = (int16_t)((t>=0.0)?(t+0.5):(t-0.5));
228 } 260 }
229 else 261 else
230 ((float*)s->w)[i*L+j] = (float)s->up*(*wt); 262 ((float*)s->w)[i*L+j] = (float)s->up*(*wt);
243 return rv; 275 return rv;
244 } 276 }
245 case AF_CONTROL_COMMAND_LINE:{ 277 case AF_CONTROL_COMMAND_LINE:{
246 af_resample_t* s = (af_resample_t*)af->setup; 278 af_resample_t* s = (af_resample_t*)af->setup;
247 int rate=0; 279 int rate=0;
248 int lin=0; 280 int type=RSMP_INT;
249 sscanf((char*)arg,"%i:%i:%i", &rate, &(s->sloppy), &lin); 281 int sloppy=1;
250 if(lin) 282 sscanf((char*)arg,"%i:%i:%i", &rate, &type, &sloppy);
251 s->type = TYPE_LIN; 283 s->setup = (sloppy?FREQ_SLOPPY:FREQ_EXACT) |
284 (clamp(type,RSMP_LIN,RSMP_FLOAT));
252 return af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET, &rate); 285 return af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET, &rate);
253 } 286 }
254 case AF_CONTROL_POST_CREATE: 287 case AF_CONTROL_POST_CREATE:
255 ((af_resample_t*)af->setup)->type = 288 if((((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) == AF_INIT_FLOAT)
256 ((af_cfg_t*)arg)->force == AF_INIT_SLOW ? TYPE_INT : TYPE_FLOAT; 289 ((af_resample_t*)af->setup)->setup |= RSMP_FLOAT;
257 return AF_OK; 290 return AF_OK;
258 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: 291 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
259 // Reinit must be called after this function has been called 292 // Reinit must be called after this function has been called
260 293
261 // Sanity check 294 // Sanity check
291 324
292 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) 325 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
293 return NULL; 326 return NULL;
294 327
295 // Run resampling 328 // Run resampling
296 switch(s->type){ 329 switch(s->setup & RSMP_MASK){
297 case(TYPE_INT): 330 case(RSMP_INT):
298 # define FORMAT_I 1 331 # define FORMAT_I 1
299 if(s->up>s->dn){ 332 if(s->up>s->dn){
300 # define UP 333 # define UP
301 # include "af_resample.h" 334 # include "af_resample.h"
302 # undef UP 335 # undef UP
305 # define DN 338 # define DN
306 # include "af_resample.h" 339 # include "af_resample.h"
307 # undef DN 340 # undef DN
308 } 341 }
309 break; 342 break;
310 case(TYPE_FLOAT): 343 case(RSMP_FLOAT):
311 # undef FORMAT_I 344 # undef FORMAT_I
312 # define FORMAT_F 1 345 # define FORMAT_F 1
313 if(s->up>s->dn){ 346 if(s->up>s->dn){
314 # define UP 347 # define UP
315 # include "af_resample.h" 348 # include "af_resample.h"
319 # define DN 352 # define DN
320 # include "af_resample.h" 353 # include "af_resample.h"
321 # undef DN 354 # undef DN
322 } 355 }
323 break; 356 break;
324 case(TYPE_LIN): 357 case(RSMP_LIN):
325 len = linint(c, l, s); 358 len = linint(c, l, s);
326 break; 359 break;
327 } 360 }
328 361
329 // Set output data 362 // Set output data
343 af->mul.d=1; 376 af->mul.d=1;
344 af->data=calloc(1,sizeof(af_data_t)); 377 af->data=calloc(1,sizeof(af_data_t));
345 af->setup=calloc(1,sizeof(af_resample_t)); 378 af->setup=calloc(1,sizeof(af_resample_t));
346 if(af->data == NULL || af->setup == NULL) 379 if(af->data == NULL || af->setup == NULL)
347 return AF_ERROR; 380 return AF_ERROR;
381 ((af_resample_t*)af->setup)->setup = RSMP_INT | FREQ_SLOPPY;
348 return AF_OK; 382 return AF_OK;
349 } 383 }
350 384
351 // Description of this plugin 385 // Description of this plugin
352 af_info_t af_info_resample = { 386 af_info_t af_info_resample = {