home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Sound / DelfMPEG / src / DelfMPEG.c < prev    next >
C/C++ Source or Header  |  1999-10-27  |  25KB  |  714 lines

  1. /*****************************************************************************
  2.  
  3.     DelfMPEG - MPEG audio player for Delfina DSP
  4.     Copyright (C) 1999  Michael Henke
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. *****************************************************************************/
  21.  
  22.  
  23.  
  24. #define DELFINA_SAMPLES 1152
  25. #define LOADBUFFERS     256     /* number of segments in ring buffer */
  26. #define BUFFERSIZE      1792    /* MPG_MAXFRAMESIZE */
  27.  
  28. #include <proto/exec.h>
  29. #include <proto/dos.h>
  30. #include <proto/asyncio.h>
  31. #include <proto/timer.h>
  32. #include <proto/reqtools.h>
  33. #include <exec/interrupts.h>
  34. #include <exec/execbase.h>
  35. #include <libraries/asyncio.h>
  36. #include <devices/timer.h>
  37. #include <libraries/reqtools.h>
  38. #include <math.h>
  39. #include <limits.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42.  
  43. static UBYTE version[]="$VER: DelfMPEG 0.2 (Wed 27-Oct-1999)";
  44. static UBYTE template[]="FILES/M,VERBOSE/S,NOPLAY/S,SHOWTAG/S,NOFASTL/S,NOFASTP/S";
  45.  
  46. struct loadbuf {
  47.     UBYTE *ptr;
  48.     ULONG framesize, delfcopysize, header;
  49.     UWORD layer, mode, modext, freq, errprot, br_ind, crc;
  50.     UWORD sblimit, jsbound, translate;
  51.     struct loadbuf *next;
  52. };
  53.  
  54. struct loadbuf load_buf[LOADBUFFERS], *curr_load, *curr_play;
  55. far UBYTE load_memory[BUFFERSIZE*LOADBUFFERS];
  56.  
  57. static ULONG mpg_freq[4]={44100,48000,32000,77777};
  58. static UBYTE *mpg_modename[4]={"stereo   ","j-stereo ","dual-ch  ","single-ch"};
  59. static UBYTE *mpg_layername[3]={"I  ","II ","III"};
  60. static UWORD mpg_bitrate[3][16]=
  61.         { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, /* I */
  62.           {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},   /* II */
  63.           {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0} }; /* III */
  64. static UWORD mpg_translate[3][2][16] =
  65.            { { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } ,    /* 44100 stereo */
  66.                { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } ,  /* 44100 mono   */
  67.              { { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } ,    /* 48000 stereo */
  68.                { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } ,  /* 48000 mono   */
  69.              { { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } ,    /* 32000 stereo */
  70.                { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } }; /* 32000 mono   */
  71. static UWORD mpg_sblimit[4]={27,30,8,12};
  72.  
  73. static ULONG ID3v1_TAG;
  74. static UBYTE ID3v1_buffer[142];
  75.  
  76. #define SBLIMIT                 32
  77. #define SCALE_BLOCK             12
  78. #define SSLIMIT                 18
  79. #define MPG_MD_STEREO           0
  80. #define MPG_MD_JOINT_STEREO     1
  81. #define MPG_MD_DUAL_CHANNEL     2
  82. #define MPG_MD_MONO             3
  83. #define HDR_MPEG1               0xfff80000
  84. #define HDR_CONSTANT            0x00060c00  /* layer, sampling frequency */
  85. #define ID3V1                   0x54414700  /* TAG */
  86. #define ID3V2                   0x49443300  /* ID3 */
  87.  
  88. UBYTE get_delfina_48khz[32];    /* input buffer for GetVar() */
  89. ULONG delfina_48khz=0;
  90.  
  91. extern struct DelfObj DSP56K_PCM;
  92. extern struct DelfObj DSP56K_MP2;
  93. extern struct DelfObj DSP56K_MP3;
  94.  
  95. #include <libraries/delfina.h>
  96.  
  97. extern struct ExecBase *SysBase;
  98. struct Library *DelfinaBase=NULL;
  99. struct Library *AsyncIOBase=NULL;
  100. struct Library *TimerBase=NULL;
  101. struct ReqToolsBase *ReqToolsBase=NULL;
  102.  
  103. struct AsyncFile *file;
  104. struct FileInfoBlock *fib=NULL;
  105. struct TagItem tag_done={TAG_DONE};
  106. UBYTE rtfilename[128]={0};
  107. struct Task *mytask;
  108. ULONG bytes_total, bytes_loaded, buffers_filled, buffers_missed;
  109. ULONG firstheader, prevheader, currheader, frames_loaded, frames_played;
  110. struct Interrupt delfint={0};
  111. struct DelfPrg *prg_pcm=NULL, *prg_mp2=NULL, *prg_mp3=NULL;
  112. struct DelfModule *mod_pcm=NULL;
  113. DELFPTR mem_mp2=NULL, mem_mp2p=NULL;
  114. int key=0;
  115.  
  116. ULONG mono,freq,layer,pause,noplay,showtag;
  117. ULONG verbose, ende=0, havetag, nofastl, nofastp;
  118. int rc=0;
  119.  
  120.  
  121.  
  122.  
  123.  
  124. /*
  125. **
  126. ** Delfina interrupt server **
  127. **
  128. */
  129. void int_server(void)
  130. {
  131.     if(pause)
  132.     {
  133.         /*
  134.         ** mute **
  135.         */
  136.         Delf_Run( prg_pcm->prog+2, 99, DRUNF_ASYNCH, 0, 0, 0, 0 );
  137.     }
  138.     else
  139.     {
  140.         if(buffers_filled>0)
  141.         {
  142.             switch(layer)
  143.             {
  144.                 case 2:
  145.                     /*
  146.                     ** send framedata to Delfina and launch MP2 decoder **
  147.                     */
  148.                     Delf_CopyMem( curr_play->ptr,
  149.                                   (void*)(prg_mp2->xdata+2048),
  150.                                   curr_play->delfcopysize,
  151.                                   DCPF_FROM_AMY|DCPF_XDATA|DCPF_24BIT );
  152.                     Delf_Run( prg_mp2->prog+2, 99, DRUNF_ASYNCH,
  153.                               mono,
  154.                               Delf_Peek(prg_pcm->ydata,DMEMF_YDATA),
  155.                               curr_play->translate,
  156.                               curr_play->jsbound );
  157.                     break;
  158.                 case 3:
  159.                     /*
  160.                     ** send framedata to Delfina and launch MP3 decoder **
  161.                     */
  162. /**********************
  163.                     Delf_CopyMem( curr_play->ptr,
  164.                                   (void*)prg_mp3->ydata,
  165.                                   curr_play->delfcopysize,
  166.                                   DCPF_FROM_AMY|DCPF_YDATA|DCPF_24BIT );
  167.                     Delf_Run( prg_mp3->prog+2, 99, DRUNF_ASYNCH,
  168.                               mono,
  169.                               Delf_Peek(prg_pcm->ydata,DMEMF_YDATA),
  170.                               0,0 );
  171. **********************/
  172.                     break;
  173.                 default:
  174.                     break;
  175.             }
  176.             frames_played++;
  177.             buffers_filled--;
  178.             curr_play=curr_play->next;
  179.         }
  180.         else buffers_missed++;
  181.     }
  182. }
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189. /*
  190. **
  191. ** allocate Delfina resources **
  192. **
  193. */
  194. int init_delfina(void)
  195. {
  196.     if(noplay) return(0);
  197.  
  198.     if(!(prg_pcm=Delf_AddPrg(&DSP56K_PCM))) {
  199.         printf("**not enough Delfina memory\n");
  200.         return(0);
  201.     }
  202.     Delf_Run(prg_pcm->prog,0,0,mono,0,freq,0);
  203.  
  204.     switch(layer)
  205.     {
  206.         case 2:
  207.             if(!nofastl) mem_mp2 =Delf_AllocMem( 96, DMEMF_LDATA|DMEMF_INTERNAL|DMEMF_ALIGN_64 );
  208.             if(!nofastp) mem_mp2p=Delf_AllocMem( 32, DMEMF_PROG |DMEMF_INTERNAL );
  209.             prg_mp2 =Delf_AddPrg( &DSP56K_MP2 );
  210.             if( !prg_mp2 ) {
  211.                 printf("**not enough Delfina memory\n");
  212.                 return(0);
  213.             }
  214.             Delf_Run( prg_mp2->prog, 0, 0, mem_mp2, mem_mp2p, 0, 0 );
  215.             if( (!mem_mp2 && !nofastl) || (!mem_mp2p && !nofastp) ) {
  216.                 printf("warning: not enough internal DSP memory\n"
  217.                        "the MPEG decoder might run too slow and could even crash!\n");
  218.             }
  219.             break;
  220.         case 3:
  221.             printf("**layer %d decoder is not implemented yet\n",layer);
  222.             return(0);
  223. /****************
  224.             if(!(prg_mp3=Delf_AddPrg(&DSP56K_MP3))) {
  225.                 printf("**not enough Delfina memory\n");
  226.                 return(0);
  227.             }
  228.             Delf_Run( prg_mp3->prog, 0, 0, 0, 0, 0, 0 );
  229. ****************/
  230.             break;
  231.         default:
  232.             printf("**layer %d is currently not supported\n",layer);
  233.             return(0);
  234.     }
  235.  
  236.     if(!(mod_pcm=Delf_AddModule( DM_Inputs, 0,
  237.                                 DM_Outputs, 1,
  238.                                 DM_Code, prg_pcm->prog+4,
  239.                                 DM_Freq, 48000,     /* always 48kHz output */
  240.                                 DM_Name, "DelfMPEG", 0)))
  241.     {
  242.         printf("**couldn't create DelfModule\n");
  243.         return(0);
  244.     }
  245.  
  246.     delfint.is_Code=(void(*)(void))int_server;
  247.     if (!(key=Delf_AddIntServer(prg_pcm->prog,&delfint))) {
  248.         printf("**couldn't create interrupt server\n");
  249.         return(0);
  250.     }
  251.  
  252.     return(1);
  253. }
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260. /*
  261. **
  262. ** free Delfina resources **
  263. **
  264. */
  265. void cleanup_delfina(void)
  266. {
  267.     Disable();
  268.     if (key)     { Delf_RemIntServer(key);  key=0; }
  269.     if (mod_pcm) { Delf_RemModule(mod_pcm); mod_pcm=NULL; }
  270.     if (prg_pcm) { Delf_RemPrg(prg_pcm);    prg_pcm=NULL; }
  271.     if (prg_mp2) { Delf_RemPrg(prg_mp2);    prg_mp2=NULL; }
  272.     if (prg_mp3) { Delf_RemPrg(prg_mp3);    prg_mp3=NULL; }
  273.     if (mem_mp2) { Delf_FreeMem(mem_mp2,DMEMF_LDATA|DMEMF_INTERNAL); mem_mp2=NULL; }
  274.     if (mem_mp2p){ Delf_FreeMem(mem_mp2p,DMEMF_PROG|DMEMF_INTERNAL); mem_mp2p=NULL; }
  275.     Enable();
  276. }
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284. /*
  285. **
  286. ** analyze frame header and load frame **
  287. **
  288. */
  289. int read_frame(struct loadbuf *lb)
  290. {
  291.     /** let's ignore these header infos (we don't need them here)
  292.     *** ->version, ->extension, ->copyright, ->original, ->emphasis **/
  293.     lb->header  = currheader;
  294.     lb->layer   = 4-((currheader>>17)&3);
  295.     lb->mode    = ((currheader>>6)&0x3);
  296.     lb->modext  = ((currheader>>4)&0x3);
  297.     lb->br_ind  = ((currheader>>12)&0xf);
  298.     lb->freq    = ((currheader>>10)&0x3);
  299.     lb->errprot = ((currheader>>16)&0x1)^0x1;
  300.  
  301.     lb->translate= mpg_translate[lb->freq]
  302.                                 [(lb->mode==MPG_MD_MONO)?1:0]
  303.                                 [lb->br_ind];
  304.     lb->sblimit = mpg_sblimit[lb->translate];
  305.     lb->jsbound = (lb->mode==MPG_MD_JOINT_STEREO) ?
  306.                             (lb->modext<<2)+4 : lb->sblimit;
  307.  
  308.     lb->framesize = (mpg_bitrate[lb->layer-1][lb->br_ind]*144000)
  309.                     /mpg_freq[lb->freq] + ((currheader>>9)&0x1); /* padding */
  310.     lb->delfcopysize = lb->framesize-4;
  311.     if(lb->errprot)
  312.     {
  313.         ReadAsync(file,&lb->crc,2);
  314.         lb->delfcopysize-=2;
  315.     }
  316.     ReadAsync(file,lb->ptr,lb->delfcopysize);
  317.     return(0);
  318. }
  319.  
  320.  
  321.  
  322.  
  323.     
  324.  
  325.  
  326. int main(void)
  327. {
  328.     struct RDArgs *rdargs;
  329.     LONG args[6]={0,0,0,0,0,0}, r1, i, taskpri;
  330.     ULONG sigs;
  331.     UBYTE **files_pt, *filename;
  332.     double duration, duration2;
  333.     ULONG minutes, seconds, millisec;
  334.     struct timeval time1,time2;
  335.     struct rtFileRequester *rtfilereq=NULL;
  336.     struct rtFileList *rtfilelist=NULL, *rtfilelist_curr=NULL;
  337.     BPTR lock_newdir=NULL, lock_olddir=NULL;
  338.     
  339.     /*
  340.     **
  341.     ** read args **
  342.     **
  343.     */
  344.     printf("\33[1m%s by Smack/Infect!\33[0m\n",&version[6]);
  345.     rdargs=ReadArgs(template,args,NULL);
  346.     files_pt=(char**)args[0];
  347.     verbose=args[1];
  348.     noplay=args[2];
  349.     showtag=args[3];
  350.     nofastl=args[4];
  351.     nofastp=args[5];
  352.  
  353.     if(verbose)
  354.         printf(
  355.         "\n"
  356.         "  DelfMPEG - MPEG audio player for Delfina DSP\n"
  357.         "  Copyright (C) 1999  Michael Henke\n"
  358.         "\n"
  359.         "  This program is free software; you can redistribute it and/or modify\n"
  360.         "  it under the terms of the GNU General Public License as published by\n"
  361.         "  the Free Software Foundation; either version 2 of the License, or\n"
  362.         "  (at your option) any later version.\n"
  363.         "\n"
  364.         "  This program is distributed in the hope that it will be useful,\n"
  365.         "  but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
  366.         "  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
  367.         "  GNU General Public License for more details.\n"
  368.         "\n"
  369.         "  You should have received a copy of the GNU General Public License\n"
  370.         "  along with this program; if not, write to the Free Software\n"
  371.         "  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
  372.         "\n"  );
  373.  
  374.  
  375.     /*
  376.     **
  377.     ** open libraries & stuff **
  378.     **
  379.     */
  380.     if(!noplay)
  381.     {
  382.         if (!(DelfinaBase=OpenLibrary("delfina.library",4))) {
  383.             printf("**unable to open delfina.library V4\n");
  384.             rc=20;
  385.             goto exit_clean;
  386.         }
  387.     }
  388.     if (!(AsyncIOBase=OpenLibrary("asyncio.library",39))) {
  389.         printf("**unable to open asyncio.library V39\n");
  390.         rc=20;
  391.         goto exit_clean;
  392.     }
  393.     TimerBase=(struct Library*)FindName(&SysBase->DeviceList,"timer.device");
  394.     if(0<(GetVar("DELFINA_48KHZ",get_delfina_48khz,32,LV_VAR)))
  395.     {
  396.         delfina_48khz=strtoul(get_delfina_48khz,NULL,10);
  397.         if(verbose) printf("  ////read ENV: DELFINA_48KHZ = '%s' (%ldHz)\n",get_delfina_48khz,delfina_48khz);
  398.         if(delfina_48khz==ULONG_MAX) delfina_48khz=0;
  399.     }
  400.     mytask=FindTask(NULL);
  401.     if(!(fib=AllocDosObject(DOS_FIB,&tag_done)))
  402.     {
  403.         rc=20;
  404.         goto exit_clean;
  405.     }
  406.  
  407.     /*
  408.     **
  409.     ** init load buffers **
  410.     **
  411.     */
  412.     for(i=0;i<LOADBUFFERS;i++)
  413.     {
  414.         load_buf[i].ptr =&load_memory[i*BUFFERSIZE];
  415.         load_buf[i].next=&load_buf[i+1];
  416.     }
  417.     load_buf[LOADBUFFERS-1].next=&load_buf[0];
  418.  
  419.     /*
  420.     **
  421.     ** reqtools filerequester if no files specified **
  422.     **
  423.     */
  424.     if(!files_pt)
  425.     {
  426.         if((ReqToolsBase=(struct ReqToolsBase*)OpenLibrary("reqtools.library",38)))
  427.         {
  428.             if(!(rtfilereq=rtAllocRequest(RT_FILEREQ,NULL)))
  429.             {
  430.                 rc=10;
  431.                 goto exit_clean;
  432.             }
  433.         }
  434.         else
  435.         {
  436.             rc=5;
  437.             goto exit_clean;
  438.         }
  439.     }
  440.  
  441. next_filereq:
  442.     if(rtfilereq)
  443.     {
  444.         rtfilelist=rtFileRequest( rtfilereq, &rtfilename[0],
  445.                                   "DelfMPEG: select MPEG audio files",
  446.                                   RTFI_Flags, FREQF_MULTISELECT|FREQF_PATGAD,
  447.                                   TAG_DONE );
  448.         if(rtfilelist)
  449.         {
  450.             rtfilelist_curr=rtfilelist;
  451.             if(rtfilereq->Dir)
  452.             {
  453.                 lock_newdir=Lock(rtfilereq->Dir,SHARED_LOCK);
  454.                 lock_olddir=CurrentDir(lock_newdir);
  455.             }
  456.         }
  457.         else goto exit_clean;
  458.     }
  459.  
  460.     /*
  461.     **
  462.     ** files loop **
  463.     **
  464.     */
  465.     do
  466.     {
  467.         /*
  468.         **
  469.         ** get next filename **
  470.         **
  471.         */
  472.         if(rtfilelist)
  473.         {
  474.             if(rtfilelist_curr)
  475.             {
  476.                 filename=rtfilelist_curr->Name;
  477.                 rtfilelist_curr=rtfilelist_curr->Next;
  478.             }
  479.             else filename=NULL;
  480.         }
  481.         else filename=(*files_pt++);
  482.         if(!filename) break;
  483.         printf("\n  file: %s\n",filename);
  484.  
  485.         curr_load=curr_play=&load_buf[0];
  486.         bytes_loaded=buffers_filled=buffers_missed=0;
  487.         firstheader=prevheader=currheader=0;
  488.         frames_loaded=frames_played=0;
  489.         pause=1;
  490.  
  491.         /*
  492.         **
  493.         ** open file **
  494.         **
  495.         */
  496.         if((file=OpenAsync(filename,MODE_READ,128*1024)))
  497.         {
  498.             /*
  499.             **
  500.             ** read first frame **
  501.             **
  502.             */
  503.             ExamineFH(file->af_File,fib);
  504.             bytes_total=fib->fib_Size;
  505.             r1=ReadAsync(file,&currheader,4);
  506.             if( (r1==4) &&
  507.                 ((currheader&HDR_MPEG1)==HDR_MPEG1) )
  508.             {
  509.                 if(showtag)
  510.                 {
  511.                     SeekAsync(file, -128, MODE_END);
  512.                     ID3v1_TAG=0; havetag=0;
  513.                     ReadAsync(file, &ID3v1_TAG, 3);
  514.                     if((ID3v1_TAG&ID3V1)==ID3V1)
  515.                     {
  516.                         ReadAsync(file,&ID3v1_buffer[00],30); /* title  */
  517.                         ReadAsync(file,&ID3v1_buffer[31],30); /* artist */
  518.                         ReadAsync(file,&ID3v1_buffer[62],30); /* album  */
  519.                         ReadAsync(file,&ID3v1_buffer[93],04); /* year   */
  520.                         ReadAsync(file,&ID3v1_buffer[98],30); /* comment*/
  521.                         ReadAsync(file,&ID3v1_buffer[141],1); /* genre  */
  522.                         for(i=0;i<124;i++)
  523.                         {
  524.                             if(ID3v1_buffer[i]<0x20) ID3v1_buffer[i]=0x20;
  525.                         }
  526.                         ID3v1_buffer[30]=0x00;
  527.                         ID3v1_buffer[30+1+30]=0x00;
  528.                         ID3v1_buffer[30+1+30+1+30]=0x00;
  529.                         ID3v1_buffer[30+1+30+1+30+1+4]=0x00;
  530.                         ID3v1_buffer[30+1+30+1+30+1+4+1+30]=0x00;
  531.                         havetag=1;
  532.                     }
  533.                     SeekAsync(file, 4, MODE_START);
  534.                 }
  535.  
  536.                 read_frame(curr_load);
  537.  
  538.                 freq=mpg_freq[curr_load->freq];
  539.                 mono=(curr_load->mode==MPG_MD_MONO) ? 1 : 0;
  540.                 layer=curr_load->layer;
  541.                 duration=(double)bytes_total/((double)freq/1152.0)/(double)curr_load->framesize;
  542.                 printf("  type: layer %s %03dkbps %ldHz %s\n",
  543.                             mpg_layername[layer-1],
  544.                             mpg_bitrate[layer-1][curr_load->br_ind],
  545.                             freq,
  546.                             mpg_modename[curr_load->mode] );
  547.                 millisec=(ULONG)(1000.0*modf(duration,&duration2));
  548.                 minutes=(ULONG)(duration2/60.0);
  549.                 seconds=(ULONG)(duration2-minutes*60.0);
  550.                 printf("  time: %02ld min %02ld.%03ld sec\n",minutes,seconds,millisec);
  551.                 if(verbose) printf("  ////filesize/framesize: %ld/%ld bytes\n",bytes_total,curr_load->framesize);
  552.                 if(delfina_48khz)
  553.                 {
  554.                     freq=(ULONG)((double)freq*48000.0/(double)delfina_48khz);
  555.                     if(verbose) printf("  ////adjusted freq: %ldHz\n",freq);
  556.                 }
  557.  
  558.                 if(showtag && havetag)
  559.                 {
  560.                     printf( "  TAG ID3v1\n      title: %s\n     artist: %s\n"
  561.                             "      album: %s\n    comment: %s\n"
  562.                             "       year: %s    genre: %d\n",
  563.                             &ID3v1_buffer[00], /* title  */
  564.                             &ID3v1_buffer[31], /* artist */
  565.                             &ID3v1_buffer[62], /* album  */
  566.                             &ID3v1_buffer[98], /* comment*/
  567.                             &ID3v1_buffer[93], /* year   */
  568.                             (int)ID3v1_buffer[141] ); /* genre  */
  569.                 }
  570.  
  571.                 firstheader=prevheader=currheader;
  572.                 buffers_filled++;
  573.                 frames_loaded++;
  574.                 bytes_loaded+=curr_load->framesize;
  575.                 curr_load=curr_load->next;
  576.  
  577.                 if( init_delfina() )
  578.                 {
  579.                     printf("  playing..."); fflush(stdout);
  580.                     taskpri=SetTaskPri(mytask,9);
  581.                     pause=0;
  582.                     GetSysTime(&time1);
  583.                     /*
  584.                     **
  585.                     ** frames loop **
  586.                     **
  587.                     */
  588.                     while(!ende)
  589.                     {
  590.                         sigs=mytask->tc_SigRecvd;
  591.                         if(sigs&SIGBREAKF_CTRL_C)
  592.                         {
  593.                             printf(" break CTRL-C\n");
  594.                             mytask->tc_SigRecvd&=!SIGBREAKF_CTRL_C;
  595.                             pause=1;
  596.                             break;  /* exit frames loop */
  597.                         }
  598.                         if(sigs&SIGBREAKF_CTRL_D)
  599.                         {
  600.                             printf(" break CTRL-D\n");
  601.                             mytask->tc_SigRecvd&=!SIGBREAKF_CTRL_D;
  602.                             pause=1;
  603.                             ende=1;
  604.                             break;  /* exit frames loop */
  605.                         }
  606.                         if(sigs&SIGBREAKF_CTRL_E)
  607.                         {
  608.                             mytask->tc_SigRecvd&=!SIGBREAKF_CTRL_E;
  609.                             if(pause)
  610.                             {
  611.                                 printf("\n  playing..."); fflush(stdout);
  612.                                 pause=0;
  613.                             }
  614.                             else
  615.                             {
  616.                                 pause=1;
  617.                                 printf(" pause"); fflush(stdout);
  618.                             }
  619.                         }
  620.                         if( (buffers_filled<LOADBUFFERS) &&
  621.                             (bytes_loaded<bytes_total) )
  622.                         {
  623.                             r1=ReadAsync(file,&currheader,4);
  624.                             if( (r1==4) &&
  625.                                 ((currheader&HDR_MPEG1)==HDR_MPEG1) )
  626.                             {
  627.                                 if((currheader&HDR_CONSTANT)==(prevheader&HDR_CONSTANT))
  628.                                 {
  629.                                     read_frame(curr_load);
  630. /*    printf("//////sblimit/jsbound/alloc_table: %d/%d/%d\n",curr_load->sblimit,curr_load->jsbound,curr_load->translate);*/
  631.                                     prevheader=currheader;
  632.                                     buffers_filled++;
  633.                                     frames_loaded++;
  634.                                     bytes_loaded+=curr_load->framesize;
  635.                                     curr_load=curr_load->next;
  636.                                 }
  637.                                 else
  638.                                 {
  639.                                     printf(" (invalid MPEG file)");
  640.                                     if(verbose)
  641.                                         printf("\n  **position=0x%08lx  currheader=0x%08lx\n  ",bytes_loaded,currheader);
  642.                                     bytes_loaded=bytes_total; /* force EOF */
  643.                                     fflush(stdout);
  644.                                 }
  645.                             }
  646.                             else  /* frame header error */
  647.                             {
  648.                                 if(r1==4)
  649.                                 {
  650.                                     printf(" (non-audio data)");
  651.                                     if(verbose)
  652.                                         printf("\n  ////position=0x%08lx  currheader=0x%08lx\n  ",bytes_loaded,currheader);
  653.                                 }
  654.                                 bytes_loaded=bytes_total;   /* force EOF */
  655.                                 fflush(stdout);
  656.                             }
  657.                         }
  658.                         else
  659.                         {
  660.                             if( (bytes_loaded>=bytes_total) &&
  661.                                 (frames_played>=frames_loaded) )
  662.                             {
  663.                                 printf(" done\n");
  664.                                 pause=1;
  665.                                 break;  /* exit frames loop */
  666.                             }
  667.                             Delay(1);
  668.                         }
  669.                     }
  670.                     GetSysTime(&time2);
  671.                     SetTaskPri(mytask,taskpri);
  672.                     if((buffers_missed>1) && verbose)
  673.                     {
  674.                         printf("  note: irq was missing data %ld times\n",buffers_missed-1);
  675.                     }
  676.                     SubTime(&time2,&time1);
  677.                     millisec=(ULONG)((double)time2.tv_micro/1000.0);
  678.                     minutes=(ULONG)((double)time2.tv_secs/60.0);
  679.                     seconds=(ULONG)((double)time2.tv_secs-minutes*60.0);
  680.                     duration2=(double)time2.tv_secs+(double)time2.tv_micro/1000000.0;
  681.                     if(verbose)
  682.                     {
  683.                         printf("  ////frames played/loaded: %ld/%ld\n",frames_played,frames_loaded);
  684.                         printf("  ////elapsed time: %02ld min %02ld.%03ld sec\n",minutes, seconds, millisec);
  685.                     }
  686.                 }
  687.                 cleanup_delfina();
  688.             }
  689.             else printf("**MPEG file not recognized\n");
  690.             CloseAsync(file);
  691.         }
  692.         else printf("**unable to open file\n");
  693.         cleanup_delfina();
  694.     } while(!ende);
  695.  
  696.     if(rtfilelist)
  697.     {
  698.         if(lock_olddir) { CurrentDir(lock_olddir); lock_olddir=NULL; }
  699.         if(lock_newdir) { UnLock(lock_newdir); lock_newdir=NULL; }
  700.         rtFreeFileList(rtfilelist); rtfilelist=NULL;
  701.         if(!ende) goto next_filereq;
  702.     }
  703.  
  704. exit_clean:
  705.     if(rdargs) FreeArgs(rdargs);
  706.     if(fib) FreeDosObject(DOS_FIB,fib);
  707.     if(rtfilereq) rtFreeRequest(rtfilereq);
  708.     if(ReqToolsBase) CloseLibrary((struct Library*)ReqToolsBase);
  709.     if(AsyncIOBase) CloseLibrary(AsyncIOBase);
  710.     if(DelfinaBase) CloseLibrary(DelfinaBase);
  711.     return(rc);
  712. }
  713.  
  714.