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.
27 #include "libavutil/common.h"
28 #include "libavutil/mathematics.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 filterlength is choosen 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
46 #include "af_resample_template.c"
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
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
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
);
94 out16
[len
++]=in16
[pt
>>STEPACCURACY
];
97 s
->pt
=pt
& ((1LL<<STEPACCURACY
)-1);
102 out32
[len
++]=in32
[pt
>>STEPACCURACY
];
106 s
->pt
=pt
& ((1LL<<STEPACCURACY
)-1);
114 out16
[len
+tmp
]=in16
[tmp
+(pt
>>STEPACCURACY
)*nch
];
119 s
->pt
=pt
& ((1LL<<STEPACCURACY
)-1);
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
;
131 // Make sure this filter isn't redundant
132 if((af
->data
->rate
== data
->rate
) || (af
->data
->rate
== 0))
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
;
142 af_msg(AF_MSG_VERBOSE
,"[resample] Using linear interpolation. \n");
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
;
154 s
->setup
= (s
->setup
& ~RSMP_MASK
) | RSMP_INT
;
155 af
->data
->format
= AF_FORMAT_S16_NE
;
158 af_msg(AF_MSG_VERBOSE
,"[resample] Using %s processing and %s frequecy"
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
)
166 data
->format
= af
->data
->format
;
167 data
->bps
= af
->data
->bps
;
168 af
->data
->nch
= data
->nch
;
172 // Initialization and runtime control
173 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
176 case AF_CONTROL_REINIT
:{
177 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
178 af_data_t
* n
= (af_data_t
*)arg
; // New configureation
182 // Free space for circular bufers
184 for(i
=1;i
<af
->data
->nch
;i
++)
191 if(AF_DETACH
== (rv
= set_types(af
,n
)))
194 // If linear interpolation
195 if((s
->setup
& RSMP_MASK
) == RSMP_LIN
){
197 s
->step
=((uint64_t)n
->rate
<<STEPACCURACY
)/(uint64_t)af
->data
->rate
+1LL;
198 af_msg(AF_MSG_DEBUG0
,"[resample] Linear interpolation step: 0x%016"PRIX64
".\n",
200 af
->mul
= (double)af
->data
->rate
/ n
->rate
;
204 // Calculate up and down sampling factors
205 d
=av_gcd(af
->data
->rate
,n
->rate
);
207 // If sloppy resampling is enabled limit the upsampling factor
208 if(((s
->setup
& FREQ_MASK
) == FREQ_SLOPPY
) && (af
->data
->rate
/d
> 5000)){
209 int up
=af
->data
->rate
/2;
212 while(af
->data
->rate
/(d
*m
) > 5000){
219 // Create space for circular bufers
220 s
->xq
= malloc(n
->nch
*sizeof(void*));
221 for(i
=0;i
<n
->nch
;i
++)
222 s
->xq
[i
] = malloc(2*L
*af
->data
->bps
);
225 // Check if the the design needs to be redone
226 if(s
->up
!= af
->data
->rate
/d
|| s
->dn
!= n
->rate
/d
){
231 s
->up
= af
->data
->rate
/d
;
236 // Calculate cuttof frequency for filter
237 fc
= 1/(float)(max(s
->up
,s
->dn
));
238 // Allocate space for polyphase filter bank and protptype filter
239 w
= malloc(sizeof(float) * s
->up
*L
);
242 s
->w
= malloc(L
*s
->up
*af
->data
->bps
);
244 // Design prototype filter type using Kaiser window with beta = 10
245 if(NULL
== w
|| NULL
== s
->w
||
246 -1 == af_filter_design_fir(s
->up
*L
, w
, &fc
, LP
|KAISER
, 10.0)){
247 af_msg(AF_MSG_ERROR
,"[resample] Unable to design prototype filter.\n");
250 // Copy data from prototype to polyphase filter
252 for(j
=0;j
<L
;j
++){//Columns
253 for(i
=0;i
<s
->up
;i
++){//Rows
254 if((s
->setup
& RSMP_MASK
) == RSMP_INT
){
255 float t
=(float)s
->up
*32767.0*(*wt
);
256 ((int16_t*)s
->w
)[i
*L
+j
] = (int16_t)((t
>=0.0)?(t
+0.5):(t
-0.5));
259 ((float*)s
->w
)[i
*L
+j
] = (float)s
->up
*(*wt
);
264 af_msg(AF_MSG_VERBOSE
,"[resample] New filter designed up: %i "
265 "down: %i\n", s
->up
, s
->dn
);
268 // Set multiplier and delay
269 af
->delay
= 0; // not set correctly, but shouldn't be too large anyway
270 af
->mul
= (double)s
->up
/ s
->dn
;
273 case AF_CONTROL_COMMAND_LINE
:{
274 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
278 sscanf((char*)arg
,"%i:%i:%i", &rate
, &sloppy
, &type
);
279 s
->setup
= (sloppy
?FREQ_SLOPPY
:FREQ_EXACT
) |
280 (clamp(type
,RSMP_LIN
,RSMP_FLOAT
));
281 return af
->control(af
,AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
, &rate
);
283 case AF_CONTROL_POST_CREATE
:
284 if((((af_cfg_t
*)arg
)->force
& AF_INIT_FORMAT_MASK
) == AF_INIT_FLOAT
)
285 ((af_resample_t
*)af
->setup
)->setup
= RSMP_FLOAT
;
287 case AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
:
288 // Reinit must be called after this function has been called
291 if(((int*)arg
)[0] < 8000 || ((int*)arg
)[0] > 192000){
292 af_msg(AF_MSG_ERROR
,"[resample] The output sample frequency "
293 "must be between 8kHz and 192kHz. Current value is %i \n",
298 af
->data
->rate
=((int*)arg
)[0];
299 af_msg(AF_MSG_VERBOSE
,"[resample] Changing sample rate "
300 "to %iHz\n",af
->data
->rate
);
307 static void uninit(struct af_instance_s
* af
)
310 free(af
->data
->audio
);
314 // Filter data through filter
315 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
317 int len
= 0; // Length of output data
318 af_data_t
* c
= data
; // Current working data
319 af_data_t
* l
= af
->data
; // Local data
320 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
322 if(AF_OK
!= RESIZE_LOCAL_BUFFER(af
,data
))
326 switch(s
->setup
& RSMP_MASK
){
331 # include "af_resample_template.c"
336 # include "af_resample_template.c"
345 # include "af_resample_template.c"
350 # include "af_resample_template.c"
355 len
= linint(c
, l
, s
);
367 // Allocate memory and set function pointers
368 static int af_open(af_instance_t
* af
){
373 af
->data
=calloc(1,sizeof(af_data_t
));
374 af
->setup
=calloc(1,sizeof(af_resample_t
));
375 if(af
->data
== NULL
|| af
->setup
== NULL
)
377 ((af_resample_t
*)af
->setup
)->setup
= RSMP_INT
| FREQ_SLOPPY
;
381 // Description of this plugin
382 af_info_t af_info_resample
= {
383 "Sample frequency conversion",