Mercurial > mplayer.hg
annotate libaf/af_resample.h @ 27985:1c77b86d355d
Remove a ColorFill that is not necessary since the surface it is used
on has exactly the same size as the video image and the video will
be copied into it before it is used the first time.
author | reimar |
---|---|
date | Mon, 24 Nov 2008 09:46:23 +0000 |
parents | 32e21d1beb48 |
children |
rev | line source |
---|---|
8607 | 1 /*============================================================================= |
2 // | |
13602
14090f7300a8
The full name of the GPL is GNU General Public License.
diego
parents:
8957
diff
changeset
|
3 // This software has been released under the terms of the GNU General Public |
8607 | 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 | |
25994
32e21d1beb48
This header should not have multiple inclusion guards, it is meant
diego
parents:
25553
diff
changeset
|
17 /* This header intentionally has no multiple inclusion guards. It is meant to |
32e21d1beb48
This header should not have multiple inclusion guards, it is meant
diego
parents:
25553
diff
changeset
|
18 * be included multiple times and generates different code depending on the |
32e21d1beb48
This header should not have multiple inclusion guards, it is meant
diego
parents:
25553
diff
changeset
|
19 * value of certain #defines. */ |
25553
6ac1ece1f9fe
Add multiple inclusion guards to all header files that lack them.
diego
parents:
24595
diff
changeset
|
20 |
8607 | 21 #undef L |
22 #undef SHIFT | |
23 #undef FORMAT | |
24 #undef FIR | |
25 #undef ADDQUE | |
26 | |
24595 | 27 /* The length Lxx definition selects the length of each poly phase |
8607 | 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)\ | |
8957
36a5cdca733b
bunkus: Encapsulated arguments to #define in ( ... ) so that the #defines can be safely used like functions: mydef(flag ? val1 : val2)
mosu
parents:
8607
diff
changeset
|
73 xq[xi]=xq[(xi)+L]=*(in);\ |
36a5cdca733b
bunkus: Encapsulated arguments to #define in ( ... ) so that the #defines can be safely used like functions: mydef(flag ? val1 : val2)
mosu
parents:
8607
diff
changeset
|
74 xi=((xi)-1)&(L-1); |
8607 | 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 */ |