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