Commit files by Steinar Gunderson, forgotten in r30866.
[mplayer/glamo.git] / libaf / af_resample_template.c
blob4d4c5922ca7d1e712099286ebcad5e4dabce8679
1 /*
2 * Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 /* This file contains the resampling engine, the sample format is
22 controlled by the FORMAT parameter, the filter length by the L
23 parameter and the resampling type by UP and DN. This file should
24 only be included by af_resample.c
27 #undef L
28 #undef SHIFT
29 #undef FORMAT
30 #undef FIR
31 #undef ADDQUE
33 /* The length Lxx definition selects the length of each poly phase
34 component. Valid definitions are L8 and L16 where the number
35 defines the nuber of taps. This definition affects the
36 computational complexity, the performance and the memory usage.
39 /* The FORMAT_x parameter selects the sample format type currently
40 float and int16 are supported. Thes two formats are selected by
41 defining eiter FORMAT_F or FORMAT_I. The advantage of using float
42 is that the amplitude and therefore the SNR isn't affected by the
43 filtering, the disadvantage is that it is a lot slower.
46 #if defined(FORMAT_I)
47 #define SHIFT >>16
48 #define FORMAT int16_t
49 #else
50 #define SHIFT
51 #define FORMAT float
52 #endif
54 // Short filter
55 #if defined(L8)
57 #define L 8 // Filter length
58 // Unrolled loop to speed up execution
59 #define FIR(x,w,y) \
60 (y[0]) = ( w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3] \
61 + w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7] ) SHIFT
65 #else /* L8/L16 */
67 #define L 16
68 // Unrolled loop to speed up execution
69 #define FIR(x,w,y) \
70 y[0] = ( w[0] *x[0] +w[1] *x[1] +w[2] *x[2] +w[3] *x[3] \
71 + w[4] *x[4] +w[5] *x[5] +w[6] *x[6] +w[7] *x[7] \
72 + w[8] *x[8] +w[9] *x[9] +w[10]*x[10]+w[11]*x[11] \
73 + w[12]*x[12]+w[13]*x[13]+w[14]*x[14]+w[15]*x[15] ) SHIFT
75 #endif /* L8/L16 */
77 // Macro to add data to circular que
78 #define ADDQUE(xi,xq,in)\
79 xq[xi]=xq[(xi)+L]=*(in);\
80 xi=((xi)-1)&(L-1);
82 #if defined(UP)
84 uint32_t ci = l->nch; // Index for channels
85 uint32_t nch = l->nch; // Number of channels
86 uint32_t inc = s->up/s->dn;
87 uint32_t level = s->up%s->dn;
88 uint32_t up = s->up;
89 uint32_t dn = s->dn;
90 uint32_t ns = c->len/l->bps;
91 register FORMAT* w = s->w;
93 register uint32_t wi = 0;
94 register uint32_t xi = 0;
96 // Index current channel
97 while(ci--){
98 // Temporary pointers
99 register FORMAT* x = s->xq[ci];
100 register FORMAT* in = ((FORMAT*)c->audio)+ci;
101 register FORMAT* out = ((FORMAT*)l->audio)+ci;
102 FORMAT* end = in+ns; // Block loop end
103 wi = s->wi; xi = s->xi;
105 while(in < end){
106 register uint32_t i = inc;
107 if(wi<level) i++;
109 ADDQUE(xi,x,in);
110 in+=nch;
111 while(i--){
112 // Run the FIR filter
113 FIR((&x[xi]),(&w[wi*L]),out);
114 len++; out+=nch;
115 // Update wi to point at the correct polyphase component
116 wi=(wi+dn)%up;
121 // Save values that needs to be kept for next time
122 s->wi = wi;
123 s->xi = xi;
124 #endif /* UP */
126 #if defined(DN) /* DN */
127 uint32_t ci = l->nch; // Index for channels
128 uint32_t nch = l->nch; // Number of channels
129 uint32_t inc = s->dn/s->up;
130 uint32_t level = s->dn%s->up;
131 uint32_t up = s->up;
132 uint32_t dn = s->dn;
133 uint32_t ns = c->len/l->bps;
134 FORMAT* w = s->w;
136 register int32_t i = 0;
137 register uint32_t wi = 0;
138 register uint32_t xi = 0;
140 // Index current channel
141 while(ci--){
142 // Temporary pointers
143 register FORMAT* x = s->xq[ci];
144 register FORMAT* in = ((FORMAT*)c->audio)+ci;
145 register FORMAT* out = ((FORMAT*)l->audio)+ci;
146 register FORMAT* end = in+ns; // Block loop end
147 i = s->i; wi = s->wi; xi = s->xi;
149 while(in < end){
151 ADDQUE(xi,x,in);
152 in+=nch;
153 if((--i)<=0){
154 // Run the FIR filter
155 FIR((&x[xi]),(&w[wi*L]),out);
156 len++; out+=nch;
158 // Update wi to point at the correct polyphase component
159 wi=(wi+dn)%up;
161 // Insert i number of new samples in queue
162 i = inc;
163 if(wi<level) i++;
167 // Save values that needs to be kept for next time
168 s->wi = wi;
169 s->xi = xi;
170 s->i = i;
171 #endif /* DN */