Consistently use tabs in svn:externals
[mplayer/glamo.git] / libaf / af_resample.c
blobc2cfb4b74f9a8a85a1e214f1ae73434d9139696a
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 "af.h"
29 #include "dsp.h"
31 /* Below definition selects the length of each poly phase component.
32 Valid definitions are L8 and L16, where the number denotes the
33 length of the filter. This definition affects the computational
34 complexity (see play()), the performance (see filter.h) and the
35 memory usage. The filterlength is choosen to 8 if the machine is
36 slow and to 16 if the machine is fast and has MMX.
39 #if !defined(HAVE_MMX) // This machine is slow
40 #define L8
41 #else
42 #define L16
43 #endif
45 #include "af_resample_template.c"
47 // Filtering types
48 #define RSMP_LIN (0<<0) // Linear interpolation
49 #define RSMP_INT (1<<0) // 16 bit integer
50 #define RSMP_FLOAT (2<<0) // 32 bit floating point
51 #define RSMP_MASK (3<<0)
53 // Defines for sloppy or exact resampling
54 #define FREQ_SLOPPY (0<<2)
55 #define FREQ_EXACT (1<<2)
56 #define FREQ_MASK (1<<2)
58 // Accuracy for linear interpolation
59 #define STEPACCURACY 32
61 // local data
62 typedef struct af_resample_s
64 void* w; // Current filter weights
65 void** xq; // Circular buffers
66 uint32_t xi; // Index for circular buffers
67 uint32_t wi; // Index for w
68 uint32_t i; // Number of new samples to put in x queue
69 uint32_t dn; // Down sampling factor
70 uint32_t up; // Up sampling factor
71 uint64_t step; // Step size for linear interpolation
72 uint64_t pt; // Pointer remainder for linear interpolation
73 int setup; // Setup parameters cmdline or through postcreate
74 } af_resample_t;
76 // Fast linear interpolation resample with modest audio quality
77 static int linint(af_data_t* c,af_data_t* l, af_resample_t* s)
79 uint32_t len = 0; // Number of input samples
80 uint32_t nch = l->nch; // Words pre transfer
81 uint64_t step = s->step;
82 int16_t* in16 = ((int16_t*)c->audio);
83 int16_t* out16 = ((int16_t*)l->audio);
84 int32_t* in32 = ((int32_t*)c->audio);
85 int32_t* out32 = ((int32_t*)l->audio);
86 uint64_t end = ((((uint64_t)c->len)/2LL)<<STEPACCURACY);
87 uint64_t pt = s->pt;
88 uint16_t tmp;
90 switch (nch){
91 case 1:
92 while(pt < end){
93 out16[len++]=in16[pt>>STEPACCURACY];
94 pt+=step;
96 s->pt=pt & ((1LL<<STEPACCURACY)-1);
97 break;
98 case 2:
99 end/=2;
100 while(pt < end){
101 out32[len++]=in32[pt>>STEPACCURACY];
102 pt+=step;
104 len=(len<<1);
105 s->pt=pt & ((1LL<<STEPACCURACY)-1);
106 break;
107 default:
108 end /=nch;
109 while(pt < end){
110 tmp=nch;
111 do {
112 tmp--;
113 out16[len+tmp]=in16[tmp+(pt>>STEPACCURACY)*nch];
114 } while (tmp);
115 len+=nch;
116 pt+=step;
118 s->pt=pt & ((1LL<<STEPACCURACY)-1);
120 return len;
123 /* Determine resampling type and format */
124 static int set_types(struct af_instance_s* af, af_data_t* data)
126 af_resample_t* s = af->setup;
127 int rv = AF_OK;
128 float rd = 0;
130 // Make sure this filter isn't redundant
131 if((af->data->rate == data->rate) || (af->data->rate == 0))
132 return AF_DETACH;
133 /* If sloppy and small resampling difference (2%) */
134 rd = abs((float)af->data->rate - (float)data->rate)/(float)data->rate;
135 if((((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (rd < 0.02) &&
136 (data->format != (AF_FORMAT_FLOAT_NE))) ||
137 ((s->setup & RSMP_MASK) == RSMP_LIN)){
138 s->setup = (s->setup & ~RSMP_MASK) | RSMP_LIN;
139 af->data->format = AF_FORMAT_S16_NE;
140 af->data->bps = 2;
141 af_msg(AF_MSG_VERBOSE,"[resample] Using linear interpolation. \n");
143 else{
144 /* If the input format is float or if float is explicitly selected
145 use float, otherwise use int */
146 if((data->format == (AF_FORMAT_FLOAT_NE)) ||
147 ((s->setup & RSMP_MASK) == RSMP_FLOAT)){
148 s->setup = (s->setup & ~RSMP_MASK) | RSMP_FLOAT;
149 af->data->format = AF_FORMAT_FLOAT_NE;
150 af->data->bps = 4;
152 else{
153 s->setup = (s->setup & ~RSMP_MASK) | RSMP_INT;
154 af->data->format = AF_FORMAT_S16_NE;
155 af->data->bps = 2;
157 af_msg(AF_MSG_VERBOSE,"[resample] Using %s processing and %s frequecy"
158 " conversion.\n",
159 ((s->setup & RSMP_MASK) == RSMP_FLOAT)?"floating point":"integer",
160 ((s->setup & FREQ_MASK) == FREQ_SLOPPY)?"inexact":"exact");
163 if(af->data->format != data->format || af->data->bps != data->bps)
164 rv = AF_FALSE;
165 data->format = af->data->format;
166 data->bps = af->data->bps;
167 af->data->nch = data->nch;
168 return rv;
171 // Initialization and runtime control
172 static int control(struct af_instance_s* af, int cmd, void* arg)
174 switch(cmd){
175 case AF_CONTROL_REINIT:{
176 af_resample_t* s = (af_resample_t*)af->setup;
177 af_data_t* n = (af_data_t*)arg; // New configureation
178 int i,d = 0;
179 int rv = AF_OK;
181 // Free space for circular bufers
182 if(s->xq){
183 for(i=1;i<af->data->nch;i++)
184 if(s->xq[i])
185 free(s->xq[i]);
186 free(s->xq);
187 s->xq = NULL;
190 if(AF_DETACH == (rv = set_types(af,n)))
191 return AF_DETACH;
193 // If linear interpolation
194 if((s->setup & RSMP_MASK) == RSMP_LIN){
195 s->pt=0LL;
196 s->step=((uint64_t)n->rate<<STEPACCURACY)/(uint64_t)af->data->rate+1LL;
197 af_msg(AF_MSG_DEBUG0,"[resample] Linear interpolation step: 0x%016"PRIX64".\n",
198 s->step);
199 af->mul = (double)af->data->rate / n->rate;
200 return rv;
203 // Calculate up and down sampling factors
204 d=ff_gcd(af->data->rate,n->rate);
206 // If sloppy resampling is enabled limit the upsampling factor
207 if(((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (af->data->rate/d > 5000)){
208 int up=af->data->rate/2;
209 int dn=n->rate/2;
210 int m=2;
211 while(af->data->rate/(d*m) > 5000){
212 d=ff_gcd(up,dn);
213 up/=2; dn/=2; m*=2;
215 d*=m;
218 // Create space for circular bufers
219 s->xq = malloc(n->nch*sizeof(void*));
220 for(i=0;i<n->nch;i++)
221 s->xq[i] = malloc(2*L*af->data->bps);
222 s->xi = 0;
224 // Check if the 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 cuttof frequency for filter
236 fc = 1/(float)(max(s->up,s->dn));
237 // Allocate space for polyphase filter bank and protptype 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 af_msg(AF_MSG_ERROR,"[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 af_msg(AF_MSG_VERBOSE,"[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_resample_t*)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 af_msg(AF_MSG_ERROR,"[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 af_msg(AF_MSG_VERBOSE,"[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 if(af->data)
309 free(af->data->audio);
310 free(af->data);
313 // Filter data through filter
314 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
316 int len = 0; // Length of output data
317 af_data_t* c = data; // Current working data
318 af_data_t* l = af->data; // Local data
319 af_resample_t* s = (af_resample_t*)af->setup;
321 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
322 return NULL;
324 // Run resampling
325 switch(s->setup & RSMP_MASK){
326 case(RSMP_INT):
327 # define FORMAT_I 1
328 if(s->up>s->dn){
329 # define UP
330 # include "af_resample_template.c"
331 # undef UP
333 else{
334 # define DN
335 # include "af_resample_template.c"
336 # undef DN
338 break;
339 case(RSMP_FLOAT):
340 # undef FORMAT_I
341 # define FORMAT_F 1
342 if(s->up>s->dn){
343 # define UP
344 # include "af_resample_template.c"
345 # undef UP
347 else{
348 # define DN
349 # include "af_resample_template.c"
350 # undef DN
352 break;
353 case(RSMP_LIN):
354 len = linint(c, l, s);
355 break;
358 // Set output data
359 c->audio = l->audio;
360 c->len = len*l->bps;
361 c->rate = l->rate;
363 return c;
366 // Allocate memory and set function pointers
367 static int af_open(af_instance_t* af){
368 af->control=control;
369 af->uninit=uninit;
370 af->play=play;
371 af->mul=1;
372 af->data=calloc(1,sizeof(af_data_t));
373 af->setup=calloc(1,sizeof(af_resample_t));
374 if(af->data == NULL || af->setup == NULL)
375 return AF_ERROR;
376 ((af_resample_t*)af->setup)->setup = RSMP_INT | FREQ_SLOPPY;
377 return AF_OK;
380 // Description of this plugin
381 af_info_t af_info_resample = {
382 "Sample frequency conversion",
383 "resample",
384 "Anders",
386 AF_FLAGS_REENTRANT,
387 af_open