home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / packery / fp_adpcm / x2adpcm / source / x2adpcm.c < prev   
C/C++ Source or Header  |  1977-12-31  |  5KB  |  230 lines

  1.  
  2. /*     Convert any known sample format (datatypes!) to ADPCM    */
  3. /* Written in 1995 by Christian Buchner. This is Public Domain. */
  4.  
  5. /* Note: TAB SIZE = 4 */
  6.  
  7. /* History:
  8.  
  9.    added version string (still V1.0)
  10.    improved datatypes error output (->V1.1)
  11.  
  12. */
  13.  
  14. /* Includes */
  15.  
  16. #include <proto/dos.h>
  17. #include <proto/exec.h>
  18. #include <proto/intuition.h>
  19. #include <proto/datatypes.h>
  20. #include <clib/alib_stdio_protos.h>
  21. #include <libraries/dos.h>
  22. #include <intuition/intuition.h>
  23. #include <exec/io.h>
  24. #include <exec/memory.h>
  25. #include <exec/execbase.h>
  26. #include <datatypes/datatypes.h>
  27. #include <datatypes/datatypesclass.h>
  28. #include <datatypes/soundclass.h>
  29. #include <string.h>
  30. #include <stdarg.h>
  31.  
  32.  
  33. /* Version string */
  34.  
  35. UBYTE Version[]="$VER: X2ADPCM 1.1 "__AMIGADATE__" by Christian Buchner";
  36.  
  37.  
  38. /*******************************************************************************/
  39.  
  40. extern __asm ULONG CompressADPCM2(        register __a0 UBYTE *Source,
  41.                                         register __d0 ULONG Length,
  42.                                         register __a1 UBYTE *Destination,
  43.                                         register __d1 ULONG JoinCode    );
  44.  
  45. extern __asm ULONG CompressADPCM3(        register __a0 UBYTE *Source,
  46.                                         register __d0 ULONG Length,
  47.                                         register __a1 UBYTE *Destination,
  48.                                         register __d1 ULONG JoinCode    );
  49.  
  50. /*******************************************************************************/
  51.  
  52.  
  53. #define INPUT_SIZE 16384
  54.  
  55.  
  56. /* Library bases */
  57.  
  58. struct DosLibrary *DOSBase;
  59. struct Library *DataTypesBase;
  60. struct IntuitionBase *IntuitionBase;
  61.  
  62.  
  63. UBYTE *Template="FROM/A,TO/K/A,BITS/K/N";
  64.  
  65. struct ArgArray
  66. {
  67.     UBYTE *aa_From;
  68.     UBYTE *aa_To;
  69.     ULONG *aa_Bits;
  70. };
  71.  
  72. struct ArgArray AA;
  73. struct RDArgs *RDArgs;
  74. UBYTE ProgName[60];
  75.  
  76. /*******************************************************************************/
  77.  
  78.  
  79. /* void __saveds main() */
  80.  
  81. LONG __saveds main()
  82. {
  83.     ULONG Bits=2;
  84.     
  85.     if (DOSBase=(struct DosLibrary*)OpenLibrary("dos.library",37))
  86.     {
  87.         if (DataTypesBase=OpenLibrary("datatypes.library",39))
  88.         {
  89.             if (!GetProgramName(ProgName,sizeof(ProgName))) strcpy(ProgName,"CDRipper");
  90.             
  91.             if (!(RDArgs=ReadArgs(Template,(LONG *)&AA,0)))
  92.             {
  93.                 PrintFault(IoErr(),ProgName);
  94.             }
  95.             else
  96.             {
  97.                 if (AA.aa_Bits) Bits= *AA.aa_Bits;
  98.                 
  99.                 if (Bits != 2 && Bits != 3)
  100.                 {
  101.                     Printf("Illegal bit number. Use 2 for ADPCM2 and 3 for ADPCM3.\n");
  102.                 }
  103.                 else
  104.                 {
  105.                     Object *Sound;
  106.                     
  107.                     if (Sound=NewDTObject(AA.aa_From, DTA_GroupID, GID_SOUND, TAG_DONE))
  108.                     {
  109.                         UBYTE *Sample;
  110.                         ULONG Length;
  111.                         ULONG Period;
  112.                         
  113.                         if (GetDTAttrs(Sound, SDTA_Sample, &Sample, SDTA_SampleLength, &Length, SDTA_Period, &Period, TAG_DONE) != 3)
  114.                         {
  115.                             Printf("Cannot get sample attributes!\n");
  116.                         }
  117.                         else
  118.                         {
  119.                             UBYTE *ADPCMBuffer;
  120.                             ULONG ADPCMLen;
  121.                             
  122.                             if (Bits==2) ADPCMLen=(INPUT_SIZE+3)/4;
  123.                             if (Bits==3) ADPCMLen=(INPUT_SIZE+7)/8*3;
  124.                             
  125.                             if (!(ADPCMBuffer=AllocVec(ADPCMLen,MEMF_ANY|MEMF_CLEAR)))
  126.                             {
  127.                                 Printf("No memory for ADPCM buffer!\n");
  128.                             }
  129.                             else
  130.                             {
  131.                                 BPTR OutFile;
  132.                                 
  133.                                 if (!(OutFile=Open(AA.aa_To,MODE_NEWFILE)))
  134.                                 {
  135.                                     Printf("Cannot open '%s' for output: ",AA.aa_To);
  136.                                     PrintFault(IoErr(),NULL);
  137.                                 }
  138.                                 else
  139.                                 {
  140.                                     ULONG Frequency=(*(struct ExecBase**)(4))->ex_EClockFrequency*5/Period;
  141.                                     ULONG Offset;
  142.                                     ULONG JoinCode=0;
  143.                                     
  144.                                     if (Bits==2) Write(OutFile,"ADPCM2", 6);
  145.                                     if (Bits==3) Write(OutFile,"ADPCM3", 6);
  146.                                     
  147.                                     Write(OutFile,&Frequency, sizeof(Frequency));
  148.                                     
  149.                                     for (Offset=0; Offset<Length; )
  150.                                     {
  151.                                         ULONG Left=Length-Offset;
  152.                                         ULONG Do = Left < INPUT_SIZE ?
  153.                                                    Left : INPUT_SIZE;
  154.                                         
  155.                                         Printf("\rCompressing/Saving (%02ld%%)",100*Offset/Length);
  156.                                         
  157.                                         if (Bits==2) ADPCMLen=(Do+3)/4;
  158.                                         if (Bits==3) ADPCMLen=(Do+7)/8*3;
  159.                                         
  160.                                         if (Bits==2) JoinCode=CompressADPCM2(Sample+Offset, Do, ADPCMBuffer, JoinCode);
  161.                                         if (Bits==3) JoinCode=CompressADPCM3(Sample+Offset, Do, ADPCMBuffer, JoinCode);
  162.                                         
  163.                                         Write(OutFile, ADPCMBuffer, ADPCMLen);
  164.                                         
  165.                                         Offset+=Do;
  166.                                         
  167.                                         if (CheckSignal(SIGBREAKF_CTRL_C))
  168.                                         {
  169.                                             PrintFault(ERROR_BREAK,NULL);
  170.                                             break;
  171.                                         }
  172.                                     }
  173.                                     Printf("\rCompressing/Saving finished\n",100*(Length-Offset)/Length);
  174.                                     
  175.                                     Close(OutFile);
  176.                                 }
  177.                                 FreeVec(ADPCMBuffer);
  178.                             }
  179.                         }
  180.                         DisposeDTObject(Sound);
  181.                     }
  182.                     else
  183.                     {
  184.                         LONG Error=IoErr();
  185.                         
  186.                         if (Error>=2000)
  187.                         {
  188.                             Printf("%s: ",AA.aa_From);
  189.                             Printf(GetDTString(Error),AA.aa_From);
  190.                             Printf("\n");
  191.                         }
  192.                         else
  193.                         {
  194.                             PrintFault(Error, AA.aa_From);
  195.                         }
  196.                     }
  197.                 }
  198.                 FreeArgs(RDArgs);
  199.             }
  200.             CloseLibrary(DataTypesBase);
  201.         }
  202.         CloseLibrary((struct Library*)DOSBase);
  203.     }
  204. }
  205.  
  206.  
  207. /*******************************************************************************/
  208.  
  209. /* Show a message to the user */
  210.  
  211. void __stdargs Message(UBYTE *Msg,...)
  212. {
  213.     va_list Arg;
  214.     struct EasyStruct Req={sizeof(struct EasyStruct),0,"X2ADPCM message",0,"Okay"};
  215.     Req.es_TextFormat=Msg;
  216.     va_start(Arg,Msg);
  217.     
  218.     if (IntuitionBase)
  219.     {
  220.         EasyRequestArgs(NULL,&Req,0,Arg);
  221.     }
  222.     else
  223.     {
  224.         VPrintf(Msg,Arg);
  225.         Printf("\n");
  226.     }
  227.     
  228.     va_end(Arg);
  229. }
  230.