home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / HUDBA / COOLED / PLUGINS / MPDECODE / MPG.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-17  |  21.2 KB  |  702 lines

  1. #include <windows.h>
  2. #include "..\filters.h"
  3. #include "common.h"
  4. #include "decoder.h"
  5.  
  6. typedef short PCM[2][3][SBLIMIT];
  7.     PCM FAR *pcm_sample;
  8. typedef unsigned int SAM[2][3][SBLIMIT];
  9.     SAM FAR *sample;
  10. typedef double FRA[2][3][SBLIMIT];
  11.     FRA FAR *fraction;
  12. typedef double VE[2][HAN_SIZE];
  13.     VE FAR *w;
  14.  
  15.     Bit_stream_struc  bs;
  16.     frame_params      fr_ps;
  17.     layer             info;
  18.     unsigned long     sample_frames;
  19.     int               themode=0;
  20.  
  21.     int               i, j, k, stereo, done=FALSE, clip, sync;
  22.     int               error_protection, crc_error_count, total_error_count;
  23.     unsigned int      old_crc, new_crc;
  24.     unsigned int      bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT],
  25.                       scale_index[2][3][SBLIMIT];
  26.     unsigned long     bitsPerSlot, samplesPerFrame, frameNum = 0;
  27.     unsigned long     frameBits, gotBits = 0;
  28.     char              encoded_file_name[MAX_NAME_SIZE];
  29.     char              decoded_file_name[MAX_NAME_SIZE];
  30.     char              t[50];
  31.     int               need_aiff;
  32.     int topSb = 0;           
  33.     
  34.     DWORD bbufat=0;
  35.     
  36.     #define MPEG_LAYER1 1
  37. #define MPEG_LAYER2 2
  38. #define MPEG_MODEL1 4
  39. #define MPEG_MODEL2 8
  40. #define MPEG_EMPHANO 16
  41. #define MPEG_EMPHA1 32
  42. #define MPEG_EMPHA2 64 
  43. #define MPEG_JOINTSTEREO 128
  44. #define MPEG_ERRORPROTECTION 0x010000
  45. #define MPEG_COPYRIGHT         0x020000
  46. #define MPEG_ORIGINAL         0x040000
  47.     
  48. typedef struct output_tag  // any special vars associated with output file
  49.     {short nFile;         
  50.      long lSize;
  51.     } MYOUTPUT;
  52.  
  53. typedef struct input_tag // any special vars associated with input file
  54.     {short nFile;
  55.      long lSize;
  56.      long lSamprate;
  57.      DWORD options;
  58.     } MYINPUT;
  59.  
  60. HANDLE myInstance=NULL;
  61.  
  62. BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
  63. {
  64.    switch (fdwReason)
  65.    {
  66.       case DLL_PROCESS_ATTACH:
  67.         /* Code from LibMain inserted here.  Return TRUE to keep the
  68.             DLL loaded or return FALSE to fail loading the DLL.
  69.  
  70.             You may have to modify the code in your original LibMain to
  71.             account for the fact that it may be called more than once.
  72.             You will get one DLL_PROCESS_ATTACH for each process that
  73.             loads the DLL. This is different from LibMain which gets
  74.             called only once when the DLL is loaded. The only time this
  75.             is critical is when you are using shared data sections.
  76.             If you are using shared data sections for statically
  77.             allocated data, you will need to be careful to initialize it
  78.             only once. Check your code carefully.
  79.  
  80.             Certain one-time initializations may now need to be done for
  81.             each process that attaches. You may also not need code from
  82.             your original LibMain because the operating system may now
  83.             be doing it for you.
  84.          */
  85.  
  86.          myInstance=hModule;
  87.     
  88.          break;
  89.  
  90.       case DLL_THREAD_ATTACH:
  91.          /* Called each time a thread is created in a process that has
  92.             already loaded (attached to) this DLL. Does not get called
  93.             for each thread that exists in the process before it loaded
  94.             the DLL.
  95.  
  96.             Do thread-specific initialization here.
  97.          */
  98.          break;
  99.  
  100.       case DLL_THREAD_DETACH:
  101.          /* Same as above, but called when a thread in the process
  102.             exits.
  103.  
  104.             Do thread-specific cleanup here.
  105.          */
  106.          break;
  107.  
  108.       case DLL_PROCESS_DETACH:
  109.          /* Code from _WEP inserted here.  This code may (like the
  110.             LibMain) not be necessary.  Check to make certain that the
  111.             operating system is not doing it for you.
  112.          */
  113.          myInstance=NULL;
  114.          break;
  115.    }
  116.  
  117.    /* The return value is only used for DLL_PROCESS_ATTACH; all other
  118.       conditions are ignored.  */
  119.    return TRUE;   // successful DLL_PROCESS_ATTACH
  120. }
  121.  
  122. // Fill COOLQUERY structure with information regarding this file filter
  123.  
  124. __declspec(dllexport) short FAR PASCAL QueryCoolFilter(COOLQUERY far * cq)
  125. {   lstrcpy(cq->szName,"MPEG");         
  126.     lstrcpy(cq->szCopyright,"MPEG II Decoder (GNU General Public License)");
  127.     lstrcpy(cq->szExt,"MP2");
  128.     lstrcpy(cq->szExt2,"MP1");
  129.     lstrcpy(cq->szExt3,"MPG");
  130.     cq->lChunkSize=16384; 
  131.     cq->dwFlags=QF_RATEADJUSTABLE|QF_CANLOAD;
  132.     cq->Stereo8=0; 
  133.     cq->Stereo16=R_32075|R_44100|R_48000;
  134.     cq->Stereo24=0;
  135.     cq->Stereo32=0;
  136.     cq->Mono8=0; 
  137.     cq->Mono16=R_32075|R_44100|R_48000;
  138.     cq->Mono24=0;
  139.     cq->Mono32=0;
  140.     cq->Quad32=0;
  141.     cq->Quad16=0;
  142.     cq->Quad8=0;
  143.     return C_VALIDLIBRARY;
  144. }
  145.  
  146. __declspec(dllexport) long FAR PASCAL FilterGetFileSize(HANDLE hInput)
  147. {       long lSize=0L;
  148.     //char m[50];
  149.     //wsprintf(m,"FilterGetSize: Handle=%04X\n",hInput);
  150.     //OutputDebugString(m);
  151.     if (hInput)
  152.     {       MYINPUT far *mi;
  153.         mi=(MYINPUT far *)GlobalLock(hInput);
  154.         lSize=mi->lSize;
  155.         //wsprintf(m,"FilterGetSize: Size = %ld\n",lSize);
  156.         //OutputDebugString(m);
  157.         GlobalUnlock(hInput);
  158.     }
  159.     return lSize;
  160. }
  161.  
  162. __declspec(dllexport) BOOL FAR PASCAL FilterUnderstandsFormat(LPSTR filename)
  163. {    //char m[100];
  164.     //wsprintf(m,"Checking VOC support for %s\n",filename);
  165.     //OutputDebugString(m);
  166.     if ((lstrlen(filename)>4) && 
  167.         ((strcmpi(filename+lstrlen(filename)-4,".mpg")==0) ||
  168.          (strcmpi(filename+lstrlen(filename)-4,".mp2")==0) ||
  169.          (strcmpi(filename+lstrlen(filename)-4,".mp1")==0)         
  170.          ))
  171.     {    //OutputDebugString("Supported VOC!\n");
  172.           return TRUE;
  173.       }
  174.       return FALSE;
  175. }
  176.  
  177. __declspec(dllexport) DWORD FAR PASCAL FilterOptions(HANDLE hInput)
  178. {   MYINPUT far *mi;
  179.     DWORD options;
  180.     if (!hInput) return 0;
  181.     mi=(MYINPUT far *)GlobalLock(hInput);
  182.     options=(DWORD)mi->options;
  183.     GlobalUnlock(hInput);
  184.     return options;
  185. }
  186.  
  187. /*
  188. #define MPEG_LAYER1 1
  189. #define MPEG_LAYER2 2
  190. #define MPEG_MODEL1 4
  191. #define MPEG_MODEL2 8
  192. #define MPEG_EMPHANO 16
  193. #define MPEG_EMPHA1 32
  194. #define MPEG_EMPHA2 64 
  195. #define MPEG_JOINTSTEREO 128
  196. #define MPEG_ERRORPROTECTION 0x010000
  197. #define MPEG_COPYRIGHT         0x020000
  198. #define MPEG_ORIGINAL         0x040000
  199. */
  200.  
  201. __declspec(dllexport) DWORD FAR PASCAL FilterOptionsString(HANDLE hInput, LPSTR szString)
  202. {   MYINPUT far *mi;
  203.     DWORD options;
  204.     short compression;
  205.     short sf; 
  206.     double bps;
  207.     short x,y;
  208.     short r;
  209.     
  210.     short bitrate[3][15] = {
  211.             {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
  212.             {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
  213.             {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}
  214.            };
  215.          
  216.     
  217.     if (!hInput) return 0;
  218.     mi=(MYINPUT far *)GlobalLock(hInput);
  219.     options=(DWORD)mi->options;
  220.     
  221.     lstrcpy(szString,"MPEG Encoded ");
  222.     if (options&MPEG_LAYER1)
  223.     {    lstrcpy(szString+lstrlen(szString),"Layer I ");
  224.         r=0;
  225.     }
  226.     else
  227.     {    lstrcpy(szString+lstrlen(szString),"Layer II ");
  228.         r=1;
  229.     }
  230.     if (options&MPEG_MODEL1)
  231.         lstrcpy(szString+lstrlen(szString),"Model 1 ");
  232.     else    
  233.         lstrcpy(szString+lstrlen(szString),"Model 2 ");
  234.     compression=(short)((options>>8)&0x0F);
  235.     
  236.     
  237.     if (mi->lSamprate<=32075) sf = 2;
  238.     else if (mi->lSamprate<=44100) sf = 0;
  239.     else if (mi->lSamprate<=48000) sf = 1;
  240.     else sf = 1;
  241.       
  242.     bps=(double)bitrate[r][compression]*1024.0/(double)mi->lSamprate;
  243.     x=(short)bps;
  244.     bps=bps-(double)x;
  245.     y=(short)(bps*100);
  246.     wsprintf(szString+lstrlen(szString),"%01d.%02d bits/sample (%d bps)",x,y,bitrate[r][compression]);
  247.     GlobalUnlock(hInput);
  248.     return options;
  249. }
  250.  
  251.  
  252. __declspec(dllexport) DWORD FAR PASCAL FilterCanWriteSpecial(HANDLE hOutput, DWORD idType)
  253. {
  254.  return 0L;
  255. }
  256.  
  257. __declspec(dllexport) DWORD FAR PASCAL FilterCanReadSpecial(HANDLE hInput, DWORD idType)
  258. {
  259.  return 0L;
  260. }
  261.                      
  262. __declspec(dllexport) DWORD FAR PASCAL FilterWriteSpecial(HANDLE hOutput, DWORD idType, unsigned char far *buf, DWORD dwSize)
  263. {
  264.  return 0L;
  265. }
  266.  
  267. __declspec(dllexport) DWORD FAR PASCAL FilterReadSpecial(HANDLE hOutput, DWORD idType, unsigned char far *buf, DWORD dwSize)
  268. {
  269.  return 0L;
  270. }
  271.  
  272.  
  273.  
  274. __declspec(dllexport) HANDLE FAR PASCAL OpenFilterOutput(LPSTR lpstrFilename,long lSamprate,WORD wBitsPerSample,WORD wChannels,long lSize,long far *lpChunkSize,DWORD dwOptions)
  275. {       HANDLE hOutput;
  276.     short nFile;
  277.     nFile=_lcreat(lpstrFilename,0);
  278.     if (nFile==-1) return NULL;
  279.     hOutput=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,sizeof(MYOUTPUT));
  280.     if (hOutput)
  281.     {   MYOUTPUT far *mo;
  282.     mo=(MYOUTPUT far *)GlobalLock(hOutput);
  283.     mo->nFile=nFile;
  284.     mo->lSize=lSize;
  285.     GlobalUnlock(hOutput);
  286.     }
  287.     *lpChunkSize=16384;
  288.     return hOutput;
  289. }
  290.  
  291. __declspec(dllexport) void FAR PASCAL CloseFilterOutput(HANDLE hOutput)
  292. {   if (hOutput)
  293.     {       MYOUTPUT far *mo;
  294.         mo=(MYOUTPUT far *)GlobalLock(hOutput);
  295.         if (mo->nFile!=-1)
  296.         {       _lclose(mo->nFile);
  297.             mo->nFile=-1;
  298.         }
  299.         GlobalUnlock(hOutput);
  300.         GlobalFree(hOutput);
  301.     }
  302. }
  303.  
  304. __declspec(dllexport) DWORD FAR PASCAL WriteFilterOutput(HANDLE hOutput, unsigned char far *buf, long lBytes)
  305. {       DWORD written=0L;
  306.     if (hOutput)
  307.     {       MYOUTPUT far *mo;
  308.         mo=(MYOUTPUT far *)GlobalLock(hOutput);
  309.         written=(DWORD)_lwrite(mo->nFile,buf,(UINT)lBytes);
  310.         GlobalUnlock(hOutput);
  311.     }
  312.     return written; 
  313. }
  314.  
  315.  
  316. HANDLE hMemory=NULL;
  317. unsigned char far *memory=NULL;
  318. long bbuflen=0;     
  319.  
  320. short CycleToFillMemory(void);
  321.  
  322. // return handle that will be passed in to close, and write routines
  323. __declspec(dllexport) HANDLE FAR PASCAL OpenFilterInput( LPSTR lpstrFilename,
  324.                                             long far *lSamprate,
  325.                                             WORD far *wBitsPerSample,
  326.                                             WORD far *wChannels,
  327.                                             HWND hWnd,
  328.                                             long far *lChunkSize)
  329. {       HANDLE hInput;
  330.     //char m[100];
  331.     char lpszFilename[128];
  332.     long lBitRate;
  333.     short source; 
  334.     long fullsize;
  335.     DWORD dwOptions;
  336.     
  337.     dwOptions=0;
  338.     
  339.     source=_lopen(lpstrFilename,OF_READ);
  340.     if (source==-1) return NULL;     
  341.     
  342.     fullsize=_llseek(source,0L,2);
  343.     _lclose(source);
  344.     
  345.     hInput=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,sizeof(MYINPUT));
  346.     if (hInput)
  347.     {   MYINPUT far *mi;
  348.     mi=(MYINPUT far *)GlobalLock(hInput);
  349.     //wsprintf(m,"OpenFilterInput: Size = %ld\n",mi->lSize);
  350.     //OutputDebugString(m);
  351.     //_llseek(nFile,0L,0);
  352.     // return 0 for cool to inquire user for sample rates
  353.     *lSamprate=44100;
  354.     *wBitsPerSample=16;
  355.     *wChannels=2;
  356.     *lChunkSize=16384;
  357.     
  358.     /* Most large variables are declared dynamically to ensure
  359.        compatibility with smaller machines */
  360.     
  361.     {//char m[100];
  362.      //wsprintf(m,"My instance = %04X\n",myInstance);
  363.      //OutputDebugString(m);
  364.      GetModuleFileName(myInstance,(LPSTR)lpszFilename,128);
  365.      //OutputDebugString(lpszFilename);
  366.      //OutputDebugString("\n");
  367.      lstrcpy(strrchr((LPSTR)lpszFilename,'\\'),"\\MPEG.DAT");
  368.     };
  369.     
  370.     if (table_ready(lpszFilename)==1)  // davej@microsoft.com compiled data files into one
  371.     {    //char m[100];
  372.          //wsprintf(m,"Could not open %s!\n",(LPSTR)lpszFilename);
  373.          //OutputDebugString(m);
  374.          GlobalUnlock(hInput);
  375.          GlobalFree(hInput);
  376.          return NULL;
  377.     }
  378.     
  379.     pcm_sample = (PCM FAR *) mem_alloc((long) sizeof(PCM), "PCM Samp");
  380.     sample = (SAM FAR *) mem_alloc((long) sizeof(SAM), "Sample");
  381.     fraction = (FRA FAR *) mem_alloc((long) sizeof(FRA), "fraction");
  382.     w = (VE FAR *) mem_alloc((long) sizeof(VE), "w");
  383.  
  384.     fr_ps.header = &info;
  385.     fr_ps.tab_num = -1;                /* no table loaded */
  386.     fr_ps.alloc = NULL;
  387.     for (i=0;i<HAN_SIZE;i++) for (j=0;j<2;j++) (*w)[j][i] = 0.0;
  388.     
  389.     lstrcpy(encoded_file_name,lpstrFilename);
  390.     
  391.     open_bit_stream_r(&bs, encoded_file_name, BUFFER_SIZE);
  392.     
  393.     *lChunkSize=BUFFER_SIZE;
  394.  
  395.     sample_frames = 0;
  396.     //{char m[128];
  397.     // wsprintf(m,"OpenFilterInput: Returning handle %04X, lchunksize=%ld\n",hInput,(*lChunkSize));
  398.     // OutputDebugString(m);
  399.     //}
  400.     hMemory=GlobalAlloc(GMEM_MOVEABLE,16384);
  401.     memory=(unsigned char far *)GlobalLock(hMemory);
  402.     bbufat=0;
  403.     bbuflen=0;
  404.     
  405.     
  406.     CycleToFillMemory();
  407.     
  408.     *wChannels=stereo;
  409.     *lSamprate=(long)(s_freq[info.sampling_frequency]*1000.0);
  410.      
  411.     lBitRate=(long)(bitrate[info.lay-1][info.bitrate_index])*1024/8;
  412.     
  413.     if (themode==MPG_MD_JOINT_STEREO)
  414.         dwOptions|=MPEG_JOINTSTEREO;
  415.     dwOptions|=(info.bitrate_index<<8);
  416.     if (info.error_protection)
  417.         dwOptions|=MPEG_ERRORPROTECTION;
  418.     if (info.copyright)
  419.         dwOptions|=MPEG_COPYRIGHT;
  420.     if (info.original)
  421.         dwOptions|=MPEG_ORIGINAL;
  422.        if (info.lay==1)
  423.            dwOptions|=MPEG_LAYER1;
  424.        else
  425.            dwOptions|=MPEG_LAYER2;
  426.        
  427.        dwOptions|=MPEG_MODEL2;
  428.        
  429.        if (info.emphasis==1)
  430.            dwOptions|=MPEG_EMPHA1;
  431.        else if (info.emphasis==3)
  432.            dwOptions|=MPEG_EMPHA2;
  433.        else
  434.            dwOptions|=MPEG_EMPHANO;
  435.        
  436.        mi->options=dwOptions;
  437.     
  438.        
  439.     mi->lSize=(long)(2.0*(double)(*wChannels)*(double)(*lSamprate)*((double)fullsize/(double)lBitRate*1.03));
  440.     
  441.     //{char m[140];
  442.     // wsprintf(m,"bytes/sec = %ld, total size = %ld, samprate=%ld, channels=%d, ucsize = %ld\n",
  443.     //           lBitRate,fullsize,(*lSamprate),(*wChannels),mi->lSize);
  444.     // OutputDebugString(m);
  445.     //};
  446.     
  447.     //mi->lSize+=8192; // breathing room?
  448.     mi->lSamprate=*lSamprate;
  449.     
  450.     GlobalUnlock(hInput);
  451.     }
  452.     
  453.     return hInput;
  454. }
  455.  
  456. __declspec(dllexport) void FAR PASCAL CloseFilterInput(HANDLE hInput)
  457. {   if (hInput)  
  458.     {       MYINPUT far *mi;
  459.         mi=(MYINPUT far *)GlobalLock(hInput);
  460.         
  461.         close_bit_stream_r(&bs);
  462.         
  463.         GlobalUnlock(hInput);
  464.         GlobalFree(hInput);
  465.       
  466.           mem_free((void **)&pcm_sample);
  467.           mem_free((void **)&sample);
  468.           mem_free((void **)&fraction);
  469.           mem_free((void **)&w);
  470.  
  471.         if (memory)
  472.         {    GlobalUnlock(hMemory);
  473.             memory=NULL;
  474.         }
  475.         if (hMemory)
  476.         {    GlobalFree(hMemory);
  477.             hMemory=NULL;
  478.         }
  479.         
  480.     }
  481. }
  482.  
  483. short CycleToFillMemory(void)
  484. {       unsigned char far *buf;
  485.         //char m[128];
  486.         //ProfStart(); 
  487.     
  488.         buf=memory+bbuflen;
  489.         bbufat=0;
  490.         //OutputDebugString("Setting bbufat to 0\n");
  491.         //wsprintf(m,"buf = memory + %ld\n",bbuflen);
  492.         //OutputDebugString(m);
  493.         
  494.        
  495.         
  496.        if (end_bs(&bs)) 
  497.             {    //ProfStop();
  498.                return 1;
  499.             }
  500.        
  501.        
  502.        sync = seek_sync(&bs, SYNC_WORD, SYNC_WORD_LNGTH);
  503.        frameBits = sstell(&bs) - gotBits;
  504.        if(frameNum > 0)        /* don't want to prshort on 1st loop; no lay */
  505.           if(frameBits%bitsPerSlot)
  506.              {//char m[128];
  507.               //wsprintf(m,"Got %ld bits = %ld slots plus %ld\n",
  508.               //       frameBits, frameBits/bitsPerSlot, frameBits%bitsPerSlot);
  509.               //OutputDebugString(m);
  510.              }
  511.        gotBits += frameBits;
  512.  
  513.        if (!sync) {
  514.           //OutputDebugString("Frame cannot be located\n");
  515.           //OutputDebugString("Input stream may be empty\n");
  516.           done = TRUE;
  517.           /* finally write out the buffer */
  518.           if (info.lay == 2) out_fifo(*pcm_sample, 3, &fr_ps, done,
  519.                                       buf, &sample_frames);
  520.           else               out_fifo(*pcm_sample, 1, &fr_ps, done,
  521.                                       buf, &sample_frames);
  522.           //ProfStop();
  523.                
  524.           return -1;
  525.        }
  526.  
  527.        decode_info(&bs, &fr_ps);
  528.        hdr_to_frps(&fr_ps);
  529.        themode = fr_ps.header->mode;
  530.        stereo = fr_ps.stereo;
  531.        error_protection = info.error_protection;
  532.        crc_error_count = 0;
  533.        total_error_count = 0;
  534.        //if(frameNum == 0) WriteHdr(&fr_ps);  /* printout layer/mode */
  535.        //{char m[100];
  536.        // wsprintf(m, "{%4lu}", frameNum++);
  537.        // OutputDebugString(m);
  538.        //}
  539.        if (error_protection) buffer_CRC(&bs, &old_crc);
  540.        switch (info.lay) {
  541.  
  542.           case 1: {
  543.              bitsPerSlot = 32;        samplesPerFrame = 384;
  544.              I_decode_bitalloc(&bs,bit_alloc,&fr_ps);
  545.              I_decode_scale(&bs, bit_alloc, scale_index, &fr_ps);
  546.  
  547.              if (error_protection) {
  548.                 I_CRC_calc(&fr_ps, bit_alloc, &new_crc);
  549.                 if (new_crc != old_crc) {
  550.                    crc_error_count++;
  551.                    total_error_count++;
  552.                    recover_CRC_error(*pcm_sample, crc_error_count,
  553.                                      &fr_ps, buf, &sample_frames);
  554.                    break;
  555.                 }
  556.                 else crc_error_count = 0;
  557.              }
  558.  
  559.              clip = 0;
  560.              for (i=0;i<SCALE_BLOCK;i++) {
  561.                 I_buffer_sample(&bs,(*sample),bit_alloc,&fr_ps);
  562.                 I_dequantize_sample(*sample,*fraction,bit_alloc,&fr_ps);
  563.                 I_denormalize_sample((*fraction),scale_index,&fr_ps);
  564.                 if(topSb>0)        /* clear channels to 0 */
  565.                    for(j=topSb; j<fr_ps.sblimit; ++j)
  566.                       for(k=0; k<stereo; ++k)
  567.                          (*fraction)[k][0][j] = 0;
  568.  
  569.                 for (j=0;j<stereo;j++) {
  570.                    clip += SubBandSynthesis (&((*fraction)[j][0][0]), j,
  571.                                              &((*pcm_sample)[j][0][0]));
  572.                 }
  573.                 out_fifo(*pcm_sample, 1, &fr_ps, done,
  574.                          buf, &sample_frames);
  575.              }
  576.              if(clip > 0) 
  577.                  {//char m[100];
  578.                   //wsprintf(m,"%d output samples clipped\n", clip);
  579.                   //OutputDebugString(m);
  580.                  }
  581.              break;
  582.           }
  583.  
  584.           case 2: {
  585.              bitsPerSlot = 8;        samplesPerFrame = 1152;
  586.                 II_decode_bitalloc(&bs, bit_alloc, &fr_ps);
  587.              
  588.              II_decode_scale(&bs, scfsi, bit_alloc, scale_index, &fr_ps);
  589.              
  590.              if (error_protection) { 
  591.                 II_CRC_calc(&fr_ps, bit_alloc, scfsi, &new_crc);
  592.                 if (new_crc != old_crc) {
  593.                    crc_error_count++;
  594.                    total_error_count++;
  595.                    recover_CRC_error(*pcm_sample, crc_error_count,
  596.                                      &fr_ps, buf, &sample_frames);
  597.                    break;
  598.                 }
  599.                 else crc_error_count = 0;
  600.              }
  601.                                  
  602.              
  603.              clip = 0;
  604.              for (i=0;i<SCALE_BLOCK;i++) {
  605.              
  606.                 II_buffer_sample(&bs,(*sample),bit_alloc,&fr_ps);
  607.              
  608.                 II_dequantize_sample((*sample),bit_alloc,(*fraction),&fr_ps);
  609.              
  610.                 II_denormalize_sample((*fraction),scale_index,&fr_ps,i>>2);
  611.              
  612.  
  613.                 if(topSb>0)        /* debug : clear channels to 0 */
  614.                    for(j=topSb; j<fr_ps.sblimit; ++j)
  615.                       for(k=0; k<stereo; ++k)
  616.                          (*fraction)[k][0][j] =
  617.                          (*fraction)[k][1][j] =
  618.                          (*fraction)[k][2][j] = 0;
  619.                                              
  620.                                     
  621.                 for (j=0;j<3;j++) for (k=0;k<stereo;k++) {
  622.                    clip += SubBandSynthesis (&((*fraction)[k][j][0]), k,
  623.                                              &((*pcm_sample)[k][j][0]));
  624.                                                     
  625.                                              
  626.                 }                   
  627.                 
  628.                 out_fifo(*pcm_sample, 3, &fr_ps, done, buf,
  629.                          &sample_frames);
  630.                 
  631.              }
  632.              if(clip > 0) 
  633.                  {//char m[100];
  634.                   //wsprintf(m,"%d samples clipped\n", clip);
  635.                   //OutputDebugString(m);
  636.                  }
  637.              break;
  638.           }
  639.  
  640.        }
  641.  
  642.      //{char m[100];
  643.      // wsprintf(m,"bbufat = %ld, bbuflen = %ld, adding, bbuflen now = %ld\n",bbufat,bbuflen,bbuflen+bbufat);
  644.      // OutputDebugString(m);
  645.      //};
  646.       
  647.      bbuflen+=bbufat;
  648.      //ProfStop();          
  649.      return 0;
  650.  
  651. }
  652.  
  653.  
  654. __declspec(dllexport) DWORD FAR PASCAL ReadFilterInput(HANDLE hInput, unsigned char far *bufout, long lBytes)
  655. {       DWORD read=0L;
  656.     if (hInput)
  657.     {   MYINPUT far *mi;
  658.         //char m[100];
  659.         mi=(MYINPUT far *)GlobalLock(hInput);
  660.         
  661.             
  662.        while (bbuflen<lBytes)
  663.        {short er;
  664.           if ((er=CycleToFillMemory())==1)
  665.           {    //wsprintf(m,"End of File, copying %ld bytes of memory to bufout\n",bbuflen);
  666.                //OutputDebugString(m);
  667.                CopyMemory(bufout,memory,(short)bbuflen);
  668.                  return bbufat;
  669.              }      
  670.              if (er==-1) break;
  671.        }    
  672.         
  673.     // have bbuflen bytes at memory,
  674.     // want lBytes bytes at bufout
  675.     
  676.     {short amount;
  677.      //char m[100];
  678.      amount=(short)lBytes;
  679.      if (amount>(short)bbuflen)
  680.          amount=(short)bbuflen;
  681.      //wsprintf(m,"lBytes = %ld, amount = %d (bbuflen=%ld)\n",lBytes,amount,bbuflen);
  682.      //OutputDebugString(m);
  683.      CopyMemory(bufout,memory,amount);        
  684.      //wsprintf(m,"Copied %d bytes from start of memory to bufout\n",amount);
  685.      //OutputDebugString(m);
  686.      MoveMemory(memory,memory+amount,(short)bbuflen-amount);
  687.      //wsprintf(m,"Moved %ld bytes from memory + %d to memory\n",bbuflen-(long)amount,amount);
  688.      //OutputDebugString(m);
  689.      bbuflen-=amount;
  690.      bbufat=amount;    
  691.      //wsprintf(m,"Now bbuflen = %ld, and bbufat = %ld\n",bbuflen,bbufat);
  692.      //OutputDebugString(m);
  693.     };        
  694.     
  695.         
  696.         //wsprintf(m,"ReadFilterInput: Read %ld bytes to bufout\n",bbufat);
  697.         //OutputDebugString(m);
  698.         GlobalUnlock(hInput);
  699.     }
  700.     return bbufat;    
  701. }
  702.