14 /************************************************************************
18 * PURPOSE: Overlapping window on PCM samples
21 * 32 16-bit pcm samples are scaled to fractional 2's complement and
22 * concatenated to the end of the window buffer #x#. The updated window
23 * buffer #x# is then windowed by the analysis window #c# to produce the
26 ************************************************************************/
28 void window_subband (short **buffer
, double z
[64], int k
)
30 typedef double XX
[2][HAN_SIZE
];
34 static int off
[2] = { 0, 0 };
37 double *ep0
, *ep1
, *ep2
, *ep3
, *ep4
, *ep5
, *ep6
, *ep7
;
39 x
= (XX
*) mem_alloc (sizeof (XX
), "x");
40 memset (x
, 0, 2 * HAN_SIZE
* sizeof (double));
45 /* replace 32 oldest samples with 32 new samples */
46 for (i
= 0; i
< 32; i
++)
47 xk
[31 - i
+ off
[k
]] = (double) *(*buffer
)++ / SCALE
;
58 /* shift samples into proper window positions */
59 for (i
= 0; i
< 64; i
++) {
60 t
= xk
[(i
+ off
[k
]) & (512 - 1)] * *ep0
++;
61 t
+= xk
[(i
+ 64 + off
[k
]) & (512 - 1)] * *ep1
++;
62 t
+= xk
[(i
+ 128 + off
[k
]) & (512 - 1)] * *ep2
++;
63 t
+= xk
[(i
+ 192 + off
[k
]) & (512 - 1)] * *ep3
++;
64 t
+= xk
[(i
+ 256 + off
[k
]) & (512 - 1)] * *ep4
++;
65 t
+= xk
[(i
+ 320 + off
[k
]) & (512 - 1)] * *ep5
++;
66 t
+= xk
[(i
+ 384 + off
[k
]) & (512 - 1)] * *ep6
++;
67 t
+= xk
[(i
+ 448 + off
[k
]) & (512 - 1)] * *ep7
++;
71 off
[k
] += 480; /*offset is modulo (HAN_SIZE-1) */
72 off
[k
] &= HAN_SIZE
- 1;
77 /************************************************************************
81 * PURPOSE: Calculates the analysis filter bank coefficients
84 * The windowed samples #z# is filtered by the digital filter matrix #m#
85 * to produce the subband samples #s#. This done by first selectively
86 * picking out values from the windowed samples, and then multiplying
87 * them by the filter matrix, producing 32 subband samples.
89 ************************************************************************/
90 void filter_subband (double z
[HAN_SIZE
], double s
[SBLIMIT
])
95 static double m
[16][32];
100 create_dct_matrix (m
);
104 for (i
= 1; i
<= 16; i
++)
105 yprime
[i
] = z
[i
+ 16] + z
[16 - i
];
106 for (i
= 17; i
<= 31; i
++)
107 yprime
[i
] = z
[i
+ 16] - z
[80 - i
];
109 for (i
= 15; i
>= 0; i
--) {
110 register double s0
= 0.0, s1
= 0.0;
111 register double *mp
= m
[i
];
112 register double *xinp
= yprime
;
113 for (j
= 0; j
< 8; j
++) {
114 s0
+= *mp
++ * *xinp
++;
115 s1
+= *mp
++ * *xinp
++;
116 s0
+= *mp
++ * *xinp
++;
117 s1
+= *mp
++ * *xinp
++;
123 #endif //REFERENCECODE
125 void create_dct_matrix (double filter
[16][32])
129 for (i
= 0; i
< 16; i
++)
130 for (k
= 0; k
< 32; k
++) {
131 if ((filter
[i
][k
] = 1e9
* cos ((double) ((2 * i
+ 1) * k
* PI64
))) >= 0)
132 modf (filter
[i
][k
] + 0.5, &filter
[i
][k
]);
134 modf (filter
[i
][k
] - 0.5, &filter
[i
][k
]);
135 filter
[i
][k
] *= 1e-9;
141 /***********************************************************************
142 An implementation of a modified window subband as seen in Kumar & Zubair's
143 "A high performance software implentation of mpeg audio encoder"
144 I think from IEEE ASCAP 1996 proceedings
146 input: shift in 32*12 (384) new samples into a 864 point buffer.
147 ch - which channel we're looking at.
149 This routine basically does 12 calls to window subband all in one go.
150 Not yet called in code. here for testing only.
151 ************************************************************************/
152 void window_subband12 (short **buffer
, int ch
)
154 static double x
[2][864]; /* 2 channels, 864 buffer for each */
156 double t
[12]; /* a temp buffer for summing values */
157 double y
[12][64]; /* 12 output arrays of 64 values */
159 static double c
[512]; /* enwindow array */
163 xk
= x
[ch
]; /* an easier way of referencing the array */
165 /* shift 384 new samples into the buffer */
166 for (i
= 863; i
>= 384; i
--)
168 for (i
= 383; i
>= 0; i
--)
169 xk
[i
] = (double) *(*buffer
)++ / SCALE
;
171 for (j
= 0; j
< 64; j
++) {
172 for (k
= 0; k
< 12; k
++)
174 for (i
= 0; i
< 8; i
++) {
177 t
[0] += c0
* xk
[m
+ 352];
178 t
[1] += c0
* xk
[m
+ 320];
179 t
[2] += c0
* xk
[m
+ 288];
180 t
[3] += c0
* xk
[m
+ 256];
181 t
[4] += c0
* xk
[m
+ 224];
182 t
[5] += c0
* xk
[m
+ 192];
183 t
[6] += c0
* xk
[m
+ 160];
184 t
[7] += c0
* xk
[m
+ 128];
185 t
[8] += c0
* xk
[m
+ 96];
186 t
[9] += c0
* xk
[m
+ 64];
187 t
[10] += c0
* xk
[m
+ 32];
190 for (i
= 0; i
< 12; i
++) {
198 //____________________________________________________________________________
199 //____ WindowFilterSubband() _________________________________________
200 //____ RS&A - Feb 2003 _______________________________________________________
201 void WindowFilterSubband (short *pBuffer
, int ch
, double s
[SBLIMIT
])
204 int pa
, pb
, pc
, pd
, pe
, pf
, pg
, ph
;
211 static double x
[2][512];
212 static double m
[16][32];
223 for (i
= 0; i
< 2; i
++)
224 for (j
= 0; j
< 512; j
++)
226 create_dct_matrix (m
);
229 dp
= x
[ch
] + off
[ch
] + half
[ch
] * 256;
231 /* replace 32 oldest samples with 32 new samples */
232 for (i
= 0; i
< 32; i
++)
233 dp
[(31 - i
) * 8] = (double) pBuffer
[i
] / SCALE
;
235 // looks like "school example" but does faster ...
236 dp
= (x
[ch
] + half
[ch
] * 256);
246 for (i
= 0; i
< 32; i
++) {
249 t
= dp2
[pa
] * pEnw
[0];
250 t
+= dp2
[pb
] * pEnw
[64];
251 t
+= dp2
[pc
] * pEnw
[128];
252 t
+= dp2
[pd
] * pEnw
[192];
253 t
+= dp2
[pe
] * pEnw
[256];
254 t
+= dp2
[pf
] * pEnw
[320];
255 t
+= dp2
[pg
] * pEnw
[384];
256 t
+= dp2
[ph
] * pEnw
[448];
260 yprime
[0] = y
[16]; // Michael Chen´s dct filter
262 dp
= half
[ch
] ? x
[ch
] : (x
[ch
] + 256);
263 pa
= half
[ch
] ? (off
[ch
] + 1) & 7 : off
[ch
];
272 for (i
= 0; i
< 32; i
++) {
274 pEnw
= enwindow
+ i
+ 32;
275 t
= dp2
[pa
] * pEnw
[0];
276 t
+= dp2
[pb
] * pEnw
[64];
277 t
+= dp2
[pc
] * pEnw
[128];
278 t
+= dp2
[pd
] * pEnw
[192];
279 t
+= dp2
[pe
] * pEnw
[256];
280 t
+= dp2
[pf
] * pEnw
[320];
281 t
+= dp2
[pg
] * pEnw
[384];
282 t
+= dp2
[ph
] * pEnw
[448];
284 // 1st pass on Michael Chen´s dct filter
286 yprime
[i
] = y
[i
+ 16] + y
[16 - i
];
289 // 2nd pass on Michael Chen´s dct filter
290 for (i
= 17; i
< 32; i
++)
291 yprime
[i
] = y
[i
+ 16] - y
[80 - i
];
293 for (i
= 15; i
>= 0; i
--) {
294 register double s0
= 0.0, s1
= 0.0;
295 register double *mp
= m
[i
];
296 register double *xinp
= yprime
;
297 for (j
= 0; j
< 8; j
++) {
298 s0
+= *mp
++ * *xinp
++;
299 s1
+= *mp
++ * *xinp
++;
300 s0
+= *mp
++ * *xinp
++;
301 s1
+= *mp
++ * *xinp
++;
307 half
[ch
] = (half
[ch
] + 1) & 1;
309 off
[ch
] = (off
[ch
] + 7) & 7;