annotate libaf/af_resample.h @ 25317:7f3cb5408f28

Fixed VIDIX color bug that was introduced when Radeon VIDIX driver was synchronized with vidix.sf.net. The red color was saturating. Corrected value fixes the issue and restore the color to the level it used to have before synchronization. Meaning of the value remains unknow but was retrieved from register's value of a Radeon 9000 card, so it may need further testing. Patch by Guillaume Lecerf (foxcore at gmail dot com)
author ben
date Mon, 10 Dec 2007 19:27:46 +0000
parents 85f669a84e7a
children 6ac1ece1f9fe
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8607
d6f40a06867b Changes includes:
anders
parents:
diff changeset
1 /*=============================================================================
d6f40a06867b Changes includes:
anders
parents:
diff changeset
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
d6f40a06867b Changes includes:
anders
parents:
diff changeset
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
d6f40a06867b Changes includes:
anders
parents:
diff changeset
5 //
d6f40a06867b Changes includes:
anders
parents:
diff changeset
6 // Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au
d6f40a06867b Changes includes:
anders
parents:
diff changeset
7 //
d6f40a06867b Changes includes:
anders
parents:
diff changeset
8 //=============================================================================
d6f40a06867b Changes includes:
anders
parents:
diff changeset
9 */
d6f40a06867b Changes includes:
anders
parents:
diff changeset
10
d6f40a06867b Changes includes:
anders
parents:
diff changeset
11 /* This file contains the resampling engine, the sample format is
d6f40a06867b Changes includes:
anders
parents:
diff changeset
12 controlled by the FORMAT parameter, the filter length by the L
d6f40a06867b Changes includes:
anders
parents:
diff changeset
13 parameter and the resampling type by UP and DN. This file should
d6f40a06867b Changes includes:
anders
parents:
diff changeset
14 only be included by af_resample.c
d6f40a06867b Changes includes:
anders
parents:
diff changeset
15 */
d6f40a06867b Changes includes:
anders
parents:
diff changeset
16
d6f40a06867b Changes includes:
anders
parents:
diff changeset
17 #undef L
d6f40a06867b Changes includes:
anders
parents:
diff changeset
18 #undef SHIFT
d6f40a06867b Changes includes:
anders
parents:
diff changeset
19 #undef FORMAT
d6f40a06867b Changes includes:
anders
parents:
diff changeset
20 #undef FIR
d6f40a06867b Changes includes:
anders
parents:
diff changeset
21 #undef ADDQUE
d6f40a06867b Changes includes:
anders
parents:
diff changeset
22
24595
85f669a84e7a cosmetics: misc typo fixes
diego
parents: 13602
diff changeset
23 /* The length Lxx definition selects the length of each poly phase
8607
d6f40a06867b Changes includes:
anders
parents:
diff changeset
24 component. Valid definitions are L8 and L16 where the number
d6f40a06867b Changes includes:
anders
parents:
diff changeset
25 defines the nuber of taps. This definition affects the
d6f40a06867b Changes includes:
anders
parents:
diff changeset
26 computational complexity, the performance and the memory usage.
d6f40a06867b Changes includes:
anders
parents:
diff changeset
27 */
d6f40a06867b Changes includes:
anders
parents:
diff changeset
28
d6f40a06867b Changes includes:
anders
parents:
diff changeset
29 /* The FORMAT_x parameter selects the sample format type currently
d6f40a06867b Changes includes:
anders
parents:
diff changeset
30 float and int16 are supported. Thes two formats are selected by
d6f40a06867b Changes includes:
anders
parents:
diff changeset
31 defining eiter FORMAT_F or FORMAT_I. The advantage of using float
d6f40a06867b Changes includes:
anders
parents:
diff changeset
32 is that the amplitude and therefore the SNR isn't affected by the
d6f40a06867b Changes includes:
anders
parents:
diff changeset
33 filtering, the disadvantage is that it is a lot slower.
d6f40a06867b Changes includes:
anders
parents:
diff changeset
34 */
d6f40a06867b Changes includes:
anders
parents:
diff changeset
35
d6f40a06867b Changes includes:
anders
parents:
diff changeset
36 #if defined(FORMAT_I)
d6f40a06867b Changes includes:
anders
parents:
diff changeset
37 #define SHIFT >>16
d6f40a06867b Changes includes:
anders
parents:
diff changeset
38 #define FORMAT int16_t
d6f40a06867b Changes includes:
anders
parents:
diff changeset
39 #else
d6f40a06867b Changes includes:
anders
parents:
diff changeset
40 #define SHIFT
d6f40a06867b Changes includes:
anders
parents:
diff changeset
41 #define FORMAT float
d6f40a06867b Changes includes:
anders
parents:
diff changeset
42 #endif
d6f40a06867b Changes includes:
anders
parents:
diff changeset
43
d6f40a06867b Changes includes:
anders
parents:
diff changeset
44 // Short filter
d6f40a06867b Changes includes:
anders
parents:
diff changeset
45 #if defined(L8)
d6f40a06867b Changes includes:
anders
parents:
diff changeset
46
d6f40a06867b Changes includes:
anders
parents:
diff changeset
47 #define L 8 // Filter length
d6f40a06867b Changes includes:
anders
parents:
diff changeset
48 // Unrolled loop to speed up execution
d6f40a06867b Changes includes:
anders
parents:
diff changeset
49 #define FIR(x,w,y) \
d6f40a06867b Changes includes:
anders
parents:
diff changeset
50 (y[0]) = ( w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3] \
d6f40a06867b Changes includes:
anders
parents:
diff changeset
51 + w[4]*x[4]+w[5]*x[5]+w[6]*x[6]+w[7]*x[7] ) SHIFT
d6f40a06867b Changes includes:
anders
parents:
diff changeset
52
d6f40a06867b Changes includes:
anders
parents:
diff changeset
53
d6f40a06867b Changes includes:
anders
parents:
diff changeset
54
d6f40a06867b Changes includes:
anders
parents:
diff changeset
55 #else /* L8/L16 */
d6f40a06867b Changes includes:
anders
parents:
diff changeset
56
d6f40a06867b Changes includes:
anders
parents:
diff changeset
57 #define L 16
d6f40a06867b Changes includes:
anders
parents:
diff changeset
58 // Unrolled loop to speed up execution
d6f40a06867b Changes includes:
anders
parents:
diff changeset
59 #define FIR(x,w,y) \
d6f40a06867b Changes includes:
anders
parents:
diff changeset
60 y[0] = ( w[0] *x[0] +w[1] *x[1] +w[2] *x[2] +w[3] *x[3] \
d6f40a06867b Changes includes:
anders
parents:
diff changeset
61 + w[4] *x[4] +w[5] *x[5] +w[6] *x[6] +w[7] *x[7] \
d6f40a06867b Changes includes:
anders
parents:
diff changeset
62 + w[8] *x[8] +w[9] *x[9] +w[10]*x[10]+w[11]*x[11] \
d6f40a06867b Changes includes:
anders
parents:
diff changeset
63 + w[12]*x[12]+w[13]*x[13]+w[14]*x[14]+w[15]*x[15] ) SHIFT
d6f40a06867b Changes includes:
anders
parents:
diff changeset
64
d6f40a06867b Changes includes:
anders
parents:
diff changeset
65 #endif /* L8/L16 */
d6f40a06867b Changes includes:
anders
parents:
diff changeset
66
d6f40a06867b Changes includes:
anders
parents:
diff changeset
67 // Macro to add data to circular que
d6f40a06867b Changes includes:
anders
parents:
diff changeset
68 #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
69 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
70 xi=((xi)-1)&(L-1);
8607
d6f40a06867b Changes includes:
anders
parents:
diff changeset
71
d6f40a06867b Changes includes:
anders
parents:
diff changeset
72 #if defined(UP)
d6f40a06867b Changes includes:
anders
parents:
diff changeset
73
d6f40a06867b Changes includes:
anders
parents:
diff changeset
74 uint32_t ci = l->nch; // Index for channels
d6f40a06867b Changes includes:
anders
parents:
diff changeset
75 uint32_t nch = l->nch; // Number of channels
d6f40a06867b Changes includes:
anders
parents:
diff changeset
76 uint32_t inc = s->up/s->dn;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
77 uint32_t level = s->up%s->dn;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
78 uint32_t up = s->up;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
79 uint32_t dn = s->dn;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
80 uint32_t ns = c->len/l->bps;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
81 register FORMAT* w = s->w;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
82
d6f40a06867b Changes includes:
anders
parents:
diff changeset
83 register uint32_t wi = 0;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
84 register uint32_t xi = 0;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
85
d6f40a06867b Changes includes:
anders
parents:
diff changeset
86 // Index current channel
d6f40a06867b Changes includes:
anders
parents:
diff changeset
87 while(ci--){
d6f40a06867b Changes includes:
anders
parents:
diff changeset
88 // Temporary pointers
d6f40a06867b Changes includes:
anders
parents:
diff changeset
89 register FORMAT* x = s->xq[ci];
d6f40a06867b Changes includes:
anders
parents:
diff changeset
90 register FORMAT* in = ((FORMAT*)c->audio)+ci;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
91 register FORMAT* out = ((FORMAT*)l->audio)+ci;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
92 FORMAT* end = in+ns; // Block loop end
d6f40a06867b Changes includes:
anders
parents:
diff changeset
93 wi = s->wi; xi = s->xi;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
94
d6f40a06867b Changes includes:
anders
parents:
diff changeset
95 while(in < end){
d6f40a06867b Changes includes:
anders
parents:
diff changeset
96 register uint32_t i = inc;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
97 if(wi<level) i++;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
98
d6f40a06867b Changes includes:
anders
parents:
diff changeset
99 ADDQUE(xi,x,in);
d6f40a06867b Changes includes:
anders
parents:
diff changeset
100 in+=nch;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
101 while(i--){
d6f40a06867b Changes includes:
anders
parents:
diff changeset
102 // Run the FIR filter
d6f40a06867b Changes includes:
anders
parents:
diff changeset
103 FIR((&x[xi]),(&w[wi*L]),out);
d6f40a06867b Changes includes:
anders
parents:
diff changeset
104 len++; out+=nch;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
105 // Update wi to point at the correct polyphase component
d6f40a06867b Changes includes:
anders
parents:
diff changeset
106 wi=(wi+dn)%up;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
107 }
d6f40a06867b Changes includes:
anders
parents:
diff changeset
108 }
d6f40a06867b Changes includes:
anders
parents:
diff changeset
109
d6f40a06867b Changes includes:
anders
parents:
diff changeset
110 }
d6f40a06867b Changes includes:
anders
parents:
diff changeset
111 // Save values that needs to be kept for next time
d6f40a06867b Changes includes:
anders
parents:
diff changeset
112 s->wi = wi;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
113 s->xi = xi;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
114 #endif /* UP */
d6f40a06867b Changes includes:
anders
parents:
diff changeset
115
d6f40a06867b Changes includes:
anders
parents:
diff changeset
116 #if defined(DN) /* DN */
d6f40a06867b Changes includes:
anders
parents:
diff changeset
117 uint32_t ci = l->nch; // Index for channels
d6f40a06867b Changes includes:
anders
parents:
diff changeset
118 uint32_t nch = l->nch; // Number of channels
d6f40a06867b Changes includes:
anders
parents:
diff changeset
119 uint32_t inc = s->dn/s->up;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
120 uint32_t level = s->dn%s->up;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
121 uint32_t up = s->up;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
122 uint32_t dn = s->dn;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
123 uint32_t ns = c->len/l->bps;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
124 FORMAT* w = s->w;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
125
d6f40a06867b Changes includes:
anders
parents:
diff changeset
126 register int32_t i = 0;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
127 register uint32_t wi = 0;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
128 register uint32_t xi = 0;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
129
d6f40a06867b Changes includes:
anders
parents:
diff changeset
130 // Index current channel
d6f40a06867b Changes includes:
anders
parents:
diff changeset
131 while(ci--){
d6f40a06867b Changes includes:
anders
parents:
diff changeset
132 // Temporary pointers
d6f40a06867b Changes includes:
anders
parents:
diff changeset
133 register FORMAT* x = s->xq[ci];
d6f40a06867b Changes includes:
anders
parents:
diff changeset
134 register FORMAT* in = ((FORMAT*)c->audio)+ci;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
135 register FORMAT* out = ((FORMAT*)l->audio)+ci;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
136 register FORMAT* end = in+ns; // Block loop end
d6f40a06867b Changes includes:
anders
parents:
diff changeset
137 i = s->i; wi = s->wi; xi = s->xi;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
138
d6f40a06867b Changes includes:
anders
parents:
diff changeset
139 while(in < end){
d6f40a06867b Changes includes:
anders
parents:
diff changeset
140
d6f40a06867b Changes includes:
anders
parents:
diff changeset
141 ADDQUE(xi,x,in);
d6f40a06867b Changes includes:
anders
parents:
diff changeset
142 in+=nch;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
143 if((--i)<=0){
d6f40a06867b Changes includes:
anders
parents:
diff changeset
144 // Run the FIR filter
d6f40a06867b Changes includes:
anders
parents:
diff changeset
145 FIR((&x[xi]),(&w[wi*L]),out);
d6f40a06867b Changes includes:
anders
parents:
diff changeset
146 len++; out+=nch;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
147
d6f40a06867b Changes includes:
anders
parents:
diff changeset
148 // Update wi to point at the correct polyphase component
d6f40a06867b Changes includes:
anders
parents:
diff changeset
149 wi=(wi+dn)%up;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
150
d6f40a06867b Changes includes:
anders
parents:
diff changeset
151 // Insert i number of new samples in queue
d6f40a06867b Changes includes:
anders
parents:
diff changeset
152 i = inc;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
153 if(wi<level) i++;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
154 }
d6f40a06867b Changes includes:
anders
parents:
diff changeset
155 }
d6f40a06867b Changes includes:
anders
parents:
diff changeset
156 }
d6f40a06867b Changes includes:
anders
parents:
diff changeset
157 // Save values that needs to be kept for next time
d6f40a06867b Changes includes:
anders
parents:
diff changeset
158 s->wi = wi;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
159 s->xi = xi;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
160 s->i = i;
d6f40a06867b Changes includes:
anders
parents:
diff changeset
161 #endif /* DN */