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