spudec: Fix calc_bbox to always return sensible values
[mplayer/glamo.git] / libaf / af_resample.c
blob5dd0e70329af6f17be7f50017be597e19a9db0e5
1 /*
2 * This audio filter changes the sample rate.
4 * Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
6 * This file is part of MPlayer.
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <inttypes.h>
27 #include "libavutil/common.h"
28 #include "libavutil/mathematics.h"
29 #include "af.h"
30 #include "dsp.h"
32 /* Below definition selects the length of each poly phase component.
33 Valid definitions are L8 and L16, where the number denotes the
34 length of the filter. This definition affects the computational
35 complexity (see play()), the performance (see filter.h) and the
36 memory usage. The filter length is chosen to 8 if the machine is
37 slow and to 16 if the machine is fast and has MMX.
40 #if !HAVE_MMX // This machine is slow
41 #define L8
42 #else
43 #define L16
44 #endif
46 #include "af_resample_template.c"
48 // Filtering types
49 #define RSMP_LIN (0<<0) // Linear interpolation
50 #define RSMP_INT (1<<0) // 16 bit integer
51 #define RSMP_FLOAT (2<<0) // 32 bit floating point
52 #define RSMP_MASK (3<<0)
54 // Defines for sloppy or exact resampling
55 #define FREQ_SLOPPY (0<<2)
56 #define FREQ_EXACT (1<<2)
57 #define FREQ_MASK (1<<2)
59 // Accuracy for linear interpolation
60 #define STEPACCURACY 32
62 // local data
63 typedef struct af_resample_s
65 void* w; // Current filter weights
66 void** xq; // Circular buffers
67 uint32_t xi; // Index for circular buffers
68 uint32_t wi; // Index for w
69 uint32_t i; // Number of new samples to put in x queue
70 uint32_t dn; // Down sampling factor
71 uint32_t up; // Up sampling factor
72 uint64_t step; // Step size for linear interpolation
73 uint64_t pt; // Pointer remainder for linear interpolation
74 int setup; // Setup parameters cmdline or through postcreate
75 } af_resample_t;
77 // Fast linear interpolation resample with modest audio quality
78 static int linint(af_data_t* c,af_data_t* l, af_resample_t* s)
80 uint32_t len = 0; // Number of input samples
81 uint32_t nch = l->nch; // Words pre transfer
82 uint64_t step = s->step;
83 int16_t* in16 = ((int16_t*)c->audio);
84 int16_t* out16 = ((int16_t*)l->audio);
85 int32_t* in32 = ((int32_t*)c->audio);
86 int32_t* out32 = ((int32_t*)l->audio);
87 uint64_t end = ((((uint64_t)c->len)/2LL)<<STEPACCURACY);
88 uint64_t pt = s->pt;
89 uint16_t tmp;
91 switch (nch){
92 case 1:
93 while(pt < end){
94 out16[len++]=in16[pt>>STEPACCURACY];
95 pt+=step;
97 s->pt=pt & ((1LL<<STEPACCURACY)-1);
98 break;
99 case 2:
100 end/=2;
101 while(pt < end){
102 out32[len++]=in32[pt>>STEPACCURACY];
103 pt+=step;
105 len=(len<<1);
106 s->pt=pt & ((1LL<<STEPACCURACY)-1);
107 break;
108 default:
109 end /=nch;
110 while(pt < end){
111 tmp=nch;
112 do {
113 tmp--;
114 out16[len+tmp]=in16[tmp+(pt>>STEPACCURACY)*nch];
115 } while (tmp);
116 len+=nch;
117 pt+=step;
119 s->pt=pt & ((1LL<<STEPACCURACY)-1);
121 return len;
124 /* Determine resampling type and format */
125 static int set_types(struct af_instance_s* af, af_data_t* data)
127 af_resample_t* s = af->setup;
128 int rv = AF_OK;
129 float rd = 0;
131 // Make sure this filter isn't redundant
132 if((af->data->rate == data->rate) || (af->data->rate == 0))
133 return AF_DETACH;
134 /* If sloppy and small resampling difference (2%) */
135 rd = abs((float)af->data->rate - (float)data->rate)/(float)data->rate;
136 if((((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (rd < 0.02) &&
137 (data->format != (AF_FORMAT_FLOAT_NE))) ||
138 ((s->setup & RSMP_MASK) == RSMP_LIN)){
139 s->setup = (s->setup & ~RSMP_MASK) | RSMP_LIN;
140 af->data->format = AF_FORMAT_S16_NE;
141 af->data->bps = 2;
142 mp_msg(MSGT_AFILTER, MSGL_V, "[resample] Using linear interpolation. \n");
144 else{
145 /* If the input format is float or if float is explicitly selected
146 use float, otherwise use int */
147 if((data->format == (AF_FORMAT_FLOAT_NE)) ||
148 ((s->setup & RSMP_MASK) == RSMP_FLOAT)){
149 s->setup = (s->setup & ~RSMP_MASK) | RSMP_FLOAT;
150 af->data->format = AF_FORMAT_FLOAT_NE;
151 af->data->bps = 4;
153 else{
154 s->setup = (s->setup & ~RSMP_MASK) | RSMP_INT;
155 af->data->format = AF_FORMAT_S16_NE;
156 af->data->bps = 2;
158 mp_msg(MSGT_AFILTER, MSGL_V, "[resample] Using %s processing and %s frequecy"
159 " conversion.\n",
160 ((s->setup & RSMP_MASK) == RSMP_FLOAT)?"floating point":"integer",
161 ((s->setup & FREQ_MASK) == FREQ_SLOPPY)?"inexact":"exact");
164 if(af->data->format != data->format || af->data->bps != data->bps)
165 rv = AF_FALSE;
166 data->format = af->data->format;
167 data->bps = af->data->bps;
168 af->data->nch = data->nch;
169 return rv;
172 // Initialization and runtime control
173 static int control(struct af_instance_s* af, int cmd, void* arg)
175 switch(cmd){
176 case AF_CONTROL_REINIT:{
177 af_resample_t* s = af->setup;
178 af_data_t* n = arg; // New configuration
179 int i,d = 0;
180 int rv = AF_OK;
182 // Free space for circular buffers
183 if(s->xq){
184 free(s->xq[0]);
185 free(s->xq);
186 s->xq = NULL;
189 if(AF_DETACH == (rv = set_types(af,n)))
190 return AF_DETACH;
192 // If linear interpolation
193 if((s->setup & RSMP_MASK) == RSMP_LIN){
194 s->pt=0LL;
195 s->step=((uint64_t)n->rate<<STEPACCURACY)/(uint64_t)af->data->rate+1LL;
196 mp_msg(MSGT_AFILTER, MSGL_DBG2, "[resample] Linear interpolation step: 0x%016"PRIX64".\n",
197 s->step);
198 af->mul = (double)af->data->rate / n->rate;
199 return rv;
202 // Calculate up and down sampling factors
203 d=av_gcd(af->data->rate,n->rate);
205 // If sloppy resampling is enabled limit the upsampling factor
206 if(((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (af->data->rate/d > 5000)){
207 int up=af->data->rate/2;
208 int dn=n->rate/2;
209 int m=2;
210 while(af->data->rate/(d*m) > 5000){
211 d=av_gcd(up,dn);
212 up/=2; dn/=2; m*=2;
214 d*=m;
217 // Create space for circular buffers
218 s->xq = malloc(n->nch*sizeof(void*));
219 s->xq[0] = calloc(n->nch, 2*L*af->data->bps);
220 for(i=1;i<n->nch;i++)
221 s->xq[i] = (uint8_t *)s->xq[i-1] + 2*L*af->data->bps;
222 s->xi = 0;
224 // Check if the design needs to be redone
225 if(s->up != af->data->rate/d || s->dn != n->rate/d){
226 float* w;
227 float* wt;
228 float fc;
229 int j;
230 s->up = af->data->rate/d;
231 s->dn = n->rate/d;
232 s->wi = 0;
233 s->i = 0;
235 // Calculate cutoff frequency for filter
236 fc = 1/(float)(max(s->up,s->dn));
237 // Allocate space for polyphase filter bank and prototype filter
238 w = malloc(sizeof(float) * s->up *L);
239 if(NULL != s->w)
240 free(s->w);
241 s->w = malloc(L*s->up*af->data->bps);
243 // Design prototype filter type using Kaiser window with beta = 10
244 if(NULL == w || NULL == s->w ||
245 -1 == af_filter_design_fir(s->up*L, w, &fc, LP|KAISER , 10.0)){
246 mp_msg(MSGT_AFILTER, MSGL_ERR, "[resample] Unable to design prototype filter.\n");
247 return AF_ERROR;
249 // Copy data from prototype to polyphase filter
250 wt=w;
251 for(j=0;j<L;j++){//Columns
252 for(i=0;i<s->up;i++){//Rows
253 if((s->setup & RSMP_MASK) == RSMP_INT){
254 float t=(float)s->up*32767.0*(*wt);
255 ((int16_t*)s->w)[i*L+j] = (int16_t)((t>=0.0)?(t+0.5):(t-0.5));
257 else
258 ((float*)s->w)[i*L+j] = (float)s->up*(*wt);
259 wt++;
262 free(w);
263 mp_msg(MSGT_AFILTER, MSGL_V, "[resample] New filter designed up: %i "
264 "down: %i\n", s->up, s->dn);
267 // Set multiplier and delay
268 af->delay = 0; // not set correctly, but shouldn't be too large anyway
269 af->mul = (double)s->up / s->dn;
270 return rv;
272 case AF_CONTROL_COMMAND_LINE:{
273 af_resample_t* s = af->setup;
274 int rate=0;
275 int type=RSMP_INT;
276 int sloppy=1;
277 sscanf((char*)arg,"%i:%i:%i", &rate, &sloppy, &type);
278 s->setup = (sloppy?FREQ_SLOPPY:FREQ_EXACT) |
279 (clamp(type,RSMP_LIN,RSMP_FLOAT));
280 return af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET, &rate);
282 case AF_CONTROL_POST_CREATE:
283 if((((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) == AF_INIT_FLOAT)
284 ((af_resample_t*)af->setup)->setup = RSMP_FLOAT;
285 return AF_OK;
286 case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET:
287 // Reinit must be called after this function has been called
289 // Sanity check
290 if(((int*)arg)[0] < 8000 || ((int*)arg)[0] > 192000){
291 mp_msg(MSGT_AFILTER, MSGL_ERR, "[resample] The output sample frequency "
292 "must be between 8kHz and 192kHz. Current value is %i \n",
293 ((int*)arg)[0]);
294 return AF_ERROR;
297 af->data->rate=((int*)arg)[0];
298 mp_msg(MSGT_AFILTER, MSGL_V, "[resample] Changing sample rate "
299 "to %iHz\n",af->data->rate);
300 return AF_OK;
302 return AF_UNKNOWN;
305 // Deallocate memory
306 static void uninit(struct af_instance_s* af)
308 af_resample_t *s = af->setup;
309 if (s) {
310 if (s->xq) free(s->xq[0]);
311 free(s->xq);
312 free(s->w);
313 free(s);
315 if(af->data)
316 free(af->data->audio);
317 free(af->data);
320 // Filter data through filter
321 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
323 int len = 0; // Length of output data
324 af_data_t* c = data; // Current working data
325 af_data_t* l = af->data; // Local data
326 af_resample_t* s = af->setup;
328 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
329 return NULL;
331 // Run resampling
332 switch(s->setup & RSMP_MASK){
333 case(RSMP_INT):
334 # define FORMAT_I 1
335 if(s->up>s->dn){
336 # define UP
337 # include "af_resample_template.c"
338 # undef UP
340 else{
341 # define DN
342 # include "af_resample_template.c"
343 # undef DN
345 break;
346 case(RSMP_FLOAT):
347 # undef FORMAT_I
348 # define FORMAT_F 1
349 if(s->up>s->dn){
350 # define UP
351 # include "af_resample_template.c"
352 # undef UP
354 else{
355 # define DN
356 # include "af_resample_template.c"
357 # undef DN
359 break;
360 case(RSMP_LIN):
361 len = linint(c, l, s);
362 break;
365 // Set output data
366 c->audio = l->audio;
367 c->len = len*l->bps;
368 c->rate = l->rate;
370 return c;
373 // Allocate memory and set function pointers
374 static int af_open(af_instance_t* af){
375 af->control=control;
376 af->uninit=uninit;
377 af->play=play;
378 af->mul=1;
379 af->data=calloc(1,sizeof(af_data_t));
380 af->setup=calloc(1,sizeof(af_resample_t));
381 if(af->data == NULL || af->setup == NULL)
382 return AF_ERROR;
383 ((af_resample_t*)af->setup)->setup = RSMP_INT | FREQ_SLOPPY;
384 return AF_OK;
387 // Description of this plugin
388 af_info_t af_info_resample = {
389 "Sample frequency conversion",
390 "resample",
391 "Anders",
393 AF_FLAGS_REENTRANT,
394 af_open