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