home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1998 #5 / AmigaPlus_CD-ROM_Nr.5-98.iso / pd / musik / warpamp / src / main.c < prev    next >
C/C++ Source or Header  |  1998-03-20  |  14KB  |  481 lines

  1.  
  2. #define AUDIO
  3. #define BUFSIZE  18432 * 8
  4.  
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #include <clib/exec_protos.h>
  11. #include <exec/types.h>
  12. #include <exec/libraries.h>
  13. #include <exec/lists.h>
  14. #include <exec/memory.h>
  15. #include <libraries/prelude.h>
  16. #include <clib/prelude_protos.h>
  17. #include <clib/dos_protos.h>
  18. #include <clib/powerpc_protos.h>
  19. #include <powerpc/memoryPPC.h>
  20. #include <clib/asl_protos.h>
  21. #include <libraries/asl.h>
  22. #include <utility/tagitem.h>
  23.  
  24. #include "amp.h"
  25. #include "audio.h"
  26. #include "getbits.h"
  27. #include "huffman.h"
  28. #include "layer2.h"
  29. #include "layer3.h"
  30. #include "transform.h"
  31. #include "misc2.h"
  32. #include "dump.h"
  33.  
  34. extern struct ExecBase *SysBase;
  35. struct PreludeBase *PreludeBase=NULL;
  36.  
  37. UBYTE version [] = "\0$VER: WarpAMP 0.5 (19.3.98)";
  38.  
  39. int    mysignal;
  40. ULONG   Signals;
  41.  
  42. UBYTE   *PlayBuffer[2];
  43. ULONG   Buffer;
  44. ULONG BufferFill;
  45. UBYTE *BufferPointer;
  46.  
  47. ULONG PlayCnt;
  48. ULONG PlayMode;
  49. ULONG PlayFreq;
  50. BOOL snd_eof;
  51. int noout=1;
  52. int ppcmem=1;
  53. int filespec=0;
  54. char infile[1024];
  55. struct FileRequester *smr=0;
  56. char *name;
  57. char fname[1024];
  58. FILE *fp;
  59. char prog[1024];
  60. FILE *fil=0;
  61. int useprog=0;
  62. int repeat=0;
  63. int quit=0;
  64.  
  65. extern struct Library *AslBase;
  66.  
  67. struct TagItem tags[]={
  68. ASLFR_DoPatterns,
  69. 1,
  70. ASLFR_InitialPattern,
  71. (ULONG)"#?.(mpg|mpeg|mp3|mp2)",
  72. ASLFR_DoMultiSelect,1,
  73. 0,0};
  74.  
  75. struct TagItem tags2[]={
  76. ASLFR_DoPatterns,
  77. 1,
  78. ASLFR_InitialPattern,
  79. (ULONG)"#?.(prg)",
  80. 0,0};
  81.  
  82. int main(int argc, char **argv) {
  83.         struct Task *ThisTask;
  84.         struct PrlCtrl *prl;
  85.         BYTE OldPri;
  86.         int f;
  87.  
  88.  AslBase=(struct Library *)OpenLibrary("asl.library",36);
  89.  if (!AslBase)
  90.  {
  91.   printf("Could not open asl.library!\n");
  92.   exit(0);
  93.  }
  94.  
  95.         ThisTask=FindTask(NULL);
  96.  
  97.         PreludeBase=(struct PreludeBase *)OpenLibrary("prelude.library", 2);
  98.         if(PreludeBase==NULL) {
  99.                 fprintf(stderr, "\nError: Can't open prelude.library v2\n\n");
  100.                 return(5);
  101.         }
  102.  
  103.         ppcmem=1;
  104.         filespec=0;
  105.         for (f=1;f<argc;f++)
  106.         {
  107.          if (strstr(argv[f],"-nobat")) ppcmem=0;
  108.          if (!strstr(argv[f],"-")) {strcpy(infile,argv[f]);filespec=1;}
  109.          if (strstr(argv[f],"-program"))
  110.          {
  111.           useprog=1;
  112.           if (f+1<argc) {strcpy(prog,argv[f+1]);useprog=2;}
  113.           f=f+1;
  114.          }
  115.         }
  116.       
  117.         if (!ppcmem)
  118.         {
  119.          PlayBuffer[0]=AllocVecPPC(BUFSIZE, MEMF_CLEAR|MEMF_PUBLIC,8);
  120.          PlayBuffer[1]=AllocVecPPC(BUFSIZE, MEMF_CLEAR|MEMF_PUBLIC,8);
  121.         }
  122.         else
  123.         {
  124.          PlayBuffer[0]=AllocVecPPC(BUFSIZE,MEMF_CLEAR|MEMF_PUBLIC|MEMF_BAT|MEMF_CACHEOFF,8);
  125.          PlayBuffer[1]=AllocVecPPC(BUFSIZE,MEMF_CLEAR|MEMF_PUBLIC|MEMF_BAT|MEMF_CACHEOFF,8);
  126.         }
  127.  
  128.         if(PlayBuffer[0]==NULL || PlayBuffer[1]==NULL) {
  129.                 if(PlayBuffer[0]) FreeVecPPC(PlayBuffer[0]);
  130.                 fprintf(stderr, "\nError: Out of memory for playback buffers\n\n");
  131.                 return(5);
  132.         }
  133.  
  134.         prl=PreludeBase->PrlCtrl;
  135.         prl->PL_SigTask=ThisTask;
  136.         mysignal=AllocSignal(-1);
  137.         prl->PL_SigMask=1L<<mysignal;
  138.  
  139.         A_DUMP_BINARY=FALSE;
  140.         A_QUIET=FALSE;
  141.         A_FORMAT_WAVE=FALSE;
  142.         A_SHOW_CNT=FALSE;
  143.         A_SET_VOLUME=-1;
  144.         A_SHOW_TIME=1;
  145.         A_AUDIO_PLAY=FALSE;
  146.         A_WRITE_TO_FILE=TRUE;
  147.         A_MSG_STDOUT=FALSE;
  148.         A_DOWNMIX=FALSE;
  149.  
  150.  
  151.         initialise_decoder();
  152.  
  153.     
  154.         if ((argc<2)||(!filespec))
  155.         {
  156.          int f;
  157.          smr=AllocAslRequest(ASL_FileRequest,0);
  158.          if (!smr)
  159.          {
  160.           printf("Could not open File-Requester!\n");
  161.           if (AslBase) CloseLibrary(AslBase);
  162.          }
  163.          if (!useprog)
  164.          {
  165.           if (!AslRequest(smr,tags))
  166.           {
  167.            printf("Could not open File-Requester!\n");
  168.            if (AslBase) CloseLibrary(AslBase);
  169.           }
  170.          }
  171.          else if (useprog!=2)
  172.          {
  173.           if (!AslRequest(smr,tags2))
  174.           {
  175.            printf("Could not open File-Requester!\n");
  176.            if (AslBase) CloseLibrary(AslBase);         
  177.           }
  178.           name=&(fname[0]);
  179.           strcpy(name,((struct FileRequester *)smr)->fr_Drawer);
  180.           if (strlen(name)>0)
  181.           if ((name[strlen(name)-1]!='/')&&(name[strlen(name)-1]!=':')) strcat(name,"/");
  182.           strcat(name,smr->fr_File);
  183.           strcpy(prog,name);
  184.          }
  185.  
  186.         }
  187.         Buffer=0;
  188.         BufferPointer=PlayBuffer[0];
  189.         BufferFill=0;
  190.         PlayCnt=0;
  191.  
  192.         fprintf(stderr, "\n\-------------------------------------------\n");
  193.         fprintf(stderr,"WarpAMP 0.5 - 1998, (C) by Steffen Haeuser\n");
  194.         fprintf(stderr,"based on amp (C) Tomislav Uzelac  1996,1997\n");
  195.         fprintf(stderr,"Prelude Play Code based on PreludeAMP which is\n");
  196.         fprintf(stderr,"(C) by Thomas Wenzel\n");
  197.         fprintf(stderr,"Use without infile to invoke Filerequester\n");
  198.         fprintf(stderr,"The Filerequester supports MultiSelect\n");
  199.         fprintf(stderr,"use -program to load a program consisting\n");
  200.         fprintf(stderr,"of a textfile, one title per line\n");
  201.         fprintf(stderr,"use a small-case repeat in the last line\n");
  202.         fprintf(stderr,"to run the program in a loop\n");
  203.         fprintf(stderr,"use -nobat to enable Caches\n");
  204.         fprintf(stderr,"-------------------------------------------\n");
  205.  
  206.         OldPri=SetTaskPri(ThisTask, 5);
  207.  
  208.         if (filespec)
  209.         {
  210.           fp=fopen(infile,"r");
  211.           if (!fp)
  212.           {
  213.            printf("Could not open file %s!\n",name);
  214.            if (AslBase) CloseLibrary(AslBase);
  215.            if (PreludeBase) CloseLibrary((struct Library *)PreludeBase);
  216.            if (smr) FreeAslRequest(smr);
  217.            exit(0);
  218.           }
  219.           else fclose(fp);
  220.           play(infile,0);
  221.           goto endit; // Goto's considered harmful :)
  222.         }
  223.         else if (!useprog)
  224.         {
  225.          for (f=1;f<=smr->fr_NumArgs;f++)
  226.          {
  227.           name=&(fname[0]);
  228.           strcpy(name,((struct FileRequester *)smr)->fr_Drawer);
  229.           if (strlen(name)>0)
  230.           if ((name[strlen(name)-1]!='/')&&(name[strlen(name)-1]!=':')) strcat(name,"/");
  231.           strcat(name,smr->fr_ArgList[f-1].wa_Name);
  232.           fp=fopen(name,"r");
  233.           if (!fp)
  234.           {
  235.            printf("Could not open file %s!\n",name);
  236.            if (AslBase) CloseLibrary(AslBase);
  237.            if (PreludeBase) CloseLibrary((struct Library *)PreludeBase);
  238.            if (smr) FreeAslRequest(smr);
  239.            exit(0);
  240.           }
  241.           else fclose(fp);
  242.           strcpy(infile,name);
  243.           play(infile, 0);
  244.           if (quit) goto endit;
  245.          }
  246.         }
  247.         else
  248.         {
  249.          char test[1024];
  250.          printf("\nPROGRAM: %s\n",prog);
  251. do
  252.         {
  253.          fil=fopen(prog,"r");
  254.          if (fil)
  255.          {
  256.           while(!feof(fil))
  257.           {
  258.            fscanf(fil,"%s",test);
  259.            if ((!feof(fil))&&(!strstr(test,"repeat")))
  260.            {
  261.             fp=fopen(test,"r");
  262.             if (!fp)
  263.             {
  264.              printf("Could not open file %s!\n",test);
  265.              if (AslBase) CloseLibrary(AslBase);
  266.              if (PreludeBase) CloseLibrary((struct Library *)PreludeBase);
  267.              if (smr) FreeAslRequest(smr);
  268.              exit(0);
  269.             }
  270.             else fclose(fp);
  271.             strcpy(infile,test);
  272.             play(infile,0);
  273.             if (quit) goto endit;
  274.            }
  275.            else if (strstr(test,"repeat"))
  276.            {
  277.             repeat=1;
  278.            }
  279.           }
  280.          }
  281.          else printf("Could not open Program File!!!\n");
  282.         } while(repeat);
  283.         if (fil) fclose(fil);
  284.        }
  285. endit:
  286.         SetTaskPri(ThisTask, OldPri);
  287.  
  288.         PrlStop(0);
  289.         KillPrlPlayList();
  290.         FreeVecPPC(PlayBuffer[0]);
  291.         FreeVecPPC(PlayBuffer[1]);
  292.         if(mysignal != -1) FreeSignal(mysignal);
  293.  
  294.         if (smr) FreeAslRequest(smr);
  295.         if (PreludeBase) CloseLibrary((struct Library *) PreludeBase);
  296.         if (AslBase) CloseLibrary((struct Library *)AslBase);
  297.         return(0);
  298. }
  299.  
  300.  
  301.  
  302. /* call this once at the beginning */
  303. void initialise_decoder(void) {
  304.         premultiply();
  305.         imdct_init();
  306.         calculate_t43();
  307. }
  308.  
  309. /* call this before each file is played */
  310. void initialise_globals(void) {
  311.         append=data=nch=0; 
  312.         f_bdirty=TRUE;
  313.         bclean_bytes=0;
  314.  
  315.         memset(s,0,sizeof s);
  316.         memset(res,0,sizeof res);
  317. }
  318.  
  319.  
  320. void play(char *inFileStr, char *outFileStr) {
  321.         if (strcmp(inFileStr,"-")==0) {
  322.                 in_file=stdin;
  323.         }
  324.         else {
  325.                 if ((in_file=fopen(inFileStr,"r"))==NULL) {
  326.                         fprintf(stderr, "Could not open file: %s\n",inFileStr);
  327.                         return;
  328.                 }
  329.         }
  330.         if (outFileStr) {
  331.                 if (strcmp(outFileStr,"-")==0)
  332.                         {out_file=stdout;noout=1;}
  333.         else
  334.                 {
  335.                  if ((out_file=fopen(outFileStr,"w"))==NULL) {
  336.                         fprintf(stderr, "Could not write to file: %s\n",outFileStr);
  337.                         return;
  338.                  }
  339.                  noout=0;
  340.                 }
  341.         }
  342.  
  343.         decodeMPEG();
  344.         
  345.         fclose(in_file);
  346.         if ((!A_AUDIO_PLAY)&&(!noout)) fclose(out_file);
  347.         fprintf(stderr, "\n");
  348. }
  349.  
  350. int decodeMPEG(void) {
  351.         struct AUDIO_HEADER header;
  352.         int cnt=0,g;
  353.  
  354.         initialise_globals();
  355.  
  356.         if ((g=gethdr(&header))!=0) {
  357.                 report_header_error(g);
  358.                 return -1;
  359.         }
  360.  
  361.         if (header.protection_bit==0) getcrc();
  362.  
  363.         show_header(&header);
  364.  
  365.         if (header.layer==1) {
  366.                 if (layer3_frame(&header,cnt)) {
  367.                         fprintf(stderr, " error. blip.\n");
  368.                         return -1;
  369.                 }
  370.         } else if (header.layer==2)
  371.                 if (layer2_frame(&header,cnt)) {
  372.                         fprintf(stderr, " error. blip.\n");
  373.                         return -1;
  374.                 }
  375.  
  376.  
  377.         if (nch==2) PlayMode = PRL_FMT | PRL_FMTX | PRL_Stereo;
  378.         else        PlayMode = PRL_FMT | PRL_FMTX;
  379.         PlayFreq=t_sampling_frequency[header.ID][header.sampling_frequency];
  380.  
  381.         /*
  382.          * decoder loop **********************************
  383.          */
  384.         snd_eof=FALSE;
  385.         cnt=0;
  386.         while (!snd_eof) {
  387.                 while (!snd_eof) {
  388.                         if ((g=gethdr(&header))!=0) {
  389.                         report_header_error(g);
  390.                                 snd_eof=TRUE;
  391.                                 break;
  392.       }
  393.  
  394.                         if (header.protection_bit==0) getcrc();
  395.  
  396.                         statusDisplay(&header,cnt);     
  397.  
  398.                         if (header.layer==1) {
  399.                                 if (layer3_frame(&header,cnt)) {
  400.                                         fprintf(stderr, " error. blip.\n");
  401.                                         return -1;
  402.                                 }
  403.                         } else if (header.layer==2)
  404.                                 if (layer2_frame(&header,cnt)) {
  405.                                         fprintf(stderr, " error. blip.\n");
  406.                                         return -1;
  407.                                 }
  408.                         cnt++;
  409.                 }
  410.         }
  411.         return 0;
  412. }
  413.  
  414. void report_header_error(int err) {
  415.         switch (err) {
  416.                 case GETHDR_ERR: fprintf(stderr, "error reading mpeg bitstream. exiting.\n");
  417.                                  break;
  418.                 case GETHDR_NS:  fprintf(stderr, "this is a file in MPEG 2.5 format, which is not defined\n");
  419.                                  fprintf(stderr, "by ISO/MPEG. It is \"a special Fraunhofer format\".\n");
  420.                                  fprintf(stderr, "amp does not support this format. sorry.\n");
  421.                                  break;
  422.                 case GETHDR_FL1: fprintf(stderr, "ISO/MPEG layer 1 is not supported by amp (yet).\n");
  423.                                  break;
  424.                 case GETHDR_FF:  fprintf(stderr, "free format bitstreams are not supported. sorry.\n");
  425.                                  break; 
  426.                 case GETHDR_SYN: fprintf(stderr, "oops, we're out of sync.\n");
  427.                      break;
  428.                 case GETHDR_EOF: break;
  429.         }       
  430. }
  431.  
  432.  
  433. void statusDisplay(struct AUDIO_HEADER *header, int frameNo) {
  434.         int minutes,seconds;
  435.  
  436.         if ((A_SHOW_CNT || A_SHOW_TIME) && !(frameNo%10))
  437.                 fprintf(stderr, "\r");
  438.         if (A_SHOW_CNT && !(frameNo%10) ) {
  439.                 fprintf(stderr, "Frame { %d } ",frameNo);
  440.         }
  441.         if (A_SHOW_TIME && !(frameNo%10)) {
  442.                 seconds=frameNo*1152/t_sampling_frequency[header->ID][header->sampling_frequency];
  443.                 minutes=seconds/60;
  444.                 seconds=seconds % 60;
  445.                 fprintf(stderr, "Time [%d:%02d]", minutes, seconds);
  446.         }
  447.         if (A_SHOW_CNT || A_SHOW_TIME)
  448.                 fflush(stderr);
  449. }
  450.  
  451. BOOL WayBehind=FALSE;
  452. void printout(void) {
  453.         int len;
  454.         int j;
  455.  
  456.         if (nch==2) j=32 * 18 * 2;
  457.         else        j=32 * 18;
  458.  
  459.         len=sizeof(short)*j;
  460.  
  461.         memcpy(BufferPointer, sample_buffer, len);
  462.         BufferPointer += len;
  463.         BufferFill    += len;
  464.  
  465.         if(BufferFill >= BUFSIZE) {
  466.                 PrlPlay(PlayBuffer[Buffer], BUFSIZE, PlayMode, PlayFreq);
  467.                 Buffer=1-Buffer;
  468.  
  469.                 BufferPointer=PlayBuffer[Buffer];
  470.                 BufferFill=0;
  471.  
  472.                 PlayCnt++;
  473.                 if(PlayCnt >1) Signals=Wait(1L<<mysignal | SIGBREAKF_CTRL_C);
  474.  
  475.                 if(Signals & SIGBREAKF_CTRL_C) {snd_eof=TRUE;quit=1;}
  476.         }
  477. }
  478.  
  479. void die(char *str, ...) {
  480. }
  481.