home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.70.zip / src / ins2snd2.c < prev    next >
C/C++ Source or Header  |  2008-04-01  |  7KB  |  279 lines

  1. /*
  2.  * GoatTracker V2.0 Instrument -> Sound effect convertor
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include "bme_end.h"
  10. #include "gcommon.h"
  11.  
  12. int main(int argc, char **argv);
  13. unsigned char swapnybbles(unsigned char n);
  14. void outputbyte(unsigned char c);
  15.  
  16. int covert = 0;
  17. int binary = 0;
  18. int bytecount = 0;
  19. FILE *handle;
  20. FILE *out;
  21.  
  22. int main(int argc, char **argv)
  23. {
  24.   int c,d;
  25.   int prevwave = 0xff;
  26.   int currwave = 0;
  27.   int fileok = 0;
  28.   INSTR instr;
  29.   int wavelen,pulselen,filtlen;  
  30.   unsigned char ident[4] = {0};
  31.   unsigned char wavetable[MAX_TABLELEN*2];
  32.   unsigned char pulsetable[MAX_TABLELEN*2];
  33.   unsigned char filttable[MAX_TABLELEN*2];
  34.   unsigned char pulse = 0;
  35.  
  36.  
  37.   if (argc < 3)
  38.   {
  39.     printf("Usage: INS2SND2 <instrumentfile> <sourcecodefile> <options>\n"
  40.            "-b Produce binary output\n"
  41.            "-c Produce output in CovertScript format (deprecated)\n\n"
  42.            "Takes a GoatTracker V1.xx or V2 instrument and outputs the corresponding sound\n"
  43.            "effect data as source code (default) or binary. Things that can't be converted\n"
  44.            "and will result in an error:\n"
  45.            "- Waveforms greater than $81\n"
  46.            "- Relative notes\n"
  47.            "- Wavetable longer than 128 bytes\n"
  48.            "- Absolute notes C-0 & C#0\n"
  49.            "Things that will be lost in conversion:\n"
  50.            "- Wavetable loops\n"
  51.            "- Pulsewidth modulation\n"
  52.            "- Filter settings\n");
  53.     return 1;
  54.   }
  55.  
  56.   if (argc > 3)
  57.   {
  58.     for (c = 3; c < argc; c++)
  59.     {
  60.       if (((argv[c][0] == '-') || (argv[c][0] == '/')) && (strlen(argv[c]) > 1))
  61.       {
  62.         int ch = tolower(argv[c][1]);
  63.         switch(ch)
  64.         {
  65.           case 'b':
  66.           binary = 1;
  67.           break;
  68.  
  69.           case 'c':
  70.           covert = 1;
  71.           break;
  72.         }
  73.       }
  74.     }
  75.   }
  76.  
  77.  
  78.   handle = fopen(argv[1], "rb");
  79.   if (!handle)
  80.   {
  81.     printf("ERROR: Can't open instrumentfile\n");
  82.     return 1;
  83.   }
  84.  
  85.   memset(wavetable, 0, MAX_TABLELEN*2);
  86.   memset(pulsetable, 0, MAX_TABLELEN*2);
  87.   memset(filttable, 0, MAX_TABLELEN*2);
  88.  
  89.   fread(ident, 4, 1, handle);
  90.   if (!memcmp(ident, "GTI!", 4))
  91.   {
  92.     fileok = 1;
  93.     instr.ad = fread8(handle);
  94.     instr.sr = fread8(handle);
  95.     pulse = fread8(handle) & 0xfe;
  96.     fread8(handle); // Throw away pulse speed
  97.     fread8(handle); // Throw away pulse limit low
  98.     fread8(handle); // Throw away pulse limit high
  99.     fread8(handle); // Throw away filtersetting
  100.     wavelen = fread8(handle);
  101.     fread(&instr.name, MAX_INSTRNAMELEN, 1, handle);
  102.     fread(wavetable, wavelen, 1, handle);
  103.   }
  104.   if (!memcmp(ident, "GTI2", 4))
  105.   {
  106.     fileok = 1;
  107.     instr.ad = fread8(handle);
  108.     instr.sr = fread8(handle);
  109.     instr.ptr[0] = fread8(handle);
  110.     instr.ptr[1] = fread8(handle);
  111.     instr.ptr[2] = fread8(handle);
  112.     instr.vibdelay = fread8(handle);
  113.     instr.ptr[3] = fread8(handle);
  114.     instr.gatetimer = fread8(handle);
  115.     instr.firstwave = fread8(handle);
  116.     fread(&instr.name, MAX_INSTRNAMELEN, 1, handle);
  117.     wavelen = fread8(handle);
  118.     for (c = 0; c < wavelen; c++)
  119.       wavetable[c*2] = fread8(handle);
  120.     for (c = 0; c < wavelen; c++)
  121.       wavetable[c*2+1] = fread8(handle);
  122.     pulselen = fread8(handle);
  123.     for (c = 0; c < pulselen; c++)
  124.       pulsetable[c*2] = fread8(handle);
  125.     for (c = 0; c < pulselen; c++)
  126.       pulsetable[c*2+1] = fread8(handle);
  127.     filtlen = fread8(handle);
  128.     for (c = 0; c < filtlen; c++)
  129.       filttable[c*2] = fread8(handle);
  130.     for (c = 0; c < filtlen; c++)
  131.       filttable[c*2+1] = fread8(handle);
  132.     pulse = (pulsetable[0] << 4) | (pulsetable[1] >> 4);
  133.   }
  134.   if ((!memcmp(ident, "GTI3", 4)) || (!memcmp(ident, "GTI4", 4) || (!memcmp(ident, "GTI5", 4))))
  135.   {
  136.     fileok = 1;
  137.     instr.ad = fread8(handle);
  138.     instr.sr = fread8(handle);
  139.     instr.ptr[0] = fread8(handle);
  140.     instr.ptr[1] = fread8(handle);
  141.     instr.ptr[2] = fread8(handle);
  142.     instr.ptr[3] = fread8(handle);
  143.     instr.vibdelay = fread8(handle);
  144.     instr.gatetimer = fread8(handle);
  145.     instr.firstwave = fread8(handle);
  146.     fread(&instr.name, MAX_INSTRNAMELEN, 1, handle);
  147.     wavelen = fread8(handle);
  148.     for (c = 0; c < wavelen; c++)
  149.       wavetable[c*2] = fread8(handle);
  150.     for (c = 0; c < wavelen; c++)
  151.       wavetable[c*2+1] = fread8(handle);
  152.     pulselen = fread8(handle);
  153.     for (c = 0; c < pulselen; c++)
  154.       pulsetable[c*2] = fread8(handle);
  155.     for (c = 0; c < pulselen; c++)
  156.       pulsetable[c*2+1] = fread8(handle);
  157.     filtlen = fread8(handle);
  158.     for (c = 0; c < filtlen; c++)
  159.       filttable[c*2] = fread8(handle);
  160.     for (c = 0; c < filtlen; c++)
  161.       filttable[c*2+1] = fread8(handle);
  162.     pulse = (pulsetable[0] << 4) | (pulsetable[1] >> 4);
  163.   }
  164.   fclose(handle);
  165.   if (!fileok)
  166.   {
  167.     printf("ERROR: File is not a GoatTracker instrument!\n");
  168.     return 1;
  169.   }
  170.  
  171.   if (!binary)
  172.     out = fopen(argv[2], "wt");
  173.   else
  174.     out = fopen(argv[2], "wb");
  175.  
  176.   if (!out)
  177.   {
  178.     printf("ERROR: Can't write to output file.\n");
  179.     return 1;
  180.   }
  181.  
  182.   d = 0;
  183.   outputbyte(instr.ad);
  184.   d++;
  185.   outputbyte(instr.sr);
  186.   d++;
  187.   outputbyte(swapnybbles(pulse));
  188.   d++;
  189.  
  190.   for (c = 0; c < MAX_TABLELEN; c++)
  191.   {
  192.     if (wavetable[c*2] == 0xff)
  193.     {
  194.       outputbyte(0);
  195.       d++;
  196.       break;
  197.     }
  198.     if (wavetable[c*2+1] < 0x82)
  199.     {
  200.       printf("ERROR: Relative note or absolute C-0, C#0 found\n");
  201.       fclose(out);
  202.       return 1;
  203.     }
  204.     if (wavetable[c*2] > 0x81)
  205.     {
  206.       printf("ERROR: Waveform greater than $81 found\n");
  207.       fclose(out);
  208.       return 1;
  209.     }
  210.     if (wavetable[c*2])
  211.     {
  212.       currwave = wavetable[c*2];
  213.     }
  214.     outputbyte(wavetable[c*2+1]);
  215.     d++;
  216.     if (currwave != prevwave)
  217.     {
  218.       outputbyte(currwave);
  219.       prevwave = currwave;
  220.       d++;
  221.     }
  222.   }
  223.   if (d > 255)
  224.   {
  225.     fclose(out);
  226.     printf("ERROR: Sound effect exceeds 255 bytes\n");
  227.     return 1;
  228.   }
  229.   fclose(out);
  230.   return 0;
  231. }
  232.  
  233. void outputbyte(unsigned char c)
  234. {
  235.   if (binary)
  236.     fwrite8(out, c);
  237.   else
  238.   {
  239.     if (!covert)
  240.     {
  241.       if (!bytecount)
  242.       {
  243.         fprintf(out, "        dc.b ");
  244.       }
  245.       else fprintf(out, ",");
  246.       fprintf(out, "$%02X", c);
  247.       bytecount++;
  248.       if (bytecount == 16)
  249.       {
  250.         bytecount = 0;
  251.         fprintf(out, "\n");
  252.       }
  253.     }
  254.     else
  255.     {
  256.       if (bytecount)
  257.       {
  258.         fprintf(out,",");
  259.       }
  260.       if (bytecount == 16)
  261.       {
  262.         fprintf(out,"\n");
  263.         bytecount = 0;
  264.       }
  265.       bytecount++;
  266.       fprintf(out, "0x%02x", c);
  267.     }
  268.   }
  269. }
  270.  
  271. unsigned char swapnybbles(unsigned char n)
  272. {
  273.   unsigned char highnybble = n >> 4;
  274.   unsigned char lownybble = n & 0xf;
  275.  
  276.   return (lownybble << 4) | highnybble;
  277. }
  278.  
  279.