~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libaf/af_resample.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=============================================================================
 
2
//      
 
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.
 
5
//
 
6
//  Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au
 
7
//
 
8
//=============================================================================
 
9
*/
 
10
 
 
11
/* This audio filter changes the sample rate. */
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <unistd.h>
 
15
#include <inttypes.h>
 
16
 
 
17
#include "af.h"
 
18
#include "dsp.h"
 
19
 
 
20
/* Below definition selects the length of each poly phase component.
 
21
   Valid definitions are L8 and L16, where the number denotes the
 
22
   length of the filter. This definition affects the computational
 
23
   complexity (see play()), the performance (see filter.h) and the
 
24
   memory usage. The filterlenght is choosen to 8 if the machine is
 
25
   slow and to 16 if the machine is fast and has MMX.  
 
26
*/
 
27
 
 
28
#if !defined(HAVE_MMX) // This machine is slow
 
29
#define L8 
 
30
#else
 
31
#define L16
 
32
#endif
 
33
 
 
34
#include "af_resample.h"
 
35
 
 
36
// Filtering types
 
37
#define RSMP_LIN        (0<<0)  // Linear interpolation
 
38
#define RSMP_INT        (1<<0)  // 16 bit integer 
 
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)
 
46
 
 
47
// Accuracy for linear interpolation
 
48
#define STEPACCURACY 32
 
49
 
 
50
// local data
 
51
typedef struct af_resample_s
 
52
{
 
53
  void*         w;      // Current filter weights
 
54
  void**        xq;     // Circular buffers
 
55
  uint32_t      xi;     // Index for circular buffers
 
56
  uint32_t      wi;     // Index for w
 
57
  uint32_t      i;      // Number of new samples to put in x queue 
 
58
  uint32_t      dn;     // Down sampling factor
 
59
  uint32_t      up;     // Up sampling factor 
 
60
  uint64_t      step;   // Step size for linear interpolation
 
61
  uint64_t      pt;     // Pointer remainder for linear interpolation
 
62
  int           setup;  // Setup parameters cmdline or through postcreate
 
63
} af_resample_t;
 
64
 
 
65
// Fast linear interpolation resample with modest audio quality
 
66
static int linint(af_data_t* c,af_data_t* l, af_resample_t* s)
 
67
{
 
68
  uint32_t      len   = 0;              // Number of input samples
 
69
  uint32_t      nch   = l->nch;         // Words pre transfer
 
70
  uint64_t      step  = s->step; 
 
71
  int16_t*      in16  = ((int16_t*)c->audio);
 
72
  int16_t*      out16 = ((int16_t*)l->audio);
 
73
  int32_t*      in32  = ((int32_t*)c->audio);
 
74
  int32_t*      out32 = ((int32_t*)l->audio);
 
75
  uint64_t      end   = ((((uint64_t)c->len)/2LL)<<STEPACCURACY);
 
76
  uint64_t      pt    = s->pt;
 
77
  uint16_t      tmp;
 
78
  
 
79
  switch (nch){
 
80
  case 1:
 
81
    while(pt < end){
 
82
      out16[len++]=in16[pt>>STEPACCURACY];          
 
83
      pt+=step;
 
84
    }
 
85
    s->pt=pt & ((1LL<<STEPACCURACY)-1);
 
86
    break;              
 
87
  case 2:
 
88
    end/=2;
 
89
    while(pt < end){
 
90
      out32[len++]=in32[pt>>STEPACCURACY];          
 
91
      pt+=step;
 
92
    }
 
93
    len=(len<<1);
 
94
    s->pt=pt & ((1LL<<STEPACCURACY)-1);
 
95
    break;
 
96
  default:      
 
97
    end /=nch;
 
98
    while(pt < end){
 
99
      tmp=nch;
 
100
      do {       
 
101
        tmp--;   
 
102
        out16[len+tmp]=in16[tmp+(pt>>STEPACCURACY)*nch];            
 
103
      } while (tmp);
 
104
      len+=nch;
 
105
      pt+=step;
 
106
    }   
 
107
    s->pt=pt & ((1LL<<STEPACCURACY)-1);
 
108
  }
 
109
  return len;
 
110
}
 
111
 
 
112
/* Determine resampling type and format */
 
113
static int set_types(struct af_instance_s* af, af_data_t* data)
 
114
{
 
115
  af_resample_t* s = af->setup;
 
116
  int rv = AF_OK;
 
117
  float rd = 0;
 
118
 
 
119
  // Make sure this filter isn't redundant 
 
120
  if((af->data->rate == data->rate) || (af->data->rate == 0))
 
121
    return AF_DETACH;
 
122
  /* If sloppy and small resampling difference (2%) */
 
123
  rd = abs((float)af->data->rate - (float)data->rate)/(float)data->rate;
 
124
  if((((s->setup & FREQ_MASK) == FREQ_SLOPPY) && (rd < 0.02) && 
 
125
      (data->format != (AF_FORMAT_FLOAT_NE))) || 
 
126
     ((s->setup & RSMP_MASK) == RSMP_LIN)){
 
127
    s->setup = (s->setup & ~RSMP_MASK) | RSMP_LIN;
 
128
    af->data->format = AF_FORMAT_S16_NE;
 
129
    af->data->bps    = 2;
 
130
    af_msg(AF_MSG_VERBOSE,"[resample] Using linear interpolation. \n");
 
131
  }
 
132
  else{
 
133
    /* If the input format is float or if float is explicitly selected
 
134
       use float, otherwise use int */
 
135
    if((data->format == (AF_FORMAT_FLOAT_NE)) || 
 
136
       ((s->setup & RSMP_MASK) == RSMP_FLOAT)){
 
137
      s->setup = (s->setup & ~RSMP_MASK) | RSMP_FLOAT;
 
138
      af->data->format = AF_FORMAT_FLOAT_NE;
 
139
      af->data->bps    = 4;
 
140
    }
 
141
    else{
 
142
      s->setup = (s->setup & ~RSMP_MASK) | RSMP_INT;
 
143
      af->data->format = AF_FORMAT_S16_NE;
 
144
      af->data->bps    = 2;
 
145
    }
 
146
    af_msg(AF_MSG_VERBOSE,"[resample] Using %s processing and %s frequecy"
 
147
           " conversion.\n",
 
148
           ((s->setup & RSMP_MASK) == RSMP_FLOAT)?"floating point":"integer",
 
149
           ((s->setup & FREQ_MASK) == FREQ_SLOPPY)?"inexact":"exact");
 
150
  }
 
151
 
 
152
  if(af->data->format != data->format || af->data->bps != data->bps)
 
153
    rv = AF_FALSE;
 
154
  data->format = af->data->format;
 
155
  data->bps = af->data->bps;
 
156
  af->data->nch = data->nch;
 
157
  return rv;
 
158
}
 
159
 
 
160
// Initialization and runtime control
 
161
static int control(struct af_instance_s* af, int cmd, void* arg)
 
162
{
 
163
  switch(cmd){
 
164
  case AF_CONTROL_REINIT:{
 
165
    af_resample_t* s   = (af_resample_t*)af->setup; 
 
166
    af_data_t*     n   = (af_data_t*)arg; // New configureation
 
167
    int            i,d = 0;
 
168
    int            rv  = AF_OK;
 
169
 
 
170
    // Free space for circular bufers
 
171
    if(s->xq){
 
172
      for(i=1;i<af->data->nch;i++)
 
173
        if(s->xq[i])
 
174
          free(s->xq[i]);
 
175
      free(s->xq);
 
176
    }
 
177
 
 
178
    if(AF_DETACH == (rv = set_types(af,n)))
 
179
      return AF_DETACH;
 
180
    
 
181
    // If linear interpolation 
 
182
    if((s->setup & RSMP_MASK) == RSMP_LIN){
 
183
      s->pt=0LL;
 
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",
 
186
             s->step);
 
187
      af->mul.n = af->data->rate;
 
188
      af->mul.d = n->rate;
 
189
      af_frac_cancel(&af->mul);
 
190
      return rv;
 
191
    }
 
192
 
 
193
    // Calculate up and down sampling factors
 
194
    d=af_gcd(af->data->rate,n->rate);
 
195
 
 
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;
 
199
      int dn=n->rate/2;
 
200
      int m=2;
 
201
      while(af->data->rate/(d*m) > 5000){
 
202
        d=af_gcd(up,dn); 
 
203
        up/=2; dn/=2; m*=2;
 
204
      }
 
205
      d*=m;
 
206
    }
 
207
 
 
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);
 
212
    s->xi = 0;
 
213
 
 
214
    // Check if the the design needs to be redone
 
215
    if(s->up != af->data->rate/d || s->dn != n->rate/d){
 
216
      float* w;
 
217
      float* wt;
 
218
      float fc;
 
219
      int j;
 
220
      s->up = af->data->rate/d; 
 
221
      s->dn = n->rate/d;
 
222
      
 
223
      // Calculate cuttof frequency for filter
 
224
      fc = 1/(float)(max(s->up,s->dn));
 
225
      // Allocate space for polyphase filter bank and protptype filter
 
226
      w = malloc(sizeof(float) * s->up *L);
 
227
      if(NULL != s->w)
 
228
        free(s->w);
 
229
      s->w = malloc(L*s->up*af->data->bps);
 
230
 
 
231
      // Design prototype filter type using Kaiser window with beta = 10
 
232
      if(NULL == w || NULL == s->w || 
 
233
         -1 == af_filter_design_fir(s->up*L, w, &fc, LP|KAISER , 10.0)){
 
234
        af_msg(AF_MSG_ERROR,"[resample] Unable to design prototype filter.\n");
 
235
        return AF_ERROR;
 
236
      }
 
237
      // Copy data from prototype to polyphase filter
 
238
      wt=w;
 
239
      for(j=0;j<L;j++){//Columns
 
240
        for(i=0;i<s->up;i++){//Rows
 
241
          if((s->setup & RSMP_MASK) == RSMP_INT){
 
242
            float t=(float)s->up*32767.0*(*wt);
 
243
            ((int16_t*)s->w)[i*L+j] = (int16_t)((t>=0.0)?(t+0.5):(t-0.5));
 
244
          }
 
245
          else
 
246
            ((float*)s->w)[i*L+j] = (float)s->up*(*wt);
 
247
          wt++;
 
248
        }
 
249
      }
 
250
      free(w);
 
251
      af_msg(AF_MSG_VERBOSE,"[resample] New filter designed up: %i "
 
252
             "down: %i\n", s->up, s->dn);
 
253
    }
 
254
 
 
255
    // Set multiplier and delay
 
256
    af->delay = (double)(1000*L/2)/((double)n->rate);
 
257
    af->mul.n = s->up;
 
258
    af->mul.d = s->dn;
 
259
    return rv;
 
260
  }
 
261
  case AF_CONTROL_COMMAND_LINE:{
 
262
    af_resample_t* s   = (af_resample_t*)af->setup; 
 
263
    int rate=0;
 
264
    int type=RSMP_INT;
 
265
    int sloppy=1;
 
266
    sscanf((char*)arg,"%i:%i:%i", &rate, &sloppy, &type);
 
267
    s->setup = (sloppy?FREQ_SLOPPY:FREQ_EXACT) | 
 
268
      (clamp(type,RSMP_LIN,RSMP_FLOAT));
 
269
    return af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET, &rate);
 
270
  }
 
271
  case AF_CONTROL_POST_CREATE:  
 
272
    if((((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) == AF_INIT_FLOAT)
 
273
      ((af_resample_t*)af->setup)->setup = RSMP_FLOAT;
 
274
    return AF_OK;
 
275
  case AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET: 
 
276
    // Reinit must be called after this function has been called
 
277
    
 
278
    // Sanity check
 
279
    if(((int*)arg)[0] < 8000 || ((int*)arg)[0] > 192000){
 
280
      af_msg(AF_MSG_ERROR,"[resample] The output sample frequency " 
 
281
             "must be between 8kHz and 192kHz. Current value is %i \n",
 
282
             ((int*)arg)[0]);
 
283
      return AF_ERROR;
 
284
    }
 
285
 
 
286
    af->data->rate=((int*)arg)[0]; 
 
287
    af_msg(AF_MSG_VERBOSE,"[resample] Changing sample rate "  
 
288
           "to %iHz\n",af->data->rate);
 
289
    return AF_OK;
 
290
  }
 
291
  return AF_UNKNOWN;
 
292
}
 
293
 
 
294
// Deallocate memory 
 
295
static void uninit(struct af_instance_s* af)
 
296
{
 
297
  if(af->data)
 
298
    free(af->data);
 
299
}
 
300
 
 
301
// Filter data through filter
 
302
static af_data_t* play(struct af_instance_s* af, af_data_t* data)
 
303
{
 
304
  int            len = 0;        // Length of output data
 
305
  af_data_t*     c   = data;     // Current working data
 
306
  af_data_t*     l   = af->data; // Local data
 
307
  af_resample_t* s   = (af_resample_t*)af->setup;
 
308
 
 
309
  if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
 
310
    return NULL;
 
311
 
 
312
  // Run resampling
 
313
  switch(s->setup & RSMP_MASK){
 
314
  case(RSMP_INT):
 
315
# define FORMAT_I 1
 
316
    if(s->up>s->dn){
 
317
#     define UP
 
318
#     include "af_resample.h"
 
319
#     undef UP 
 
320
    }
 
321
    else{
 
322
#     define DN
 
323
#     include "af_resample.h"
 
324
#     undef DN
 
325
    }
 
326
    break;
 
327
  case(RSMP_FLOAT):
 
328
# undef FORMAT_I
 
329
# define FORMAT_F 1
 
330
    if(s->up>s->dn){
 
331
#     define UP
 
332
#     include "af_resample.h"
 
333
#     undef UP 
 
334
    }
 
335
    else{
 
336
#     define DN
 
337
#     include "af_resample.h"
 
338
#     undef DN
 
339
    }
 
340
    break;
 
341
  case(RSMP_LIN):
 
342
    len = linint(c, l, s);
 
343
    break;
 
344
  }
 
345
 
 
346
  // Set output data
 
347
  c->audio = l->audio;
 
348
  c->len   = len*l->bps;
 
349
  c->rate  = l->rate;
 
350
  
 
351
  return c;
 
352
}
 
353
 
 
354
// Allocate memory and set function pointers
 
355
static int open(af_instance_t* af){
 
356
  af->control=control;
 
357
  af->uninit=uninit;
 
358
  af->play=play;
 
359
  af->mul.n=1;
 
360
  af->mul.d=1;
 
361
  af->data=calloc(1,sizeof(af_data_t));
 
362
  af->setup=calloc(1,sizeof(af_resample_t));
 
363
  if(af->data == NULL || af->setup == NULL)
 
364
    return AF_ERROR;
 
365
  ((af_resample_t*)af->setup)->setup = RSMP_INT | FREQ_SLOPPY;
 
366
  return AF_OK;
 
367
}
 
368
 
 
369
// Description of this plugin
 
370
af_info_t af_info_resample = {
 
371
  "Sample frequency conversion",
 
372
  "resample",
 
373
  "Anders",
 
374
  "",
 
375
  AF_FLAGS_REENTRANT,
 
376
  open
 
377
};
 
378