1 
2 /*
3  * Copyright (C) 2000-2002 Kare Sjolander <kare@speech.kth.se>
4  *
5  * This file is part of the Snack Sound Toolkit.
6  * The latest version can be found at http://www.speech.kth.se/snack/
7  *
8 
9  This file is derived from
10 
11  amp MPEG audio decoder (version 0.7.3)
12  (C) Tomislav Uzelac  1996,1997
13 
14 This software can be used freely for any purpose. It can be distributed
15 freely, as long as it is not sold commercially without permission from
16 Tomislav Uzelac <tuzelac@rasip.fer.hr>. However, including this software
17 on CD_ROMs containing other free software is explicitly permitted even
18 when a modest distribution fee is charged for the CD, as long as this
19 software is not a primary selling argument for the CD.
20 
21 Building derived versions of this software is permitted, as long as they
22 are not sold commercially without permission from Tomislav Uzelac
23 <tuzelac@rasip.fer.hr>. Any derived versions must be clearly marked as
24 such, and must be called by a name other than amp. Any derived versions
25 must retain this copyright notice.
26 */
27 
28 #include <stdlib.h>
29 #include "snack.h"
30 #include "jkFormatMP3.h"
31 #include <string.h>
32 #define FRAS2(is,a) ((is) > 0 ? t_43[(is)]*(a):-t_43[-(is)]*(a))
33 #define MAXFRAMESIZE 2106  /* frame size starting at header */
34 static char *gblOutputbuf;
35 static char *gblReadbuf;
36 static int gblBufind = 0;
37 static Tcl_Channel gblGch;
38 static int fool_opt = 0;
39 extern int debugLevel;
40 
41 extern int useOldObjAPI;
42 /* "getbits.c" */
43 
44 static int
45 _fillbfr(int size)
46 {
47   if (gblGch != NULL) {
48     size = Tcl_Read(gblGch, (char *) _buffer, size);
49   } else {
50     memcpy((char *) _buffer, &gblReadbuf[gblBufind], size);
51     gblBufind += size;
52   }
53   _bptr = 0;
54   return(size);
55 }
56 
57 static unsigned int
58 _getbits(int n)
59 {
60   unsigned int pos,ret_value;
61 
62   pos = _bptr >> 3;
63   ret_value = _buffer[pos] << 24 |
64     _buffer[pos+1] << 16 |
65     _buffer[pos+2] << 8 |
66     _buffer[pos+3];
canbe(pnumb,fnumb)67   ret_value <<= _bptr & 7;
68   ret_value >>= 32 - n;
69   _bptr += n;
70   return ret_value;
71 }
72 
73 static int
candy(cand,pnumb,fnumb)74 fillbfr(int advance)
75 {
76   int overflow;
77 
78   if (gblGch != NULL) {
79     int read = Tcl_Read(gblGch, (char *) &gblBuffer[gblAppend], advance);
80 
81     if (read <= 0) return(read);
82   } else {
83     memcpy((char *) &gblBuffer[gblAppend], &gblReadbuf[gblBufind], advance);
84     gblBufind += advance;
85   }
86 
87   if ( gblAppend + advance >= BUFFER_SIZE ) {
88     overflow = gblAppend + advance - BUFFER_SIZE;
89     memcpy (gblBuffer,&gblBuffer[BUFFER_SIZE], overflow);
90     if (overflow < 4) memcpy(&gblBuffer[BUFFER_SIZE],gblBuffer,4);
91     gblAppend = overflow;
92   } else gblAppend+=advance;
93   return advance;
94 }
95 
96 /* these functions read from the buffer. a separate viewbits/flushbits
97  * functions are there primarily for the new huffman decoding scheme
98  */
99 static
100 unsigned int viewbits(int n)
101 {
102   unsigned int pos,ret_value;
103 
104   pos = gblData >> 3;
105   ret_value = gblBuffer[pos] << 24 |
106     gblBuffer[pos+1] << 16 |
107     gblBuffer[pos+2] << 8 |
108     gblBuffer[pos+3];
109   ret_value <<= gblData & 7;
110   ret_value >>= 32 - n;
111 
112   return ret_value;
113 }
114 
115 static void
116 sackbits(int n)
117 {
118   gblData += n;
119   gblData &= 8*BUFFER_SIZE-1;
get_fcand(npole,freq,band,nform,pcan)120 }
121 
122 static unsigned int
123 getbits(int n)
124 {
125   if (n) {
126     unsigned int ret_value;
127     ret_value=viewbits(n);
128     sackbits(n);
129     return ret_value;
130   } else
131     return 0;
132 }
133 /*
134  * gethdr reads and validates the current 4 bytes are a valid header.
set_nominal_freqs(f1)135  */
136 static int
137 gethdr(struct AUDIO_HEADER *header)
138 {
139   int s,br;
140   int bitrate,fs,mean_frame_size;
141   /* check for frame sync first */
142   if ((s=_getbits(11)) != 0x7ff) {
143     return GETHDR_ERR;
144   }
145   header->fullID = _getbits(2);
146   if (header->fullID == 1) {
147     return GETHDR_ERR;  /* invalid ID */
148   }
149   header->ID    =header->fullID&0x1;
150   header->layer=_getbits(2);
151   /* only support layer3
152   if (header->layer == 0) {
153     return GETHDR_ERR;
154   }
155   */
156   if (header->layer != 1) {
157     return GETHDR_ERR;
158   }
159   header->protection_bit=_getbits(1);
160   header->bitrate_index=_getbits(4);
161   if (header->bitrate_index == 0xFF || header->bitrate_index == 0) {
162     /* free bitrate=0 is also invalid */
163     return GETHDR_ERR;
164   }
165   header->sampling_frequency=_getbits(2);
166   if (header->sampling_frequency == 3) {
167     return GETHDR_ERR;       /* 3 is invalid */
168   }
169   header->padding_bit=_getbits(1);
170   header->private_bit=_getbits(1);
171   header->mode=_getbits(2); /* channel mode */
172   bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
173   fs=t_sampling_frequency[header->fullID][header->sampling_frequency];
174   mean_frame_size = (bitrate * sr_lookup[header->ID] / fs);   /* This frame size */
175   if (mean_frame_size > MAXFRAMESIZE) {
176      return GETHDR_ERR;
177   }
178   /*
179    * Validate bitrate channel mode combinations for layer 2
180    * layer 2 not yet supported.
181    */
182   if (header->layer == 2) {
183      br=bitrate;
184      switch (header->mode) {
185         case 0x00: /* stereo */
186         case 0x01: /* intensity */
187         case 0x02: /* dual channel */
188            if (br==32 || br==48 || br==56 || br == 80) {
189               if (debugLevel > 0) {
190                  Snack_WriteLogInt("1 Invalid channel/mode combo",header->mode);
191               }
192                return GETHDR_ERR;
193            };
194            break;
195         case 0x03: /* single channel */
196            if (br>=224) {
197               if (debugLevel > 0) {
198                  Snack_WriteLogInt("2 Invalid channel/mode combo",header->mode);
199               }
200                return GETHDR_ERR;
201            };
202            break;
203      }
204   }
205 
206   header->mode_extension=_getbits(2);
207   if (header->mode!=1) header->mode_extension=0; /* ziher je.. */
208   header->copyright=_getbits(1);
209   header->original=_getbits(1);
210   header->emphasis=_getbits(2);
211 /*printf("gethdr %x %x %x %x\n",_buffer[0], _buffer[1],_buffer[2], _buffer[3]);*/
212   return 0;
213 }
214 
215 /* dummy function, to get crc out of the way
216 */
217 static void
218 getcrc()
219 {
220   _fillbfr(2);
221   _getbits(16);
222 }
223 
224 /* sizes of side_info:
225  * MPEG1   1ch 17    2ch 32
226  * MPEG2   1ch  9    2ch 17
227  */
228 static void
229 getinfo(struct AUDIO_HEADER *header,struct SIDE_INFO *info)
230 {
231   int gr,ch,scfsi_band,region,window;
232   int nch,bv;
233   info->error[0]=0;
234   info->error[1]=0;
235   if (header->mode==3) {
236     nch=1;
237     if (header->ID) {
238       _fillbfr(17);
239       info->main_data_begin=_getbits(9);
240       _getbits(5);
241     } else {
242       _fillbfr(9);
243       info->main_data_begin=_getbits(8);
244       _getbits(1);
245     }
246   } else {
247     nch=2;
248     if (header->ID) {
249       _fillbfr(32);
250       info->main_data_begin=_getbits(9);
251       _getbits(3);
252     } else {
253       _fillbfr(17);
254       info->main_data_begin=_getbits(8);
255       _getbits(2);
256     }
257   }
258   /* scalefactors to granules */
259   if (header->ID) for (ch=0;ch<nch;ch++)
260     for (scfsi_band=0;scfsi_band<4;scfsi_band++)
261       info->scfsi[ch][scfsi_band]=_getbits(1);
262   for (gr=0;gr<(header->ID ? 2:1);gr++)
263     for (ch=0;ch<nch;ch++) {
264      /*
265       * Number of bits used for scalefactors (part2)
266       * Huffman encoded data (part3) of the appropriate granule/channel
267       */
268       info->part2_3_length[gr][ch]=_getbits(12);
269       if (info->part2_3_length[gr][ch] == 0 && debugLevel > 1) {
270          Snack_WriteLogInt("  blank part 2/3 length gr=",gr);
271       }
272       bv = _getbits(9);
273       info->global_gain[gr][ch]=_getbits(8);
274       /* big_value can't be > 576 (288 << 1), usually denotes a stream error */
275       if (bv > 288) {
276          if (debugLevel > 0) {
277             Snack_WriteLogInt("  Invalid big value ",bv);
278             Snack_WriteLogInt("         on channel ",ch);
279          }
280          for (ch=0;ch<nch;ch++)
281             info->error[ch] = 1; /* force error on all channels */
282          info->big_values[gr][ch]=0;
283       } else {
284          info->big_values[gr][ch]=bv;
285       }
286       if (header->ID)
287          info->scalefac_compress[gr][ch]=_getbits(4);
288       else
289          info->scalefac_compress[gr][ch]=_getbits(9);
290       info->window_switching_flag[gr][ch]=_getbits(1);
291 
292       if (info->window_switching_flag[gr][ch]) {
293         info->block_type[gr][ch]=_getbits(2);
294         info->mixed_block_flag[gr][ch]=_getbits(1);
295 
296         for (region=0;region<2;region++)
297           info->table_select[gr][ch][region]=_getbits(5);
298         info->table_select[gr][ch][2]=0;
299 
300         for (window=0;window<3;window++)
301           info->subblock_gain[gr][ch][window]=_getbits(3);
302       } else {
303         for (region=0;region<3;region++)
304           info->table_select[gr][ch][region]=_getbits(5);
305 
306         info->region0_count[gr][ch]=_getbits(4);
307         info->region1_count[gr][ch]=_getbits(3);
308         info->block_type[gr][ch]=0;
309       }
310 
311       if (header->ID) info->preflag[gr][ch]=_getbits(1);
312       info->scalefac_scale[gr][ch]=_getbits(1);
313       info->count1table_select[gr][ch]=_getbits(1);
314     }
315   return;
316 }
317 
318 /* "getdata.c" */
319 
320 /* layer3 scalefactor decoding. should we check for the number
321  * of bits read, just in case?
322  */
323 static int
324 decode_scalefactors(mp3Info *ext, struct SIDE_INFO *info,struct AUDIO_HEADER *header,int gr,int ch)
325 {
326   int sfb,window;
327   int slen1,slen2;
328   int i1,i2,i=0;
329   int j,k;
330   if (header->ID==1) {
331     /* this is MPEG-1 scalefactors format, quite different than
332      * the MPEG-2 format.
333      */
334     slen1=t_slen1[info->scalefac_compress[gr][ch]];
335     slen2=t_slen2[info->scalefac_compress[gr][ch]];
336     i1=3*slen1;
337     i2=3*slen2;
338 
339     if (info->window_switching_flag[gr][ch] && info->block_type[gr][ch]==2) {
340       if (info->mixed_block_flag[gr][ch]) {
341         for (sfb=0;sfb<8;sfb++) {
342           ext->scalefac_l[gr][ch][sfb]=getbits(slen1);
343           i+=slen1;
344         }
345         for (sfb=3;sfb<6;sfb++) {
346           for (window=0;window<3;window++)
347             ext->scalefac_s[gr][ch][sfb][window]=getbits(slen1);
348           i+=i1;
349         }
350         for (;sfb<12;sfb++) {
351           for (window=0;window<3;window++)
352             ext->scalefac_s[gr][ch][sfb][window]=getbits(slen2);
353           i+=i2;
354         }
355       } else { /* !mixed_block_flag */
356         for (sfb=0;sfb<6;sfb++) {
357           for (window=0;window<3;window++)
358             ext->scalefac_s[gr][ch][sfb][window]=getbits(slen1);
359           i+=i1;
360         }
361         for (;sfb<12;sfb++) {
362           for (window=0;window<3;window++)
363             ext->scalefac_s[gr][ch][sfb][window]=getbits(slen2);
364           i+=i2;
365         }
366       }
367       for (window=0;window<3;window++)
368         ext->scalefac_s[gr][ch][12][window]=0;
369     } else { /* block_type!=2 */
370       if ( !info->scfsi[ch][0] || !gr )
371         for (sfb=0;sfb<6;sfb++) {
372           ext->scalefac_l[gr][ch][sfb]=getbits(slen1);
373           i+=slen1;
374         }
375       else for (sfb=0;sfb<6;sfb++) {
376         ext->scalefac_l[1][ch][sfb]=ext->scalefac_l[0][ch][sfb];
377       }
378       if ( !info->scfsi[ch][1] || !gr )
379         for (sfb=6;sfb<11;sfb++) {
380           ext->scalefac_l[gr][ch][sfb]=getbits(slen1);
381           i+=slen1;
382         }
383       else for (sfb=6;sfb<11;sfb++) {
384         ext->scalefac_l[1][ch][sfb]=ext->scalefac_l[0][ch][sfb];
385       }
386       if ( !info->scfsi[ch][2] || !gr )
387         for (sfb=11;sfb<16;sfb++) {
388           ext->scalefac_l[gr][ch][sfb]=getbits(slen2);
389           i+=slen2;
390         }
391       else for (sfb=11;sfb<16;sfb++) {
392         ext->scalefac_l[1][ch][sfb]=ext->scalefac_l[0][ch][sfb];
393       }
394       if ( !info->scfsi[ch][3] || !gr )
395         for (sfb=16;sfb<21;sfb++) {
396           ext->scalefac_l[gr][ch][sfb]=getbits(slen2);
397           i+=slen2;
398         }
399       else for (sfb=16;sfb<21;sfb++) {
400         ext->scalefac_l[1][ch][sfb]=ext->scalefac_l[0][ch][sfb];
401       }
402       ext->scalefac_l[gr][ch][21]=0;
403     }
404   } else { /* ID==0 */
405     int index = 0,index2,spooky_index;
406     int slen[5],nr_of_sfb[5]; /* actually, there's four of each, not five, labelled 1 through 4, but
407                                * what's a word of storage compared to one's sanity. so [0] is irellevant.
408                                */
409 
410     /* ok, so we got 3 indexes.
411      * spooky_index - indicates whether we use the normal set of slen eqs and nr_of_sfb tables
412      *                or the one for the right channel of intensity stereo coded frame
413      * index        - corresponds to the value of scalefac_compress, as listed in the standard
414      * index2       - 0 for long blocks, 1 for short wo/ mixed_block_flag, 2 for short with it
415      */
416     if ( (header->mode_extension==1 || header->mode_extension==3) && ch==1) { /* right ch... */
417       int int_scalefac_compress=info->scalefac_compress[0][ch]>>1;
418       ext->intensity_scale=info->scalefac_compress[0][1]&1;
419       spooky_index=1;
420       if (int_scalefac_compress < 180) {
421         slen[1]=int_scalefac_compress/36;
422         slen[2]=(int_scalefac_compress%36)/6;
423         slen[3]=(int_scalefac_compress%36)%6;
424         slen[4]=0;
425         info->preflag[0][ch]=0;
426         index=0;
427       }
428       if ( 180 <= int_scalefac_compress && int_scalefac_compress < 244) {
429         slen[1]=((int_scalefac_compress-180)%64)>>4;
430         slen[2]=((int_scalefac_compress-180)%16)>>2;
431         slen[3]=(int_scalefac_compress-180)%4;
432         slen[4]=0;
433         info->preflag[0][ch]=0;
434         index=1;
435       }
436       if ( 244 <= int_scalefac_compress && int_scalefac_compress < 255) {
437         slen[1]=(int_scalefac_compress-244)/3;
438         slen[2]=(int_scalefac_compress-244)%3;
439         slen[3]=0;
440         slen[4]=0;
441         info->preflag[0][ch]=0;
integerize(time,freq)442         index=2;
443       }
444     } else { /* the usual */
445       spooky_index=0;
446       if (info->scalefac_compress[0][ch] < 400) {
447         slen[1]=(info->scalefac_compress[0][ch]>>4)/5;
448         slen[2]=(info->scalefac_compress[0][ch]>>4)%5;
449         slen[3]=(info->scalefac_compress[0][ch]%16)>>2;
450         slen[4]=info->scalefac_compress[0][ch]%4;
451         info->preflag[0][ch]=0;
eround(flnum)452         index=0;
453       }
454       if (info->scalefac_compress[0][ch] >= 400 && info->scalefac_compress[0][ch] < 500) {
455         slen[1]=((info->scalefac_compress[0][ch]-400)>>2)/5;
456         slen[2]=((info->scalefac_compress[0][ch]-400)>>2)%5;
457         slen[3]=(info->scalefac_compress[0][ch]-400)%4;
458         slen[4]=0;
lpc_poles(sp,wdur,frame_int,lpc_ord,preemp,lpc_type,w_type)459         info->preflag[0][ch]=0;
460         index=1;
461       }
462       if (info->scalefac_compress[0][ch] >= 500 && info->scalefac_compress[0][ch] < 512) {
463         slen[1]=(info->scalefac_compress[0][ch]-500)/3;
464         slen[2]=(info->scalefac_compress[0][ch]-500)%3;
465         slen[3]=0;
466         slen[4]=0;
467         info->preflag[0][ch]=1;
468         index=2;
469       }
470     }
471 
472     if (info->window_switching_flag[0][ch] && info->block_type[0][ch]==2)
473       if (info->mixed_block_flag[0][ch]) index2=2;
474       else index2=1;
475     else index2=0;
476 
477     for (j=1;j<=4;j++) nr_of_sfb[j]=spooky_table[spooky_index][index][index2][j-1];
478 
479     /* now we'll do some actual scalefactor extraction, and a little more.
480      * for each scalefactor band we'll set the value of ext->is_max to indicate
481      * illegal is_pos, since with MPEG2 it's not 'hardcoded' to 7.
482      */
483     if (!info->window_switching_flag[0][ch] || (info->window_switching_flag[0][ch] && info->block_type[0][ch]!=2)) {
484       sfb=0;
485       for (j=1;j<=4;j++) {
486         for (k=0;k<nr_of_sfb[j];k++) {
487           ext->scalefac_l[0][ch][sfb]=getbits(slen[j]);
488           i+=slen[j];
489           if (ch) ext->is_max[sfb]=(1<<slen[j])-1;
490           sfb++;
491         }
492       }
493       /* There may be a bug here, sfb is left at 21
494          indicating there are 21 scale factors,
495          last one is ?always? blank and
496          later causes a crash if garbage
497          scalefac_l[0][ch][21] is not used.
498       */
499     } else if (info->block_type[0][ch]==2) {
500       if (!info->mixed_block_flag[0][ch]) {
501         sfb=0;
502         for (j=1;j<=4;j++) {
503           for (k=0;k<nr_of_sfb[j];k+=3) {
504             /* we assume here that nr_of_sfb is divisible by 3. it is.
505              */
506             ext->scalefac_s[0][ch][sfb][0]=getbits(slen[j]);
507             ext->scalefac_s[0][ch][sfb][1]=getbits(slen[j]);
508             ext->scalefac_s[0][ch][sfb][2]=getbits(slen[j]);
509             i+=3*slen[j];
510             if (ch) ext->is_max[sfb+6]=(1<<slen[j])-1;
511             sfb++;
512           }
513         }
514       } else {
515         /* what we do here is:
516          * 1. assume that for every fs, the two lowest subbands are equal to the
517          *    six lowest scalefactor bands for long blocks/MPEG2. they are.
518          * 2. assume that for every fs, the two lowest subbands are equal to the
519          *    three lowest scalefactor bands for short blocks. they are.
520          */
521         sfb=0;
522         for (k=0;k<6;k++) {
523           ext->scalefac_l[0][ch][sfb]=getbits(slen[1]);
524           i+=slen[j];
525           if (ch) ext->is_max[sfb]=(1<<slen[1])-1;
526           sfb++;
527         }
528         nr_of_sfb[1]-=6;
529         sfb=3;
530         for (j=1;j<=4;j++) {
531           for (k=0;k<nr_of_sfb[j];k+=3) {
532             ext->scalefac_s[0][ch][sfb][0]=getbits(slen[j]);
533             ext->scalefac_s[0][ch][sfb][1]=getbits(slen[j]);
534             ext->scalefac_s[0][ch][sfb][2]=getbits(slen[j]);
535             i+=3*slen[j];
536             if (ch) ext->is_max[sfb+6]=(1<<slen[j])-1;
537             sfb++;
538           }
539         }
540       }
541     }
542   }
543   return i;
544 }
545 
546 /* this is for huffman decoding, but inlined funcs have to go first
547  */
548 static int
549 _qsign(int x,int *q)
550 {
551   int ret_value=0,i;
552   for (i=3;i>=0;i--)
553     if ((x>>i) & 1) {
554       if (getbits(1)) *q++=-1;
555       else *q++=1;
556       ret_value++;
557     }
558     else *q++=0;
559   return ret_value;
frand()560 }
561 
562 static int
563 decode_huffman_data(mp3Info *ext,struct SIDE_INFO *info,int gr,int ch,int ssize)
564 {
565   int l,i,cnt,x=0,y=0, cmp=0;
566   int q[4],r[3],linbits[3],tr[4]={0,0,0,0};
567   int big_value = info->big_values[gr][ch] << 1;
568   for (l=0;l<3;l++) {
569     tr[l]=info->table_select[gr][ch][l];
570     linbits[l]=t_linbits[info->table_select[gr][ch][l]];
571   }
572 
573   tr[3]=32+info->count1table_select[gr][ch];
574 
575   /* we have to be careful here because big_values are not necessarily
576    * aligned with sfb boundaries
577    */
578   if (!info->window_switching_flag[gr][ch] && info->block_type[gr][ch]==0) {
579 
580     /* this code needed some cleanup
581      */
582     r[0]=ext->t_l[info->region0_count[gr][ch]] + 1;
583     if (r[0] > big_value)
584       r[0]=r[1]=big_value;
585     else {
586       r[1]=ext->t_l[ info->region0_count[gr][ch] + info->region1_count[gr][ch] + 1 ] + 1;
587       if (r[1] > big_value)
588         r[1]=big_value;
589     }
590     r[2]=big_value;
591 
592   } else {
593 
594     if (info->block_type[gr][ch]==2 && info->mixed_block_flag[gr][ch]==0)
595       r[0]=3*(ext->t_s[2]+1);
596     else
597       r[0]=ext->t_l[7]+1;
598 
599     if (r[0] > big_value)
600       r[0]=big_value;
601 
602     r[1]=r[2]=big_value;
603   }
604 
605   l=0; cnt=0;
606   for (i=0;i<3;i++) {
607     for (;l<r[i];l+=2) {
608       int j = linbits[i];
609 
610       cnt+=huffman_decode(tr[i],&x,&y);
611 
612       if (x==15 && j>0) {
613         x+=getbits(j);
614         cnt+=j;
615       }
616       if (x) {
617         if (getbits(1)) x=-x;
618         cnt++;
619       }
620       if (y==15 && j>0) {
621         y+=getbits(j);
622         cnt+=j;
623       }
624       if (y) {
625         if (getbits(1)) y=-y;
626         cnt++;
627       }
628 
629       /*      if (SHOW_HUFFBITS) printf(" (%d,%d) %d\n",x,y, SHOW_HUFFBITS);*/
630       ext->is[ch][l]=x;
631       ext->is[ch][l+1]=y;
632     }
633   }
634   cmp = (info->part2_3_length[gr][ch] - ssize);
635   while ((cnt < cmp) && (l<576)) {
636     cnt+=huffman_decode(tr[3],&x,&y);
637     cnt+=_qsign(x,q);
638     for (i=0;i<4;i++)
639       ext->is[ch][l+i]=q[i]; /* ziher je ziher, is[578]*/
640     l+=4;
641     /* if (SHOW_HUFFBITS) printf(" (%d,%d,%d,%d)\n",q[0],q[1],q[2],q[3]); */
642   }
643   /*
644    * If we detected an error in the header for this frame, blank it out
645    * to prevent audible spikes.
646    */
647    if (info->error[ch]) {
648       if (debugLevel > 0) {
649          Snack_WriteLogInt ("  blanking gain",cnt-cmp);
650       }
651       info->global_gain[gr][ch]=0;
652    } else {
653      /*
654       * Debug code to print out excessive mismatches in bits
655       */
656       if (cnt > cmp) {
657          if ((cnt - cmp) > 100) {
658             if (debugLevel > 0)
659                Snack_WriteLogInt ("  BITS DISCARDED",cnt - cmp);
660          }
661       }
662       else if (cnt < cmp) {
663          if ((cmp-cnt) > 800) {
664             if (debugLevel > 0) {
665                Snack_WriteLogInt ("  BITS NOT USED",cmp - cnt);
666                Snack_WriteLogInt ("           GAIN",info->global_gain[gr][ch]);
667             }
668 
669          }
670       }
671    }
672   /*  set position to start of the next gr/ch, only needed on a mismatch
673    */
674   if (cnt != cmp ) {
675     gblData-=cnt-cmp;
676     gblData&= 8*BUFFER_SIZE - 1;
677   }
678   if (l<576) {
679      ext->non_zero[ch]=l;
680      /* zero out everything else
681       */
682      for (;l<576;l++)
683         ext->is[ch][l]=0;
684   } else {
685      ext->non_zero[ch]=576;
686   }
687   return 1;
688 }
689 
690 /*
691  * fras == Formula for Requantization and All Scaling **************************
692  */
693 static float
694 fras_l(int sfb,int global_gain,int scalefac_scale,int scalefac,int preflag)
695 {
696   int a,scale;
697   if (scalefac_scale) scale=2;
698   else scale=1;
699   a=global_gain - 210 - (scalefac << scale);
700   if (preflag) a-=(t_pretab[sfb] << scale);
701 
702   /* bugfix, Mar 13 97: shifting won't produce a legal result if we shift by more than 31
703    * since global_gain<256, this can only occur for (very) negative values of a.
704    */
705   if (a < -127) return 0;
706 
707   /* a minor change here as well, no point in abs() if we now that a<0
get_abs_maximum(d,n)708    */
709   if (a>=0) return tab[a&3]*(1 << (a>>2));
710   else return tabi[(-a)&3]/(1 << ((-a) >> 2));
711 }
712 
713 static float
714 fras_s(int global_gain,int subblock_gain,int scalefac_scale,int scalefac)
715 {
716   int a;
717   a=global_gain - 210 - (subblock_gain << 3);
718   if (scalefac_scale) a-= (scalefac << 2);
719   else a-= (scalefac << 1);
720 
721   if (a < -127) return 0;
722 
723   if (a>=0) return tab[a&3]*(1 << (a>>2));
724   else return tabi[(-a)&3]/(1 << ((-a) >> 2));
725 }
726 
727 /* this should be faster than pow()
728  */
dwnsamp(buf,in_samps,buf2,out_samps,insert,decimate,ncoef,ic,smin,smax)729 /*
730 static float
731 fras2(int is,float a)
732 {
733   if (is > 0) return t_43[is]*a;
734   else return -t_43[-is]*a;
735 }
736 */
737 /*
738  * requantize_mono *************************************************************
739  */
740 
741 /* generally, the two channels do not have to be of the same block type - that's why we do two passes with requantize_mono.
742  * if ms or intensity stereo is enabled we do a single pass with requantize_ms because both channels are same block type
743  */
744 
745 static void
746 requantize_mono(mp3Info *ext, int gr,int ch,struct SIDE_INFO *info,struct AUDIO_HEADER *header)
747 {
748   int l,i,sfb;
749   float a;
750   int global_gain=info->global_gain[gr][ch];
751   int scalefac_scale=info->scalefac_scale[gr][ch];
752   int sfreq=header->sampling_frequency;
753   /* TFW: sfreq must be less than 3, used as an index into t_reorder */
754   if (sfreq >= 3) return;
755 
756   /* TFW - Note: There needs to be error checking here on header info */
757   no_of_imdcts[0]=no_of_imdcts[1]=32;
758 
759   if (info->window_switching_flag[gr][ch] && info->block_type[gr][ch]==2)
760     if (info->mixed_block_flag[gr][ch]) {
761       /*
762        * requantize_mono - mixed blocks/long block part **********************
763        */
764       int window,window_len,preflag=0; /* pretab is all zero in this low frequency area */
765       int scalefac=ext->scalefac_l[gr][ch][0];
766 
767       l=0;sfb=0;
768       a=fras_l(sfb,global_gain,scalefac_scale,scalefac,preflag);
769       while (l<36) {
770         ext->xr[ch][0][l]=FRAS2(ext->is[ch][l],a);
771         if (l==ext->t_l[sfb]) {
772           scalefac=ext->scalefac_l[gr][ch][++sfb];
773           a=fras_l(sfb,global_gain,scalefac_scale,scalefac,preflag);
774         }
775         l++;
776       }
777       /*
778        * requantize_mono - mixed blocks/short block part *********************
779        */
780       sfb=3;
781       window_len=ext->t_s[sfb]-ext->t_s[sfb-1];
782       while (l<ext->non_zero[ch]) {
783         for (window=0;window<3;window++) {
784           int scalefac=ext->scalefac_s[gr][ch][sfb][window];
785           int subblock_gain=info->subblock_gain[gr][ch][window];
786           a=fras_s(global_gain,subblock_gain,scalefac_scale,scalefac);
787           for (i=0;i<window_len;i++) {
788             ext->xr[ch][0][t_reorder[header->ID][sfreq][l]]=FRAS2(ext->is[ch][l],a);
789             l++;
790           }
791         }
792         sfb++;
793         window_len=ext->t_s[sfb]-ext->t_s[sfb-1];
794       }
795       while (l<576) ext->xr[ch][0][t_reorder[header->ID][sfreq][l++]]=0;
796     } else {
797       /*
798        * requantize mono - short blocks **************************************
799        */
800       int window,window_len;
801 
802       sfb=0; l=0;
803       window_len=ext->t_s[0]+1;
804       while (l<ext->non_zero[ch]) {
805         for (window=0;window<3;window++) {
806           int scalefac=ext->scalefac_s[gr][ch][sfb][window];
807           int subblock_gain=info->subblock_gain[gr][ch][window];
808           float a=fras_s(global_gain,subblock_gain,scalefac_scale,scalefac);
809           for (i=0;i<window_len;i++) {
810             ext->xr[ch][0][t_reorder[header->ID][sfreq][l]]=FRAS2(ext->is[ch][l],a);
811             l++;
812           }
813         }
814         sfb++;
815         window_len=ext->t_s[sfb]-ext->t_s[sfb-1];
816       }
817       while (l<576) ext->xr[ch][0][t_reorder[header->ID][sfreq][l++]]=0;
818     }
819   else {
820     /* long blocks */
821     int preflag=info->preflag[gr][ch];
822     int scalefac=ext->scalefac_l[gr][ch][0];
823 
824     sfb=0; l=0;
825     a=fras_l(sfb,global_gain,scalefac_scale,scalefac,preflag);
826     while (l<ext->non_zero[ch]) {
827       ext->xr[ch][0][l]=FRAS2(ext->is[ch][l],a);
828       if (l==ext->t_l[sfb]) {
829         scalefac=ext->scalefac_l[gr][ch][++sfb];
830         a=fras_l(sfb,global_gain,scalefac_scale,scalefac,preflag);
831       }
832       l++;
833     }
834     while (l<576) ext->xr[ch][0][l++]=0;
835   }
836 }
837 
838 /*
839  * stereo stuff ****************************************************************
840  */
841 static int
842 find_isbound(mp3Info *ext, int isbound[3],int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header)
843 {
844   int sfb,window,window_len,ms_flag,tmp,i;
845 
846   isbound[0]=isbound[1]=isbound[2]=-1;
847   no_of_imdcts[0]=no_of_imdcts[1]=32;
848 
849   if (header->mode_extension==1 || header->mode_extension==3) {
850     if (info->window_switching_flag[gr][0] && info->block_type[gr][0]==2) {
851 
852       /* find that isbound!
853        */
854       tmp=ext->non_zero[1];
855       sfb=0; while ((3*ext->t_s[sfb]+2) < tmp  && sfb < 12) sfb++;
856       while ((isbound[0]<0 || isbound[1]<0 || isbound[2]<0) && !(info->mixed_block_flag[gr][0] && sfb<3) && sfb) {
857         for (window=0;window<3;window++) {
858           if (sfb==0) {
859             window_len=ext->t_s[0]+1;
860             tmp=(window+1)*window_len - 1;
861           } else {
862             window_len=ext->t_s[sfb]-ext->t_s[sfb-1];
863             tmp=(3*ext->t_s[sfb-1]+2) + (window+1)*window_len;
864           }
865           if (isbound[window] < 0)
866             for (i=0;i<window_len;i++)
867               if (ext->is[1][tmp--] != 0) {
868                 isbound[window]=ext->t_s[sfb]+1;
869                 break;
870               }
871         }
872         sfb--;
873       }
874 
875       /* mixed block magic now...
876        */
877       if (sfb==2 && info->mixed_block_flag[gr][0]) {
878         if (isbound[0]<0 && isbound[1]<0 && isbound[2]<0) {
879           tmp=35;
880           while (ext->is[1][tmp] == 0) tmp--;
881           sfb=0; while (ext->t_l[sfb] < tmp  && sfb < 21) sfb++;
highpass(s)882           isbound[0]=isbound[1]=isbound[2]=ext->t_l[sfb]+1;
883         } else for (window=0;window<3;window++)
884           if (isbound[window]<0) isbound[window]=36;
885       }
886       if (header->ID==1) isbound[0]=isbound[1]=isbound[2]=max(isbound[0],max(isbound[1],isbound[2]));
887 
888       /* just how many imdcts?
889        */
890       tmp=ext->non_zero[0];
891       sfb=0; while ((3*ext->t_s[sfb]+2) < tmp && sfb < 12) sfb++;
892       no_of_imdcts[0]=no_of_imdcts[1]=(ext->t_s[sfb]-1)/6+1; /* 18?????? */
893 
894     } else {
895 
896       /* long blocks now
897        */
898       tmp=ext->non_zero[1];
899       while (ext->is[1][tmp] == 0) tmp--;
900       sfb=0; while (ext->t_l[sfb] < tmp && sfb < 21) sfb++;
901       isbound[0]=isbound[1]=isbound[2]=ext->t_l[sfb]+1;
902       no_of_imdcts[0]=no_of_imdcts[1]=(ext->non_zero[0]-1)/18+1; /* left channel should have more elements here */
903     }
904     if (header->mode_extension==1) ms_flag=0;
905     else ms_flag=1;
906   } else {
907 
908     /* intensity stereo is, regretably, turned off
909      */
910     ms_flag=1;
911 
912     /* i really put a lot of work in this, but it still looks like shit (works, though)
913      */
914     if (!info->window_switching_flag[gr][0] || (info->window_switching_flag[gr][0] && info->block_type[gr][0]!=2))
915       isbound[0]=isbound[1]=isbound[2]=(max(ext->non_zero[0],ext->non_zero[1]));
916     else isbound[0]=isbound[1]=isbound[2]=576;
917 
918     if (info->window_switching_flag[gr][0] && info->block_type[gr][0]==2) {
919       /* should do for mixed blocks too, though i havent tested... */
920       tmp=(max(ext->non_zero[0],ext->non_zero[1]))/3;
921       sfb=0; while (ext->t_s[sfb]<tmp && sfb<12) sfb++;
922       no_of_imdcts[0]=no_of_imdcts[1]=(ext->t_s[sfb]-1)/6+1;
923     }
924     else no_of_imdcts[0]=no_of_imdcts[1]=(isbound[0]-1)/18+1;
925 
926   }
formantCmd(Sound * s,Tcl_Interp * interp,int objc,Tcl_Obj * CONST objv[])927 
928   return ms_flag;
929 }
930 
931 static void
932 stereo_s(mp3Info *ext, int l,float a[2],int pos,int ms_flag,int is_pos,struct AUDIO_HEADER *header)
933 {
934   float ftmp,Mi,Si;
935 
936   if (l>=576) {
937      if (debugLevel > 0) {
938         Snack_WriteLogInt("stereo_s: big value too big",l);
939      }
940      return; /* brrr... */
941   }
942 
943   if ((is_pos != IS_ILLEGAL) && (header->ID==1)) {
944     ftmp=FRAS2(ext->is[0][l],a[0]);
945     ext->xr[0][0][pos]=(1-t_is[is_pos])*ftmp;
946     ext->xr[1][0][pos]=t_is[is_pos]*ftmp;
947     return;
948   }
949 
950   if ((is_pos != IS_ILLEGAL) && (header->ID==0)) {
951     ftmp=FRAS2(ext->is[0][l],a[0]);
952     if (is_pos&1) {
953       ext->xr[0][0][pos]= t_is2[ext->intensity_scale][(is_pos+1)>>1] * ftmp;
954       ext->xr[1][0][pos]= ftmp;
955     } else {
956       ext->xr[0][0][pos]= ftmp;
957       ext->xr[1][0][pos]= t_is2[ext->intensity_scale][is_pos>>1] * ftmp;
958     }
959     return;
960   }
961 
962   if (ms_flag) {
963     Mi=FRAS2(ext->is[0][l],a[0]);
964     Si=FRAS2(ext->is[1][l],a[1]);
965     ext->xr[0][0][pos]=(float) ((Mi+Si)*i_sq2);
966     ext->xr[1][0][pos]=(float) ((Mi-Si)*i_sq2);
967   } else {
968     ext->xr[0][0][pos]=FRAS2(ext->is[0][l],a[0]);
969     ext->xr[1][0][pos]=FRAS2(ext->is[1][l],a[1]);
970   }
971 }
972 
973 static void
974 stereo_l(mp3Info *ext, int l,float a[2],int ms_flag,int is_pos,struct AUDIO_HEADER *header)
975 {
976   float ftmp,Mi,Si;
977   if (l>=576) {
978      if (debugLevel > 0) {
979         Snack_WriteLogInt("stereo_s: big value too big",l);
980      }
981      return;
982   }
983 
984   if ((is_pos != IS_ILLEGAL) && (header->ID==1)) {
985     ftmp=FRAS2(ext->is[0][l],a[0]);
986     ext->xr[0][0][l]=(1-t_is[is_pos])*ftmp;
987     ext->xr[1][0][l]=t_is[is_pos]*ftmp;
988     return;
989   }
990 
991   if ((is_pos != IS_ILLEGAL) && (header->ID==0)) {
992     ftmp=FRAS2(ext->is[0][l],a[0]);
993     if (is_pos&1) {
994       ext->xr[0][0][l]= t_is2[ext->intensity_scale][(is_pos+1)>>1] * ftmp;
995       ext->xr[1][0][l]= ftmp;
996     } else {
997       ext->xr[0][0][l]= ftmp;
998       ext->xr[1][0][l]= t_is2[ext->intensity_scale][is_pos>>1] * ftmp;
999     }
1000     return;
1001   }
1002 
1003   if (ms_flag) {
1004     Mi=FRAS2(ext->is[0][l],a[0]);
1005     Si=FRAS2(ext->is[1][l],a[1]);
1006     ext->xr[0][0][l]=(float) ((Mi+Si)*i_sq2);
1007     ext->xr[1][0][l]=(float) ((Mi-Si)*i_sq2);
1008   } else {
1009     ext->xr[0][0][l]=FRAS2(ext->is[0][l],a[0]);
1010     ext->xr[1][0][l]=FRAS2(ext->is[1][l],a[1]);
1011   }
1012 
1013 }
1014 /*
1015 #ifdef WIN
1016 #pragma optimize("", off)
1017 #endif
1018 */
1019 /* requantize_ms */
1020 
1021 static void
1022 requantize_ms(mp3Info *ext, int gr,struct SIDE_INFO *info,struct AUDIO_HEADER *header)
1023 {
1024   int l,sfb,ms_flag,is_pos,i,ch;
1025   int *global_gain,subblock_gain[2],*scalefac_scale,scalefac[2]={0,0},isbound[3];
1026   int sfreq=header->sampling_frequency;
1027   int id = header->ID;
1028   float a[2];
1029 
1030   global_gain=info->global_gain[gr];
1031   scalefac_scale=info->scalefac_scale[gr];
1032   if (info->window_switching_flag[gr][0] && info->block_type[gr][0]==2)
1033     if (info->mixed_block_flag[gr][0]) {
1034       /*
1035        * mixed blocks w/stereo processing - long block part ******************
1036        */
1037       int window,window_len;
1038       int preflag[2]={0,0};
1039 
1040       ms_flag=find_isbound(ext, isbound,gr,info,header);
1041 
1042       sfb=0; l=0;
1043       for (ch=0;ch<2;ch++) {
1044         scalefac[ch]=ext->scalefac_l[gr][ch][0];
1045         a[ch]=fras_l(0,global_gain[ch],scalefac_scale[ch],scalefac[ch],preflag[ch]);
1046       }
1047 
1048 
1049       while (l<36) {
1050         int is_pos;
1051         if (l<isbound[0]) is_pos=IS_ILLEGAL;
1052         else {
1053           is_pos=scalefac[1];
1054           if (id==1) { /* MPEG1 */
1055             if (is_pos==7) is_pos=IS_ILLEGAL;
1056             else /* MPEG2 */
1057               if (is_pos==ext->is_max[sfb]) is_pos=IS_ILLEGAL;
1058           }
1059         }
1060 
1061         stereo_l(ext, l,a,ms_flag,is_pos,header);
1062 
1063         if (l==ext->t_l[sfb]) {
1064           sfb++;
1065           for (ch=0;ch<2;ch++) {
1066             scalefac[ch]=ext->scalefac_l[gr][ch][sfb];
1067             a[ch]=fras_l(sfb,global_gain[ch],scalefac_scale[ch],scalefac[ch],preflag[ch]);
1068           }
1069         }
1070 
1071         l++;
1072       }
1073       /*
1074        * mixed blocks w/stereo processing - short block part *****************
1075        */
1076       sfb=3;
1077       window_len=ext->t_s[sfb]-ext->t_s[sfb-1];
1078 
1079       while (l<(max(ext->non_zero[0],ext->non_zero[1]))) {
1080         for (window=0;window<3;window++) {
1081           subblock_gain[0]=info->subblock_gain[gr][0][window];
1082           subblock_gain[1]=info->subblock_gain[gr][1][window];
1083           scalefac[0]=ext->scalefac_s[gr][0][sfb][window];
1084           scalefac[1]=ext->scalefac_s[gr][1][sfb][window];
1085 
1086           if (ext->t_s[sfb] < isbound[window]) {
1087             is_pos=IS_ILLEGAL;
1088             a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
1089             a[1]=fras_s(global_gain[1],subblock_gain[1],scalefac_scale[1],scalefac[1]);
1090           } else {
1091             is_pos=scalefac[1];
1092             if (id==1) { /* MPEG1 */
1093               if (is_pos==7) is_pos=IS_ILLEGAL;
1094               else /* MPEG2 */
1095                 if (is_pos==ext->is_max[sfb+6]) is_pos=IS_ILLEGAL;
1096             }
1097 
1098             a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
1099           }
1100 
1101           for (i=0;i<window_len && l < 576;i++) {
1102             stereo_s(ext, l,a,t_reorder[id][sfreq][l],ms_flag,is_pos,header);
1103             l++;
1104           }
1105         }
1106         sfb++;
1107         window_len=ext->t_s[sfb]-ext->t_s[sfb-1];
1108       }
1109       while (l<576) {
1110         int reorder = t_reorder[id][sfreq][l++];
1111         ext->xr[0][0][reorder]=ext->xr[1][0][reorder]=0;
1112       }
1113     } else {
1114       /*
1115        * requantize_ms - short blocks w/stereo processing ********************
1116        */
1117       int window,window_len;
1118 
1119       ms_flag=find_isbound(ext, isbound,gr,info,header);
1120       sfb=0; l=0;
1121       window_len=ext->t_s[0]+1;
1122 
1123       while (l<(max(ext->non_zero[0],ext->non_zero[1]))) {
1124         for (window=0;window<3;window++) {
1125           subblock_gain[0]=info->subblock_gain[gr][0][window];
1126           subblock_gain[1]=info->subblock_gain[gr][1][window];
1127 
1128           scalefac[0]=ext->scalefac_s[gr][0][sfb][window]&0x3F; /* clamp values to < 63 */
1129           scalefac[1]=ext->scalefac_s[gr][1][sfb][window]&0x3F;
1130 
1131           if (ext->t_s[sfb] < isbound[window]) {
1132             is_pos=IS_ILLEGAL;
1133             a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
1134             a[1]=fras_s(global_gain[1],subblock_gain[1],scalefac_scale[1],scalefac[1]);
1135           } else {
1136             is_pos=scalefac[1];
1137             if (id==1) { /* MPEG1 */
1138               if (is_pos==7) is_pos=IS_ILLEGAL;
1139               else /* MPEG2 */
1140                 if (is_pos==ext->is_max[sfb+6]) is_pos=IS_ILLEGAL;
1141             }
1142 
1143             a[0]=fras_s(global_gain[0],subblock_gain[0],scalefac_scale[0],scalefac[0]);
1144           }
1145 
1146           for (i=0;i<window_len && l < 576;i++) {
1147             stereo_s(ext, l,a,t_reorder[id][sfreq][l],ms_flag,is_pos,header);
1148             l++;
1149           }
1150         }
1151         window_len=-ext->t_s[sfb]+ext->t_s[sfb+1];
1152         sfb++;
1153       }
1154       while (l<576) {
1155         int reorder = t_reorder[id][sfreq][l++];
1156 
1157         ext->xr[0][0][reorder]=ext->xr[1][0][reorder]=0;
1158       }
1159     }
1160   else {
1161     /*
1162      * long blocks w/stereo processing *************************************
1163      */
1164     int *preflag=info->preflag[gr];
1165 
1166     ms_flag=find_isbound(ext, isbound,gr,info,header);
1167 
1168     sfb=0; l=0;
1169     scalefac[0]=ext->scalefac_l[gr][0][sfb];
1170     a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
1171     scalefac[1]=ext->scalefac_l[gr][1][sfb];
1172     a[1]=fras_l(sfb,global_gain[1],scalefac_scale[1],scalefac[1],preflag[1]);
1173     while (l< isbound[0]) {
1174       int is_pos=IS_ILLEGAL;
1175       stereo_l(ext, l,a,ms_flag,is_pos,header);
1176       if (l==ext->t_l[sfb]) {
1177         sfb++;
1178         scalefac[0]=ext->scalefac_l[gr][0][sfb];
1179         a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
1180         scalefac[1]=ext->scalefac_l[gr][1][sfb];
1181         a[1]=fras_l(sfb,global_gain[1],scalefac_scale[1],scalefac[1],preflag[1]);
1182       }
1183       l++;
1184     }
1185     while (l<(max(ext->non_zero[0],ext->non_zero[1]))) {
1186       int is_pos=scalefac[1];
1187       if (id==1) { /* MPEG1 */
1188         if (is_pos==7) is_pos=IS_ILLEGAL;
1189         else /* MPEG2 */
1190           if (is_pos==ext->is_max[sfb]) is_pos=IS_ILLEGAL;
1191       }
1192 
1193       stereo_l(ext, l,a,ms_flag,is_pos,header);
1194       if (l==ext->t_l[sfb]) {
1195         sfb++;
1196         scalefac[0]=ext->scalefac_l[gr][0][sfb];
1197         scalefac[1]=ext->scalefac_l[gr][1][sfb];
1198         a[0]=fras_l(sfb,global_gain[0],scalefac_scale[0],scalefac[0],preflag[0]);
1199       }
1200       l++;
1201     }
1202     while (l<576) {
1203       ext->xr[0][0][l]=0;
1204       ext->xr[1][0][l]=0;
1205       l++;
1206     }
1207   }
1208 }
1209 /*
1210 #ifdef WIN
1211 #pragma optimize("", on)
1212 #endif
1213 */
1214 /*
1215  * antialiasing butterflies
1216  *
1217  */
1218 static void
1219 alias_reduction(mp3Info *ext, int ch)
1220 {
1221   int sb,i;
1222 
1223   for (sb=1;sb<32;sb++) {
1224     float *x = ext->xr[ch][sb];
1225 
1226     for (i=0;i<8;i++) {
1227       float a = x[i];
1228       float b = x[-1-i];
1229       x[-1-i] = b * Cs[i] - a * Ca[i];
1230       x[i]    = a * Cs[i] + b * Ca[i];
1231     }
1232   }
1233 }
1234 
1235 /* huffman_decode() is supposed to be faster now
1236  * decodes one codeword and returns no. of bits
1237  */
1238 static int
1239 huffman_decode(int tbl,int *x,int *y)
1240 {
1241   unsigned int chunk;
1242   register unsigned int *h_tab;
1243   register unsigned int lag;
1244   register unsigned int half_lag;
1245   int len;
1246 
1247   h_tab=tables[tbl];
1248   chunk=viewbits(19);
1249 
1250   h_tab += h_cue[tbl][chunk >> (19-NC_O)];
1251 
1252   /* TFW: Errors in file can cause h_tab to be null,
1253      return immediatly with 0 len in this case */
1254   if (h_tab==0)
1255      return 0;
1256 
1257   len=(*h_tab>>8)&0x1f;
1258 
1259   /* check for an immediate hit, so we can decode those short codes very f
1260      ast
1261      */
1262   if ((*h_tab>>(32-len)) != (chunk>>(19-len))) {
1263     if (chunk >> (19-NC_O) < N_CUE-1)
1264       lag=(h_cue[tbl][(chunk >> (19-NC_O))+1] -
1265            h_cue[tbl][chunk >> (19-NC_O)]);
1266     else {
1267       /* we strongly depend on h_cue[N_CUE-1] to point to
1268        * the last entry in the huffman table, so we should
1269        * not get here anyway. if it didn't, we'd have to
1270        * have another table with huffman tables lengths, and
1271        * it would be a mess. just in case, scream&shout.
1272        */
1273       /*      printf(" h_cue clobbered. this is a bug. blip.\n");*/
1274       exit (-1);
1275     }
1276     chunk <<= 32-19;
1277     chunk |= 0x1ff;
1278 
1279     half_lag = lag >> 1;
1280 
1281     h_tab += half_lag;
1282     lag -= half_lag;
1283 
1284     while (lag > 1) {
1285       half_lag = lag >> 1;
1286 
1287       if (*h_tab < chunk)
1288         h_tab += half_lag;
1289       else
1290         h_tab -= half_lag;
1291 
1292       lag -= half_lag;
1293     }
1294 
1295     len=(*h_tab>>8)&0x1f;
1296     if ((*h_tab>>(32-len)) != (chunk>>(32-len))) {
1297       if (*h_tab > chunk)
1298         h_tab--;
1299       else
1300         h_tab++;
1301 
1302       len=(*h_tab>>8)&0x1f;
1303     }
1304   }
1305   sackbits(len);
1306   *x=(*h_tab>>4)&0xf;
1307   *y=*h_tab&0xf;
1308   return len;
1309 }
1310 
1311 #include <math.h>
1312 
1313 #define roundf(x) (floor((x)+(float )0.5f))
1314 #define PI12      0.261799387f
1315 #define PI36      0.087266462f
1316 #define COSPI3    0.500000000f
1317 #define COSPI6    0.866025403f
1318 #define DCTODD1   0.984807753f
1319 #define DCTODD2  -0.342020143f
1320 #define DCTODD3  -0.642787609f
1321 #define DCTEVEN1  0.939692620f
1322 #define DCTEVEN2 -0.173648177f
1323 #define DCTEVEN3 -0.766044443f
1324 
1325 static void
1326 imdct_init()
1327 {
1328   int i;
1329 
1330   for(i=0;i<36;i++) /* 0 */
1331     win[0][i] = (float) sin(PI36 *(i+0.5));
1332   for(i=0;i<18;i++) /* 1 */
1333     win[1][i] = (float) sin(PI36 *(i+0.5));
1334   for(i=18;i<24;i++)
1335     win[1][i] = 1.0f;
1336   for(i=24;i<30;i++)
1337     win[1][i] = (float) sin(PI12 *(i+0.5-18));
1338   for(i=30;i<36;i++)
1339     win[1][i] = 0.0f;
1340   for(i=0;i<6;i++) /* 3 */
1341     win[3][i] = 0.0f;
1342   for(i=6;i<12;i++)
1343     win[3][i] = (float) sin(PI12 * (i+ 0.5 - 6.0));
1344   for(i=12;i<18;i++)
1345     win[3][i] = 1.0f;
1346   for(i=18;i<36;i++)
1347     win[3][i] = (float) sin(PI36 * (i + 0.5));
1348 }
1349 
1350 /*
1351 This uses Byeong Gi Lee's Fast Cosine Transform algorithm to
1352 decompose the 36 point and 12 point IDCT's into 9 point and 3
1353 point IDCT's, respectively. Then the 9 point IDCT is computed
1354 by a modified version of Mikko Tommila's IDCT algorithm, based on
1355 the WFTA. See his comments before the first 9 point IDCT. The 3
1356 point IDCT is already efficient to implement. -- Jeff Tsay. */
1357 
1358 void imdct(mp3Info *ext,int win_type,int sb,int ch) {
1359   /*------------------------------------------------------------------*/
1360   /*                                                                  */
1361   /*    Function: Calculation of the inverse MDCT                     */
1362   /*    In the case of short blocks the 3 output vectors are already  */
1363   /*    overlapped and added in this modul.                           */
1364   /*                                                                  */
1365   /*    New layer3                                                    */
1366   /*                                                                  */
1367   /*------------------------------------------------------------------*/
1368 
1369    float    tmp[18], save, sum;
1370    float  pp1, pp2;
1371    float   *win_bt;
1372    int     i, p, ss;
1373    float *in = ext->xr[ch][sb];
1374    float out[36];
1375 
1376    if (win_type == 2) {
1377       for (p=0;p<36;p+=9) {
1378          out[p]   = out[p+1] = out[p+2] = out[p+3] =
1379                                           out[p+4] = out[p+5] = out[p+6] = out[p+7] =
1380                                                                            out[p+8] = 0.0f;
1381       }
1382 
1383       for (ss=0;ss<18;ss+=6) {
1384 
1385       /*
1386        *  12 point IMDCT
1387        */
1388 
1389       /* Begin 12 point IDCT */
1390 
1391       /* Input aliasing for 12 pt IDCT*/
1392          in[5+ss]+=in[4+ss];in[4+ss]+=in[3+ss];in[3+ss]+=in[2+ss];
1393          in[2+ss]+=in[1+ss];in[1+ss]+=in[0+ss];
1394 
1395                                       /* Input aliasing on odd indices (for 6 point IDCT) */
1396          in[5+ss] += in[3+ss];  in[3+ss]  += in[1+ss];
1397 
1398                                            /* 3 point IDCT on even indices */
1399 
1400          pp2 = in[4+ss] * 0.500000000f;
1401          pp1 = in[2+ss] * 0.866025403f;
1402          sum = in[0+ss] + pp2;
1403          tmp[1]= in[0+ss] - in[4+ss];
1404          tmp[0]= sum + pp1;
1405          tmp[2]= sum - pp1;
1406 
1407                                            /* End 3 point IDCT on even indices */
1408 
1409                                            /* 3 point IDCT on odd indices (for 6 point IDCT) */
1410 
1411          pp2 = in[5+ss] * 0.500000000f;
1412          pp1 = in[3+ss] * 0.866025403f;
1413          sum = in[1+ss] + pp2;
1414          tmp[4] = in[1+ss] - in[5+ss];
1415          tmp[5] = sum + pp1;
1416          tmp[3] = sum - pp1;
1417 
1418                                            /* End 3 point IDCT on odd indices*/
1419 
1420                                            /* Twiddle factors on odd indices (for 6 point IDCT)*/
1421 
1422          tmp[3] *= 1.931851653f;
1423          tmp[4] *= 0.707106781f;
1424          tmp[5] *= 0.517638090f;
1425 
1426                                            /* Output butterflies on 2 3 point IDCT's (for 6 point IDCT)*/
1427 
1428          save = tmp[0];
1429          tmp[0] += tmp[5];
1430          tmp[5] = save - tmp[5];
1431          save = tmp[1];
1432          tmp[1] += tmp[4];
1433          tmp[4] = save - tmp[4];
1434          save = tmp[2];
1435          tmp[2] += tmp[3];
1436          tmp[3] = save - tmp[3];
1437 
1438 /* End 6 point IDCT */
1439 
1440 /* Twiddle factors on indices (for 12 point IDCT) */
1441 
1442          tmp[0]  *=  0.504314480f;
1443          tmp[1]  *=  0.541196100f;
1444          tmp[2]  *=  0.630236207f;
1445          tmp[3]  *=  0.821339815f;
1446          tmp[4]  *=  1.306562965f;
1447          tmp[5]  *=  3.830648788f;
1448 
1449 /* End 12 point IDCT */
1450 
1451 /* Shift to 12 point modified IDCT, multiply by window type 2 */
1452          tmp[8]  = -tmp[0] * 0.793353340f;
1453          tmp[9]  = -tmp[0] * 0.608761429f;
1454          tmp[7]  = -tmp[1] * 0.923879532f;
1455          tmp[10] = -tmp[1] * 0.382683432f;
1456          tmp[6]  = -tmp[2] * 0.991444861f;
1457          tmp[11] = -tmp[2] * 0.130526192f;
1458 
1459          tmp[0]  =  tmp[3];
1460          tmp[1]  =  tmp[4] * 0.382683432f;
1461          tmp[2]  =  tmp[5] * 0.608761429f;
1462 
1463          tmp[3]  = -tmp[5] * 0.793353340f;
1464          tmp[4]  = -tmp[4] * 0.923879532f;
1465          tmp[5]  = -tmp[0] * 0.991444861f;
1466 
1467          tmp[0] *= 0.130526192f;
1468 
1469          out[ss + 6]  += tmp[0];
1470          out[ss + 7]  += tmp[1];
1471          out[ss + 8]  += tmp[2];
1472          out[ss + 9]  += tmp[3];
1473          out[ss + 10] += tmp[4];
1474          out[ss + 11] += tmp[5];
1475          out[ss + 12] += tmp[6];
1476          out[ss + 13] += tmp[7];
1477          out[ss + 14] += tmp[8];
1478          out[ss + 15] += tmp[9];
1479          out[ss + 16] += tmp[10];
1480          out[ss + 17] += tmp[11];
1481 
1482       }
1483       for (i=0;i<18;i++) ext->res[sb][i]=out[i] + ext->s[ch][sb][i];
1484       for (;i<36;i++) ext->s[ch][sb][i-18]=out[i];
1485 
1486    } else {
1487 
1488   /* 36 point IDCT */
1489 
1490   /* input aliasing for 36 point IDCT */
1491       in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14]; in[14]+=in[13];
1492       in[13]+=in[12]; in[12]+=in[11]; in[11]+=in[10]; in[10]+=in[9];
1493       in[9] +=in[8];  in[8] +=in[7];  in[7] +=in[6];  in[6] +=in[5];
1494       in[5] +=in[4];  in[4] +=in[3];  in[3] +=in[2];  in[2] +=in[1];
1495       in[1] +=in[0];
1496 
1497 /* 18 point IDCT for odd indices */
1498 
1499 /* input aliasing for 18 point IDCT */
1500       in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
1501       in[9] +=in[7];  in[7] +=in[5];  in[5] +=in[3];  in[3] +=in[1];
1502 
1503 /* 9 point IDCT on even indices */
1504 
1505 /* original: */
1506 
1507 /*   for(i=0; i<9; i++) {
1508 sum = 0.0;
1509 
1510 for(j=0;j<18;j+=2)
1511 sum += in[j] * cos(PI36 * (2*i + 1) * j);
1512 
1513 tmp[i] = sum;
1514 } */
1515 
1516 /* 9 Point Inverse Discrete Cosine Transform
1517 //
1518 // This piece of code is Copyright 1997 Mikko Tommila and is freely usable
1519 // by anybody. The algorithm itself is of course in the public domain.
1520 //
1521 // Again derived heuristically from the 9-point WFTA.
1522 //
1523 // The algorithm is optimized (?) for speed, not for small rounding errors or
1524 // good readability.
1525 //
1526 // 36 additions, 11 multiplications
1527 //
1528 // Again this is very likely sub-optimal.
1529 //
1530 // The code is optimized to use a minimum number of temporary variables,
1531 // so it should compile quite well even on 8-register Intel x86 processors.
1532 // This makes the code quite obfuscated and very difficult to understand.
1533 //
1534 // References:
1535 // [1] S. Winograd: "On Computing the Discrete Fourier Transform",
1536 //     Mathematics of Computation, Volume 32, Number 141, January 1978,
1537 //     Pages 175-199
1538 
1539    Some modifications for maplay by Jeff Tsay */
1540       {
1541          float t0, t1, t2, t3, t4, t5, t6, t7;
1542 
1543          t1 = COSPI3 * in[12];
1544          t2 = COSPI3 * (in[8] + in[16] - in[4]);
1545 
1546          t3 = in[0] + t1;
1547          t4 = in[0] - t1 - t1;
1548          t5 = t4 - t2;
1549 
1550          t0 = DCTEVEN1 * (in[4] + in[8]);
1551          t1 = DCTEVEN2 * (in[8] - in[16]);
1552 
1553          tmp[4] = t4 + t2 + t2;
1554          t2 = DCTEVEN3 * (in[4] + in[16]);
1555 
1556          t6 = t3 - t0 - t2;
1557          t0 += t3 + t1;
1558          t3 += t2 - t1;
1559 
1560          t2 = DCTODD1 * (in[2]  + in[10]);
1561          t4 = DCTODD2 * (in[10] - in[14]);
1562          t7 = COSPI6 * in[6];
1563 
1564          t1 = t2 + t4 + t7;
1565          tmp[0] = t0 + t1;
1566          tmp[8] = t0 - t1;
1567          t1 = DCTODD3 * (in[2] + in[14]);
1568          t2 += t1 - t7;
1569 
1570          tmp[3] = t3 + t2;
1571          t0 = COSPI6 * (in[10] + in[14] - in[2]);
1572          tmp[5] = t3 - t2;
1573 
1574          t4 -= t1 + t7;
1575 
1576          tmp[1] = t5 - t0;
1577          tmp[7] = t5 + t0;
1578          tmp[2] = t6 + t4;
1579          tmp[6] = t6 - t4;
1580       }
1581 
1582 /* End 9 point IDCT on even indices*/
1583 
1584     /* original:*/
1585 /*   for(i=0; i<9; i++) {
1586        sum = 0.0;
1587        for(j=0;j<18;j+=2)
1588          sum += in[j+1] * cos(PI36 * (2*i + 1) * j);
1589        tmp[17-i] = sum;
1590    } */
1591 
1592 /* This includes multiplication by the twiddle factors
1593    at the end -- Jeff.*/
1594       {
1595          float t0, t1, t2, t3, t4, t5, t6, t7;
1596 
1597          t1 = COSPI3 * in[13];
1598          t2 = COSPI3 * (in[9] + in[17] - in[5]);
1599 
1600          t3 = in[1] + t1;
1601          t4 = in[1] - t1 - t1;
1602          t5 = t4 - t2;
1603 
1604          t0 = DCTEVEN1 * (in[5] + in[9]);
1605          t1 = DCTEVEN2 * (in[9] - in[17]);
1606 
1607          tmp[13] = (t4 + t2 + t2)*0.707106781f;
1608          t2 = DCTEVEN3 * (in[5] + in[17]);
1609 
1610          t6 = t3 - t0 - t2;
1611          t0 += t3 + t1;
1612          t3 += t2 - t1;
1613 
1614          t2 = DCTODD1 * (in[3]  + in[11]);
1615          t4 = DCTODD2 * (in[11] - in[15]);
1616          t7 = COSPI6  * in[7];
1617 
1618          t1 = t2 + t4 + t7;
1619          tmp[17] = (t0 + t1) * 0.501909918f;
1620          tmp[9]  = (t0 - t1) * 5.736856623f;
1621          t1 = DCTODD3 * (in[3] + in[15]);
1622          t2 += t1 - t7;
1623 
1624          tmp[14] = (t3 + t2) * 0.610387294f;
1625          t0 = COSPI6 * (in[11] + in[15] - in[3]);
1626          tmp[12] = (t3 - t2) * 0.871723397f;
1627 
1628          t4 -= t1 + t7;
1629 
1630          tmp[16] = (t5 - t0) * 0.517638090f;
1631          tmp[10] = (t5 + t0) * 1.931851653f;
1632          tmp[15] = (t6 + t4) * 0.551688959f;
1633          tmp[11] = (t6 - t4) * 1.183100792f;
1634       }
1635 
1636 /* End 9 point IDCT on odd indices */
1637 
1638 /* Butterflies on 9 point IDCT's */
1639       for (i=0;i<9;i++) {
1640          save = tmp[i];
1641          tmp[i] += tmp[17-i];
1642          tmp[17-i] = save - tmp[17-i];
1643       }
1644 /* end 18 point IDCT */
1645 
1646 /* twiddle factors for 36 point IDCT */
1647 
1648       tmp[0] *=  -0.500476342f;
1649       tmp[1] *=  -0.504314480f;
1650       tmp[2] *=  -0.512139757f;
1651       tmp[3] *=  -0.524264562f;
1652       tmp[4] *=  -0.541196100f;
1653       tmp[5] *=  -0.563690973f;
1654       tmp[6] *=  -0.592844523f;
1655       tmp[7] *=  -0.630236207f;
1656       tmp[8] *=  -0.678170852f;
1657       tmp[9] *=  -0.740093616f;
1658       tmp[10]*=  -0.821339815f;
1659       tmp[11]*=  -0.930579498f;
1660       tmp[12]*=  -1.082840285f;
1661       tmp[13]*=  -1.306562965f;
1662       tmp[14]*=  -1.662754762f;
1663       tmp[15]*=  -2.310113158f;
1664       tmp[16]*=  -3.830648788f;
1665       tmp[17]*= -11.46279281f;
1666 
1667 /* end 36 point IDCT */
1668 
1669 /* shift to modified IDCT */
1670       win_bt = win[win_type];
1671 
1672       ext->res[sb][0] =-tmp[9]  * win_bt[0] + ext->s[ch][sb][0];
1673       ext->res[sb][1] =-tmp[10] * win_bt[1] + ext->s[ch][sb][1];
1674       ext->res[sb][2] =-tmp[11] * win_bt[2] + ext->s[ch][sb][2];
1675       ext->res[sb][3] =-tmp[12] * win_bt[3] + ext->s[ch][sb][3];
1676       ext->res[sb][4] =-tmp[13] * win_bt[4] + ext->s[ch][sb][4];
1677       ext->res[sb][5] =-tmp[14] * win_bt[5] + ext->s[ch][sb][5];
1678       ext->res[sb][6] =-tmp[15] * win_bt[6] + ext->s[ch][sb][6];
1679       ext->res[sb][7] =-tmp[16] * win_bt[7] + ext->s[ch][sb][7];
1680       ext->res[sb][8] =-tmp[17] * win_bt[8] + ext->s[ch][sb][8];
1681 
1682       ext->res[sb][9] = tmp[17] * win_bt[9] + ext->s[ch][sb][9];
1683       ext->res[sb][10]= tmp[16] * win_bt[10] + ext->s[ch][sb][10];
1684       ext->res[sb][11]= tmp[15] * win_bt[11] + ext->s[ch][sb][11];
1685       ext->res[sb][12]= tmp[14] * win_bt[12] + ext->s[ch][sb][12];
1686       ext->res[sb][13]= tmp[13] * win_bt[13] + ext->s[ch][sb][13];
1687       ext->res[sb][14]= tmp[12] * win_bt[14] + ext->s[ch][sb][14];
1688       ext->res[sb][15]= tmp[11] * win_bt[15] + ext->s[ch][sb][15];
1689       ext->res[sb][16]= tmp[10] * win_bt[16] + ext->s[ch][sb][16];
1690       ext->res[sb][17]= tmp[9]  * win_bt[17] + ext->s[ch][sb][17];
1691 
1692 
1693       ext->s[ch][sb][0]= tmp[8]  * win_bt[18];
1694       ext->s[ch][sb][1]= tmp[7]  * win_bt[19];
1695       ext->s[ch][sb][2]= tmp[6]  * win_bt[20];
1696       ext->s[ch][sb][3]= tmp[5]  * win_bt[21];
1697       ext->s[ch][sb][4]= tmp[4]  * win_bt[22];
1698       ext->s[ch][sb][5]= tmp[3]  * win_bt[23];
1699       ext->s[ch][sb][6]= tmp[2]  * win_bt[24];
1700       ext->s[ch][sb][7]= tmp[1]  * win_bt[25];
1701       ext->s[ch][sb][8]= tmp[0]  * win_bt[26];
1702 
1703       ext->s[ch][sb][9]= tmp[0]  * win_bt[27];
1704       ext->s[ch][sb][10]= tmp[1]  * win_bt[28];
1705       ext->s[ch][sb][11]= tmp[2]  * win_bt[29];
1706       ext->s[ch][sb][12]= tmp[3]  * win_bt[30];
1707       ext->s[ch][sb][13]= tmp[4]  * win_bt[31];
1708       ext->s[ch][sb][14]= tmp[5]  * win_bt[32];
1709       ext->s[ch][sb][15]= tmp[6]  * win_bt[33];
1710       ext->s[ch][sb][16]= tmp[7]  * win_bt[34];
1711       ext->s[ch][sb][17]= tmp[8]  * win_bt[35];
1712    }
1713 
1714    if (sb&1) for (i=1;i<18;i+=2) ext->res[sb][i]=-ext->res[sb][i];
1715 }
1716 
1717 /* fast DCT according to Lee[84]
1718  * reordering according to Konstantinides[94]
1719  */
1720 void poly(mp3Info* ext, const int ch,int f) {
1721    float c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15;
1722    float c16,c17,c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31;
1723    float d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15;
1724    float d16,d17,d18,d19,d20,d21,d22,d23,d24,d25,d26,d27,d28,d29,d30,d31;
1725    int start = ext->u_start[ch];
1726    int div = ext->u_div[ch];
1727    int nch = ext->nch;
1728    float (*u_p)[16];
1729 
1730 /* step 1: initial reordering and 1st (16 wide) butterflies
1731  */
1732 
1733    d0 =ext->res[ 0][f]; d16=(d0  - ext->res[31][f]) *  b1; d0 += ext->res[31][f];
1734    d1 =ext->res[ 1][f]; d17=(d1  - ext->res[30][f]) *  b3; d1 += ext->res[30][f];
1735    d3 =ext->res[ 2][f]; d19=(d3  - ext->res[29][f]) *  b5; d3 += ext->res[29][f];
1736    d2 =ext->res[ 3][f]; d18=(d2  - ext->res[28][f]) *  b7; d2 += ext->res[28][f];
1737    d6 =ext->res[ 4][f]; d22=(d6  - ext->res[27][f]) *  b9; d6 += ext->res[27][f];
1738    d7 =ext->res[ 5][f]; d23=(d7  - ext->res[26][f]) * b11; d7 += ext->res[26][f];
1739    d5 =ext->res[ 6][f]; d21=(d5  - ext->res[25][f]) * b13; d5 += ext->res[25][f];
1740    d4 =ext->res[ 7][f]; d20=(d4  - ext->res[24][f]) * b15; d4 += ext->res[24][f];
1741    d12=ext->res[ 8][f]; d28=(d12 - ext->res[23][f]) * b17; d12+= ext->res[23][f];
1742    d13=ext->res[ 9][f]; d29=(d13 - ext->res[22][f]) * b19; d13+= ext->res[22][f];
1743    d15=ext->res[10][f]; d31=(d15 - ext->res[21][f]) * b21; d15+= ext->res[21][f];
1744    d14=ext->res[11][f]; d30=(d14 - ext->res[20][f]) * b23; d14+= ext->res[20][f];
1745    d10=ext->res[12][f]; d26=(d10 - ext->res[19][f]) * b25; d10+= ext->res[19][f];
1746    d11=ext->res[13][f]; d27=(d11 - ext->res[18][f]) * b27; d11+= ext->res[18][f];
1747    d9 =ext->res[14][f]; d25=(d9  - ext->res[17][f]) * b29; d9 += ext->res[17][f];
1748    d8 =ext->res[15][f]; d24=(d8  - ext->res[16][f]) * b31; d8 += ext->res[16][f];
1749 
1750 /* step 2: 8-wide butterflies
1751  */
1752    c0 = d0 + d8 ; c8 = ( d0 - d8 ) *  b2;
1753    c1 = d1 + d9 ; c9 = ( d1 - d9 ) *  b6;
1754    c2 = d2 + d10; c10= ( d2 - d10) * b14;
1755    c3 = d3 + d11; c11= ( d3 - d11) * b10;
1756    c4 = d4 + d12; c12= ( d4 - d12) * b30;
1757    c5 = d5 + d13; c13= ( d5 - d13) * b26;
1758    c6 = d6 + d14; c14= ( d6 - d14) * b18;
1759    c7 = d7 + d15; c15= ( d7 - d15) * b22;
1760 
1761    c16=d16 + d24; c24= (d16 - d24) *  b2;
1762    c17=d17 + d25; c25= (d17 - d25) *  b6;
1763    c18=d18 + d26; c26= (d18 - d26) * b14;
1764    c19=d19 + d27; c27= (d19 - d27) * b10;
1765    c20=d20 + d28; c28= (d20 - d28) * b30;
1766    c21=d21 + d29; c29= (d21 - d29) * b26;
1767    c22=d22 + d30; c30= (d22 - d30) * b18;
1768    c23=d23 + d31; c31= (d23 - d31) * b22;
1769 
1770 /* step 3: 4-wide butterflies
1771  */
1772    d0 = c0 + c4 ; d4 = ( c0 - c4 ) *  b4;
1773    d1 = c1 + c5 ; d5 = ( c1 - c5 ) * b12;
1774    d2 = c2 + c6 ; d6 = ( c2 - c6 ) * b28;
1775    d3 = c3 + c7 ; d7 = ( c3 - c7 ) * b20;
1776 
1777    d8 = c8 + c12; d12= ( c8 - c12) *  b4;
1778    d9 = c9 + c13; d13= ( c9 - c13) * b12;
1779    d10= c10+ c14; d14= (c10 - c14) * b28;
1780    d11= c11+ c15; d15= (c11 - c15) * b20;
1781 
1782    d16= c16+ c20; d20= (c16 - c20) *  b4;
1783    d17= c17+ c21; d21= (c17 - c21) * b12;
1784    d18= c18+ c22; d22= (c18 - c22) * b28;
1785    d19= c19+ c23; d23= (c19 - c23) * b20;
1786 
1787    d24= c24+ c28; d28= (c24 - c28) *  b4;
1788    d25= c25+ c29; d29= (c25 - c29) * b12;
1789    d26= c26+ c30; d30= (c26 - c30) * b28;
1790    d27= c27+ c31; d31= (c27 - c31) * b20;
1791 
1792 /* step 4: 2-wide butterflies
1793  */
1794 /**/    c0 = d0 + d2 ; c2 = ( d0 - d2 ) *  b8;
1795    c1 = d1 + d3 ; c3 = ( d1 - d3 ) * b24;
1796 /**/    c4 = d4 + d6 ; c6 = ( d4 - d6 ) *  b8;
1797    c5 = d5 + d7 ; c7 = ( d5 - d7 ) * b24;
1798 /**/    c8 = d8 + d10; c10= ( d8 - d10) *  b8;
1799    c9 = d9 + d11; c11= ( d9 - d11) * b24;
1800 /**/    c12= d12+ d14; c14= (d12 - d14) *  b8;
1801    c13= d13+ d15; c15= (d13 - d15) * b24;
1802 /**/    c16= d16+ d18; c18= (d16 - d18) *  b8;
1803    c17= d17+ d19; c19= (d17 - d19) * b24;
1804 /**/    c20= d20+ d22; c22= (d20 - d22) *  b8;
1805    c21= d21+ d23; c23= (d21 - d23) * b24;
1806 /**/    c24= d24+ d26; c26= (d24 - d26) *  b8;
1807    c25= d25+ d27; c27= (d25 - d27) * b24;
1808 /**/    c28= d28+ d30; c30= (d28 - d30) *  b8;
1809    c29= d29+ d31; c31= (d29 - d31) * b24;
1810 
1811 /* step 5: 1-wide butterflies
1812  */
1813    d0 = c0 + c1 ; d1 = ( c0 - c1 ) * b16;
1814    d2 = c2 + c3 ; d3 = ( c2 - c3 ) * b16;
1815    d4 = c4 + c5 ; d5 = ( c4 - c5 ) * b16;
1816    d6 = c6 + c7 ; d7 = ( c6 - c7 ) * b16;
1817    d8 = c8 + c9 ; d9 = ( c8 - c9 ) * b16;
1818    d10= c10+ c11; d11= (c10 - c11) * b16;
1819    d12= c12+ c13; d13= (c12 - c13) * b16;
1820    d14= c14+ c15; d15= (c14 - c15) * b16;
1821    d16= c16+ c17; d17= (c16 - c17) * b16;
1822    d18= c18+ c19; d19= (c18 - c19) * b16;
1823    d20= c20+ c21; d21= (c20 - c21) * b16;
1824    d22= c22+ c23; d23= (c22 - c23) * b16;
1825    d24= c24+ c25; d25= (c24 - c25) * b16;
1826    d26= c26+ c27; d27= (c26 - c27) * b16;
1827    d28= c28+ c29; d29= (c28 - c29) * b16;
1828    d30= c30+ c31; d31= (c30 - c31) * b16;
1829 
1830 /* step 6: final resolving & reordering
1831  * the other 32 are stored for use with the next granule
1832  */
1833 
1834    u_p = (float (*)[16]) &ext->u[ch][div][0][start];
1835 
1836 /*16*/                 u_p[0][0] =+d1 ;
1837    u_p[31][0] = -(u_p[1][0] =+d16 +d17 +d18 +d22 -d30);
1838    u_p[30][0] = -(u_p[2][0] =+d8 +d9 +d10 -d14);
1839    u_p[29][0] = -(u_p[3][0] =-d16 -d17 -d18 -d22 +d24 +d25 +d26);
1840 /*20*/  u_p[28][0] = -(u_p[4][0] =+d4 +d5 -d6);
1841    u_p[27][0] = -(u_p[5][0] =+d16 +d17 +d18 +d20 +d21 -d24 -d25 -d26);
1842    u_p[26][0] = -(u_p[6][0] =-d8 -d9 -d10 +d12 +d13);
1843    u_p[25][0] = -(u_p[7][0] =-d16 -d17 -d18 -d20 -d21 +d28 +d29);
1844 /*24*/  u_p[24][0] = -(u_p[8][0] =-d2 +d3);
1845    u_p[23][0] = -(u_p[9][0] =+d16 +d17 +d19 +d20 +d21 -d28 -d29);
1846    u_p[22][0] = -(u_p[10][0] =+d8 +d9 +d11 -d12 -d13);
1847    u_p[21][0] = -(u_p[11][0] =-d16 -d17 -d19 -d20 -d21 +d24 +d25 +d27);
1848 /*28*/  u_p[20][0] = -(u_p[12][0] =-d4 -d5 +d7);
1849    u_p[19][0] = -(u_p[13][0] =+d16 +d17 +d19 +d23 -d24 -d25 -d27);
1850    u_p[18][0] = -(u_p[14][0] =-d8 -d9 -d11 +d15);
1851    u_p[17][0] = -(u_p[15][0]   =-d16 -d17 -d19 -d23 +d31);
1852    u_p[16][0] = 0.0f;
1853 
1854 /* the other 32 are stored for use with the next granule
1855  */
1856 
1857    u_p = (float (*)[16]) &ext->u[ch][!div][0][start];
1858 
1859 /*0*/   u_p[16][0] = -2*d0;
1860    u_p[15][0] = u_p[17][0] = -(+d16 );
1861    u_p[14][0] = u_p[18][0] = -(+d8 );
1862    u_p[13][0] = u_p[19][0] = -(-d16 +d24 );
1863 /*4*/   u_p[12][0] = u_p[20][0] = -(+d4 );
1864    u_p[11][0] = u_p[21][0] = -(+d16 +d20 -d24 );
1865    u_p[10][0] = u_p[22][0] = -(-d8 +d12 );
1866    u_p[9][0] = u_p[23][0] = -(-d16 -d20 +d28 );
1867 /*8*/   u_p[8][0] = u_p[24][0] = -(+d2 );
1868    u_p[7][0] = u_p[25][0] = -(+d16 +d18 +d20 -d28 );
1869    u_p[6][0] = u_p[26][0] = -(+d8 +d10 -d12 );
1870    u_p[5][0] = u_p[27][0] = -(-d16 -d18 -d20 +d24 +d26 );
1871 /*12*/  u_p[4][0] = u_p[28][0] = -(-d4 +d6 );
1872    u_p[3][0] = u_p[29][0] = -(+d16 +d18 +d22 -d24 -d26 );
1873    u_p[2][0] = u_p[30][0] = -(-d8 -d10 +d14 );
1874    u_p[1][0] = u_p[31][0] = -(-d16 -d18 -d22 +d30 );
1875    u_p[0][0] = -d1;
1876 
1877 
1878 /* we're doing dewindowing and calculating final samples now
1879  */
1880 
1881    {
1882       int j;
1883       float out;
1884       float *dewindow = (float*) t_dewindow;
1885       float *u_ptr;
1886 
1887       u_p = ext->u[ch][div];
1888 
1889       if (nch == 2) {
1890 
1891          fool_opt = (int) u_p;
1892 
1893          switch (start) {
1894 #if !defined(MEDIUM_STEREO_CACHE) && !defined(SMALL_STEREO_CACHE)
1895             case 0:
1896                u_ptr = (float *) u_p;
1897 
1898                for (j=0;j<32;j++) {
1899                   out  = *u_ptr++ * *dewindow++;
1900                   out += *u_ptr++ * *dewindow++;
1901                   out += *u_ptr++ * *dewindow++;
1902                   out += *u_ptr++ * *dewindow++;
1903                   out += *u_ptr++ * *dewindow++;
1904                   out += *u_ptr++ * *dewindow++;
1905                   out += *u_ptr++ * *dewindow++;
1906                   out += *u_ptr++ * *dewindow++;
1907                   out += *u_ptr++ * *dewindow++;
1908                   out += *u_ptr++ * *dewindow++;
1909                   out += *u_ptr++ * *dewindow++;
1910                   out += *u_ptr++ * *dewindow++;
1911                   out += *u_ptr++ * *dewindow++;
1912                   out += *u_ptr++ * *dewindow++;
1913                   out += *u_ptr++ * *dewindow++;
1914                   out += *u_ptr++ * *dewindow++;
1915 
1916                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
1917                }
1918                break;
1919 
1920             case 1:
1921                for (j=0;j<32;j++) {
1922                   u_ptr = u_p[j];
1923 
1924                   out  = u_ptr[1] * *dewindow++;
1925                   out += u_ptr[2] * *dewindow++;
1926                   out += u_ptr[3] * *dewindow++;
1927                   out += u_ptr[4] * *dewindow++;
1928                   out += u_ptr[5] * *dewindow++;
1929                   out += u_ptr[6] * *dewindow++;
1930                   out += u_ptr[7] * *dewindow++;
1931                   out += u_ptr[8] * *dewindow++;
1932                   out += u_ptr[9] * *dewindow++;
1933                   out += u_ptr[10] * *dewindow++;
1934                   out += u_ptr[11] * *dewindow++;
1935                   out += u_ptr[12] * *dewindow++;
1936                   out += u_ptr[13] * *dewindow++;
1937                   out += u_ptr[14] * *dewindow++;
1938                   out += u_ptr[15] * *dewindow++;
1939                   out += u_ptr[0] * *dewindow++;
1940 
1941                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ?-32768.0f : out;*/
1942                }
1943                break;
1944 
1945             case 2:
1946                for (j=0;j<32;j++) {
1947                   u_ptr = u_p[j];
1948 
1949                   out  = u_ptr[2] * *dewindow++;
1950                   out += u_ptr[3] * *dewindow++;
1951                   out += u_ptr[4] * *dewindow++;
1952                   out += u_ptr[5] * *dewindow++;
1953                   out += u_ptr[6] * *dewindow++;
1954                   out += u_ptr[7] * *dewindow++;
1955                   out += u_ptr[8] * *dewindow++;
1956                   out += u_ptr[9] * *dewindow++;
1957                   out += u_ptr[10] * *dewindow++;
1958                   out += u_ptr[11] * *dewindow++;
1959                   out += u_ptr[12] * *dewindow++;
1960                   out += u_ptr[13] * *dewindow++;
1961                   out += u_ptr[14] * *dewindow++;
1962                   out += u_ptr[15] * *dewindow++;
1963                   out += u_ptr[0] * *dewindow++;
1964                   out += u_ptr[1] * *dewindow++;
1965 
1966                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
1967                }
1968                break;
1969 
1970             case 3:
1971                for (j=0;j<32;j++) {
1972                   u_ptr = u_p[j];
1973 
1974                   out  = u_ptr[3] * *dewindow++;
1975                   out += u_ptr[4] * *dewindow++;
1976                   out += u_ptr[5] * *dewindow++;
1977                   out += u_ptr[6] * *dewindow++;
1978                   out += u_ptr[7] * *dewindow++;
1979                   out += u_ptr[8] * *dewindow++;
1980                   out += u_ptr[9] * *dewindow++;
1981                   out += u_ptr[10] * *dewindow++;
1982                   out += u_ptr[11] * *dewindow++;
1983                   out += u_ptr[12] * *dewindow++;
1984                   out += u_ptr[13] * *dewindow++;
1985                   out += u_ptr[14] * *dewindow++;
1986                   out += u_ptr[15] * *dewindow++;
1987                   out += u_ptr[0] * *dewindow++;
1988                   out += u_ptr[1] * *dewindow++;
1989                   out += u_ptr[2] * *dewindow++;
1990 
1991                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
1992                }
1993                break;
1994 
1995             case 4:
1996                for (j=0;j<32;j++) {
1997                   u_ptr = u_p[j];
1998 
1999                   out  = u_ptr[4] * *dewindow++;
2000                   out += u_ptr[5] * *dewindow++;
2001                   out += u_ptr[6] * *dewindow++;
2002                   out += u_ptr[7] * *dewindow++;
2003                   out += u_ptr[8] * *dewindow++;
2004                   out += u_ptr[9] * *dewindow++;
2005                   out += u_ptr[10] * *dewindow++;
2006                   out += u_ptr[11] * *dewindow++;
2007                   out += u_ptr[12] * *dewindow++;
2008                   out += u_ptr[13] * *dewindow++;
2009                   out += u_ptr[14] * *dewindow++;
2010                   out += u_ptr[15] * *dewindow++;
2011                   out += u_ptr[0] * *dewindow++;
2012                   out += u_ptr[1] * *dewindow++;
2013                   out += u_ptr[2] * *dewindow++;
2014                   out += u_ptr[3] * *dewindow++;
2015 
2016                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2017                }
2018                break;
2019 
2020             case 5:
2021                for (j=0;j<32;j++) {
2022                   u_ptr = u_p[j];
2023 
2024                   out  = u_ptr[5] * *dewindow++;
2025                   out += u_ptr[6] * *dewindow++;
2026                   out += u_ptr[7] * *dewindow++;
2027                   out += u_ptr[8] * *dewindow++;
2028                   out += u_ptr[9] * *dewindow++;
2029                   out += u_ptr[10] * *dewindow++;
2030                   out += u_ptr[11] * *dewindow++;
2031                   out += u_ptr[12] * *dewindow++;
2032                   out += u_ptr[13] * *dewindow++;
2033                   out += u_ptr[14] * *dewindow++;
2034                   out += u_ptr[15] * *dewindow++;
2035                   out += u_ptr[0] * *dewindow++;
2036                   out += u_ptr[1] * *dewindow++;
2037                   out += u_ptr[2] * *dewindow++;
2038                   out += u_ptr[3] * *dewindow++;
2039                   out += u_ptr[4] * *dewindow++;
2040 
2041                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2042                }
2043                break;
2044 
2045             case 6:
2046                for (j=0;j<32;j++) {
2047                   u_ptr = u_p[j];
2048 
2049                   out  = u_ptr[6] * *dewindow++;
2050                   out += u_ptr[7] * *dewindow++;
2051                   out += u_ptr[8] * *dewindow++;
2052                   out += u_ptr[9] * *dewindow++;
2053                   out += u_ptr[10] * *dewindow++;
2054                   out += u_ptr[11] * *dewindow++;
2055                   out += u_ptr[12] * *dewindow++;
2056                   out += u_ptr[13] * *dewindow++;
2057                   out += u_ptr[14] * *dewindow++;
2058                   out += u_ptr[15] * *dewindow++;
2059                   out += u_ptr[0] * *dewindow++;
2060                   out += u_ptr[1] * *dewindow++;
2061                   out += u_ptr[2] * *dewindow++;
2062                   out += u_ptr[3] * *dewindow++;
2063                   out += u_ptr[4] * *dewindow++;
2064                   out += u_ptr[5] * *dewindow++;
2065 
2066                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2067                }
2068                break;
2069 
2070             case 7:
2071                for (j=0;j<32;j++) {
2072                   u_ptr = u_p[j];
2073 
2074                   out  = u_ptr[7] * *dewindow++;
2075                   out += u_ptr[8] * *dewindow++;
2076                   out += u_ptr[9] * *dewindow++;
2077                   out += u_ptr[10] * *dewindow++;
2078                   out += u_ptr[11] * *dewindow++;
2079                   out += u_ptr[12] * *dewindow++;
2080                   out += u_ptr[13] * *dewindow++;
2081                   out += u_ptr[14] * *dewindow++;
2082                   out += u_ptr[15] * *dewindow++;
2083                   out += u_ptr[0] * *dewindow++;
2084                   out += u_ptr[1] * *dewindow++;
2085                   out += u_ptr[2] * *dewindow++;
2086                   out += u_ptr[3] * *dewindow++;
2087                   out += u_ptr[4] * *dewindow++;
2088                   out += u_ptr[5] * *dewindow++;
2089                   out += u_ptr[6] * *dewindow++;
2090 
2091                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2092                }
2093                break;
2094 
2095 #endif
2096 #if !defined(SMALL_STEREO_CACHE)
2097             case 8:
2098                for (j=0;j<32;j++) {
2099                   u_ptr = u_p[j];
2100 
2101                   out  = u_ptr[8] * *dewindow++;
2102                   out += u_ptr[9] * *dewindow++;
2103                   out += u_ptr[10] * *dewindow++;
2104                   out += u_ptr[11] * *dewindow++;
2105                   out += u_ptr[12] * *dewindow++;
2106                   out += u_ptr[13] * *dewindow++;
2107                   out += u_ptr[14] * *dewindow++;
2108                   out += u_ptr[15] * *dewindow++;
2109                   out += u_ptr[0] * *dewindow++;
2110                   out += u_ptr[1] * *dewindow++;
2111                   out += u_ptr[2] * *dewindow++;
2112                   out += u_ptr[3] * *dewindow++;
2113                   out += u_ptr[4] * *dewindow++;
2114                   out += u_ptr[5] * *dewindow++;
2115                   out += u_ptr[6] * *dewindow++;
2116                   out += u_ptr[7] * *dewindow++;
2117 
2118                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2119                }
2120                break;
2121 
2122             case 9:
2123                for (j=0;j<32;j++) {
2124                   u_ptr = u_p[j];
2125 
2126                   out  = u_ptr[9] * *dewindow++;
2127                   out += u_ptr[10] * *dewindow++;
2128                   out += u_ptr[11] * *dewindow++;
2129                   out += u_ptr[12] * *dewindow++;
2130                   out += u_ptr[13] * *dewindow++;
2131                   out += u_ptr[14] * *dewindow++;
2132                   out += u_ptr[15] * *dewindow++;
2133                   out += u_ptr[0] * *dewindow++;
2134                   out += u_ptr[1] * *dewindow++;
2135                   out += u_ptr[2] * *dewindow++;
2136                   out += u_ptr[3] * *dewindow++;
2137                   out += u_ptr[4] * *dewindow++;
2138                   out += u_ptr[5] * *dewindow++;
2139                   out += u_ptr[6] * *dewindow++;
2140                   out += u_ptr[7] * *dewindow++;
2141                   out += u_ptr[8] * *dewindow++;
2142 
2143                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2144                }
2145                break;
2146 
2147             case 10:
2148                for (j=0;j<32;j++) {
2149                   u_ptr = u_p[j];
2150 
2151                   out  = u_ptr[10] * *dewindow++;
2152                   out += u_ptr[11] * *dewindow++;
2153                   out += u_ptr[12] * *dewindow++;
2154                   out += u_ptr[13] * *dewindow++;
2155                   out += u_ptr[14] * *dewindow++;
2156                   out += u_ptr[15] * *dewindow++;
2157                   out += u_ptr[0] * *dewindow++;
2158                   out += u_ptr[1] * *dewindow++;
2159                   out += u_ptr[2] * *dewindow++;
2160                   out += u_ptr[3] * *dewindow++;
2161                   out += u_ptr[4] * *dewindow++;
2162                   out += u_ptr[5] * *dewindow++;
2163                   out += u_ptr[6] * *dewindow++;
2164                   out += u_ptr[7] * *dewindow++;
2165                   out += u_ptr[8] * *dewindow++;
2166                   out += u_ptr[9] * *dewindow++;
2167 
2168                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2169                }
2170                break;
2171 
2172             case 11:
2173                for (j=0;j<32;j++) {
2174                   u_ptr = u_p[j];
2175 
2176                   out  = u_ptr[11] * *dewindow++;
2177                   out += u_ptr[12] * *dewindow++;
2178                   out += u_ptr[13] * *dewindow++;
2179                   out += u_ptr[14] * *dewindow++;
2180                   out += u_ptr[15] * *dewindow++;
2181                   out += u_ptr[0] * *dewindow++;
2182                   out += u_ptr[1] * *dewindow++;
2183                   out += u_ptr[2] * *dewindow++;
2184                   out += u_ptr[3] * *dewindow++;
2185                   out += u_ptr[4] * *dewindow++;
2186                   out += u_ptr[5] * *dewindow++;
2187                   out += u_ptr[6] * *dewindow++;
2188                   out += u_ptr[7] * *dewindow++;
2189                   out += u_ptr[8] * *dewindow++;
2190                   out += u_ptr[9] * *dewindow++;
2191                   out += u_ptr[10] * *dewindow++;
2192 
2193                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2194                }
2195                break;
2196 
2197             case 12:
2198                for (j=0;j<32;j++) {
2199                   u_ptr = u_p[j];
2200 
2201                   out  = u_ptr[12] * *dewindow++;
2202                   out += u_ptr[13] * *dewindow++;
2203                   out += u_ptr[14] * *dewindow++;
2204                   out += u_ptr[15] * *dewindow++;
2205                   out += u_ptr[0] * *dewindow++;
2206                   out += u_ptr[1] * *dewindow++;
2207                   out += u_ptr[2] * *dewindow++;
2208                   out += u_ptr[3] * *dewindow++;
2209                   out += u_ptr[4] * *dewindow++;
2210                   out += u_ptr[5] * *dewindow++;
2211                   out += u_ptr[6] * *dewindow++;
2212                   out += u_ptr[7] * *dewindow++;
2213                   out += u_ptr[8] * *dewindow++;
2214                   out += u_ptr[9] * *dewindow++;
2215                   out += u_ptr[10] * *dewindow++;
2216                   out += u_ptr[11] * *dewindow++;
2217 
2218                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2219                }
2220                break;
2221 
2222             case 13:
2223                for (j=0;j<32;j++) {
2224                   u_ptr = u_p[j];
2225 
2226                   out  = u_ptr[13] * *dewindow++;
2227                   out += u_ptr[14] * *dewindow++;
2228                   out += u_ptr[15] * *dewindow++;
2229                   out += u_ptr[0] * *dewindow++;
2230                   out += u_ptr[1] * *dewindow++;
2231                   out += u_ptr[2] * *dewindow++;
2232                   out += u_ptr[3] * *dewindow++;
2233                   out += u_ptr[4] * *dewindow++;
2234                   out += u_ptr[5] * *dewindow++;
2235                   out += u_ptr[6] * *dewindow++;
2236                   out += u_ptr[7] * *dewindow++;
2237                   out += u_ptr[8] * *dewindow++;
2238                   out += u_ptr[9] * *dewindow++;
2239                   out += u_ptr[10] * *dewindow++;
2240                   out += u_ptr[11] * *dewindow++;
2241                   out += u_ptr[12] * *dewindow++;
2242 
2243                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2244                }
2245                break;
2246 
2247             case 14:
2248                for (j=0;j<32;j++) {
2249                   u_ptr = u_p[j];
2250 
2251                   out  = u_ptr[14] * *dewindow++;
2252                   out += u_ptr[15] * *dewindow++;
2253                   out += u_ptr[0] * *dewindow++;
2254                   out += u_ptr[1] * *dewindow++;
2255                   out += u_ptr[2] * *dewindow++;
2256                   out += u_ptr[3] * *dewindow++;
2257                   out += u_ptr[4] * *dewindow++;
2258                   out += u_ptr[5] * *dewindow++;
2259                   out += u_ptr[6] * *dewindow++;
2260                   out += u_ptr[7] * *dewindow++;
2261                   out += u_ptr[8] * *dewindow++;
2262                   out += u_ptr[9] * *dewindow++;
2263                   out += u_ptr[10] * *dewindow++;
2264                   out += u_ptr[11] * *dewindow++;
2265                   out += u_ptr[12] * *dewindow++;
2266                   out += u_ptr[13] * *dewindow++;
2267 
2268                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2269                }
2270                break;
2271 
2272             case 15:
2273                for (j=0;j<32;j++) {
2274                   u_ptr = u_p[j];
2275 
2276                   out  = u_ptr[15] * *dewindow++;
2277                   out += u_ptr[0] * *dewindow++;
2278                   out += u_ptr[1] * *dewindow++;
2279                   out += u_ptr[2] * *dewindow++;
2280                   out += u_ptr[3] * *dewindow++;
2281                   out += u_ptr[4] * *dewindow++;
2282                   out += u_ptr[5] * *dewindow++;
2283                   out += u_ptr[6] * *dewindow++;
2284                   out += u_ptr[7] * *dewindow++;
2285                   out += u_ptr[8] * *dewindow++;
2286                   out += u_ptr[9] * *dewindow++;
2287                   out += u_ptr[10] * *dewindow++;
2288                   out += u_ptr[11] * *dewindow++;
2289                   out += u_ptr[12] * *dewindow++;
2290                   out += u_ptr[13] * *dewindow++;
2291                   out += u_ptr[14] * *dewindow++;
2292 
2293                   ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2294                }
2295                break;
2296 #endif
2297 #if defined(MEDIUM_STEREO_CACHE) || defined(SMALL_STEREO_CACHE)
2298             default:
2299                {
2300                   int i=start;
2301 
2302                   for (j=0;j<32;j++) {
2303                      u_ptr = u_p[j];
2304 
2305                      out  = u_ptr[i++ & 0xf] * *dewindow++;
2306                      out += u_ptr[i++ & 0xf] * *dewindow++;
2307                      out += u_ptr[i++ & 0xf] * *dewindow++;
2308                      out += u_ptr[i++ & 0xf] * *dewindow++;
2309                      out += u_ptr[i++ & 0xf] * *dewindow++;
2310                      out += u_ptr[i++ & 0xf] * *dewindow++;
2311                      out += u_ptr[i++ & 0xf] * *dewindow++;
2312                      out += u_ptr[i++ & 0xf] * *dewindow++;
2313                      out += u_ptr[i++ & 0xf] * *dewindow++;
2314                      out += u_ptr[i++ & 0xf] * *dewindow++;
2315                      out += u_ptr[i++ & 0xf] * *dewindow++;
2316                      out += u_ptr[i++ & 0xf] * *dewindow++;
2317                      out += u_ptr[i++ & 0xf] * *dewindow++;
2318                      out += u_ptr[i++ & 0xf] * *dewindow++;
2319                      out += u_ptr[i++ & 0xf] * *dewindow++;
2320                      out += u_ptr[i++ & 0xf] * *dewindow++;
2321 
2322                      ext->stereo_samples[f][j][ch] = out ;;   /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2323                   }
2324                }
2325                break;
2326 #endif
2327          }
2328 
2329          ext->u_start[ch] = (ext->u_start[ch]-1)&0xf;
2330          ext->u_div[ch] = ext->u_div[ch] ? 0 : 1;
2331       } else {
2332          switch (start) {
2333 #if !defined(MEDIUM_MONO_CACHE) && !defined(SMALL_MONO_CACHE)
2334             case 0:
2335                u_ptr = (float *) u_p;
2336 
2337                for (j=0;j<32;j++) {
2338                   out  = *u_ptr++ * *dewindow++;
2339                   out += *u_ptr++ * *dewindow++;
2340                   out += *u_ptr++ * *dewindow++;
2341                   out += *u_ptr++ * *dewindow++;
2342                   out += *u_ptr++ * *dewindow++;
2343                   out += *u_ptr++ * *dewindow++;
2344                   out += *u_ptr++ * *dewindow++;
2345                   out += *u_ptr++ * *dewindow++;
2346                   out += *u_ptr++ * *dewindow++;
2347                   out += *u_ptr++ * *dewindow++;
2348                   out += *u_ptr++ * *dewindow++;
2349                   out += *u_ptr++ * *dewindow++;
2350                   out += *u_ptr++ * *dewindow++;
2351                   out += *u_ptr++ * *dewindow++;
2352                   out += *u_ptr++ * *dewindow++;
2353                   out += *u_ptr++ * *dewindow++;
2354 
2355                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2356                }
2357                break;
2358 
2359             case 1:
2360                for (j=0;j<32;j++) {
2361                   u_ptr = u_p[j];
2362 
2363                   out  = u_ptr[1] * *dewindow++;
2364                   out += u_ptr[2] * *dewindow++;
2365                   out += u_ptr[3] * *dewindow++;
2366                   out += u_ptr[4] * *dewindow++;
2367                   out += u_ptr[5] * *dewindow++;
2368                   out += u_ptr[6] * *dewindow++;
2369                   out += u_ptr[7] * *dewindow++;
2370                   out += u_ptr[8] * *dewindow++;
2371                   out += u_ptr[9] * *dewindow++;
2372                   out += u_ptr[10] * *dewindow++;
2373                   out += u_ptr[11] * *dewindow++;
2374                   out += u_ptr[12] * *dewindow++;
2375                   out += u_ptr[13] * *dewindow++;
2376                   out += u_ptr[14] * *dewindow++;
2377                   out += u_ptr[15] * *dewindow++;
2378                   out += u_ptr[0] * *dewindow++;
2379 
2380                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2381                }
2382                break;
2383 
2384             case 2:
2385                for (j=0;j<32;j++) {
2386                   u_ptr = u_p[j];
2387 
2388                   out  = u_ptr[2] * *dewindow++;
2389                   out += u_ptr[3] * *dewindow++;
2390                   out += u_ptr[4] * *dewindow++;
2391                   out += u_ptr[5] * *dewindow++;
2392                   out += u_ptr[6] * *dewindow++;
2393                   out += u_ptr[7] * *dewindow++;
2394                   out += u_ptr[8] * *dewindow++;
2395                   out += u_ptr[9] * *dewindow++;
2396                   out += u_ptr[10] * *dewindow++;
2397                   out += u_ptr[11] * *dewindow++;
2398                   out += u_ptr[12] * *dewindow++;
2399                   out += u_ptr[13] * *dewindow++;
2400                   out += u_ptr[14] * *dewindow++;
2401                   out += u_ptr[15] * *dewindow++;
2402                   out += u_ptr[0] * *dewindow++;
2403                   out += u_ptr[1] * *dewindow++;
2404 
2405                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2406                }
2407                break;
2408 
2409             case 3:
2410                for (j=0;j<32;j++) {
2411                   u_ptr = u_p[j];
2412 
2413                   out  = u_ptr[3] * *dewindow++;
2414                   out += u_ptr[4] * *dewindow++;
2415                   out += u_ptr[5] * *dewindow++;
2416                   out += u_ptr[6] * *dewindow++;
2417                   out += u_ptr[7] * *dewindow++;
2418                   out += u_ptr[8] * *dewindow++;
2419                   out += u_ptr[9] * *dewindow++;
2420                   out += u_ptr[10] * *dewindow++;
2421                   out += u_ptr[11] * *dewindow++;
2422                   out += u_ptr[12] * *dewindow++;
2423                   out += u_ptr[13] * *dewindow++;
2424                   out += u_ptr[14] * *dewindow++;
2425                   out += u_ptr[15] * *dewindow++;
2426                   out += u_ptr[0] * *dewindow++;
2427                   out += u_ptr[1] * *dewindow++;
2428                   out += u_ptr[2] * *dewindow++;
2429 
2430                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2431                }
2432                break;
2433 
2434             case 4:
2435                for (j=0;j<32;j++) {
2436                   u_ptr = u_p[j];
2437 
2438                   out  = u_ptr[4] * *dewindow++;
2439                   out += u_ptr[5] * *dewindow++;
2440                   out += u_ptr[6] * *dewindow++;
2441                   out += u_ptr[7] * *dewindow++;
2442                   out += u_ptr[8] * *dewindow++;
2443                   out += u_ptr[9] * *dewindow++;
2444                   out += u_ptr[10] * *dewindow++;
2445                   out += u_ptr[11] * *dewindow++;
2446                   out += u_ptr[12] * *dewindow++;
2447                   out += u_ptr[13] * *dewindow++;
2448                   out += u_ptr[14] * *dewindow++;
2449                   out += u_ptr[15] * *dewindow++;
2450                   out += u_ptr[0] * *dewindow++;
2451                   out += u_ptr[1] * *dewindow++;
2452                   out += u_ptr[2] * *dewindow++;
2453                   out += u_ptr[3] * *dewindow++;
2454 
2455                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2456                }
2457                break;
2458 
2459             case 5:
2460                for (j=0;j<32;j++) {
2461                   u_ptr = u_p[j];
2462 
2463                   out  = u_ptr[5] * *dewindow++;
2464                   out += u_ptr[6] * *dewindow++;
2465                   out += u_ptr[7] * *dewindow++;
2466                   out += u_ptr[8] * *dewindow++;
2467                   out += u_ptr[9] * *dewindow++;
2468                   out += u_ptr[10] * *dewindow++;
2469                   out += u_ptr[11] * *dewindow++;
2470                   out += u_ptr[12] * *dewindow++;
2471                   out += u_ptr[13] * *dewindow++;
2472                   out += u_ptr[14] * *dewindow++;
2473                   out += u_ptr[15] * *dewindow++;
2474                   out += u_ptr[0] * *dewindow++;
2475                   out += u_ptr[1] * *dewindow++;
2476                   out += u_ptr[2] * *dewindow++;
2477                   out += u_ptr[3] * *dewindow++;
2478                   out += u_ptr[4] * *dewindow++;
2479 
2480                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2481                }
2482                break;
2483 
2484             case 6:
2485                for (j=0;j<32;j++) {
2486                   u_ptr = u_p[j];
2487 
2488                   out  = u_ptr[6] * *dewindow++;
2489                   out += u_ptr[7] * *dewindow++;
2490                   out += u_ptr[8] * *dewindow++;
2491                   out += u_ptr[9] * *dewindow++;
2492                   out += u_ptr[10] * *dewindow++;
2493                   out += u_ptr[11] * *dewindow++;
2494                   out += u_ptr[12] * *dewindow++;
2495                   out += u_ptr[13] * *dewindow++;
2496                   out += u_ptr[14] * *dewindow++;
2497                   out += u_ptr[15] * *dewindow++;
2498                   out += u_ptr[0] * *dewindow++;
2499                   out += u_ptr[1] * *dewindow++;
2500                   out += u_ptr[2] * *dewindow++;
2501                   out += u_ptr[3] * *dewindow++;
2502                   out += u_ptr[4] * *dewindow++;
2503                   out += u_ptr[5] * *dewindow++;
2504 
2505                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2506                }
2507                break;
2508 
2509             case 7:
2510                for (j=0;j<32;j++) {
2511                   u_ptr = u_p[j];
2512 
2513                   out  = u_ptr[7] * *dewindow++;
2514                   out += u_ptr[8] * *dewindow++;
2515                   out += u_ptr[9] * *dewindow++;
2516                   out += u_ptr[10] * *dewindow++;
2517                   out += u_ptr[11] * *dewindow++;
2518                   out += u_ptr[12] * *dewindow++;
2519                   out += u_ptr[13] * *dewindow++;
2520                   out += u_ptr[14] * *dewindow++;
2521                   out += u_ptr[15] * *dewindow++;
2522                   out += u_ptr[0] * *dewindow++;
2523                   out += u_ptr[1] * *dewindow++;
2524                   out += u_ptr[2] * *dewindow++;
2525                   out += u_ptr[3] * *dewindow++;
2526                   out += u_ptr[4] * *dewindow++;
2527                   out += u_ptr[5] * *dewindow++;
2528                   out += u_ptr[6] * *dewindow++;
2529 
2530                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2531                }
2532                break;
2533 
2534 #endif
2535 #if !defined(SMALL_MONO_CACHE)
2536             case 8:
2537                for (j=0;j<32;j++) {
2538                   u_ptr = u_p[j];
2539 
2540                   out  = u_ptr[8] * *dewindow++;
2541                   out += u_ptr[9] * *dewindow++;
2542                   out += u_ptr[10] * *dewindow++;
2543                   out += u_ptr[11] * *dewindow++;
2544                   out += u_ptr[12] * *dewindow++;
2545                   out += u_ptr[13] * *dewindow++;
2546                   out += u_ptr[14] * *dewindow++;
2547                   out += u_ptr[15] * *dewindow++;
2548                   out += u_ptr[0] * *dewindow++;
2549                   out += u_ptr[1] * *dewindow++;
2550                   out += u_ptr[2] * *dewindow++;
2551                   out += u_ptr[3] * *dewindow++;
2552                   out += u_ptr[4] * *dewindow++;
2553                   out += u_ptr[5] * *dewindow++;
2554                   out += u_ptr[6] * *dewindow++;
2555                   out += u_ptr[7] * *dewindow++;
2556 
2557                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2558                }
2559                break;
2560 
2561             case 9:
2562                for (j=0;j<32;j++) {
2563                   u_ptr = u_p[j];
2564 
2565                   out  = u_ptr[9] * *dewindow++;
2566                   out += u_ptr[10] * *dewindow++;
2567                   out += u_ptr[11] * *dewindow++;
2568                   out += u_ptr[12] * *dewindow++;
2569                   out += u_ptr[13] * *dewindow++;
2570                   out += u_ptr[14] * *dewindow++;
2571                   out += u_ptr[15] * *dewindow++;
2572                   out += u_ptr[0] * *dewindow++;
2573                   out += u_ptr[1] * *dewindow++;
2574                   out += u_ptr[2] * *dewindow++;
2575                   out += u_ptr[3] * *dewindow++;
2576                   out += u_ptr[4] * *dewindow++;
2577                   out += u_ptr[5] * *dewindow++;
2578                   out += u_ptr[6] * *dewindow++;
2579                   out += u_ptr[7] * *dewindow++;
2580                   out += u_ptr[8] * *dewindow++;
2581 
2582                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2583                }
2584                break;
2585 
2586             case 10:
2587                for (j=0;j<32;j++) {
2588                   u_ptr = u_p[j];
2589 
2590                   out  = u_ptr[10] * *dewindow++;
2591                   out += u_ptr[11] * *dewindow++;
2592                   out += u_ptr[12] * *dewindow++;
2593                   out += u_ptr[13] * *dewindow++;
2594                   out += u_ptr[14] * *dewindow++;
2595                   out += u_ptr[15] * *dewindow++;
2596                   out += u_ptr[0] * *dewindow++;
2597                   out += u_ptr[1] * *dewindow++;
2598                   out += u_ptr[2] * *dewindow++;
2599                   out += u_ptr[3] * *dewindow++;
2600                   out += u_ptr[4] * *dewindow++;
2601                   out += u_ptr[5] * *dewindow++;
2602                   out += u_ptr[6] * *dewindow++;
2603                   out += u_ptr[7] * *dewindow++;
2604                   out += u_ptr[8] * *dewindow++;
2605                   out += u_ptr[9] * *dewindow++;
2606 
2607                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2608                }
2609                break;
2610 
2611             case 11:
2612                for (j=0;j<32;j++) {
2613                   u_ptr = u_p[j];
2614 
2615                   out  = u_ptr[11] * *dewindow++;
2616                   out += u_ptr[12] * *dewindow++;
2617                   out += u_ptr[13] * *dewindow++;
2618                   out += u_ptr[14] * *dewindow++;
2619                   out += u_ptr[15] * *dewindow++;
2620                   out += u_ptr[0] * *dewindow++;
2621                   out += u_ptr[1] * *dewindow++;
2622                   out += u_ptr[2] * *dewindow++;
2623                   out += u_ptr[3] * *dewindow++;
2624                   out += u_ptr[4] * *dewindow++;
2625                   out += u_ptr[5] * *dewindow++;
2626                   out += u_ptr[6] * *dewindow++;
2627                   out += u_ptr[7] * *dewindow++;
2628                   out += u_ptr[8] * *dewindow++;
2629                   out += u_ptr[9] * *dewindow++;
2630                   out += u_ptr[10] * *dewindow++;
2631 
2632                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2633                }
2634                break;
2635 
2636             case 12:
2637                for (j=0;j<32;j++) {
2638                   u_ptr = u_p[j];
2639 
2640                   out  = u_ptr[12] * *dewindow++;
2641                   out += u_ptr[13] * *dewindow++;
2642                   out += u_ptr[14] * *dewindow++;
2643                   out += u_ptr[15] * *dewindow++;
2644                   out += u_ptr[0] * *dewindow++;
2645                   out += u_ptr[1] * *dewindow++;
2646                   out += u_ptr[2] * *dewindow++;
2647                   out += u_ptr[3] * *dewindow++;
2648                   out += u_ptr[4] * *dewindow++;
2649                   out += u_ptr[5] * *dewindow++;
2650                   out += u_ptr[6] * *dewindow++;
2651                   out += u_ptr[7] * *dewindow++;
2652                   out += u_ptr[8] * *dewindow++;
2653                   out += u_ptr[9] * *dewindow++;
2654                   out += u_ptr[10] * *dewindow++;
2655                   out += u_ptr[11] * *dewindow++;
2656 
2657                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2658                }
2659                break;
2660 
2661             case 13:
2662                for (j=0;j<32;j++) {
2663                   u_ptr = u_p[j];
2664 
2665                   out  = u_ptr[13] * *dewindow++;
2666                   out += u_ptr[14] * *dewindow++;
2667                   out += u_ptr[15] * *dewindow++;
2668                   out += u_ptr[0] * *dewindow++;
2669                   out += u_ptr[1] * *dewindow++;
2670                   out += u_ptr[2] * *dewindow++;
2671                   out += u_ptr[3] * *dewindow++;
2672                   out += u_ptr[4] * *dewindow++;
2673                   out += u_ptr[5] * *dewindow++;
2674                   out += u_ptr[6] * *dewindow++;
2675                   out += u_ptr[7] * *dewindow++;
2676                   out += u_ptr[8] * *dewindow++;
2677                   out += u_ptr[9] * *dewindow++;
2678                   out += u_ptr[10] * *dewindow++;
2679                   out += u_ptr[11] * *dewindow++;
2680                   out += u_ptr[12] * *dewindow++;
2681 
2682                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2683                }
2684                break;
2685 
2686             case 14:
2687                for (j=0;j<32;j++) {
2688                   u_ptr = u_p[j];
2689 
2690                   out  = u_ptr[14] * *dewindow++;
2691                   out += u_ptr[15] * *dewindow++;
2692                   out += u_ptr[0] * *dewindow++;
2693                   out += u_ptr[1] * *dewindow++;
2694                   out += u_ptr[2] * *dewindow++;
2695                   out += u_ptr[3] * *dewindow++;
2696                   out += u_ptr[4] * *dewindow++;
2697                   out += u_ptr[5] * *dewindow++;
2698                   out += u_ptr[6] * *dewindow++;
2699                   out += u_ptr[7] * *dewindow++;
2700                   out += u_ptr[8] * *dewindow++;
2701                   out += u_ptr[9] * *dewindow++;
2702                   out += u_ptr[10] * *dewindow++;
2703                   out += u_ptr[11] * *dewindow++;
2704                   out += u_ptr[12] * *dewindow++;
2705                   out += u_ptr[13] * *dewindow++;
2706 
2707                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2708                }
2709                break;
2710 
2711             case 15:
2712                for (j=0;j<32;j++) {
2713                   u_ptr = u_p[j];
2714 
2715                   out  = u_ptr[15] * *dewindow++;
2716                   out += u_ptr[0] * *dewindow++;
2717                   out += u_ptr[1] * *dewindow++;
2718                   out += u_ptr[2] * *dewindow++;
2719                   out += u_ptr[3] * *dewindow++;
2720                   out += u_ptr[4] * *dewindow++;
2721                   out += u_ptr[5] * *dewindow++;
2722                   out += u_ptr[6] * *dewindow++;
2723                   out += u_ptr[7] * *dewindow++;
2724                   out += u_ptr[8] * *dewindow++;
2725                   out += u_ptr[9] * *dewindow++;
2726                   out += u_ptr[10] * *dewindow++;
2727                   out += u_ptr[11] * *dewindow++;
2728                   out += u_ptr[12] * *dewindow++;
2729                   out += u_ptr[13] * *dewindow++;
2730                   out += u_ptr[14] * *dewindow++;
2731 
2732                   ext->mono_samples[f][j] = out ;;    /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2733                }
2734                break;
2735 #endif
2736 #if defined(MEDIUM_MONO_CACHE) || defined(SMALL_MONO_CACHE)
2737             default:
2738                {
2739                   int i=start;
2740 
2741                   for (j=0;j<32;j++) {
2742                      u_ptr = u_p[j];
2743 
2744                      out  = u_ptr[i++ & 0xf] * *dewindow++;
2745                      out += u_ptr[i++ & 0xf] * *dewindow++;
2746                      out += u_ptr[i++ & 0xf] * *dewindow++;
2747                      out += u_ptr[i++ & 0xf] * *dewindow++;
2748                      out += u_ptr[i++ & 0xf] * *dewindow++;
2749                      out += u_ptr[i++ & 0xf] * *dewindow++;
2750                      out += u_ptr[i++ & 0xf] * *dewindow++;
2751                      out += u_ptr[i++ & 0xf] * *dewindow++;
2752                      out += u_ptr[i++ & 0xf] * *dewindow++;
2753                      out += u_ptr[i++ & 0xf] * *dewindow++;
2754                      out += u_ptr[i++ & 0xf] * *dewindow++;
2755                      out += u_ptr[i++ & 0xf] * *dewindow++;
2756                      out += u_ptr[i++ & 0xf] * *dewindow++;
2757                      out += u_ptr[i++ & 0xf] * *dewindow++;
2758                      out += u_ptr[i++ & 0xf] * *dewindow++;
2759                      out += u_ptr[i++ & 0xf] * *dewindow++;
2760 
2761                      ext->mono_samples[f][j] = out ;; /*> 32767.0f ? 32767.0f : out < -32768.0f ? -32768.0f : out;*/
2762                   }
2763                }
2764                break;
2765 #endif
2766          }
2767 
2768          ext->u_start[0] = (ext->u_start[0]-1)&0xf;
2769          ext->u_div[0] = ext->u_div[0] ? 0 : 1;
2770       }
2771    }
2772 }
2773 
2774 static void
2775   premultiply() {
2776    int i,t;
2777 
2778    for (i = 0; i < 16; ++i)
2779       for (t = 0; t < 32; ++t)
2780          t_dewindow[i][t] *= 16383.5f;
2781 }
2782 
2783 /* this function decodes one layer3 audio frame, except for the header decoding
2784  * which is done in main() [audio.c]. returns 0 if everything is ok.
2785  */
2786 
2787 static int
2788 layer3_frame(mp3Info *ext, struct AUDIO_HEADER *header, int len)
2789 {
2790   static struct SIDE_INFO info;
2791 
2792   int gr,ch,sb,i,tmp;
2793   int mean_frame_size,bitrate,fs,hsize,ssize;
2794   int cnt = ext->cnt;
2795   char *rest = (char *) ext->rest;
2796   /* we need these later, hsize is the size of header+side_info */
2797 
2798   if (header->ID)
2799     if (header->mode==3) {
2800       ext->nch = 1;
2801       hsize=21;
2802     } else {
2803       ext->nch = 2;
2804       hsize=36;
2805     }
2806   else
2807     if (header->mode==3) {
2808       ext->nch = 1;
2809       hsize=13;
2810     } else {
2811       ext->nch = 2;
2812       hsize=21;
2813     }
2814 
2815   /* crc increases hsize by 2 */
2816 
2817   if (header->protection_bit==0) hsize+=2;
2818 
2819 
2820   /* read layer3 specific side_info */
2821 
2822   getinfo(header,&info);
2823 
2824   /* MPEG2 only has one granule  */
2825 
2826   bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
2827   fs=t_sampling_frequency[header->fullID][header->sampling_frequency];
2828   mean_frame_size = (bitrate * (sr_lookup[header->ID]) / fs);
2829   /* check if mdb is too big for the first few frames. this means that
2830    * a part of the stream could be missing. We must still fill the buffer
2831    */
2832   if (info.main_data_begin > gblAppend)
2833     if (cnt*mean_frame_size < 960) {
2834       if (debugLevel > 0) {
2835          Snack_WriteLogInt(" incomplete frame < 960 bytes ", cnt);
2836       }
2837       /*printf(" frame %d discarded, incomplete main_data\n",cnt);*/
2838       fillbfr(mean_frame_size + header->padding_bit - hsize);
2839       return 0;
2840     }
2841 
2842   /* now update the data 'pointer' (counting in bits) according to
2843    * the main_data_begin information
2844    */
2845   gblData = 8 * ((gblAppend - info.main_data_begin) & (BUFFER_SIZE-1));
2846 
2847   /* read into the buffer all bytes up to the start of next header */
2848 
2849   fillbfr(mean_frame_size + header->padding_bit - hsize);
2850   /* these two should go away */
2851 
2852   ext->t_l=&t_b8_l[header->ID][header->sampling_frequency][0];
2853   ext->t_s=&t_b8_s[header->ID][header->sampling_frequency][0];
2854 
2855   /* debug/dump stuff */
2856   /*  show_header(header,bitrate,fs,mean_frame_size,0);*/
2857   /*if (A_DUMP_BINARY) dump((int *)info.part2_3_length);*/
2858 
2859   /* decode the scalefactors and huffman data
2860    * this part needs to be enhanced for error robustness
2861    */
2862   for (gr=0;gr < ((header->ID) ? 2 : 1);gr++) {
2863     for (ch=0;ch<ext->nch;ch++) {
2864       /*       show_side_info(&info,gr,ch,0);*/ /* this is for debug/dump */
2865       ssize=decode_scalefactors(ext, &info,header,gr,ch);
2866       decode_huffman_data(ext,&info,gr,ch,ssize);
2867     }
2868 
2869     /* requantization, stereo processing, reordering(shortbl) */
2870     if (header->mode!=1 || (header->mode==1 && header->mode_extension==0))
2871       for (ch=0;ch<ext->nch;ch++) requantize_mono(ext, gr,ch,&info,header);
2872     else requantize_ms(ext, gr,&info,header);
2873 
2874     /* antialiasing butterflies */
2875     for (ch=0;ch<ext->nch;ch++) {
2876       if(!(info.window_switching_flag[gr][ch] && info.block_type[gr][ch]==2))
2877         alias_reduction(ext,ch);
2878     }
2879 
2880     /* just which window? */
2881     for (ch=0;ch<ext->nch;ch++) {
2882       int win_type; /* same as in the standard, long=0, start=1 ,.... */
2883 
2884       if (info.window_switching_flag[gr][ch] && info.block_type[gr][ch]==2 && info.mixed_block_flag[gr][ch])
2885         win_type=0;
2886       else if (!info.window_switching_flag[gr][ch]) win_type=0;
2887       else win_type=info.block_type[gr][ch];
2888 
2889       /* imdct ...  */
2890 
2891       for (sb=0;sb<2;sb++)
2892         imdct(ext,win_type,sb,ch);
2893 
2894       if (info.window_switching_flag[gr][ch] && info.block_type[gr][ch]==2 && info.mixed_block_flag[gr][ch])
2895         win_type=2;
2896 
2897       /* no_of_imdcts tells us how many subbands from the top are all zero
2898        * it is set by the requantize functions in misc2.c
2899        */
2900       for (sb=2;sb<no_of_imdcts[ch];sb++)
2901         imdct(ext,win_type,sb,ch);
2902 
2903       /* clear s[][][] first so we don't totally blow the cache */
2904 
2905       tmp = sb;
2906       for (;sb<32;sb++)
2907         for (i=0;i<18;i++) {
2908           ext->res[sb][i]=ext->s[ch][sb][i];
2909           ext->s[ch][sb][i]=0.0f;
2910         }
2911 
2912       /* polyphase filterbank
2913        */
2914       /* if (nch == 2) this was a bug, tomislav */
2915       for (i=0;i<18;i++)
2916         poly(ext, ch, i);
2917     }
2918     if (ext->nch == 2) {
2919       int l = min(18*32*2*4, len - ext->ind);
2920       memcpy(&gblOutputbuf[ext->ind], ext->stereo_samples, l);
2921       ext->ind += l;
2922       if (l < 18*32*2*4) {
2923         memcpy(&rest[ext->restlen],
2924            &((char *)ext->stereo_samples)[l], 18*32*2*4 - l);
2925         ext->restlen += (18*32*2*4 - l);
2926       }
2927     } else {
2928       int l = min(18*32*4, len - ext->ind);
2929       memcpy(&gblOutputbuf[ext->ind], ext->mono_samples, l);
2930       ext->ind += l;
2931       if (l < 18*32*4) {
2932         memcpy(&rest[ext->restlen],
2933                &((char *)ext->mono_samples)[l], 18*32*4 - l);
2934         ext->restlen += (18*32*4 - l);
2935       }
2936     }
2937   }    /*  for (gr... */
2938 
2939   return 0;
2940 
2941 }
2942 /* calculating t_43 instead of having that big table in misc2.h
2943  */
2944 
2945 void calculate_t43(void)
2946 {
2947 int i;
2948    for (i=0;i<8207;i++)
2949       t_43[i] = (float)pow((double)i,(double)4.0/3.0);
2950 }
2951 
2952 static int
2953 processHeader(Sound *s, struct AUDIO_HEADER *header, int cnt)
2954 {
2955   int g,i=0;
2956   mp3Info *Si = (mp3Info *)s->extHead;
2957 
2958   if (s->debug > 3) Snack_WriteLog("      Enter processHeader\n");
2959 
2960   /*
2961    * If already read the header, reuse it. Otherwise
2962    * read it from the stream.
2963    */
2964   if (Si->gotHeader) {
2965     memcpy((char *) _buffer, (char *)&(Si->headerInt), 4);
2966     _bptr=0;
2967   } else {
2968     if (_fillbfr(4) <= 0) return(1);
2969   }
2970   Si->gotHeader = 0;
2971 
2972   while ((g=gethdr(header))!=0) {
2973      /* Loop while the header is invalid, typically this won't happen
2974       * However it indicates a cut/insertion in the stream just before this.
2975       */
2976     if (_fillbfr(4) <= 0) return(1);
2977     i++;
2978   }
2979   if (s->debug > 0 && i > 0) {
2980      Snack_WriteLogInt("       Synced to valid next frame #",Si->cnt);
2981      Snack_WriteLogInt("                      bytes skipped",i*4);
2982   }
2983   if (header->protection_bit==0) getcrc();
2984 
2985   return(0);
2986  }
2987 
2988 char *
2989 GuessMP3File(char *buf, int len)
2990 {
2991   int offset = 0;
2992   int depth = 0;
2993   int matches = 0;
2994   int i;
2995   float energyLIN16 = 1.0, energyLIN16S = 1.0, ratio;
2996 
2997   if (debugLevel > 1) {
2998      Snack_WriteLogInt(" GuessMP3File Called",len);
2999   }
3000   if (len < 4) return(QUE_STRING);
3001   /* If ID3 tag or RIFF tag then we know it is an MP3 (TFW: Not specifically true, others can have ID3V2)*/
3002   if (strncmp("ID3", buf, strlen("ID3")) == 0) {
3003     return(MP3_STRING);
3004   } else if (strncasecmp("RIFF", buf, strlen("RIFF")) == 0) {
3005     if (buf[20] == 0x55) {
3006       return(MP3_STRING);
3007     }
3008   }
3009   /* If an MP3, it has no ID3V2 tag at this point*/
3010   /* No need to search entire file, a true MP3 will show up quickly */
3011 
3012   for (i = 0; i < len / 2; i++) {
3013     short sampleLIN16  = ((short *)buf)[i];
3014     short sampleLIN16S = Snack_SwapShort(sampleLIN16);
3015     energyLIN16  += (float) sampleLIN16  * (float) sampleLIN16;
3016     energyLIN16S += (float) sampleLIN16S * (float) sampleLIN16S;
3017   }
3018   if (energyLIN16 > energyLIN16S) {
3019     ratio = energyLIN16 / energyLIN16S;
3020   } else {
3021     ratio = energyLIN16S / energyLIN16;
3022   }
3023   if (ratio > 10.0) {
3024     return(NULL);
3025   }
3026 
3027   depth = min(CHANNEL_HEADER_BUFFER,len);
3028   while (offset <= depth - 4) {
3029     /* Validate frame sync and other data to make sure this is a good header */
3030      if (hasSync(&buf[offset])) {
3031       int next_frame = locateNextFrame(&buf[offset]);
3032       if (debugLevel > 1) {
3033          Snack_WriteLogInt(" GuessMP3File Found a sync at",offset);
3034       }
3035       if (offset == 0 || offset == 72) {
3036        if (debugLevel > 0) {
3037           Snack_WriteLogInt("GuessMP3File detected MP3 at",offset);
3038        }
3039         return(MP3_STRING);
3040       }
3041       /* Have one sync but dataset is too short to check for more frames */
3042       if (offset + next_frame + 4 >= len && len > depth) {
3043         if (debugLevel > 0) {
3044            Snack_WriteLogInt(" GuessMP3File Failed at",offset);
3045         }
3046         return(NULL);
3047       }
3048 
3049       /* A valid MP3 should have a header at the next location,
3050          and they should nearly match (sync + ID/Layer/Pro bit
3051          just to make sure we need one additional matche.
3052       */
3053       if (hasSync(&buf[offset+next_frame])) {
3054         matches++;
3055         /* Require at least two frames have this kind of match */
3056         if (matches > 1) {
3057           if (debugLevel > 0) {
3058              Snack_WriteLogInt("GuessMP3File detected MP3 at",offset);
3059           }
3060           return(MP3_STRING);
3061         }
3062       }
3063     }
3064     offset++;
3065   }
3066   if (offset <= depth) {
3067     return(QUE_STRING);
3068   } else {
3069      if (debugLevel > 0) {
3070         Snack_WriteLogInt(" GuessMP3File Final Failed at",offset);
3071      }
3072     return(NULL);
3073   }
3074 }
3075 
3076 static int initDone = 0;
3077 
3078 static void
3079 InitMP3()
3080 {
3081   premultiply();
3082   calculate_t43();
3083   imdct_init();
3084 }
3085 
3086 extern struct Snack_FileFormat *snackFileFormats;
3087 
3088 #define SNACK_MP3_INT 18
3089 static int ExtractI4(unsigned char *buf)
3090 {
3091    int x;
3092    /*  big endian extract  */
3093    x = buf[0];
3094    x <<= 8;
3095    x |= buf[1];
3096    x <<= 8;
3097    x |= buf[2];
3098    x <<= 8;
3099    x |= buf[3];
3100    return x;
3101 }
3102 #define FRAMES_FLAG     0x0001
3103 #define BYTES_FLAG      0x0002
3104 #define ENDCHECK        20000
3105 int
3106   GetMP3Header(Sound *S, Tcl_Interp *interp, Tcl_Channel ch, Tcl_Obj *obj,
3107                char *buf) {
3108    int offset = 0, okHeader = 0, i, j,k;
3109    int mean_frame_size = 0, bitrate = 0, fs, ID3Extra = 0;
3110    int layer, br_index, sr_index = 0, pad, mode, totalFrames=0;
3111    int passes = 0;
3112    int head_flags;
3113    int bufLen=CHANNEL_HEADER_BUFFER;
3114    int xFrames=0, xBytes=0, xAvgBitrate=0, xAvgFrameSize=0 ;
3115    float tailAverage=0.0;
3116    int tailChecked=0,tailTotal=0;
3117    mp3Info *Si = (mp3Info *)S->extHead;
3118 
3119    if (S->debug > 2) {
3120       Snack_WriteLog("    Enter GetMP3Header\n");
3121    }
3122 
3123    if (S->extHead != NULL && S->extHeadType != SNACK_MP3_INT) {
3124       Snack_FileFormat *ff;
3125 
3126       for (ff = snackFileFormats; ff != NULL; ff = ff->nextPtr) {
3127          if (strcmp(S->fileType, ff->name) == 0) {
3128             if (ff->freeHeaderProc != NULL) {
3129                (ff->freeHeaderProc)(S);
3130             }
3131          }
3132       }
3133    }
3134 
3135    if (Si == NULL) {
3136       Si = (mp3Info *) ckalloc(sizeof(mp3Info));
3137       S->extHead = (char *) Si;
3138       for (i = 0; i < 32; i++) {
3139          for (j = 0; j < 16; j++) {
3140             Si->u[0][0][i][j] = 0.0f;
3141             Si->u[0][1][i][j] = 0.0f;
3142             Si->u[1][0][i][j] = 0.0f;
3143             Si->u[1][1][i][j] = 0.0f;
3144          }
3145       }
3146       for (i = 0; i < 32; i++) {
3147          for (j = 0; j < 18; j++) {
3148             Si->s[0][i][j] = 0.0f;
3149             Si->s[1][i][j] = 0.0f;
3150          }
3151       }
3152       Si->u_start[0] = 0;
3153       Si->u_start[1] = 0;
3154       Si->u_div[0] = 0;
3155       Si->u_div[1] = 0;
3156       Si->cnt = 0;
3157 
3158       if (!initDone) {
3159          InitMP3();
3160          initDone = 1;
3161       }
3162    }
3163    /*
3164     Init scalefactors to 0
3165     */
3166    for (i = 0; i < 2; i++) {
3167       for (j = 0; j < 2; j++) {
3168          for (k = 0; k < 22; k++) {
3169             Si->scalefac_l[i][j][k] = 0;
3170          }
3171       }
3172    }
3173    for (i = 0; i < 2; i++) {
3174       for (j = 0; j < 13; j++) {
3175          for (k = 0; k < 3; k++) {
3176             Si->scalefac_s[0][i][j][k] = 0;
3177             Si->scalefac_s[1][i][j][k] = 0;
3178          }
3179       }
3180    }
3181 
3182   /**
3183    * TFW: If any ID3V2 info is to be got, it can be read here
3184    * Insert code as needed.
3185    * See: http://www.id3.org/id3v2-00.txt for more details.
3186    */
3187    S->length = -1;
3188    if (strncmp("ID3", buf, strlen("ID3")) == 0) {
3189     /* ID3 size uses 28 packed bits, or 7 LSBs of words 6-9 */
3190     /* The extra 10 bytes account for this header length)*/
3191       long idOffset = (int )((long)(buf[6]&0x7F)*2097152l
3192                              + (long)(buf[7]&0x7F)*16384l
3193                              + (long)(buf[8]&0x7F)*128l
3194                              + (long)buf[9] + 10);
3195       /* Attempt to read beyond the ID3 offset if it is too large */
3196       if (idOffset > bufLen*3/4) {
3197 
3198          if (Tcl_Seek(ch, idOffset, SEEK_SET) > 0) {
3199             bufLen = Tcl_Read(ch, &buf[0], bufLen);
3200             if (bufLen > 0) {
3201                /* local buffer is now at end of ID3 tag */
3202                offset = 0;
3203                ID3Extra = idOffset;
3204             } else {
3205                if (S->debug > 0) Snack_WriteLogInt("ID3 size is in error is too big", offset);
3206                Tcl_AppendResult(interp, "ID3 size is in error is too big", NULL);
3207                return TCL_ERROR;
3208             }
3209 
3210          } else {
3211             if (S->debug > 0) Snack_WriteLogInt("ID3 Tag is bigger than file size", offset);
3212             Tcl_AppendResult(interp, "ID3 Tag is bigger than file size", NULL);
3213             return TCL_ERROR;
3214          }
3215 
3216       } else {
3217          offset = idOffset;
3218       }
3219    }
3220    /* RIFF has additional txt attachments */
3221    else if (strncasecmp("RIFF", buf, strlen("RIFF")) == 0) {
3222       if (buf[20] == 0x55) {
3223          offset = 72;
3224          if (S->storeType == SOUND_IN_CHANNEL) {
3225             Tcl_Read(ch, &buf[S->firstNRead], 76-S->firstNRead);
3226          }
3227       }
3228    }
3229   /* Continue to scan until a satisfactory frame is found */
3230    do {
3231     /* Valid Frame sync
3232        Bit Rate not 0000 or 1111 (which are invalid)
3233        Layer 00 (reserved)
3234        Sample Rate 11 (reserved)
3235     */
3236       if (hasSync(&buf[offset])) {
3237          /*
3238           * Have a good frame sync and the header data passed the initial checks
3239           */
3240          unsigned char *xBuf = &buf[offset];
3241          int next_frame = locateNextFrame(&buf[offset]);
3242          if (next_frame > bufLen) {
3243             if (S->debug > 0) Snack_WriteLogInt("Could not find MP3 header", next_frame);
3244             Tcl_AppendResult(interp, "Could not find MP3 header", NULL);
3245             return TCL_ERROR;
3246          }
3247          if (((buf[offset + 3] & 0xc0) >> 6) != 3) {
3248             S->nchannels = 2;
3249          } else {
3250             S->nchannels = 1;
3251          }
3252          S->encoding = LIN16;
3253          S->sampsize = 2;
3254 
3255          Si->id =   (buf[offset+1] & 0x08) >> 3;
3256          Si->fullID = (buf[offset+1] & 0x18) >> 3;
3257          layer =    (buf[offset+1] & 0x06) >> 1;
3258          sr_index = (buf[offset+2] & 0x0c) >> 2;
3259 
3260          br_index = (buf[offset+2] & 0xf0) >> 4;
3261          pad =      (buf[offset+2] & 0x02) >> 1;
3262          mode =     (buf[offset+3] & 0xc0) >> 6;
3263 
3264          fs = t_sampling_frequency[Si->fullID][sr_index];
3265          S->samprate = fs;
3266          bitrate = t_bitrate[Si->id][3 - layer][br_index];
3267          /* Xing VBR Check
3268           * If a Xing VBR header exists, then use the info from there
3269           * otherwise the length and average bitrate estimate will
3270           * be incorrect.
3271           *
3272           * First, determine offset of header into Aux section
3273           */
3274          if ( Si->id ) {                              /* mpeg1 */
3275             xBuf += 4 + (mode != 3 ? 32 : 17);
3276          } else {                                       /* mpeg */
3277             xBuf += 4 + (mode != 3 ? 17 : 9);
3278          }
3279 
3280          mean_frame_size = (bitrate * sr_lookup[Si->id] / fs);   /* This frame size */
3281 
3282          /* Max should be 2926 */
3283 
3284          if (mean_frame_size > MAXFRAMESIZE) {
3285             mean_frame_size = MAXFRAMESIZE;
3286          } else if (mean_frame_size <= 0) {
3287             offset++;
3288             continue;
3289          }
3290 
3291          if (strncmp("Xing", (char *) xBuf,4)==0) {
3292          /* We have a Xing VBR header */
3293             xBuf+=4;
3294             head_flags = ExtractI4(xBuf);
3295             xBuf+=4;
3296             if ( head_flags & FRAMES_FLAG ) {
3297                xFrames   = ExtractI4(xBuf);      /* Number of frames in file */
3298                xBuf+=4;
3299             }
3300             if ( head_flags & BYTES_FLAG ) {
3301                xBytes = ExtractI4(xBuf);         /* File size (at encoding) */
3302                xBuf+=4;
3303             }
3304             /* Enough info to compute average VBR bitrate and framesize*/
3305             if ( xFrames > 0 && xBytes > 0 && (head_flags & (BYTES_FLAG | FRAMES_FLAG))) {
3306                float fAvgFrameSize = (float)xBytes/(float)xFrames;
3307                xAvgFrameSize =  (int)roundf(fAvgFrameSize);
3308                xAvgBitrate =  (int)(fAvgFrameSize * (float)fs/(float)sr_lookup[Si->id]);   /* Layer 1 */
3309             }
3310          }
3311 
3312          /* End XING stuff */
3313 
3314 
3315          /*
3316             If we didn't find a header where we first expected it
3317             then the next valid one must match the following one.
3318          */
3319          if (passes > 0) {
3320             /* Verify this frame and next frame headers match */
3321             if (hasSync(&buf[offset+next_frame]) &&
3322                 (buf[offset+3]|0x30) == (buf[offset+next_frame+3]|0x30) ) {
3323                okHeader = 1;
3324             } else {
3325                offset++;
3326             }
3327          } else {
3328             okHeader = 1;
3329          }
3330       } else {
3331          offset++;
3332       }
3333       if (offset > bufLen) {
3334          if (S->debug > 0) Snack_WriteLogInt("Could not find MP3 header", offset);
3335          Tcl_AppendResult(interp, "Could not find MP3 header", NULL);
3336          return TCL_ERROR;
3337       }
3338       passes++;
3339    } while (okHeader == 0);
3340    /*
3341     * We have a valid first sync here
3342     */
3343 
3344    if (S->debug > 0) Snack_WriteLogInt("Found MP3 header at offset", offset);
3345    /* Compute length */
3346    if (ch != NULL) {
3347       /*
3348        * Now find the end of the last valid frame in the file, skipping
3349        * the tag cruft that may throw off our length computations.
3350        */
3351       int tailsize=0;
3352       unsigned char *tailbuf = 0;
3353       int endpos = (int)Tcl_Seek(ch, 0, SEEK_END);
3354       int tailpos = (int)Tcl_Seek(ch, -ENDCHECK, SEEK_END);
3355       int indx = 0;
3356       tailsize = endpos-tailpos;
3357       if (debugLevel > 2) {
3358          Snack_WriteLogInt ("  End Pos at",endpos);
3359          Snack_WriteLogInt ("  Start Pos at",tailpos);
3360       }
3361       if (tailsize > 0) {
3362 
3363          tailbuf = Tcl_Alloc(tailsize);
3364          tailsize = Tcl_Read(ch, tailbuf, tailsize);
3365          /*
3366           * Find the first header (verify that there are two in a row for false syncs
3367           */
3368          while (indx < tailsize) {
3369             unsigned char tsr_index = (tailbuf[indx+2] & 0x0c) >> 2;
3370             if (hasSync(&tailbuf[indx]) && (sr_index == tsr_index)) {
3371                {
3372                   int frameLength = locateNextFrame(&tailbuf[indx]);
3373                   unsigned char tsr_index = (tailbuf[frameLength+indx+2] & 0x0c) >> 2;
3374                   if (hasSync(&tailbuf[frameLength+indx]) && (sr_index == tsr_index)) {
3375                      break;
3376                   }  else {
3377                      indx++;
3378                   }
3379                }
3380             } else {
3381                indx++;
3382             }
3383          }
3384          /*
3385           *  Now we know the first valid frame sync,
3386           * Walk the frames until we don't see any more
3387           */
3388          while (indx < tailsize) {
3389             unsigned char tsr_index = (tailbuf[indx+2] & 0x0c) >> 2;
3390             if (hasSync(&tailbuf[indx]) && (sr_index == tsr_index)) {
3391                int frameLength = locateNextFrame(&tailbuf[indx]);
3392                indx += frameLength;
3393                tailChecked++;
3394                tailTotal+=frameLength;
3395             } else {
3396                break;
3397             }
3398          }
3399 
3400          Tcl_Free(tailbuf);
3401       }
3402       /*
3403        * Check if tailAverage is valid, if not use mean_frame_size (which is first one found)
3404        */
3405 
3406       if (tailChecked > 3)
3407       {
3408          tailAverage=(float)tailTotal/(float)tailChecked;
3409       } else  {
3410          tailAverage=(float)mean_frame_size;
3411       }
3412       totalFrames = (int)((float)(tailpos + indx - (offset + ID3Extra)) / tailAverage);
3413    }
3414    if (obj != NULL) {
3415       if (useOldObjAPI) {
3416          totalFrames = (obj->length - (offset + ID3Extra)) / Si->bytesPerFrame;
3417       } else {
3418 #ifdef TCL_81_API
3419          int length = 0;
3420          Tcl_GetByteArrayFromObj(obj, &length);
3421          totalFrames = (length - (offset + ID3Extra)) / Si->bytesPerFrame;
3422 #endif
3423       }
3424    }
3425 
3426    /*
3427     * If Xing header, then use this data instead (assume it is accurate)
3428     */
3429    if (xAvgBitrate)
3430    {
3431       bitrate = xAvgBitrate;
3432       totalFrames = xFrames;
3433       mean_frame_size = xAvgFrameSize;
3434    } else {
3435       mean_frame_size = (int)roundf(tailAverage);
3436    }
3437    Si->bytesPerFrame = mean_frame_size;
3438    Si->bitrate = bitrate*1000;
3439    Si->bufind = offset + ID3Extra;
3440    Si->restlen = 0;
3441    Si->append = 0;
3442    Si->data = 0;
3443    Si->gotHeader = 1;
3444    memcpy((char *)&Si->headerInt, &buf[offset], 4);
3445    Si->lastByte = buf[offset+3];                 /* save for later, TFW: Can go away hopefully */
3446    Si->sr_index = sr_index;
3447 
3448    S->length = (totalFrames * 576) * (Si->id ? 2:1);
3449    S->headSize = offset + ID3Extra;
3450    S->swap = 0;
3451    S->extHead = (char *) Si;                     /* redundant */
3452    S->extHeadType = SNACK_MP3_INT;
3453    if (debugLevel > 0) {
3454        Snack_WriteLogInt ("  Frame Length",Si->bytesPerFrame);
3455       if (xAvgBitrate==0)
3456           Snack_WriteLogInt ("  CBR Avg Len x1000",(int)(tailAverage*1000.));
3457        Snack_WriteLogInt ("  Total Frames",totalFrames);
3458        Snack_WriteLogInt ("  Bit Rate",Si->bitrate);
3459   }
3460    if (S->debug > 2) Snack_WriteLogInt("    Exit GetMP3Header", S->length);
3461 
3462    return TCL_OK;
3463 }
3464 
3465 int
3466  SeekMP3File(Sound *S, Tcl_Interp *interp, Tcl_Channel ch, int pos) {
3467    int filepos, i, j, tpos;
3468    unsigned int hInt = 0;
3469    int framesize=0;
3470    mp3Info *Si = (mp3Info *)S->extHead;
3471    unsigned char *seekBuffer = NULL;
3472    if (S->debug > 0) Snack_WriteLogInt("    Enter SeekMP3File", pos);
3473 
3474    Si->bufind = S->headSize;
3475    Si->restlen = 0;
3476    Si->append = 0;
3477    Si->cnt = 0;
3478    Si->data = 0;
3479    for (i = 0; i < 32; i++) {
3480       for (j = 0; j < 16; j++) {
3481          Si->u[0][0][i][j] = 0.0f;
3482          Si->u[0][1][i][j] = 0.0f;
3483          Si->u[1][0][i][j] = 0.0f;
3484          Si->u[1][1][i][j] = 0.0f;
3485       }
3486    }
3487    Si->u_start[0] = 0;
3488    Si->u_start[1] = 0;
3489    Si->u_div[0] = 0;
3490    Si->u_div[1] = 0;
3491    for (i = 0; i < 32; i++) {
3492       for (j = 0; j < 18; j++) {
3493          Si->s[0][i][j] = 0.0f;
3494          Si->s[1][i][j] = 0.0f;
3495       }
3496    }
3497 
3498    /* Initally, get approximate position */
3499    /* TFW Note to self: ID3 Tag is accounted for in headSize */
3500 
3501    framesize = Si->id ? 1152:576; /* samples per frame */
3502    filepos = (S->headSize + (int)((float)Si->bytesPerFrame/(float)(framesize) * (float)pos) )&0xfffffffc;
3503    /*
3504     * TFW: For streams, can't seek very far. In fact, can't seek beyound the header size so all seeks fail
3505     */
3506    if (S->debug > 0) Snack_WriteLogInt("    Want to seek to", filepos);
3507    /* Sync up to next valid frame, put file position at start of data following header */
3508    hInt = Si->headerInt;
3509    if (ch != NULL) {
3510       int seekSize = max(Si->bytesPerFrame*25,20000);
3511       int index=0;
3512       tpos = (int)Tcl_Seek(ch, filepos, SEEK_SET);
3513       if (tpos < 0) {
3514          if (S->debug > 0) Snack_WriteLogInt("    Failed to seek to", filepos);
3515          return(filepos);                                  /* Denote seek beyond eof */
3516       } else {
3517          filepos = tpos;
3518       }
3519       seekBuffer = Tcl_Alloc(seekSize);
3520       if (seekBuffer == NULL) {
3521          if (S->debug > 0) Snack_WriteLogInt("    Failed to allocate seek buffer", seekSize);
3522          return -1;
3523       }
3524       seekSize = Tcl_Read(ch, seekBuffer, seekSize);
3525       if (seekSize <= 0) {
3526          if (S->debug > 0) Snack_WriteLogInt("    Read beyond EOF", filepos);
3527          Tcl_Free(seekBuffer);
3528          return(seekSize);                                      /* Denote seek beyond eof */
3529       }
3530       /**
3531        * Scan through buffer and find N consecutive frames, then
3532        * position the file channel to the start of the data
3533        * following the first header.
3534        * (Si->lastByte|0x30) == (tmp[3]|0x30)
3535        */
3536       Si->gotHeader = 0;
3537       while (index < seekSize) {
3538          int syncsNeeded = 3;
3539          int tmpIndex= index;
3540          unsigned char *ref = &seekBuffer[index];
3541          /*
3542           * Make sure we can walk N frame syncs, just to make sure
3543           * Double check against the sr index and other data we consider
3544           * static in the file just to make sure we indeed are at the
3545           * start of a frame.
3546           */
3547          while (tmpIndex < seekSize && tmpIndex > 0 && syncsNeeded > 0) {
3548             unsigned char *tmp = &seekBuffer[tmpIndex];
3549             unsigned char sr_index = (tmp[2] & 0x0c) >> 2;
3550             if (hasSync(tmp) && (sr_index == Si->sr_index) && (Si->lastByte|0x7C) == (tmp[3]|0x7C)) {
3551                int frameLength = locateNextFrame(tmp);
3552                tmpIndex += frameLength;
3553                syncsNeeded--;
3554             } else {
3555                break;
3556             }
3557          }
3558          if (syncsNeeded <= 0) {
3559             memcpy((char *)&Si->headerInt, ref, 4);
3560             Si->gotHeader = 1;
3561             if (S->debug > 2) Snack_WriteLogInt("    Seek done after", index);
3562             /*
3563              * Skip 32 bit header and position at start of data
3564              * (protection field handled elsewhere)
3565              */
3566             Tcl_Seek(ch,filepos + index + 4, SEEK_SET);
3567             Tcl_Free(seekBuffer);
3568             return(pos);
3569          }
3570          index++;
3571       }
3572       /* If we got here, we went past the eof, seek to it */
3573       Tcl_Seek(ch,0,SEEK_END);
3574       if (S->debug > 0) Snack_WriteLogInt("    Seek beyond EOF", filepos+index);
3575       pos = -1;
3576    }
3577 
3578    /*  pos = (pos - S->headSize) / (S->sampsize * S->nchannels);*/
3579 
3580    if (S->debug > 2) Snack_WriteLogInt("    Exit SeekMP3File", pos);
3581    Tcl_Free(seekBuffer);
3582    return(pos);
3583 }
3584 /**
3585  * Determine if the four words are a candidated for a sync
3586  * TFW: add sample rate param, since we know that can't change
3587  * in a stream.
3588  */
3589 int hasSync (unsigned char *buf) {
3590    if ((buf[0] & 0xff) == 0xff &&                          /* frame sync, verify valid */
3591        (buf[1] & 0xe0) == 0xe0 &&                          /* frame sync, verify valid */
3592        (buf[1] & 0x18) != 0x08 &&                          /* Version, 1 not allowed */
3593        (buf[1] & 0x06) == 0x02 &&                          /* Layer 3 only (no layer 2 support yet)*/
3594        (buf[2] & 0x0C) != 0x0c &&                          /* sample rate index, 3 not allowed */
3595        (buf[2] & 0xf0) != 0xf0) {                           /* bitrate, 15 not allowed (0 is allowed but not supported) */
3596       return 1;
3597    }
3598    else {
3599       return 0;
3600    }
3601 }
3602 /**
3603  * Return the offset to the next potential frame based on
3604  * this frames data.
3605  */
3606 int locateNextFrame (unsigned char *tmp) {
3607    int id       = (tmp[1] & 0x08) >> 3;          /* 2 or 3 (0 or 1)*/
3608    int fullID   = (tmp[1] & 0x18) >> 3;          /* full ID layer*/
3609    int layer    = (tmp[1] & 0x06) >> 1;          /* 1 for mp3 */
3610    int br_index = (tmp[2] & 0xf0) >> 4;          /* 10 for 128K layer 3 */
3611    int sr_index = (tmp[2] & 0x0c) >> 2;
3612    int padding  = (tmp[2] & 0x02) >> 1;
3613    int bitrate  = t_bitrate[id][3 - layer][br_index];
3614    int fs       = t_sampling_frequency[fullID][sr_index];   /* 44.1K normally */
3615    int next_frame_pos;
3616    if (bitrate == 0) {
3617       next_frame_pos = 1;                        /* (Free bit rate) This will move the scanner one step forward */
3618    }
3619    else {
3620       next_frame_pos = (bitrate * sr_lookup[id] / fs) + padding;
3621    }
3622    return next_frame_pos;
3623 }
3624 
3625 int
3626 ReadMP3Samples(Sound *s, Tcl_Interp *interp, Tcl_Channel ch, char *ibuf,
3627                float *obuf, int len)
3628 {
3629   struct AUDIO_HEADER header;
3630   int last = -1;
3631   char *rest = (char *)((mp3Info *)s->extHead)->rest;
3632   mp3Info *Si = (mp3Info *)s->extHead;
3633 
3634   if (s->debug > 2) Snack_WriteLogInt("    Enter ReadMP3Samples", len);
3635 
3636   len *= sizeof(float);
3637   /*
3638    * Restore the sound posititions for the common
3639    * values for this particular object.
3640    */
3641   gblGch = ch;
3642   gblOutputbuf = (char *) obuf;
3643   gblReadbuf = ibuf;
3644   gblBufind = Si->bufind;
3645   gblBuffer = Si->buffer;
3646   gblAppend = Si->append;
3647   gblData   = Si->data;
3648   Si->ind = 0;
3649   if (Si->restlen > 0) {
3650     if (Si->restlen > len) {
3651       memcpy(gblOutputbuf, rest, len);
3652       Si->ind = len;
3653       Si->restlen -= len;
3654       memcpy(rest, &rest[len], Si->restlen);
3655     } else {
3656       memcpy(gblOutputbuf, rest, Si->restlen);
3657       Si->ind = Si->restlen;
3658       Si->restlen = 0;
3659     }
3660   }
3661   /* should be already set appropriatly
3662   if (Si->cnt == 0) {
3663     Si->gotHeader = 1;
3664   }
3665   */
3666   for (;; Si->cnt++) {
3667     if (Si->ind >= len) break;
3668     if (Si->ind == last &&
3669         Si->ind > 0) break;
3670     last = Si->ind;
3671     if (processHeader(s, &header, Si->cnt)) break;
3672     if (layer3_frame((mp3Info *)s->extHead, &header, len)) break;
3673   }
3674 
3675   Si->bufind = gblBufind;
3676   Si->append = gblAppend;
3677   Si->data = gblData;
3678 
3679   if (s->debug > 2) Snack_WriteLogInt("    Exit ReadMP3Samples", Si->ind);
3680 
3681   return(Si->ind / sizeof(float));
3682 }
3683 
3684 char *
3685 ExtMP3File(char *s)
3686 {
3687   int l1 = strlen(".mp3");
3688   int l2 = strlen(s);
3689 
3690   if (strncasecmp(".mp3", &s[l2 - l1], l1) == 0) {
3691     return(MP3_STRING);
3692   }
3693   return(NULL);
3694 }
3695 
3696 int
3697 OpenMP3File(Sound *S, Tcl_Interp *interp, Tcl_Channel *ch, char *mode)
3698 {
3699   int i, j;
3700   mp3Info *Si = NULL;
3701 
3702   if (S->debug > 2) Snack_WriteLog("    Enter OpenMP3File\n");
3703 
3704   if (S->extHead != NULL && S->extHeadType != SNACK_MP3_INT) {
3705     Snack_FileFormat *ff;
3706 
3707     for (ff = snackFileFormats; ff != NULL; ff = ff->nextPtr) {
3708       if (strcmp(S->fileType, ff->name) == 0) {
3709         if (ff->freeHeaderProc != NULL) {
3710           (ff->freeHeaderProc)(S);
3711         }
3712       }
3713     }
3714   }
3715 
3716   if (S->extHead == NULL) {
3717     S->extHead = (char *) ckalloc(sizeof(mp3Info));
3718     S->extHeadType = SNACK_MP3_INT;
3719   }
3720   Si = (mp3Info *)S->extHead;
3721   for (i = 0; i < 32; i++) {
3722     for (j = 0; j < 16; j++) {
3723       Si->u[0][0][i][j] = 0.0f;
3724       Si->u[0][1][i][j] = 0.0f;
3725       Si->u[1][0][i][j] = 0.0f;
3726       Si->u[1][1][i][j] = 0.0f;
3727     }
3728   }
3729   for (i = 0; i < 32; i++) {
3730     for (j = 0; j < 18; j++) {
3731       Si->s[0][i][j] = 0.0f;
3732       Si->s[1][i][j] = 0.0f;
3733     }
3734   }
3735   Si->u_start[0] = 0;
3736   Si->u_start[1] = 0;
3737   Si->u_div[0] = 0;
3738   Si->u_div[1] = 0;
3739   Si->cnt = 0;
3740 
3741   if (!initDone) {
3742     InitMP3();
3743     initDone = 1;
3744   }
3745 
3746   if ((*ch = Tcl_OpenFileChannel(interp, S->fcname, mode, 0)) == 0) {
3747     return TCL_ERROR;
3748   }
3749   Tcl_SetChannelOption(interp, *ch, "-translation", "binary");
3750 #ifdef TCL_81_API
3751   Tcl_SetChannelOption(interp, *ch, "-encoding", "binary");
3752 #endif
3753 
3754   if (S->debug > 2) Snack_WriteLog("    Exit OpenMP3File\n");
3755 
3756   return TCL_OK;
3757 }
3758 
3759 int
3760 CloseMP3File(Sound *s, Tcl_Interp *interp, Tcl_Channel *ch)
3761 {
3762   if (s->debug > 2) Snack_WriteLog("    Enter CloseMP3File\n");
3763 
3764   Tcl_Close(interp, *ch);
3765   *ch = NULL;
3766 
3767   if (s->debug > 2) Snack_WriteLog("    Exit CloseMP3File\n");
3768 
3769   return TCL_OK;
3770 }
3771 
3772 void
3773 FreeMP3Header(Sound *s)
3774 {
3775   if (s->debug > 2) Snack_WriteLog("    Enter FreeMP3Header\n");
3776 
3777   if (s->extHead != NULL) {
3778     ckfree((char *)s->extHead);
3779     s->extHead = NULL;
3780     s->extHeadType = 0;
3781   }
3782 
3783   if (s->debug > 2) Snack_WriteLog("    Exit FreeMP3Header\n");
3784 }
3785 
3786 int
3787   ConfigMP3Header(Sound *s, Tcl_Interp *interp, int objc,
3788                   Tcl_Obj *CONST objv[]) {
3789    mp3Info *si = (mp3Info *)s->extHead;
3790    int arg, index;
3791   static CONST84 char *optionStrings[] = {
3792       "-bitrate", NULL
3793    };
3794    enum options {
3795       BITRATE
3796    };
3797 
3798    if (si == NULL || objc < 3) return 0;
3799 
3800    if (objc == 3) {                              /* get option */
3801       if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings, "option", 0,
3802                               &index) != TCL_OK) {
3803          Tcl_AppendResult(interp, ", or\n", NULL);
3804          return 0;
3805       }
3806 
3807       switch ((enum options) index) {
3808          case BITRATE:
3809             {
3810                Tcl_SetObjResult(interp, Tcl_NewIntObj(si->bitrate));
3811                break;
3812             }
3813       }
3814    } else {
3815       for (arg = 2; arg < objc; arg+=2) {
3816          int index;
3817 
3818          if (Tcl_GetIndexFromObj(interp, objv[arg], optionStrings, "option", 0,
3819                                  &index) != TCL_OK) {
3820             return TCL_ERROR;
3821          }
3822 
3823          if (arg + 1 == objc) {
3824             Tcl_AppendResult(interp, "No argument given for ",
3825                              optionStrings[index], " option\n", (char *) NULL);
3826             return 0;
3827          }
3828 
3829          switch ((enum options) index) {
3830             case BITRATE:
3831                {
3832                   break;
3833                }
3834          }
3835       }
3836    }
3837 
3838    return 1;
3839 }
3840