report if the service creation failed
[mplayer/greg.git] / libaf / af_resample.h
blob34e05cdfbe3fedd6487ddf6ed6e641bc7683903c
1 /*=============================================================================
2 //
3 // This software has been released under the terms of the GNU 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 */
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 */
17 #undef L
18 #undef SHIFT
19 #undef FORMAT
20 #undef FIR
21 #undef ADDQUE
23 /* The lenght Lxx definition selects the length of each poly phase
24 component. Valid definitions are L8 and L16 where the number
25 defines the nuber of taps. This definition affects the
26 computational complexity, the performance and the memory usage.
29 /* The FORMAT_x parameter selects the sample format type currently
30 float and int16 are supported. Thes two formats are selected by
31 defining eiter FORMAT_F or FORMAT_I. The advantage of using float
32 is that the amplitude and therefore the SNR isn't affected by the
33 filtering, the disadvantage is that it is a lot slower.
36 #if defined(FORMAT_I)
37 #define SHIFT >>16
38 #define FORMAT int16_t
39 #else
40 #define SHIFT
41 #define FORMAT float
42 #endif
44 // Short filter
45 #if defined(L8)
47 #define L 8 // Filter length
48 // Unrolled loop to speed up execution
49 #define FIR(x,w,y) \
50 (y[0]) = ( w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3] \
51 + w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7] ) SHIFT
55 #else /* L8/L16 */
57 #define L 16
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] \
62 + w[8] *x[8] +w[9] *x[9] +w[10]*x[10]+w[11]*x[11] \
63 + w[12]*x[12]+w[13]*x[13]+w[14]*x[14]+w[15]*x[15] ) SHIFT
65 #endif /* L8/L16 */
67 // Macro to add data to circular que
68 #define ADDQUE(xi,xq,in)\
69 xq[xi]=xq[(xi)+L]=*(in);\
70 xi=((xi)-1)&(L-1);
72 #if defined(UP)
74 uint32_t ci = l->nch; // Index for channels
75 uint32_t nch = l->nch; // Number of channels
76 uint32_t inc = s->up/s->dn;
77 uint32_t level = s->up%s->dn;
78 uint32_t up = s->up;
79 uint32_t dn = s->dn;
80 uint32_t ns = c->len/l->bps;
81 register FORMAT* w = s->w;
83 register uint32_t wi = 0;
84 register uint32_t xi = 0;
86 // Index current channel
87 while(ci--){
88 // Temporary pointers
89 register FORMAT* x = s->xq[ci];
90 register FORMAT* in = ((FORMAT*)c->audio)+ci;
91 register FORMAT* out = ((FORMAT*)l->audio)+ci;
92 FORMAT* end = in+ns; // Block loop end
93 wi = s->wi; xi = s->xi;
95 while(in < end){
96 register uint32_t i = inc;
97 if(wi<level) i++;
99 ADDQUE(xi,x,in);
100 in+=nch;
101 while(i--){
102 // Run the FIR filter
103 FIR((&x[xi]),(&w[wi*L]),out);
104 len++; out+=nch;
105 // Update wi to point at the correct polyphase component
106 wi=(wi+dn)%up;
111 // Save values that needs to be kept for next time
112 s->wi = wi;
113 s->xi = xi;
114 #endif /* UP */
116 #if defined(DN) /* DN */
117 uint32_t ci = l->nch; // Index for channels
118 uint32_t nch = l->nch; // Number of channels
119 uint32_t inc = s->dn/s->up;
120 uint32_t level = s->dn%s->up;
121 uint32_t up = s->up;
122 uint32_t dn = s->dn;
123 uint32_t ns = c->len/l->bps;
124 FORMAT* w = s->w;
126 register int32_t i = 0;
127 register uint32_t wi = 0;
128 register uint32_t xi = 0;
130 // Index current channel
131 while(ci--){
132 // Temporary pointers
133 register FORMAT* x = s->xq[ci];
134 register FORMAT* in = ((FORMAT*)c->audio)+ci;
135 register FORMAT* out = ((FORMAT*)l->audio)+ci;
136 register FORMAT* end = in+ns; // Block loop end
137 i = s->i; wi = s->wi; xi = s->xi;
139 while(in < end){
141 ADDQUE(xi,x,in);
142 in+=nch;
143 if((--i)<=0){
144 // Run the FIR filter
145 FIR((&x[xi]),(&w[wi*L]),out);
146 len++; out+=nch;
148 // Update wi to point at the correct polyphase component
149 wi=(wi+dn)%up;
151 // Insert i number of new samples in queue
152 i = inc;
153 if(wi<level) i++;
157 // Save values that needs to be kept for next time
158 s->wi = wi;
159 s->xi = xi;
160 s->i = i;
161 #endif /* DN */