home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 June B / Pcwk6b98.iso / Mpeg3 / Dos / MP3 / MPG12304.EXE / DECODE_4.C < prev    next >
C/C++ Source or Header  |  1997-04-10  |  10KB  |  368 lines

  1. /*
  2.  * Mpeg Layer-1,2,3 audio decoder 
  3.  * ------------------------------
  4.  * copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
  5.  * See also 'README'
  6.  * version for slower machines .. decodes only every fourth sample 
  7.  * dunno why it sounds THIS annoying (maybe we should adapt the window?)
  8.  * absolutely not optimized for this operation 
  9.  */
  10.  
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <string.h>
  14.  
  15. #include "mpg123.h"
  16.  
  17. static void tr(real *here,real *samples);
  18.  
  19. #define WRITE_SAMPLE(samples,sum,clip) \
  20.   if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
  21.   else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \
  22.   else { *(samples) = sum; }
  23.  
  24. int synth_4to1(real *bandPtr,int channel,short *samples)
  25. {
  26.   static real buf1[0x200],buf0[0x200];
  27.   static int boc[2]={1,1};
  28.   static real *buffs[2] = { buf0,buf1 };
  29.   int bo;
  30.   int clip = 0; 
  31.   real *buf = buffs[channel];
  32.   static const int step = 2;
  33.  
  34.   samples += channel;
  35.  
  36.   bo = boc[channel];
  37.   bo--;
  38.   bo &= 0xf;
  39.   boc[channel] = bo;
  40.  
  41.   tr(buf+(bo<<5),bandPtr); /* writes values from buf[0] to buf[3f] */
  42.  
  43.   if(bo & 0x1) {
  44.     register int j;
  45.     register real *window,*b0,*b1,sum;
  46.     window = decwin + 16 - bo;
  47.  
  48.     b0 = buf + 15;
  49.     b1 = buf + 15;
  50.     for (j=4;j;j--,b0+=4,b1-=4,window+=112)
  51.     {
  52.       sum  = *window++ * b0[0x000];
  53.       sum -= *window++ * b1[0x020];
  54.       sum += *window++ * b0[0x040];
  55.       sum -= *window++ * b1[0x060];
  56.       sum += *window++ * b0[0x080];
  57.       sum -= *window++ * b1[0x0a0];
  58.       sum += *window++ * b0[0x0c0];
  59.       sum -= *window++ * b1[0x0e0];
  60.       sum += *window++ * b0[0x100];
  61.       sum -= *window++ * b1[0x120];
  62.       sum += *window++ * b0[0x140];
  63.       sum -= *window++ * b1[0x160];
  64.       sum += *window++ * b0[0x180];
  65.       sum -= *window++ * b1[0x1a0];
  66.       sum += *window++ * b0[0x1c0];
  67.       sum -= *window++ * b1[0x1e0];
  68.  
  69.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  70.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  71.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  72.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  73.     }
  74.  
  75.     {
  76.       sum  = window[0] * b0[0x000];
  77.       sum += window[2] * b0[0x040];
  78.       sum += window[4] * b0[0x080];
  79.       sum += window[6] * b0[0x0c0];
  80.       sum += window[8] * b0[0x100];
  81.       sum += window[10] * b0[0x140];
  82.       sum += window[12] * b0[0x180];
  83.       sum += window[14] * b0[0x1c0];
  84.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  85.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  86.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  87.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  88.       b0-=4,b1+=4,window-=128;
  89.     }
  90.     window += bo<<1;
  91.  
  92.     for (j=3;j;j--,b0-=4,b1+=4,window-=112)
  93.     {
  94.       sum = -*(--window) * b0[0x000];
  95.       sum -= *(--window) * b1[0x020];
  96.       sum -= *(--window) * b0[0x040];
  97.       sum -= *(--window) * b1[0x060];
  98.       sum -= *(--window) * b0[0x080];
  99.       sum -= *(--window) * b1[0x0a0];
  100.       sum -= *(--window) * b0[0x0c0];
  101.       sum -= *(--window) * b1[0x0e0];
  102.       sum -= *(--window) * b0[0x100];
  103.       sum -= *(--window) * b1[0x120];
  104.       sum -= *(--window) * b0[0x140];
  105.       sum -= *(--window) * b1[0x160];
  106.       sum -= *(--window) * b0[0x180];
  107.       sum -= *(--window) * b1[0x1a0];
  108.       sum -= *(--window) * b0[0x1c0];
  109.       sum -= *(--window) * b1[0x1e0];
  110.  
  111.  
  112.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  113.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  114.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  115.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  116.     }
  117.   }
  118.   else {
  119.     register int j;
  120.     register real *window,*b0,*b1,sum;
  121.     window = decwin + 16 - bo;
  122.  
  123.     b0 = buf + 15;
  124.     b1 = buf + 15;
  125.     for (j=4;j;j--,b0-=4,b1+=4,window+=112) 
  126.     {
  127.       sum = -*window++ * b0[0x000];
  128.       sum += *window++ * b1[0x020];
  129.       sum -= *window++ * b0[0x040];
  130.       sum += *window++ * b1[0x060];
  131.       sum -= *window++ * b0[0x080];
  132.       sum += *window++ * b1[0x0a0];
  133.       sum -= *window++ * b0[0x0c0];
  134.       sum += *window++ * b1[0x0e0];
  135.       sum -= *window++ * b0[0x100];
  136.       sum += *window++ * b1[0x120];
  137.       sum -= *window++ * b0[0x140];
  138.       sum += *window++ * b1[0x160];
  139.       sum -= *window++ * b0[0x180];
  140.       sum += *window++ * b1[0x1a0];
  141.       sum -= *window++ * b0[0x1c0];
  142.       sum += *window++ * b1[0x1e0];
  143.  
  144.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  145.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  146.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  147.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  148.     }
  149.     {
  150.       sum  = window[1] * b1[0x020];
  151.       sum += window[3] * b1[0x060];
  152.       sum += window[5] * b1[0x0a0];
  153.       sum += window[7] * b1[0x0e0];
  154.       sum += window[9] * b1[0x120];
  155.       sum += window[11] * b1[0x160];
  156.       sum += window[13] * b1[0x1a0];
  157.       sum += window[15] * b1[0x1e0];
  158.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  159.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  160.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  161.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  162.       b0+=4,b1-=4,window-=128;
  163.     }
  164.     window += bo<<1;
  165.     for (j=3;j;j--,b0+=4,b1-=4,window-=112)
  166.     {
  167.       sum = -*(--window) * b0[0x000];
  168.       sum -= *(--window) * b1[0x020];
  169.       sum -= *(--window) * b0[0x040];
  170.       sum -= *(--window) * b1[0x060];
  171.       sum -= *(--window) * b0[0x080];
  172.       sum -= *(--window) * b1[0x0a0];
  173.       sum -= *(--window) * b0[0x0c0];
  174.       sum -= *(--window) * b1[0x0e0];
  175.       sum -= *(--window) * b0[0x100];
  176.       sum -= *(--window) * b1[0x120];
  177.       sum -= *(--window) * b0[0x140];
  178.       sum -= *(--window) * b1[0x160];
  179.       sum -= *(--window) * b0[0x180];
  180.       sum -= *(--window) * b1[0x1a0];
  181.       sum -= *(--window) * b0[0x1c0];
  182.       sum -= *(--window) * b1[0x1e0];
  183.  
  184.  
  185.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  186.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  187.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  188.       WRITE_SAMPLE(samples,sum,clip); samples += step;
  189.     }
  190.   }
  191.  
  192.   return(clip);
  193. }
  194.  
  195. /*
  196.  * -funroll-loops (for gcc) will remove the loops for better performance
  197.  * using loops in the source-code enhances readabillity
  198.  */
  199.  
  200. static void tr(real *here,real *samples)
  201. {
  202.   real bufs[64];
  203.  
  204.   {
  205.     int i;
  206.     for(i=8;i<32;i++)
  207.       samples[i] = 0.0;
  208.   }
  209.  
  210.  
  211.  {
  212.   register int i,j;
  213.   register real *b1,*b2,*bs,*costab;
  214.  
  215.   b1 = samples;
  216.   bs = bufs;
  217.   costab = pnts[0]+16;
  218.   b2 = b1 + 32;
  219.  
  220.   for(i=15;i>=0;i--)
  221.     *bs++ = (*b1++ + *--b2); 
  222.   for(i=15;i>=0;i--)
  223.     *bs++ = (*--b2 - *b1++) * *--costab;
  224.  
  225.   b1 = bufs;
  226.   costab = pnts[1]+8;
  227.   b2 = b1 + 16;
  228.  
  229.   {
  230.     for(i=7;i>=0;i--)
  231.       *bs++ = (*b1++ + *--b2); 
  232.     for(i=7;i>=0;i--)
  233.       *bs++ = (*--b2 - *b1++) * *--costab; 
  234.     b2 += 32;
  235.     costab += 8;
  236.     for(i=7;i>=0;i--)
  237.       *bs++ = (*b1++ + *--b2); 
  238.     for(i=7;i>=0;i--)
  239.       *bs++ = (*b1++ - *--b2) * *--costab; 
  240.     b2 += 32;
  241.   }
  242.  
  243.   bs = bufs;
  244.   costab = pnts[2];
  245.   b2 = b1 + 8;
  246.  
  247.   for(j=2;j;j--)
  248.   {
  249.     for(i=3;i>=0;i--)
  250.       *bs++ = (*b1++ + *--b2); 
  251.     for(i=3;i>=0;i--)
  252.       *bs++ = (*--b2 - *b1++) * costab[i]; 
  253.     b2 += 16;
  254.     for(i=3;i>=0;i--)
  255.       *bs++ = (*b1++ + *--b2); 
  256.     for(i=3;i>=0;i--)
  257.       *bs++ = (*b1++ - *--b2) * costab[i]; 
  258.     b2 += 16;
  259.   }
  260.  
  261.   b1 = bufs;
  262.   costab = pnts[3];
  263.   b2 = b1 + 4;
  264.  
  265.   for(j=4;j;j--)
  266.   {
  267.     *bs++ = (*b1++ + *--b2); 
  268.     *bs++ = (*b1++ + *--b2);
  269.     *bs++ = (*--b2 - *b1++) * costab[1]; 
  270.     *bs++ = (*--b2 - *b1++) * costab[0];
  271.     b2 += 8;
  272.     *bs++ = (*b1++ + *--b2); 
  273.     *bs++ = (*b1++ + *--b2);
  274.     *bs++ = (*b1++ - *--b2) * costab[1]; 
  275.     *bs++ = (*b1++ - *--b2) * costab[0];
  276.     b2 += 8;
  277.   }
  278.   bs = bufs;
  279.   costab = pnts[4];
  280.   b2 = b1 + 2;
  281.  
  282.   for(j=8;j;j--)
  283.   {
  284.     *bs++ = (*b1++ + *--b2);
  285.     *bs++ = (*--b2 - *b1++) * (*costab);
  286.     b2 += 4;
  287.     *bs++ = (*b1++ + *--b2);
  288.     *bs++ = (*b1++ - *--b2) * (*costab);
  289.     b2 += 4;
  290.   }
  291.  
  292.  }
  293.  
  294.  
  295.  {
  296.   register real *b1;
  297.   register int i;
  298.  
  299.   for(b1=bufs,i=8;i;i--,b1+=4)
  300.     b1[2] += b1[3];
  301.  
  302.   for(b1=bufs,i=4;i;i--,b1+=8)
  303.   {
  304.     b1[4] += b1[6];
  305.     b1[6] += b1[5];
  306.     b1[5] += b1[7];
  307.   }
  308.  
  309.   for(b1=bufs,i=2;i;i--,b1+=16)
  310.   {
  311.     b1[8]  += b1[12];
  312.     b1[12] += b1[10];
  313.     b1[10] += b1[14];
  314.     b1[14] += b1[9];
  315.     b1[9]  += b1[13];
  316.     b1[13] += b1[11];
  317.     b1[11] += b1[15];
  318.   }
  319.   {
  320.     b1 = bufs+16;
  321.     b1[0]  += b1[8];
  322.     b1[8]  += b1[4];
  323.     b1[4]  += b1[12];
  324.     b1[12] += b1[2];
  325.     b1[2]  += b1[10];
  326.     b1[10] += b1[6];
  327.     b1[6]  += b1[14];
  328.     b1[14] += b1[1];
  329.     b1[1]  += b1[9];
  330.     b1[9]  += b1[5];
  331.     b1[5]  += b1[13];
  332.     b1[13] += b1[3];
  333.     b1[3]  += b1[11];
  334.     b1[11] += b1[7];
  335.     b1[7]  += b1[15];
  336.   }
  337.  }
  338.  
  339. #if 1
  340.  {
  341.   register real *a1=bufs;
  342.   here[31] = *a1++; here[15] = *a1++; here[23] = *a1++; here[ 7] = *a1++;
  343.   here[27] = *a1++; here[11] = *a1++; here[19] = *a1++; here[ 3] = *a1++;
  344.   here[29] = *a1++; here[13] = *a1++; here[21] = *a1++; here[ 5] = *a1++;
  345.   here[25] = *a1++; here[ 9] = *a1++; here[17] = *a1++; here[ 1] = *a1++;
  346.   here[30] = *a1++; here[14] = *a1++; here[22] = *a1++; here[ 6] = *a1++;
  347.   here[26] = *a1++; here[10] = *a1++; here[18] = *a1++; here[ 2] = *a1++;
  348.   here[28] = *a1++; here[12] = *a1++; here[20] = *a1++; here[ 4] = *a1++;
  349.   here[24] = *a1++; here[ 8] = *a1++; here[16] = *a1++; here[ 0] = *a1;
  350.  }
  351. #else
  352.   {
  353.     static int pos[32] = {
  354.       31,15,23,7 , 27,11,19,3 , 29,13,21,5 , 25,9,17,1 ,
  355.       30,14,22,6 , 26,10,18,2 , 28,12,20,4 , 24,8,16,0 };
  356.     register int i,*p = pos;
  357.     register real *a1;
  358.  
  359.     a1 = bufs;
  360.     for(i=31;i>=0;i--)
  361.       here[*p++] = *a1++;
  362.   }
  363. #endif
  364.  
  365. }
  366.  
  367.  
  368.