comparison libaf/af_resample_template.c @ 28201:4ff973912251

Rename libaf/af_resample.h to libaf/af_resample_template.c, it is used as a macro, not as a header file.
author diego
date Fri, 02 Jan 2009 16:13:22 +0000
parents
children 72d0b1444141
comparison
equal deleted inserted replaced
28200:56868e6fb340 28201:4ff973912251
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 file contains the resampling engine, the sample format is
12 controlled by the FORMAT parameter, the filter length by the L
13 parameter and the resampling type by UP and DN. This file should
14 only be included by af_resample.c
15 */
16
17 /* This header intentionally has no multiple inclusion guards. It is meant to
18 * be included multiple times and generates different code depending on the
19 * value of certain #defines. */
20
21 #undef L
22 #undef SHIFT
23 #undef FORMAT
24 #undef FIR
25 #undef ADDQUE
26
27 /* The length Lxx definition selects the length of each poly phase
28 component. Valid definitions are L8 and L16 where the number
29 defines the nuber of taps. This definition affects the
30 computational complexity, the performance and the memory usage.
31 */
32
33 /* The FORMAT_x parameter selects the sample format type currently
34 float and int16 are supported. Thes two formats are selected by
35 defining eiter FORMAT_F or FORMAT_I. The advantage of using float
36 is that the amplitude and therefore the SNR isn't affected by the
37 filtering, the disadvantage is that it is a lot slower.
38 */
39
40 #if defined(FORMAT_I)
41 #define SHIFT >>16
42 #define FORMAT int16_t
43 #else
44 #define SHIFT
45 #define FORMAT float
46 #endif
47
48 // Short filter
49 #if defined(L8)
50
51 #define L 8 // Filter length
52 // Unrolled loop to speed up execution
53 #define FIR(x,w,y) \
54 (y[0]) = ( w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3] \
55 + w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7] ) SHIFT
56
57
58
59 #else /* L8/L16 */
60
61 #define L 16
62 // Unrolled loop to speed up execution
63 #define FIR(x,w,y) \
64 y[0] = ( w[0] *x[0] +w[1] *x[1] +w[2] *x[2] +w[3] *x[3] \
65 + w[4] *x[4] +w[5] *x[5] +w[6] *x[6] +w[7] *x[7] \
66 + w[8] *x[8] +w[9] *x[9] +w[10]*x[10]+w[11]*x[11] \
67 + w[12]*x[12]+w[13]*x[13]+w[14]*x[14]+w[15]*x[15] ) SHIFT
68
69 #endif /* L8/L16 */
70
71 // Macro to add data to circular que
72 #define ADDQUE(xi,xq,in)\
73 xq[xi]=xq[(xi)+L]=*(in);\
74 xi=((xi)-1)&(L-1);
75
76 #if defined(UP)
77
78 uint32_t ci = l->nch; // Index for channels
79 uint32_t nch = l->nch; // Number of channels
80 uint32_t inc = s->up/s->dn;
81 uint32_t level = s->up%s->dn;
82 uint32_t up = s->up;
83 uint32_t dn = s->dn;
84 uint32_t ns = c->len/l->bps;
85 register FORMAT* w = s->w;
86
87 register uint32_t wi = 0;
88 register uint32_t xi = 0;
89
90 // Index current channel
91 while(ci--){
92 // Temporary pointers
93 register FORMAT* x = s->xq[ci];
94 register FORMAT* in = ((FORMAT*)c->audio)+ci;
95 register FORMAT* out = ((FORMAT*)l->audio)+ci;
96 FORMAT* end = in+ns; // Block loop end
97 wi = s->wi; xi = s->xi;
98
99 while(in < end){
100 register uint32_t i = inc;
101 if(wi<level) i++;
102
103 ADDQUE(xi,x,in);
104 in+=nch;
105 while(i--){
106 // Run the FIR filter
107 FIR((&x[xi]),(&w[wi*L]),out);
108 len++; out+=nch;
109 // Update wi to point at the correct polyphase component
110 wi=(wi+dn)%up;
111 }
112 }
113
114 }
115 // Save values that needs to be kept for next time
116 s->wi = wi;
117 s->xi = xi;
118 #endif /* UP */
119
120 #if defined(DN) /* DN */
121 uint32_t ci = l->nch; // Index for channels
122 uint32_t nch = l->nch; // Number of channels
123 uint32_t inc = s->dn/s->up;
124 uint32_t level = s->dn%s->up;
125 uint32_t up = s->up;
126 uint32_t dn = s->dn;
127 uint32_t ns = c->len/l->bps;
128 FORMAT* w = s->w;
129
130 register int32_t i = 0;
131 register uint32_t wi = 0;
132 register uint32_t xi = 0;
133
134 // Index current channel
135 while(ci--){
136 // Temporary pointers
137 register FORMAT* x = s->xq[ci];
138 register FORMAT* in = ((FORMAT*)c->audio)+ci;
139 register FORMAT* out = ((FORMAT*)l->audio)+ci;
140 register FORMAT* end = in+ns; // Block loop end
141 i = s->i; wi = s->wi; xi = s->xi;
142
143 while(in < end){
144
145 ADDQUE(xi,x,in);
146 in+=nch;
147 if((--i)<=0){
148 // Run the FIR filter
149 FIR((&x[xi]),(&w[wi*L]),out);
150 len++; out+=nch;
151
152 // Update wi to point at the correct polyphase component
153 wi=(wi+dn)%up;
154
155 // Insert i number of new samples in queue
156 i = inc;
157 if(wi<level) i++;
158 }
159 }
160 }
161 // Save values that needs to be kept for next time
162 s->wi = wi;
163 s->xi = xi;
164 s->i = i;
165 #endif /* DN */