1 /*=============================================================================
3 // This software has been released under the terms of the GNU General Public
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
6 // Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au
8 //=============================================================================
11 /* This audio filter changes the sample rate. */
19 /* Below definition selects the length of each poly phase component.
20 Valid definitions are L8 and L16, where the number denotes the
21 length of the filter. This definition affects the computational
22 complexity (see play()), the performance (see filter.h) and the
23 memory usage. The filterlength is choosen to 8 if the machine is
24 slow and to 16 if the machine is fast and has MMX.
27 #if !defined(HAVE_MMX) // This machine is slow
33 #include "af_resample.h"
36 #define RSMP_LIN (0<<0) // Linear interpolation
37 #define RSMP_INT (1<<0) // 16 bit integer
38 #define RSMP_FLOAT (2<<0) // 32 bit floating point
39 #define RSMP_MASK (3<<0)
41 // Defines for sloppy or exact resampling
42 #define FREQ_SLOPPY (0<<2)
43 #define FREQ_EXACT (1<<2)
44 #define FREQ_MASK (1<<2)
46 // Accuracy for linear interpolation
47 #define STEPACCURACY 32
50 typedef struct af_resample_s
52 void* w
; // Current filter weights
53 void** xq
; // Circular buffers
54 uint32_t xi
; // Index for circular buffers
55 uint32_t wi
; // Index for w
56 uint32_t i
; // Number of new samples to put in x queue
57 uint32_t dn
; // Down sampling factor
58 uint32_t up
; // Up sampling factor
59 uint64_t step
; // Step size for linear interpolation
60 uint64_t pt
; // Pointer remainder for linear interpolation
61 int setup
; // Setup parameters cmdline or through postcreate
64 // Fast linear interpolation resample with modest audio quality
65 static int linint(af_data_t
* c
,af_data_t
* l
, af_resample_t
* s
)
67 uint32_t len
= 0; // Number of input samples
68 uint32_t nch
= l
->nch
; // Words pre transfer
69 uint64_t step
= s
->step
;
70 int16_t* in16
= ((int16_t*)c
->audio
);
71 int16_t* out16
= ((int16_t*)l
->audio
);
72 int32_t* in32
= ((int32_t*)c
->audio
);
73 int32_t* out32
= ((int32_t*)l
->audio
);
74 uint64_t end
= ((((uint64_t)c
->len
)/2LL)<<STEPACCURACY
);
81 out16
[len
++]=in16
[pt
>>STEPACCURACY
];
84 s
->pt
=pt
& ((1LL<<STEPACCURACY
)-1);
89 out32
[len
++]=in32
[pt
>>STEPACCURACY
];
93 s
->pt
=pt
& ((1LL<<STEPACCURACY
)-1);
101 out16
[len
+tmp
]=in16
[tmp
+(pt
>>STEPACCURACY
)*nch
];
106 s
->pt
=pt
& ((1LL<<STEPACCURACY
)-1);
111 /* Determine resampling type and format */
112 static int set_types(struct af_instance_s
* af
, af_data_t
* data
)
114 af_resample_t
* s
= af
->setup
;
118 // Make sure this filter isn't redundant
119 if((af
->data
->rate
== data
->rate
) || (af
->data
->rate
== 0))
121 /* If sloppy and small resampling difference (2%) */
122 rd
= abs((float)af
->data
->rate
- (float)data
->rate
)/(float)data
->rate
;
123 if((((s
->setup
& FREQ_MASK
) == FREQ_SLOPPY
) && (rd
< 0.02) &&
124 (data
->format
!= (AF_FORMAT_FLOAT_NE
))) ||
125 ((s
->setup
& RSMP_MASK
) == RSMP_LIN
)){
126 s
->setup
= (s
->setup
& ~RSMP_MASK
) | RSMP_LIN
;
127 af
->data
->format
= AF_FORMAT_S16_NE
;
129 af_msg(AF_MSG_VERBOSE
,"[resample] Using linear interpolation. \n");
132 /* If the input format is float or if float is explicitly selected
133 use float, otherwise use int */
134 if((data
->format
== (AF_FORMAT_FLOAT_NE
)) ||
135 ((s
->setup
& RSMP_MASK
) == RSMP_FLOAT
)){
136 s
->setup
= (s
->setup
& ~RSMP_MASK
) | RSMP_FLOAT
;
137 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
141 s
->setup
= (s
->setup
& ~RSMP_MASK
) | RSMP_INT
;
142 af
->data
->format
= AF_FORMAT_S16_NE
;
145 af_msg(AF_MSG_VERBOSE
,"[resample] Using %s processing and %s frequecy"
147 ((s
->setup
& RSMP_MASK
) == RSMP_FLOAT
)?"floating point":"integer",
148 ((s
->setup
& FREQ_MASK
) == FREQ_SLOPPY
)?"inexact":"exact");
151 if(af
->data
->format
!= data
->format
|| af
->data
->bps
!= data
->bps
)
153 data
->format
= af
->data
->format
;
154 data
->bps
= af
->data
->bps
;
155 af
->data
->nch
= data
->nch
;
159 // Initialization and runtime control
160 static int control(struct af_instance_s
* af
, int cmd
, void* arg
)
163 case AF_CONTROL_REINIT
:{
164 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
165 af_data_t
* n
= (af_data_t
*)arg
; // New configureation
169 // Free space for circular bufers
171 for(i
=1;i
<af
->data
->nch
;i
++)
178 if(AF_DETACH
== (rv
= set_types(af
,n
)))
181 // If linear interpolation
182 if((s
->setup
& RSMP_MASK
) == RSMP_LIN
){
184 s
->step
=((uint64_t)n
->rate
<<STEPACCURACY
)/(uint64_t)af
->data
->rate
+1LL;
185 af_msg(AF_MSG_DEBUG0
,"[resample] Linear interpolation step: 0x%016"PRIX64
".\n",
187 af
->mul
.n
= af
->data
->rate
;
189 af_frac_cancel(&af
->mul
);
193 // Calculate up and down sampling factors
194 d
=af_gcd(af
->data
->rate
,n
->rate
);
196 // If sloppy resampling is enabled limit the upsampling factor
197 if(((s
->setup
& FREQ_MASK
) == FREQ_SLOPPY
) && (af
->data
->rate
/d
> 5000)){
198 int up
=af
->data
->rate
/2;
201 while(af
->data
->rate
/(d
*m
) > 5000){
208 // Create space for circular bufers
209 s
->xq
= malloc(n
->nch
*sizeof(void*));
210 for(i
=0;i
<n
->nch
;i
++)
211 s
->xq
[i
] = malloc(2*L
*af
->data
->bps
);
214 // Check if the the design needs to be redone
215 if(s
->up
!= af
->data
->rate
/d
|| s
->dn
!= n
->rate
/d
){
220 s
->up
= af
->data
->rate
/d
;
225 // Calculate cuttof frequency for filter
226 fc
= 1/(float)(max(s
->up
,s
->dn
));
227 // Allocate space for polyphase filter bank and protptype filter
228 w
= malloc(sizeof(float) * s
->up
*L
);
231 s
->w
= malloc(L
*s
->up
*af
->data
->bps
);
233 // Design prototype filter type using Kaiser window with beta = 10
234 if(NULL
== w
|| NULL
== s
->w
||
235 -1 == af_filter_design_fir(s
->up
*L
, w
, &fc
, LP
|KAISER
, 10.0)){
236 af_msg(AF_MSG_ERROR
,"[resample] Unable to design prototype filter.\n");
239 // Copy data from prototype to polyphase filter
241 for(j
=0;j
<L
;j
++){//Columns
242 for(i
=0;i
<s
->up
;i
++){//Rows
243 if((s
->setup
& RSMP_MASK
) == RSMP_INT
){
244 float t
=(float)s
->up
*32767.0*(*wt
);
245 ((int16_t*)s
->w
)[i
*L
+j
] = (int16_t)((t
>=0.0)?(t
+0.5):(t
-0.5));
248 ((float*)s
->w
)[i
*L
+j
] = (float)s
->up
*(*wt
);
253 af_msg(AF_MSG_VERBOSE
,"[resample] New filter designed up: %i "
254 "down: %i\n", s
->up
, s
->dn
);
257 // Set multiplier and delay
258 af
->delay
= (double)(1000*L
/2)/((double)n
->rate
);
263 case AF_CONTROL_COMMAND_LINE
:{
264 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
268 sscanf((char*)arg
,"%i:%i:%i", &rate
, &sloppy
, &type
);
269 s
->setup
= (sloppy
?FREQ_SLOPPY
:FREQ_EXACT
) |
270 (clamp(type
,RSMP_LIN
,RSMP_FLOAT
));
271 return af
->control(af
,AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
, &rate
);
273 case AF_CONTROL_POST_CREATE
:
274 if((((af_cfg_t
*)arg
)->force
& AF_INIT_FORMAT_MASK
) == AF_INIT_FLOAT
)
275 ((af_resample_t
*)af
->setup
)->setup
= RSMP_FLOAT
;
277 case AF_CONTROL_RESAMPLE_RATE
| AF_CONTROL_SET
:
278 // Reinit must be called after this function has been called
281 if(((int*)arg
)[0] < 8000 || ((int*)arg
)[0] > 192000){
282 af_msg(AF_MSG_ERROR
,"[resample] The output sample frequency "
283 "must be between 8kHz and 192kHz. Current value is %i \n",
288 af
->data
->rate
=((int*)arg
)[0];
289 af_msg(AF_MSG_VERBOSE
,"[resample] Changing sample rate "
290 "to %iHz\n",af
->data
->rate
);
297 static void uninit(struct af_instance_s
* af
)
300 free(af
->data
->audio
);
304 // Filter data through filter
305 static af_data_t
* play(struct af_instance_s
* af
, af_data_t
* data
)
307 int len
= 0; // Length of output data
308 af_data_t
* c
= data
; // Current working data
309 af_data_t
* l
= af
->data
; // Local data
310 af_resample_t
* s
= (af_resample_t
*)af
->setup
;
312 if(AF_OK
!= RESIZE_LOCAL_BUFFER(af
,data
))
316 switch(s
->setup
& RSMP_MASK
){
321 # include "af_resample.h"
326 # include "af_resample.h"
335 # include "af_resample.h"
340 # include "af_resample.h"
345 len
= linint(c
, l
, s
);
357 // Allocate memory and set function pointers
358 static int af_open(af_instance_t
* af
){
364 af
->data
=calloc(1,sizeof(af_data_t
));
365 af
->setup
=calloc(1,sizeof(af_resample_t
));
366 if(af
->data
== NULL
|| af
->setup
== NULL
)
368 ((af_resample_t
*)af
->setup
)->setup
= RSMP_INT
| FREQ_SLOPPY
;
372 // Description of this plugin
373 af_info_t af_info_resample
= {
374 "Sample frequency conversion",